converter.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #include "config.h"
  2. #include "converter.h"
  3. #include "fpu_modes.h"
  4. #include "mixer/defs.h"
  5. SampleConverter *CreateSampleConverter(enum DevFmtType srcType, enum DevFmtType dstType, ALsizei numchans, ALsizei srcRate, ALsizei dstRate)
  6. {
  7. SampleConverter *converter;
  8. ALsizei step;
  9. if(numchans <= 0 || srcRate <= 0 || dstRate <= 0)
  10. return NULL;
  11. converter = al_calloc(16, FAM_SIZE(SampleConverter, Chan, numchans));
  12. converter->mSrcType = srcType;
  13. converter->mDstType = dstType;
  14. converter->mNumChannels = numchans;
  15. converter->mSrcTypeSize = BytesFromDevFmt(srcType);
  16. converter->mDstTypeSize = BytesFromDevFmt(dstType);
  17. converter->mSrcPrepCount = 0;
  18. converter->mFracOffset = 0;
  19. /* Have to set the mixer FPU mode since that's what the resampler code expects. */
  20. START_MIXER_MODE();
  21. step = (ALsizei)mind(((ALdouble)srcRate/dstRate*FRACTIONONE) + 0.5,
  22. MAX_PITCH * FRACTIONONE);
  23. converter->mIncrement = maxi(step, 1);
  24. if(converter->mIncrement == FRACTIONONE)
  25. converter->mResample = Resample_copy_C;
  26. else
  27. {
  28. /* TODO: Allow other resamplers. */
  29. BsincPrepare(converter->mIncrement, &converter->mState.bsinc, &bsinc12);
  30. converter->mResample = SelectResampler(BSinc12Resampler);
  31. }
  32. END_MIXER_MODE();
  33. return converter;
  34. }
  35. void DestroySampleConverter(SampleConverter **converter)
  36. {
  37. if(converter)
  38. {
  39. al_free(*converter);
  40. *converter = NULL;
  41. }
  42. }
  43. static inline ALfloat Sample_ALbyte(ALbyte val)
  44. { return val * (1.0f/128.0f); }
  45. static inline ALfloat Sample_ALubyte(ALubyte val)
  46. { return Sample_ALbyte((ALint)val - 128); }
  47. static inline ALfloat Sample_ALshort(ALshort val)
  48. { return val * (1.0f/32768.0f); }
  49. static inline ALfloat Sample_ALushort(ALushort val)
  50. { return Sample_ALshort((ALint)val - 32768); }
  51. static inline ALfloat Sample_ALint(ALint val)
  52. { return (val>>7) * (1.0f/16777216.0f); }
  53. static inline ALfloat Sample_ALuint(ALuint val)
  54. { return Sample_ALint(val - INT_MAX - 1); }
  55. static inline ALfloat Sample_ALfloat(ALfloat val)
  56. { return val; }
  57. #define DECL_TEMPLATE(T) \
  58. static inline void Load_##T(ALfloat *restrict dst, const T *restrict src, \
  59. ALint srcstep, ALsizei samples) \
  60. { \
  61. ALsizei i; \
  62. for(i = 0;i < samples;i++) \
  63. dst[i] = Sample_##T(src[i*srcstep]); \
  64. }
  65. DECL_TEMPLATE(ALbyte)
  66. DECL_TEMPLATE(ALubyte)
  67. DECL_TEMPLATE(ALshort)
  68. DECL_TEMPLATE(ALushort)
  69. DECL_TEMPLATE(ALint)
  70. DECL_TEMPLATE(ALuint)
  71. DECL_TEMPLATE(ALfloat)
  72. #undef DECL_TEMPLATE
  73. static void LoadSamples(ALfloat *dst, const ALvoid *src, ALint srcstep, enum DevFmtType srctype, ALsizei samples)
  74. {
  75. switch(srctype)
  76. {
  77. case DevFmtByte:
  78. Load_ALbyte(dst, src, srcstep, samples);
  79. break;
  80. case DevFmtUByte:
  81. Load_ALubyte(dst, src, srcstep, samples);
  82. break;
  83. case DevFmtShort:
  84. Load_ALshort(dst, src, srcstep, samples);
  85. break;
  86. case DevFmtUShort:
  87. Load_ALushort(dst, src, srcstep, samples);
  88. break;
  89. case DevFmtInt:
  90. Load_ALint(dst, src, srcstep, samples);
  91. break;
  92. case DevFmtUInt:
  93. Load_ALuint(dst, src, srcstep, samples);
  94. break;
  95. case DevFmtFloat:
  96. Load_ALfloat(dst, src, srcstep, samples);
  97. break;
  98. }
  99. }
  100. static inline ALbyte ALbyte_Sample(ALfloat val)
  101. { return fastf2i(clampf(val*128.0f, -128.0f, 127.0f)); }
  102. static inline ALubyte ALubyte_Sample(ALfloat val)
  103. { return ALbyte_Sample(val)+128; }
  104. static inline ALshort ALshort_Sample(ALfloat val)
  105. { return fastf2i(clampf(val*32768.0f, -32768.0f, 32767.0f)); }
  106. static inline ALushort ALushort_Sample(ALfloat val)
  107. { return ALshort_Sample(val)+32768; }
  108. static inline ALint ALint_Sample(ALfloat val)
  109. { return fastf2i(clampf(val*16777216.0f, -16777216.0f, 16777215.0f)) << 7; }
  110. static inline ALuint ALuint_Sample(ALfloat val)
  111. { return ALint_Sample(val)+INT_MAX+1; }
  112. static inline ALfloat ALfloat_Sample(ALfloat val)
  113. { return val; }
  114. #define DECL_TEMPLATE(T) \
  115. static inline void Store_##T(T *restrict dst, const ALfloat *restrict src, \
  116. ALint dststep, ALsizei samples) \
  117. { \
  118. ALsizei i; \
  119. for(i = 0;i < samples;i++) \
  120. dst[i*dststep] = T##_Sample(src[i]); \
  121. }
  122. DECL_TEMPLATE(ALbyte)
  123. DECL_TEMPLATE(ALubyte)
  124. DECL_TEMPLATE(ALshort)
  125. DECL_TEMPLATE(ALushort)
  126. DECL_TEMPLATE(ALint)
  127. DECL_TEMPLATE(ALuint)
  128. DECL_TEMPLATE(ALfloat)
  129. #undef DECL_TEMPLATE
  130. static void StoreSamples(ALvoid *dst, const ALfloat *src, ALint dststep, enum DevFmtType dsttype, ALsizei samples)
  131. {
  132. switch(dsttype)
  133. {
  134. case DevFmtByte:
  135. Store_ALbyte(dst, src, dststep, samples);
  136. break;
  137. case DevFmtUByte:
  138. Store_ALubyte(dst, src, dststep, samples);
  139. break;
  140. case DevFmtShort:
  141. Store_ALshort(dst, src, dststep, samples);
  142. break;
  143. case DevFmtUShort:
  144. Store_ALushort(dst, src, dststep, samples);
  145. break;
  146. case DevFmtInt:
  147. Store_ALint(dst, src, dststep, samples);
  148. break;
  149. case DevFmtUInt:
  150. Store_ALuint(dst, src, dststep, samples);
  151. break;
  152. case DevFmtFloat:
  153. Store_ALfloat(dst, src, dststep, samples);
  154. break;
  155. }
  156. }
  157. ALsizei SampleConverterAvailableOut(SampleConverter *converter, ALsizei srcframes)
  158. {
  159. ALint prepcount = converter->mSrcPrepCount;
  160. ALsizei increment = converter->mIncrement;
  161. ALsizei DataPosFrac = converter->mFracOffset;
  162. ALuint64 DataSize64;
  163. if(prepcount < 0)
  164. {
  165. /* Negative prepcount means we need to skip that many input samples. */
  166. if(-prepcount >= srcframes)
  167. return 0;
  168. srcframes += prepcount;
  169. prepcount = 0;
  170. }
  171. if(srcframes < 1)
  172. {
  173. /* No output samples if there's no input samples. */
  174. return 0;
  175. }
  176. if(prepcount < MAX_RESAMPLE_PADDING*2 &&
  177. MAX_RESAMPLE_PADDING*2 - prepcount >= srcframes)
  178. {
  179. /* Not enough input samples to generate an output sample. */
  180. return 0;
  181. }
  182. DataSize64 = prepcount;
  183. DataSize64 += srcframes;
  184. DataSize64 -= MAX_RESAMPLE_PADDING*2;
  185. DataSize64 <<= FRACTIONBITS;
  186. DataSize64 -= DataPosFrac;
  187. /* If we have a full prep, we can generate at least one sample. */
  188. return (ALsizei)clampu64((DataSize64 + increment-1)/increment, 1, BUFFERSIZE);
  189. }
  190. ALsizei SampleConverterInput(SampleConverter *converter, const ALvoid **src, ALsizei *srcframes, ALvoid *dst, ALsizei dstframes)
  191. {
  192. const ALsizei SrcFrameSize = converter->mNumChannels * converter->mSrcTypeSize;
  193. const ALsizei DstFrameSize = converter->mNumChannels * converter->mDstTypeSize;
  194. const ALsizei increment = converter->mIncrement;
  195. ALsizei pos = 0;
  196. START_MIXER_MODE();
  197. while(pos < dstframes && *srcframes > 0)
  198. {
  199. ALfloat *restrict SrcData = ASSUME_ALIGNED(converter->mSrcSamples, 16);
  200. ALfloat *restrict DstData = ASSUME_ALIGNED(converter->mDstSamples, 16);
  201. ALint prepcount = converter->mSrcPrepCount;
  202. ALsizei DataPosFrac = converter->mFracOffset;
  203. ALuint64 DataSize64;
  204. ALsizei DstSize;
  205. ALint toread;
  206. ALsizei chan;
  207. if(prepcount < 0)
  208. {
  209. /* Negative prepcount means we need to skip that many input samples. */
  210. if(-prepcount >= *srcframes)
  211. {
  212. converter->mSrcPrepCount = prepcount + *srcframes;
  213. *srcframes = 0;
  214. break;
  215. }
  216. *src = (const ALbyte*)*src + SrcFrameSize*-prepcount;
  217. *srcframes += prepcount;
  218. converter->mSrcPrepCount = 0;
  219. continue;
  220. }
  221. toread = mini(*srcframes, BUFFERSIZE - MAX_RESAMPLE_PADDING*2);
  222. if(prepcount < MAX_RESAMPLE_PADDING*2 &&
  223. MAX_RESAMPLE_PADDING*2 - prepcount >= toread)
  224. {
  225. /* Not enough input samples to generate an output sample. Store
  226. * what we're given for later.
  227. */
  228. for(chan = 0;chan < converter->mNumChannels;chan++)
  229. LoadSamples(&converter->Chan[chan].mPrevSamples[prepcount],
  230. (const ALbyte*)*src + converter->mSrcTypeSize*chan,
  231. converter->mNumChannels, converter->mSrcType, toread
  232. );
  233. converter->mSrcPrepCount = prepcount + toread;
  234. *srcframes = 0;
  235. break;
  236. }
  237. DataSize64 = prepcount;
  238. DataSize64 += toread;
  239. DataSize64 -= MAX_RESAMPLE_PADDING*2;
  240. DataSize64 <<= FRACTIONBITS;
  241. DataSize64 -= DataPosFrac;
  242. /* If we have a full prep, we can generate at least one sample. */
  243. DstSize = (ALsizei)clampu64((DataSize64 + increment-1)/increment, 1, BUFFERSIZE);
  244. DstSize = mini(DstSize, dstframes-pos);
  245. for(chan = 0;chan < converter->mNumChannels;chan++)
  246. {
  247. const ALbyte *SrcSamples = (const ALbyte*)*src + converter->mSrcTypeSize*chan;
  248. ALbyte *DstSamples = (ALbyte*)dst + converter->mDstTypeSize*chan;
  249. const ALfloat *ResampledData;
  250. ALsizei SrcDataEnd;
  251. /* Load the previous samples into the source data first, then the
  252. * new samples from the input buffer.
  253. */
  254. memcpy(SrcData, converter->Chan[chan].mPrevSamples,
  255. prepcount*sizeof(ALfloat));
  256. LoadSamples(SrcData + prepcount, SrcSamples,
  257. converter->mNumChannels, converter->mSrcType, toread
  258. );
  259. /* Store as many prep samples for next time as possible, given the
  260. * number of output samples being generated.
  261. */
  262. SrcDataEnd = (DataPosFrac + increment*DstSize)>>FRACTIONBITS;
  263. if(SrcDataEnd >= prepcount+toread)
  264. memset(converter->Chan[chan].mPrevSamples, 0,
  265. sizeof(converter->Chan[chan].mPrevSamples));
  266. else
  267. {
  268. size_t len = mini(MAX_RESAMPLE_PADDING*2, prepcount+toread-SrcDataEnd);
  269. memcpy(converter->Chan[chan].mPrevSamples, &SrcData[SrcDataEnd],
  270. len*sizeof(ALfloat));
  271. memset(converter->Chan[chan].mPrevSamples+len, 0,
  272. sizeof(converter->Chan[chan].mPrevSamples) - len*sizeof(ALfloat));
  273. }
  274. /* Now resample, and store the result in the output buffer. */
  275. ResampledData = converter->mResample(&converter->mState,
  276. SrcData+MAX_RESAMPLE_PADDING, DataPosFrac, increment,
  277. DstData, DstSize
  278. );
  279. StoreSamples(DstSamples, ResampledData, converter->mNumChannels,
  280. converter->mDstType, DstSize);
  281. }
  282. /* Update the number of prep samples still available, as well as the
  283. * fractional offset.
  284. */
  285. DataPosFrac += increment*DstSize;
  286. converter->mSrcPrepCount = mini(prepcount + toread - (DataPosFrac>>FRACTIONBITS),
  287. MAX_RESAMPLE_PADDING*2);
  288. converter->mFracOffset = DataPosFrac & FRACTIONMASK;
  289. /* Update the src and dst pointers in case there's still more to do. */
  290. *src = (const ALbyte*)*src + SrcFrameSize*(DataPosFrac>>FRACTIONBITS);
  291. *srcframes -= mini(*srcframes, (DataPosFrac>>FRACTIONBITS));
  292. dst = (ALbyte*)dst + DstFrameSize*DstSize;
  293. pos += DstSize;
  294. }
  295. END_MIXER_MODE();
  296. return pos;
  297. }
  298. ChannelConverter *CreateChannelConverter(enum DevFmtType srcType, enum DevFmtChannels srcChans, enum DevFmtChannels dstChans)
  299. {
  300. ChannelConverter *converter;
  301. if(srcChans != dstChans && !((srcChans == DevFmtMono && dstChans == DevFmtStereo) ||
  302. (srcChans == DevFmtStereo && dstChans == DevFmtMono)))
  303. return NULL;
  304. converter = al_calloc(DEF_ALIGN, sizeof(*converter));
  305. converter->mSrcType = srcType;
  306. converter->mSrcChans = srcChans;
  307. converter->mDstChans = dstChans;
  308. return converter;
  309. }
  310. void DestroyChannelConverter(ChannelConverter **converter)
  311. {
  312. if(converter)
  313. {
  314. al_free(*converter);
  315. *converter = NULL;
  316. }
  317. }
  318. #define DECL_TEMPLATE(T) \
  319. static void Mono2Stereo##T(ALfloat *restrict dst, const T *src, ALsizei frames)\
  320. { \
  321. ALsizei i; \
  322. for(i = 0;i < frames;i++) \
  323. dst[i*2 + 1] = dst[i*2 + 0] = Sample_##T(src[i]) * 0.707106781187f; \
  324. } \
  325. \
  326. static void Stereo2Mono##T(ALfloat *restrict dst, const T *src, ALsizei frames)\
  327. { \
  328. ALsizei i; \
  329. for(i = 0;i < frames;i++) \
  330. dst[i] = (Sample_##T(src[i*2 + 0])+Sample_##T(src[i*2 + 1])) * \
  331. 0.707106781187f; \
  332. }
  333. DECL_TEMPLATE(ALbyte)
  334. DECL_TEMPLATE(ALubyte)
  335. DECL_TEMPLATE(ALshort)
  336. DECL_TEMPLATE(ALushort)
  337. DECL_TEMPLATE(ALint)
  338. DECL_TEMPLATE(ALuint)
  339. DECL_TEMPLATE(ALfloat)
  340. #undef DECL_TEMPLATE
  341. void ChannelConverterInput(ChannelConverter *converter, const ALvoid *src, ALfloat *dst, ALsizei frames)
  342. {
  343. if(converter->mSrcChans == converter->mDstChans)
  344. {
  345. LoadSamples(dst, src, 1, converter->mSrcType,
  346. frames*ChannelsFromDevFmt(converter->mSrcChans, 0));
  347. return;
  348. }
  349. if(converter->mSrcChans == DevFmtStereo && converter->mDstChans == DevFmtMono)
  350. {
  351. switch(converter->mSrcType)
  352. {
  353. case DevFmtByte:
  354. Stereo2MonoALbyte(dst, src, frames);
  355. break;
  356. case DevFmtUByte:
  357. Stereo2MonoALubyte(dst, src, frames);
  358. break;
  359. case DevFmtShort:
  360. Stereo2MonoALshort(dst, src, frames);
  361. break;
  362. case DevFmtUShort:
  363. Stereo2MonoALushort(dst, src, frames);
  364. break;
  365. case DevFmtInt:
  366. Stereo2MonoALint(dst, src, frames);
  367. break;
  368. case DevFmtUInt:
  369. Stereo2MonoALuint(dst, src, frames);
  370. break;
  371. case DevFmtFloat:
  372. Stereo2MonoALfloat(dst, src, frames);
  373. break;
  374. }
  375. }
  376. else /*if(converter->mSrcChans == DevFmtMono && converter->mDstChans == DevFmtStereo)*/
  377. {
  378. switch(converter->mSrcType)
  379. {
  380. case DevFmtByte:
  381. Mono2StereoALbyte(dst, src, frames);
  382. break;
  383. case DevFmtUByte:
  384. Mono2StereoALubyte(dst, src, frames);
  385. break;
  386. case DevFmtShort:
  387. Mono2StereoALshort(dst, src, frames);
  388. break;
  389. case DevFmtUShort:
  390. Mono2StereoALushort(dst, src, frames);
  391. break;
  392. case DevFmtInt:
  393. Mono2StereoALint(dst, src, frames);
  394. break;
  395. case DevFmtUInt:
  396. Mono2StereoALuint(dst, src, frames);
  397. break;
  398. case DevFmtFloat:
  399. Mono2StereoALfloat(dst, src, frames);
  400. break;
  401. }
  402. }
  403. }