2
0

converter.c 16 KB

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