pcm_arm.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:8k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: pcm_arm.c 304 2005-10-20 11:02:59Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "../dyncode/dyncode.h"
  25. #include "pcm_soft.h"
  26. #if defined(ARM)
  27. typedef struct stack
  28. {
  29. int StackFrame[STACKFRAME];
  30. //void* this   R0
  31. //plane Dst    R1
  32. //plane Src    R2
  33. //int DstLength R3
  34. pcmstate* State;
  35. int Volume;
  36. } stack;
  37. // R0,R1 dither 
  38. // R2,R3 value
  39. // R4 Min
  40. // R5 Max
  41. // R6 tmp
  42. // R7 Step
  43. // R8 Pos
  44. // R9 SrcLeft
  45. // R10 SrcRight
  46. // R11 DstLeft
  47. // R12 DstRight
  48. // R14 DstLeftEnd
  49. void PCMLoop(pcm_soft* p,bool_t Speed)
  50. {
  51. dyninst* Loop;
  52. reg Left;
  53. reg Right;
  54. Loop = Label(1);
  55. Left = R2;
  56. if (p->UseLeft)
  57. Right = R3;
  58. else
  59. Right = R2;
  60. if (Speed)
  61. {
  62. I3S(MOV,R3,NONE,R8,LSR,8);
  63. switch (p->Src.Bits)
  64. {
  65. case 8:
  66. if (p->SrcUnsigned)
  67. {
  68. if (p->UseLeft)
  69. {
  70. Byte(); I3S(LDR,Left,R9,R3,LSL,p->SrcShift);
  71. }
  72. if (p->UseRight)
  73. {
  74. Byte(); I3S(LDR,Right,R10,R3,LSL,p->SrcShift);
  75. }
  76. }
  77. else
  78. {
  79. I3S(MOV,R3,NONE,R3,LSL,p->SrcShift);
  80. if (p->UseLeft)
  81. {
  82. SByte(); I3(LDR,Left,R9,R3);
  83. }
  84. if (p->UseRight)
  85. {
  86. SByte(); I3(LDR,Right,R10,R3);
  87. }
  88. }
  89. break;
  90. case 16:
  91. I3S(MOV,R3,NONE,R3,LSL,p->SrcShift);
  92. if (p->UseLeft)
  93. {
  94. if (p->SrcUnsigned || p->SrcSwap) Half(); else SHalf();
  95. I3(LDR,Left,R9,R3);
  96. if (p->SrcSwap)
  97. {
  98. I3S(MOV,R6,NONE,Left,LSL,24);
  99. I3S(MOV,Left,NONE,Left,LSR,8);
  100. if (p->SrcUnsigned)
  101. I3S(ORR,Left,Left,R6,LSR,16);
  102. else
  103. I3S(ORR,Left,Left,R6,ASR,16);
  104. }
  105. }
  106. if (p->UseRight)
  107. {
  108. if (p->SrcUnsigned || p->SrcSwap) Half(); else SHalf();
  109. I3(LDR,Right,R10,R3);
  110. if (p->SrcSwap)
  111. {
  112. I3S(MOV,R6,NONE,Right,LSL,24);
  113. I3S(MOV,Right,NONE,Right,LSR,8);
  114. if (p->SrcUnsigned)
  115. I3S(ORR,Right,Right,R6,LSR,16);
  116. else
  117. I3S(ORR,Right,Right,R6,ASR,16);
  118. }
  119. }
  120. break;
  121. case 32:
  122. if (p->UseLeft)
  123. I3S(LDR,Left,R9,R3,LSL,p->SrcShift);
  124. if (p->UseRight)
  125. I3S(LDR,Right,R10,R3,LSL,p->SrcShift);
  126. break;
  127. }
  128. I3(ADD,R8,R8,R7);
  129. }
  130. else
  131. {
  132. switch (p->Src.Bits)
  133. {
  134. case 8:
  135. if (p->UseLeft)
  136. {
  137. if (p->SrcUnsigned) Byte(); else SByte();
  138. I2C(LDR_POST,Left,R9,1<<p->SrcShift);
  139. }
  140. if (p->UseRight)
  141. {
  142. if (p->SrcUnsigned) Byte(); else SByte();
  143. I2C(LDR_POST,Right,R10,1<<p->SrcShift);
  144. }
  145. break;
  146. case 16:
  147. if (p->UseLeft)
  148. {
  149. if (p->SrcUnsigned || p->SrcSwap) Half(); else SHalf();
  150. I2C(LDR_POST,Left,R9,1<<p->SrcShift);
  151. if (p->SrcSwap)
  152. {
  153. I3S(MOV,R6,NONE,Left,LSL,24);
  154. I3S(MOV,Left,NONE,Left,LSR,8);
  155. if (p->SrcUnsigned)
  156. I3S(ORR,Left,Left,R6,LSR,16);
  157. else
  158. I3S(ORR,Left,Left,R6,ASR,16);
  159. }
  160. }
  161. if (p->UseRight)
  162. {
  163. if (p->SrcUnsigned || p->SrcSwap) Half(); else SHalf();
  164. I2C(LDR_POST,Right,R10,1<<p->SrcShift);
  165. if (p->SrcSwap)
  166. {
  167. I3S(MOV,R6,NONE,Right,LSL,24);
  168. I3S(MOV,Right,NONE,Right,LSR,8);
  169. if (p->SrcUnsigned)
  170. I3S(ORR,Right,Right,R6,LSR,16);
  171. else
  172. I3S(ORR,Right,Right,R6,ASR,16);
  173. }
  174. }
  175. break;
  176. case 32:
  177. if (p->UseLeft)
  178. I2C(LDR_POST,Left,R9,1<<p->SrcShift);
  179. if (p->UseRight)
  180. I2C(LDR_POST,Right,R10,1<<p->SrcShift);
  181. break;
  182. }
  183. }
  184. if (p->SrcUnsigned) 
  185. {
  186. I2C(SUB,R2,R2,p->SrcUnsigned);
  187. if (p->SrcChannels>1)
  188. I2C(SUB,R3,R3,p->SrcUnsigned);
  189. }
  190. if (p->Stereo)
  191. {
  192. if ((p->Src.Flags ^ p->Dst.Flags) & PCM_SWAPPEDSTEREO)
  193. {
  194. Left = R3;
  195. Right = R2;
  196. }
  197. else
  198. {
  199. Left = R2;
  200. Right = R3;
  201. }
  202. }
  203. else
  204. {
  205. if (p->Join)
  206. I3(ADD,R2,R2,R3);
  207. Right = Left = R2;
  208. }
  209. if (p->ActualDither)
  210. {
  211. I3(ADD,R2,R2,R0);
  212. I3(MOV,R0,NONE,R2);
  213. if (p->Stereo) 
  214. {
  215. I3(ADD,R3,R3,R1);
  216. I3(MOV,R1,NONE,R3);
  217. }
  218. }
  219. if (p->UseVolume)
  220. {
  221. if (p->Src.Bits >= 23)
  222. I3S(MOV,R2,NONE,R2,ASR,8);
  223. I3(MUL,R2,R0,R2);
  224. if (p->Stereo)
  225. {
  226. if (p->Src.Bits >= 23)
  227. I3S(MOV,R3,NONE,R3,ASR,8);
  228. I3(MUL,R3,R0,R3);
  229. }
  230. }
  231. if (p->Clip>0)
  232. {
  233. I3(CMP,NONE,R2,R4);
  234. C(LT); I3(MOV,R2,NONE,R4);
  235. I3(CMP,NONE,R2,R5);
  236. C(GT); I3(MOV,R2,NONE,R5);
  237. if (p->Stereo)
  238. {
  239. I3(CMP,NONE,R3,R4);
  240. C(LT); I3(MOV,R3,NONE,R4);
  241. I3(CMP,NONE,R3,R5);
  242. C(GT); I3(MOV,R3,NONE,R5);
  243. }
  244. }
  245. if (p->Shift)
  246. {
  247. I3S(MOV,R2,NONE,R2,ASR,-p->Shift);
  248. if (p->Stereo) I3S(MOV,R3,NONE,R3,ASR,-p->Shift);
  249. }
  250. #ifdef TARGET_PALMOS
  251. if (p->LifeDriveFix)
  252. {
  253. I3S(ADD,R6,R2,R1,LSL,1);
  254. I3S(CMP,NONE,R6,R1,LSL,2);
  255. C(LS); I2C(ORR,R2,R2,R0);
  256. if (p->Stereo)
  257. {
  258. I3S(ADD,R6,R3,R1,LSL,1);
  259. I3S(CMP,NONE,R6,R1,LSL,2);
  260. C(LS); I3(ORR,R3,R3,R0);
  261. }
  262. }
  263. #endif
  264. if (p->ActualDither)
  265. {
  266. I3S(SUB,R0,R0,R2,ASR,p->Shift);
  267. if (p->Stereo) I3S(SUB,R1,R1,R3,ASR,p->Shift);
  268. }
  269. if (p->DstUnsigned) 
  270. {
  271. I2C(ADD,Left,Left,p->DstUnsigned);
  272. if (Left != Right)
  273. I2C(ADD,Right,Right,p->DstUnsigned);
  274. }
  275. switch (p->Dst.Bits)
  276. {
  277. case 8:
  278. Byte(); I2C(STR_POST,Left,R11,1<<p->DstShift);
  279. if (p->Dst.Channels>1)
  280. {
  281. Byte(); I2C(STR_POST,Right,R12,1<<p->DstShift);
  282. }
  283. break;
  284. case 16:
  285. Half(); I2C(STR_POST,Left,R11,1<<p->DstShift);
  286. if (p->Dst.Channels>1)
  287. {
  288. Half(); I2C(STR_POST,Right,R12,1<<p->DstShift);
  289. }
  290. break;
  291. case 32:
  292. I2C(STR_POST,Left,R11,1<<p->DstShift);
  293. if (p->Dst.Channels>1)
  294. I2C(STR_POST,Right,R12,1<<p->DstShift);
  295. break;
  296. }
  297. I3(CMP,NONE,R11,R14);
  298. I0P(B,NE,Loop);
  299. if (p->ActualDither)
  300. {
  301. I2C(LDR,R4,SP,OFS(stack,State));
  302. I2C(STR,R0,R4,OFS(pcmstate,Dither[0]));
  303. I2C(STR,R1,R4,OFS(pcmstate,Dither[1]));
  304. }
  305. CodeEnd();
  306. }
  307. void PCMCompile(pcm_soft* p)
  308. {
  309. dyninst* Speed;
  310. dyninst* Min = NULL;
  311. dyninst* Max = NULL;
  312. CodeBegin();
  313. // dst pointers
  314. I2C(LDR,R11,R1,0);
  315. if (p->Dst.Channels > 1)
  316. {
  317. if (p->Dst.Flags & PCM_PLANES)
  318. I2C(LDR,R12,R1,4);
  319. else
  320. I2C(ADD,R12,R11,1<<(p->DstShift-1));
  321. }
  322. I3(ADD,R14,R11,R3); // dstend
  323. // src pointers
  324. I2C(LDR,R9,R2,0);
  325. if (p->Src.Channels > 1)
  326. {
  327. if (p->Src.Flags & PCM_PLANES)
  328. I2C(LDR,R10,R2,4);
  329. else
  330. I2C(ADD,R10,R9,p->Src.Bits>>3);
  331. }
  332. I2C(LDR,R4,SP,OFS(stack,State));
  333. I2C(LDR,R7,R4,OFS(pcmstate,Step));
  334. I2C(LDR,R8,R4,OFS(pcmstate,Pos));
  335. #ifdef TARGET_PALMOS
  336. if (p->LifeDriveFix)
  337. {
  338. I2C(LDR,R1,SP,OFS(stack,Volume));
  339. I2C(MOV,R0,NONE,63);
  340. I2C(CMP,NONE,R1,25);
  341. C(GT); I2C(MOV,R0,NONE,31);
  342. I2C(CMP,NONE,R1,50);
  343. C(GT); I2C(MOV,R0,NONE,15);
  344. I2C(CMP,NONE,R1,100);
  345. C(GT); I2C(MOV,R0,NONE,7);
  346. I2C(CMP,NONE,R1,200);
  347. C(GT); I2C(MOV,R0,NONE,3);
  348. I2C(ADD,R1,R0,1);
  349. }
  350. #endif
  351. if (p->UseVolume)
  352. I2C(LDR,R0,SP,OFS(stack,Volume));
  353. if (p->ActualDither)
  354. {
  355. I2C(LDR,R0,R4,OFS(pcmstate,Dither[0]));
  356. I2C(LDR,R1,R4,OFS(pcmstate,Dither[1]));
  357. }
  358. if (p->Clip>0)
  359. {
  360. Min = InstCreate32(p->MinLimit,NONE,NONE,NONE,0,0);
  361. Max = InstCreate32(p->MaxLimit,NONE,NONE,NONE,0,0);
  362. I1P(LDR,R4,Min,0);
  363. I1P(LDR,R5,Max,0);
  364. }
  365. Speed = Label(0);
  366. I2C(CMP,NONE,R7,256);
  367. I0P(B,NE,Speed);
  368. PCMLoop(p,0);
  369. InstPost(Speed);
  370. PCMLoop(p,1);
  371. if (Min) InstPost(Min);
  372. if (Max) InstPost(Max);
  373. }
  374. #endif