converter.c 16 KB

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