SDL_audiocvt.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "../SDL_internal.h"
  19. /* Functions for audio drivers to perform runtime conversion of audio format */
  20. #include "SDL.h"
  21. #include "SDL_audio.h"
  22. #include "SDL_audio_c.h"
  23. #include "SDL_loadso.h"
  24. #include "../SDL_dataqueue.h"
  25. #include "SDL_cpuinfo.h"
  26. #define DEBUG_AUDIOSTREAM 0
  27. #ifdef __ARM_NEON
  28. #define HAVE_NEON_INTRINSICS 1
  29. #endif
  30. #ifdef __SSE__
  31. #define HAVE_SSE_INTRINSICS 1
  32. #endif
  33. #ifdef __SSE3__
  34. #define HAVE_SSE3_INTRINSICS 1
  35. #endif
  36. #if defined(HAVE_IMMINTRIN_H) && !defined(SDL_DISABLE_IMMINTRIN_H)
  37. #define HAVE_AVX_INTRINSICS 1
  38. #endif
  39. #if defined __clang__
  40. #if (!__has_attribute(target))
  41. #undef HAVE_AVX_INTRINSICS
  42. #endif
  43. #if (defined(_MSC_VER) || defined(__SCE__)) && !defined(__AVX__)
  44. #undef HAVE_AVX_INTRINSICS
  45. #endif
  46. #elif defined __GNUC__
  47. #if (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 9)
  48. #undef HAVE_AVX_INTRINSICS
  49. #endif
  50. #endif
  51. /*
  52. * CHANNEL LAYOUTS AS SDL EXPECTS THEM:
  53. *
  54. * (Even if the platform expects something else later, that
  55. * SDL will swizzle between the app and the platform).
  56. *
  57. * Abbreviations:
  58. * - FRONT=single mono speaker
  59. * - FL=front left speaker
  60. * - FR=front right speaker
  61. * - FC=front center speaker
  62. * - BL=back left speaker
  63. * - BR=back right speaker
  64. * - SR=surround right speaker
  65. * - SL=surround left speaker
  66. * - BC=back center speaker
  67. * - LFE=low-frequency speaker
  68. *
  69. * These are listed in the order they are laid out in
  70. * memory, so "FL+FR" means "the front left speaker is
  71. * layed out in memory first, then the front right, then
  72. * it repeats for the next audio frame".
  73. *
  74. * 1 channel (mono) layout: FRONT
  75. * 2 channels (stereo) layout: FL+FR
  76. * 3 channels (2.1) layout: FL+FR+LFE
  77. * 4 channels (quad) layout: FL+FR+BL+BR
  78. * 5 channels (4.1) layout: FL+FR+LFE+BL+BR
  79. * 6 channels (5.1) layout: FL+FR+FC+LFE+BL+BR
  80. * 7 channels (6.1) layout: FL+FR+FC+LFE+BC+SL+SR
  81. * 8 channels (7.1) layout: FL+FR+FC+LFE+BL+BR+SL+SR
  82. */
  83. #ifdef HAVE_SSE3_INTRINSICS
  84. /* Convert from stereo to mono. Average left and right. */
  85. static void SDLCALL SDL_ConvertStereoToMono_SSE3(SDL_AudioCVT *cvt, SDL_AudioFormat format)
  86. {
  87. const __m128 divby2 = _mm_set1_ps(0.5f);
  88. float *dst = (float *)cvt->buf;
  89. const float *src = dst;
  90. int i = cvt->len_cvt / 8;
  91. LOG_DEBUG_CONVERT("stereo", "mono (using SSE3)");
  92. SDL_assert(format == AUDIO_F32SYS);
  93. /* Do SSE blocks as long as we have 16 bytes available.
  94. Just use unaligned load/stores, if the memory at runtime is
  95. aligned it'll be just as fast on modern processors */
  96. while (i >= 4) { /* 4 * float32 */
  97. _mm_storeu_ps(dst, _mm_mul_ps(_mm_hadd_ps(_mm_loadu_ps(src), _mm_loadu_ps(src + 4)), divby2));
  98. i -= 4;
  99. src += 8;
  100. dst += 4;
  101. }
  102. /* Finish off any leftovers with scalar operations. */
  103. while (i) {
  104. *dst = (src[0] + src[1]) * 0.5f;
  105. dst++;
  106. i--;
  107. src += 2;
  108. }
  109. cvt->len_cvt /= 2;
  110. if (cvt->filters[++cvt->filter_index]) {
  111. cvt->filters[cvt->filter_index](cvt, format);
  112. }
  113. }
  114. #endif
  115. #ifdef HAVE_SSE_INTRINSICS
  116. /* Convert from mono to stereo. Duplicate to stereo left and right. */
  117. static void SDLCALL SDL_ConvertMonoToStereo_SSE(SDL_AudioCVT *cvt, SDL_AudioFormat format)
  118. {
  119. float *dst = ((float *)(cvt->buf + (cvt->len_cvt * 2))) - 8;
  120. const float *src = ((const float *)(cvt->buf + cvt->len_cvt)) - 4;
  121. int i = cvt->len_cvt / sizeof(float);
  122. LOG_DEBUG_CONVERT("mono", "stereo (using SSE)");
  123. SDL_assert(format == AUDIO_F32SYS);
  124. /* Do SSE blocks as long as we have 16 bytes available.
  125. Just use unaligned load/stores, if the memory at runtime is
  126. aligned it'll be just as fast on modern processors */
  127. /* convert backwards, since output is growing in-place. */
  128. while (i >= 4) { /* 4 * float32 */
  129. const __m128 input = _mm_loadu_ps(src); /* A B C D */
  130. _mm_storeu_ps(dst, _mm_unpacklo_ps(input, input)); /* A A B B */
  131. _mm_storeu_ps(dst + 4, _mm_unpackhi_ps(input, input)); /* C C D D */
  132. i -= 4;
  133. src -= 4;
  134. dst -= 8;
  135. }
  136. /* Finish off any leftovers with scalar operations. */
  137. src += 3;
  138. dst += 6; /* adjust for smaller buffers. */
  139. while (i) { /* convert backwards, since output is growing in-place. */
  140. const float srcFC = src[0];
  141. dst[1] /* FR */ = srcFC;
  142. dst[0] /* FL */ = srcFC;
  143. i--;
  144. src--;
  145. dst -= 2;
  146. }
  147. cvt->len_cvt *= 2;
  148. if (cvt->filters[++cvt->filter_index]) {
  149. cvt->filters[cvt->filter_index](cvt, format);
  150. }
  151. }
  152. #endif
  153. /* Include the autogenerated channel converters... */
  154. #include "SDL_audio_channel_converters.h"
  155. /* SDL's resampler uses a "bandlimited interpolation" algorithm:
  156. https://ccrma.stanford.edu/~jos/resample/ */
  157. #include "SDL_audio_resampler_filter.h"
  158. static Sint32 ResamplerPadding(const Sint32 inrate, const Sint32 outrate)
  159. {
  160. /* This function uses integer arithmetics to avoid precision loss caused
  161. * by large floating point numbers. Sint32 is needed for the large number
  162. * multiplication. The integers are assumed to be non-negative so that
  163. * division rounds by truncation. */
  164. if (inrate == outrate) {
  165. return 0;
  166. }
  167. if (inrate > outrate) {
  168. return (RESAMPLER_SAMPLES_PER_ZERO_CROSSING * inrate + outrate - 1) / outrate;
  169. }
  170. return RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
  171. }
  172. /* lpadding and rpadding are expected to be buffers of (ResamplePadding(inrate, outrate) * chans * sizeof(float)) bytes. */
  173. static int SDL_ResampleAudio(const int chans, const int inrate, const int outrate,
  174. const float *lpadding, const float *rpadding,
  175. const float *inbuf, const int inbuflen,
  176. float *outbuf, const int outbuflen)
  177. {
  178. /* This function uses integer arithmetics to avoid precision loss caused
  179. * by large floating point numbers. For some operations, Sint32 or Sint64
  180. * are needed for the large number multiplications. The input integers are
  181. * assumed to be non-negative so that division rounds by truncation and
  182. * modulo is always non-negative. Note that the operator order is important
  183. * for these integer divisions. */
  184. const int paddinglen = ResamplerPadding(inrate, outrate);
  185. const int framelen = chans * (int)sizeof(float);
  186. const int inframes = inbuflen / framelen;
  187. /* outbuflen isn't total to write, it's total available. */
  188. const int wantedoutframes = (int)((Sint64)inframes * outrate / inrate);
  189. const int maxoutframes = outbuflen / framelen;
  190. const int outframes = SDL_min(wantedoutframes, maxoutframes);
  191. float *dst = outbuf;
  192. int i, j, chan;
  193. for (i = 0; i < outframes; i++) {
  194. const int srcindex = (int)((Sint64)i * inrate / outrate);
  195. /* Calculating the following way avoids subtraction or modulo of large
  196. * floats which have low result precision.
  197. * interpolation1
  198. * = (i / outrate * inrate) - floor(i / outrate * inrate)
  199. * = mod(i / outrate * inrate, 1)
  200. * = mod(i * inrate, outrate) / outrate */
  201. const int srcfraction = ((Sint64)i) * inrate % outrate;
  202. const float interpolation1 = ((float)srcfraction) / ((float)outrate);
  203. const int filterindex1 = ((Sint32)srcfraction) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING / outrate;
  204. const float interpolation2 = 1.0f - interpolation1;
  205. const int filterindex2 = ((Sint32)(outrate - srcfraction)) * RESAMPLER_SAMPLES_PER_ZERO_CROSSING / outrate;
  206. for (chan = 0; chan < chans; chan++) {
  207. float outsample = 0.0f;
  208. /* do this twice to calculate the sample, once for the "left wing" and then same for the right. */
  209. for (j = 0; (filterindex1 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) {
  210. const int filt_ind = filterindex1 + j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
  211. const int srcframe = srcindex - j;
  212. /* !!! FIXME: we can bubble this conditional out of here by doing a pre loop. */
  213. const float insample = (srcframe < 0) ? lpadding[((paddinglen + srcframe) * chans) + chan] : inbuf[(srcframe * chans) + chan];
  214. outsample += (float) (insample * (ResamplerFilter[filt_ind] + (interpolation1 * ResamplerFilterDifference[filt_ind])));
  215. }
  216. /* Do the right wing! */
  217. for (j = 0; (filterindex2 + (j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING)) < RESAMPLER_FILTER_SIZE; j++) {
  218. const int filt_ind = filterindex2 + j * RESAMPLER_SAMPLES_PER_ZERO_CROSSING;
  219. const int srcframe = srcindex + 1 + j;
  220. /* !!! FIXME: we can bubble this conditional out of here by doing a post loop. */
  221. const float insample = (srcframe >= inframes) ? rpadding[((srcframe - inframes) * chans) + chan] : inbuf[(srcframe * chans) + chan];
  222. outsample += (float) (insample * (ResamplerFilter[filt_ind] + (interpolation2 * ResamplerFilterDifference[filt_ind])));
  223. }
  224. *(dst++) = outsample;
  225. }
  226. }
  227. return outframes * chans * sizeof(float);
  228. }
  229. int SDL_ConvertAudio(SDL_AudioCVT *cvt)
  230. {
  231. /* !!! FIXME: (cvt) should be const; stack-copy it here. */
  232. /* !!! FIXME: (actually, we can't...len_cvt needs to be updated. Grr.) */
  233. /* Make sure there's data to convert */
  234. if (!cvt->buf) {
  235. return SDL_SetError("No buffer allocated for conversion");
  236. }
  237. /* Return okay if no conversion is necessary */
  238. cvt->len_cvt = cvt->len;
  239. if (cvt->filters[0] == NULL) {
  240. return 0;
  241. }
  242. /* Set up the conversion and go! */
  243. cvt->filter_index = 0;
  244. cvt->filters[0](cvt, cvt->src_format);
  245. return 0;
  246. }
  247. static void SDLCALL SDL_Convert_Byteswap(SDL_AudioCVT *cvt, SDL_AudioFormat format)
  248. {
  249. #if DEBUG_CONVERT
  250. SDL_Log("SDL_AUDIO_CONVERT: Converting byte order\n");
  251. #endif
  252. switch (SDL_AUDIO_BITSIZE(format)) {
  253. #define CASESWAP(b) \
  254. case b: \
  255. { \
  256. Uint##b *ptr = (Uint##b *)cvt->buf; \
  257. int i; \
  258. for (i = cvt->len_cvt / sizeof(*ptr); i; --i, ++ptr) { \
  259. *ptr = SDL_Swap##b(*ptr); \
  260. } \
  261. break; \
  262. }
  263. CASESWAP(16);
  264. CASESWAP(32);
  265. CASESWAP(64);
  266. #undef CASESWAP
  267. default:
  268. SDL_assert(!"unhandled byteswap datatype!");
  269. break;
  270. }
  271. if (cvt->filters[++cvt->filter_index]) {
  272. /* flip endian flag for data. */
  273. if (format & SDL_AUDIO_MASK_ENDIAN) {
  274. format &= ~SDL_AUDIO_MASK_ENDIAN;
  275. } else {
  276. format |= SDL_AUDIO_MASK_ENDIAN;
  277. }
  278. cvt->filters[cvt->filter_index](cvt, format);
  279. }
  280. }
  281. static int SDL_AddAudioCVTFilter(SDL_AudioCVT *cvt, SDL_AudioFilter filter)
  282. {
  283. if (cvt->filter_index >= SDL_AUDIOCVT_MAX_FILTERS) {
  284. return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS);
  285. }
  286. SDL_assert(filter != NULL);
  287. cvt->filters[cvt->filter_index++] = filter;
  288. cvt->filters[cvt->filter_index] = NULL; /* Moving terminator */
  289. return 0;
  290. }
  291. static int SDL_BuildAudioTypeCVTToFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat src_fmt)
  292. {
  293. int retval = 0; /* 0 == no conversion necessary. */
  294. if ((SDL_AUDIO_ISBIGENDIAN(src_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(src_fmt) > 8) {
  295. if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
  296. return -1;
  297. }
  298. retval = 1; /* added a converter. */
  299. }
  300. if (!SDL_AUDIO_ISFLOAT(src_fmt)) {
  301. const Uint16 src_bitsize = SDL_AUDIO_BITSIZE(src_fmt);
  302. const Uint16 dst_bitsize = 32;
  303. SDL_AudioFilter filter = NULL;
  304. switch (src_fmt & ~SDL_AUDIO_MASK_ENDIAN) {
  305. case AUDIO_S8:
  306. filter = SDL_Convert_S8_to_F32;
  307. break;
  308. case AUDIO_U8:
  309. filter = SDL_Convert_U8_to_F32;
  310. break;
  311. case AUDIO_S16:
  312. filter = SDL_Convert_S16_to_F32;
  313. break;
  314. case AUDIO_U16:
  315. filter = SDL_Convert_U16_to_F32;
  316. break;
  317. case AUDIO_S32:
  318. filter = SDL_Convert_S32_to_F32;
  319. break;
  320. default:
  321. SDL_assert(!"Unexpected audio format!");
  322. break;
  323. }
  324. if (!filter) {
  325. return SDL_SetError("No conversion from source format to float available");
  326. }
  327. if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
  328. return -1;
  329. }
  330. if (src_bitsize < dst_bitsize) {
  331. const int mult = (dst_bitsize / src_bitsize);
  332. cvt->len_mult *= mult;
  333. cvt->len_ratio *= mult;
  334. } else if (src_bitsize > dst_bitsize) {
  335. const int div = (src_bitsize / dst_bitsize);
  336. cvt->len_ratio /= div;
  337. }
  338. retval = 1; /* added a converter. */
  339. }
  340. return retval;
  341. }
  342. static int SDL_BuildAudioTypeCVTFromFloat(SDL_AudioCVT *cvt, const SDL_AudioFormat dst_fmt)
  343. {
  344. int retval = 0; /* 0 == no conversion necessary. */
  345. if (!SDL_AUDIO_ISFLOAT(dst_fmt)) {
  346. const Uint16 dst_bitsize = SDL_AUDIO_BITSIZE(dst_fmt);
  347. const Uint16 src_bitsize = 32;
  348. SDL_AudioFilter filter = NULL;
  349. switch (dst_fmt & ~SDL_AUDIO_MASK_ENDIAN) {
  350. case AUDIO_S8:
  351. filter = SDL_Convert_F32_to_S8;
  352. break;
  353. case AUDIO_U8:
  354. filter = SDL_Convert_F32_to_U8;
  355. break;
  356. case AUDIO_S16:
  357. filter = SDL_Convert_F32_to_S16;
  358. break;
  359. case AUDIO_U16:
  360. filter = SDL_Convert_F32_to_U16;
  361. break;
  362. case AUDIO_S32:
  363. filter = SDL_Convert_F32_to_S32;
  364. break;
  365. default:
  366. SDL_assert(!"Unexpected audio format!");
  367. break;
  368. }
  369. if (!filter) {
  370. return SDL_SetError("No conversion from float to format 0x%.4x available", dst_fmt);
  371. }
  372. if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
  373. return -1;
  374. }
  375. if (src_bitsize < dst_bitsize) {
  376. const int mult = (dst_bitsize / src_bitsize);
  377. cvt->len_mult *= mult;
  378. cvt->len_ratio *= mult;
  379. } else if (src_bitsize > dst_bitsize) {
  380. const int div = (src_bitsize / dst_bitsize);
  381. cvt->len_ratio /= div;
  382. }
  383. retval = 1; /* added a converter. */
  384. }
  385. if ((SDL_AUDIO_ISBIGENDIAN(dst_fmt) != 0) == (SDL_BYTEORDER == SDL_LIL_ENDIAN) && SDL_AUDIO_BITSIZE(dst_fmt) > 8) {
  386. if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
  387. return -1;
  388. }
  389. retval = 1; /* added a converter. */
  390. }
  391. return retval;
  392. }
  393. #ifdef HAVE_LIBSAMPLERATE_H
  394. static void SDL_ResampleCVT_SRC(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format)
  395. {
  396. const float *src = (const float *)cvt->buf;
  397. const int srclen = cvt->len_cvt;
  398. float *dst = (float *)(cvt->buf + srclen);
  399. const int dstlen = (cvt->len * cvt->len_mult) - srclen;
  400. const int framelen = sizeof(float) * chans;
  401. int result = 0;
  402. SRC_DATA data;
  403. SDL_zero(data);
  404. data.data_in = (float *)src; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */
  405. data.input_frames = srclen / framelen;
  406. data.data_out = dst;
  407. data.output_frames = dstlen / framelen;
  408. data.src_ratio = cvt->rate_incr;
  409. result = SRC_src_simple(&data, SRC_converter, chans); /* Simple API converts the whole buffer at once. No need for initialization. */
  410. /* !!! FIXME: Handle library failures? */
  411. #if DEBUG_CONVERT
  412. if (result != 0) {
  413. SDL_Log("src_simple() failed: %s", SRC_src_strerror(result));
  414. }
  415. #else
  416. (void)result;
  417. #endif
  418. cvt->len_cvt = data.output_frames_gen * framelen;
  419. SDL_memmove(cvt->buf, dst, cvt->len_cvt);
  420. if (cvt->filters[++cvt->filter_index]) {
  421. cvt->filters[cvt->filter_index](cvt, format);
  422. }
  423. }
  424. #endif /* HAVE_LIBSAMPLERATE_H */
  425. static void SDL_ResampleCVT(SDL_AudioCVT *cvt, const int chans, const SDL_AudioFormat format)
  426. {
  427. /* !!! FIXME in 2.1: there are ten slots in the filter list, and the theoretical maximum we use is six (seven with NULL terminator).
  428. !!! FIXME in 2.1: We need to store data for this resampler, because the cvt structure doesn't store the original sample rates,
  429. !!! FIXME in 2.1: so we steal the ninth and tenth slot. :( */
  430. const int inrate = (int)(size_t)cvt->filters[SDL_AUDIOCVT_MAX_FILTERS - 1];
  431. const int outrate = (int)(size_t)cvt->filters[SDL_AUDIOCVT_MAX_FILTERS];
  432. const float *src = (const float *)cvt->buf;
  433. const int srclen = cvt->len_cvt;
  434. /*float *dst = (float *) cvt->buf;
  435. const int dstlen = (cvt->len * cvt->len_mult);*/
  436. /* !!! FIXME: remove this if we can get the resampler to work in-place again. */
  437. float *dst = (float *)(cvt->buf + srclen);
  438. const int dstlen = (cvt->len * cvt->len_mult) - srclen;
  439. const int requestedpadding = ResamplerPadding(inrate, outrate);
  440. int paddingsamples;
  441. float *padding;
  442. if (requestedpadding < SDL_MAX_SINT32 / chans) {
  443. paddingsamples = requestedpadding * chans;
  444. } else {
  445. paddingsamples = 0;
  446. }
  447. SDL_assert(format == AUDIO_F32SYS);
  448. /* we keep no streaming state here, so pad with silence on both ends. */
  449. padding = (float *)SDL_calloc(paddingsamples ? paddingsamples : 1, sizeof(float));
  450. if (!padding) {
  451. SDL_OutOfMemory();
  452. return;
  453. }
  454. cvt->len_cvt = SDL_ResampleAudio(chans, inrate, outrate, padding, padding, src, srclen, dst, dstlen);
  455. SDL_free(padding);
  456. SDL_memmove(cvt->buf, dst, cvt->len_cvt); /* !!! FIXME: remove this if we can get the resampler to work in-place again. */
  457. if (cvt->filters[++cvt->filter_index]) {
  458. cvt->filters[cvt->filter_index](cvt, format);
  459. }
  460. }
  461. /* !!! FIXME: We only have this macro salsa because SDL_AudioCVT doesn't
  462. !!! FIXME: store channel info, so we have to have function entry
  463. !!! FIXME: points for each supported channel count and multiple
  464. !!! FIXME: vs arbitrary. When we rev the ABI, clean this up. */
  465. #define RESAMPLER_FUNCS(chans) \
  466. static void SDLCALL \
  467. SDL_ResampleCVT_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) \
  468. { \
  469. SDL_ResampleCVT(cvt, chans, format); \
  470. }
  471. RESAMPLER_FUNCS(1)
  472. RESAMPLER_FUNCS(2)
  473. RESAMPLER_FUNCS(4)
  474. RESAMPLER_FUNCS(6)
  475. RESAMPLER_FUNCS(8)
  476. #undef RESAMPLER_FUNCS
  477. #ifdef HAVE_LIBSAMPLERATE_H
  478. #define RESAMPLER_FUNCS(chans) \
  479. static void SDLCALL \
  480. SDL_ResampleCVT_SRC_c##chans(SDL_AudioCVT *cvt, SDL_AudioFormat format) \
  481. { \
  482. SDL_ResampleCVT_SRC(cvt, chans, format); \
  483. }
  484. RESAMPLER_FUNCS(1)
  485. RESAMPLER_FUNCS(2)
  486. RESAMPLER_FUNCS(4)
  487. RESAMPLER_FUNCS(6)
  488. RESAMPLER_FUNCS(8)
  489. #undef RESAMPLER_FUNCS
  490. #endif /* HAVE_LIBSAMPLERATE_H */
  491. static SDL_AudioFilter ChooseCVTResampler(const int dst_channels)
  492. {
  493. #ifdef HAVE_LIBSAMPLERATE_H
  494. if (SRC_available) {
  495. switch (dst_channels) {
  496. case 1:
  497. return SDL_ResampleCVT_SRC_c1;
  498. case 2:
  499. return SDL_ResampleCVT_SRC_c2;
  500. case 4:
  501. return SDL_ResampleCVT_SRC_c4;
  502. case 6:
  503. return SDL_ResampleCVT_SRC_c6;
  504. case 8:
  505. return SDL_ResampleCVT_SRC_c8;
  506. default:
  507. break;
  508. }
  509. }
  510. #endif /* HAVE_LIBSAMPLERATE_H */
  511. switch (dst_channels) {
  512. case 1:
  513. return SDL_ResampleCVT_c1;
  514. case 2:
  515. return SDL_ResampleCVT_c2;
  516. case 4:
  517. return SDL_ResampleCVT_c4;
  518. case 6:
  519. return SDL_ResampleCVT_c6;
  520. case 8:
  521. return SDL_ResampleCVT_c8;
  522. default:
  523. break;
  524. }
  525. return NULL;
  526. }
  527. static int SDL_BuildAudioResampleCVT(SDL_AudioCVT *cvt, const int dst_channels,
  528. const int src_rate, const int dst_rate)
  529. {
  530. SDL_AudioFilter filter;
  531. if (src_rate == dst_rate) {
  532. return 0; /* no conversion necessary. */
  533. }
  534. filter = ChooseCVTResampler(dst_channels);
  535. if (!filter) {
  536. return SDL_SetError("No conversion available for these rates");
  537. }
  538. /* Update (cvt) with filter details... */
  539. if (SDL_AddAudioCVTFilter(cvt, filter) < 0) {
  540. return -1;
  541. }
  542. /* !!! FIXME in 2.1: there are ten slots in the filter list, and the theoretical maximum we use is six (seven with NULL terminator).
  543. !!! FIXME in 2.1: We need to store data for this resampler, because the cvt structure doesn't store the original sample rates,
  544. !!! FIXME in 2.1: so we steal the ninth and tenth slot. :( */
  545. if (cvt->filter_index >= (SDL_AUDIOCVT_MAX_FILTERS - 2)) {
  546. return SDL_SetError("Too many filters needed for conversion, exceeded maximum of %d", SDL_AUDIOCVT_MAX_FILTERS - 2);
  547. }
  548. cvt->filters[SDL_AUDIOCVT_MAX_FILTERS - 1] = (SDL_AudioFilter)(uintptr_t)src_rate;
  549. cvt->filters[SDL_AUDIOCVT_MAX_FILTERS] = (SDL_AudioFilter)(uintptr_t)dst_rate;
  550. if (src_rate < dst_rate) {
  551. const double mult = ((double)dst_rate) / ((double)src_rate);
  552. cvt->len_mult *= (int)SDL_ceil(mult);
  553. cvt->len_ratio *= mult;
  554. } else {
  555. cvt->len_ratio /= ((double)src_rate) / ((double)dst_rate);
  556. }
  557. /* !!! FIXME: remove this if we can get the resampler to work in-place again. */
  558. /* the buffer is big enough to hold the destination now, but
  559. we need it large enough to hold a separate scratch buffer. */
  560. cvt->len_mult *= 2;
  561. return 1; /* added a converter. */
  562. }
  563. static SDL_bool SDL_SupportedAudioFormat(const SDL_AudioFormat fmt)
  564. {
  565. switch (fmt) {
  566. case AUDIO_U8:
  567. case AUDIO_S8:
  568. case AUDIO_U16LSB:
  569. case AUDIO_S16LSB:
  570. case AUDIO_U16MSB:
  571. case AUDIO_S16MSB:
  572. case AUDIO_S32LSB:
  573. case AUDIO_S32MSB:
  574. case AUDIO_F32LSB:
  575. case AUDIO_F32MSB:
  576. return SDL_TRUE; /* supported. */
  577. default:
  578. break;
  579. }
  580. return SDL_FALSE; /* unsupported. */
  581. }
  582. static SDL_bool SDL_SupportedChannelCount(const int channels)
  583. {
  584. return ((channels >= 1) && (channels <= 8)) ? SDL_TRUE : SDL_FALSE;
  585. }
  586. /* Creates a set of audio filters to convert from one format to another.
  587. Returns 0 if no conversion is needed, 1 if the audio filter is set up,
  588. or -1 if an error like invalid parameter, unsupported format, etc. occurred.
  589. */
  590. int SDL_BuildAudioCVT(SDL_AudioCVT *cvt,
  591. SDL_AudioFormat src_format, Uint8 src_channels, int src_rate,
  592. SDL_AudioFormat dst_format, Uint8 dst_channels, int dst_rate)
  593. {
  594. SDL_AudioFilter channel_converter = NULL;
  595. /* Sanity check target pointer */
  596. if (!cvt) {
  597. return SDL_InvalidParamError("cvt");
  598. }
  599. /* Make sure we zero out the audio conversion before error checking */
  600. SDL_zerop(cvt);
  601. if (!SDL_SupportedAudioFormat(src_format)) {
  602. return SDL_SetError("Invalid source format");
  603. }
  604. if (!SDL_SupportedAudioFormat(dst_format)) {
  605. return SDL_SetError("Invalid destination format");
  606. }
  607. if (!SDL_SupportedChannelCount(src_channels)) {
  608. return SDL_SetError("Invalid source channels");
  609. }
  610. if (!SDL_SupportedChannelCount(dst_channels)) {
  611. return SDL_SetError("Invalid destination channels");
  612. }
  613. if (src_rate <= 0) {
  614. return SDL_SetError("Source rate is equal to or less than zero");
  615. }
  616. if (dst_rate <= 0) {
  617. return SDL_SetError("Destination rate is equal to or less than zero");
  618. }
  619. if (src_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
  620. return SDL_SetError("Source rate is too high");
  621. }
  622. if (dst_rate >= SDL_MAX_SINT32 / RESAMPLER_SAMPLES_PER_ZERO_CROSSING) {
  623. return SDL_SetError("Destination rate is too high");
  624. }
  625. #if DEBUG_CONVERT
  626. SDL_Log("SDL_AUDIO_CONVERT: Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
  627. src_format, dst_format, src_channels, dst_channels, src_rate, dst_rate);
  628. #endif
  629. /* Start off with no conversion necessary */
  630. cvt->src_format = src_format;
  631. cvt->dst_format = dst_format;
  632. cvt->needed = 0;
  633. cvt->filter_index = 0;
  634. SDL_zeroa(cvt->filters);
  635. cvt->len_mult = 1;
  636. cvt->len_ratio = 1.0;
  637. cvt->rate_incr = ((double)dst_rate) / ((double)src_rate);
  638. /* Make sure we've chosen audio conversion functions (SIMD, scalar, etc.) */
  639. SDL_ChooseAudioConverters();
  640. /* Type conversion goes like this now:
  641. - byteswap to CPU native format first if necessary.
  642. - convert to native Float32 if necessary.
  643. - resample and change channel count if necessary.
  644. - convert to final data format.
  645. - byteswap back to foreign format if necessary.
  646. The expectation is we can process data faster in float32
  647. (possibly with SIMD), and making several passes over the same
  648. buffer is likely to be CPU cache-friendly, avoiding the
  649. biggest performance hit in modern times. Previously we had
  650. (script-generated) custom converters for every data type and
  651. it was a bloat on SDL compile times and final library size. */
  652. /* see if we can skip float conversion entirely. */
  653. if (src_rate == dst_rate && src_channels == dst_channels) {
  654. if (src_format == dst_format) {
  655. return 0;
  656. }
  657. /* just a byteswap needed? */
  658. if ((src_format & ~SDL_AUDIO_MASK_ENDIAN) == (dst_format & ~SDL_AUDIO_MASK_ENDIAN)) {
  659. if (SDL_AUDIO_BITSIZE(dst_format) == 8) {
  660. return 0;
  661. }
  662. if (SDL_AddAudioCVTFilter(cvt, SDL_Convert_Byteswap) < 0) {
  663. return -1;
  664. }
  665. cvt->needed = 1;
  666. return 1;
  667. }
  668. }
  669. /* Convert data types, if necessary. Updates (cvt). */
  670. if (SDL_BuildAudioTypeCVTToFloat(cvt, src_format) < 0) {
  671. return -1; /* shouldn't happen, but just in case... */
  672. }
  673. /* Channel conversion */
  674. /* SDL_SupportedChannelCount should have caught these asserts, or we added a new format and forgot to update the table. */
  675. SDL_assert(src_channels <= SDL_arraysize(channel_converters));
  676. SDL_assert(dst_channels <= SDL_arraysize(channel_converters[0]));
  677. channel_converter = channel_converters[src_channels - 1][dst_channels - 1];
  678. if ((!channel_converter) != (src_channels == dst_channels)) {
  679. /* All combinations of supported channel counts should have been handled by now, but let's be defensive */
  680. return SDL_SetError("Invalid channel combination");
  681. } else if (channel_converter != NULL) {
  682. /* swap in some SIMD versions for a few of these. */
  683. if (channel_converter == SDL_ConvertStereoToMono) {
  684. SDL_AudioFilter filter = NULL;
  685. #ifdef HAVE_SSE3_INTRINSICS
  686. if (!filter && SDL_HasSSE3()) {
  687. filter = SDL_ConvertStereoToMono_SSE3;
  688. }
  689. #endif
  690. if (filter) {
  691. channel_converter = filter;
  692. }
  693. } else if (channel_converter == SDL_ConvertMonoToStereo) {
  694. SDL_AudioFilter filter = NULL;
  695. #ifdef HAVE_SSE_INTRINSICS
  696. if (!filter && SDL_HasSSE()) {
  697. filter = SDL_ConvertMonoToStereo_SSE;
  698. }
  699. #endif
  700. if (filter) {
  701. channel_converter = filter;
  702. }
  703. }
  704. if (SDL_AddAudioCVTFilter(cvt, channel_converter) < 0) {
  705. return -1;
  706. }
  707. if (src_channels < dst_channels) {
  708. cvt->len_mult = ((cvt->len_mult * dst_channels) + (src_channels - 1)) / src_channels;
  709. }
  710. cvt->len_ratio = (cvt->len_ratio * dst_channels) / src_channels;
  711. src_channels = dst_channels;
  712. }
  713. /* Do rate conversion, if necessary. Updates (cvt). */
  714. if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) < 0) {
  715. return -1; /* shouldn't happen, but just in case... */
  716. }
  717. /* Move to final data type. */
  718. if (SDL_BuildAudioTypeCVTFromFloat(cvt, dst_format) < 0) {
  719. return -1; /* shouldn't happen, but just in case... */
  720. }
  721. cvt->needed = (cvt->filter_index != 0);
  722. return cvt->needed;
  723. }
  724. typedef int (*SDL_ResampleAudioStreamFunc)(SDL_AudioStream *stream, const void *inbuf, const int inbuflen, void *outbuf, const int outbuflen);
  725. typedef void (*SDL_ResetAudioStreamResamplerFunc)(SDL_AudioStream *stream);
  726. typedef void (*SDL_CleanupAudioStreamResamplerFunc)(SDL_AudioStream *stream);
  727. struct _SDL_AudioStream
  728. {
  729. SDL_AudioCVT cvt_before_resampling;
  730. SDL_AudioCVT cvt_after_resampling;
  731. SDL_DataQueue *queue;
  732. SDL_bool first_run;
  733. Uint8 *staging_buffer;
  734. int staging_buffer_size;
  735. int staging_buffer_filled;
  736. Uint8 *work_buffer_base; /* maybe unaligned pointer from SDL_realloc(). */
  737. int work_buffer_len;
  738. int src_sample_frame_size;
  739. SDL_AudioFormat src_format;
  740. Uint8 src_channels;
  741. int src_rate;
  742. int dst_sample_frame_size;
  743. SDL_AudioFormat dst_format;
  744. Uint8 dst_channels;
  745. int dst_rate;
  746. double rate_incr;
  747. Uint8 pre_resample_channels;
  748. int packetlen;
  749. int resampler_padding_samples;
  750. float *resampler_padding;
  751. void *resampler_state;
  752. SDL_ResampleAudioStreamFunc resampler_func;
  753. SDL_ResetAudioStreamResamplerFunc reset_resampler_func;
  754. SDL_CleanupAudioStreamResamplerFunc cleanup_resampler_func;
  755. };
  756. static Uint8 *EnsureStreamBufferSize(SDL_AudioStream *stream, int newlen)
  757. {
  758. Uint8 *ptr;
  759. size_t offset;
  760. if (stream->work_buffer_len >= newlen) {
  761. ptr = stream->work_buffer_base;
  762. } else {
  763. ptr = (Uint8 *)SDL_realloc(stream->work_buffer_base, (size_t)newlen + 32);
  764. if (!ptr) {
  765. SDL_OutOfMemory();
  766. return NULL;
  767. }
  768. /* Make sure we're aligned to 16 bytes for SIMD code. */
  769. stream->work_buffer_base = ptr;
  770. stream->work_buffer_len = newlen;
  771. }
  772. offset = ((size_t)ptr) & 15;
  773. return offset ? ptr + (16 - offset) : ptr;
  774. }
  775. #ifdef HAVE_LIBSAMPLERATE_H
  776. static int SDL_ResampleAudioStream_SRC(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
  777. {
  778. const float *inbuf = (const float *)_inbuf;
  779. float *outbuf = (float *)_outbuf;
  780. const int framelen = sizeof(float) * stream->pre_resample_channels;
  781. SRC_STATE *state = (SRC_STATE *)stream->resampler_state;
  782. SRC_DATA data;
  783. int result;
  784. SDL_assert(inbuf != ((const float *)outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */
  785. data.data_in = (float *)inbuf; /* Older versions of libsamplerate had a non-const pointer, but didn't write to it */
  786. data.input_frames = inbuflen / framelen;
  787. data.input_frames_used = 0;
  788. data.data_out = outbuf;
  789. data.output_frames = outbuflen / framelen;
  790. data.end_of_input = 0;
  791. data.src_ratio = stream->rate_incr;
  792. result = SRC_src_process(state, &data);
  793. if (result != 0) {
  794. SDL_SetError("src_process() failed: %s", SRC_src_strerror(result));
  795. return 0;
  796. }
  797. /* If this fails, we need to store them off somewhere */
  798. SDL_assert(data.input_frames_used == data.input_frames);
  799. return data.output_frames_gen * (sizeof(float) * stream->pre_resample_channels);
  800. }
  801. static void SDL_ResetAudioStreamResampler_SRC(SDL_AudioStream *stream)
  802. {
  803. SRC_src_reset((SRC_STATE *)stream->resampler_state);
  804. }
  805. static void SDL_CleanupAudioStreamResampler_SRC(SDL_AudioStream *stream)
  806. {
  807. SRC_STATE *state = (SRC_STATE *)stream->resampler_state;
  808. if (state) {
  809. SRC_src_delete(state);
  810. }
  811. stream->resampler_state = NULL;
  812. stream->resampler_func = NULL;
  813. stream->reset_resampler_func = NULL;
  814. stream->cleanup_resampler_func = NULL;
  815. }
  816. static SDL_bool SetupLibSampleRateResampling(SDL_AudioStream *stream)
  817. {
  818. int result = 0;
  819. SRC_STATE *state = NULL;
  820. if (SRC_available) {
  821. state = SRC_src_new(SRC_converter, stream->pre_resample_channels, &result);
  822. if (!state) {
  823. SDL_SetError("src_new() failed: %s", SRC_src_strerror(result));
  824. }
  825. }
  826. if (!state) {
  827. SDL_CleanupAudioStreamResampler_SRC(stream);
  828. return SDL_FALSE;
  829. }
  830. stream->resampler_state = state;
  831. stream->resampler_func = SDL_ResampleAudioStream_SRC;
  832. stream->reset_resampler_func = SDL_ResetAudioStreamResampler_SRC;
  833. stream->cleanup_resampler_func = SDL_CleanupAudioStreamResampler_SRC;
  834. return SDL_TRUE;
  835. }
  836. #endif /* HAVE_LIBSAMPLERATE_H */
  837. static int SDL_ResampleAudioStream(SDL_AudioStream *stream, const void *_inbuf, const int inbuflen, void *_outbuf, const int outbuflen)
  838. {
  839. const Uint8 *inbufend = ((const Uint8 *)_inbuf) + inbuflen;
  840. const float *inbuf = (const float *)_inbuf;
  841. float *outbuf = (float *)_outbuf;
  842. const int chans = (int)stream->pre_resample_channels;
  843. const int inrate = stream->src_rate;
  844. const int outrate = stream->dst_rate;
  845. const int paddingsamples = stream->resampler_padding_samples;
  846. const int paddingbytes = paddingsamples * sizeof(float);
  847. float *lpadding = (float *)stream->resampler_state;
  848. const float *rpadding = (const float *)inbufend; /* we set this up so there are valid padding samples at the end of the input buffer. */
  849. const int cpy = SDL_min(inbuflen, paddingbytes);
  850. int retval;
  851. SDL_assert(inbuf != ((const float *)outbuf)); /* SDL_AudioStreamPut() shouldn't allow in-place resamples. */
  852. retval = SDL_ResampleAudio(chans, inrate, outrate, lpadding, rpadding, inbuf, inbuflen, outbuf, outbuflen);
  853. /* update our left padding with end of current input, for next run. */
  854. SDL_memcpy((lpadding + paddingsamples) - (cpy / sizeof(float)), inbufend - cpy, cpy);
  855. return retval;
  856. }
  857. static void SDL_ResetAudioStreamResampler(SDL_AudioStream *stream)
  858. {
  859. /* set all the padding to silence. */
  860. const int len = stream->resampler_padding_samples;
  861. SDL_memset(stream->resampler_state, '\0', len * sizeof(float));
  862. }
  863. static void SDL_CleanupAudioStreamResampler(SDL_AudioStream *stream)
  864. {
  865. SDL_free(stream->resampler_state);
  866. }
  867. SDL_AudioStream *SDL_NewAudioStream(const SDL_AudioFormat src_format,
  868. const Uint8 src_channels,
  869. const int src_rate,
  870. const SDL_AudioFormat dst_format,
  871. const Uint8 dst_channels,
  872. const int dst_rate)
  873. {
  874. int packetlen = 4096; /* !!! FIXME: good enough for now. */
  875. Uint8 pre_resample_channels;
  876. SDL_AudioStream *retval;
  877. if (src_channels == 0) {
  878. SDL_InvalidParamError("src_channels");
  879. return NULL;
  880. }
  881. if (dst_channels == 0) {
  882. SDL_InvalidParamError("dst_channels");
  883. return NULL;
  884. }
  885. retval = (SDL_AudioStream *)SDL_calloc(1, sizeof(SDL_AudioStream));
  886. if (!retval) {
  887. SDL_OutOfMemory();
  888. return NULL;
  889. }
  890. /* If increasing channels, do it after resampling, since we'd just
  891. do more work to resample duplicate channels. If we're decreasing, do
  892. it first so we resample the interpolated data instead of interpolating
  893. the resampled data (!!! FIXME: decide if that works in practice, though!). */
  894. pre_resample_channels = SDL_min(src_channels, dst_channels);
  895. retval->first_run = SDL_TRUE;
  896. retval->src_sample_frame_size = (SDL_AUDIO_BITSIZE(src_format) / 8) * src_channels;
  897. retval->src_format = src_format;
  898. retval->src_channels = src_channels;
  899. retval->src_rate = src_rate;
  900. retval->dst_sample_frame_size = (SDL_AUDIO_BITSIZE(dst_format) / 8) * dst_channels;
  901. retval->dst_format = dst_format;
  902. retval->dst_channels = dst_channels;
  903. retval->dst_rate = dst_rate;
  904. retval->pre_resample_channels = pre_resample_channels;
  905. retval->packetlen = packetlen;
  906. retval->rate_incr = ((double)dst_rate) / ((double)src_rate);
  907. retval->resampler_padding_samples = ResamplerPadding(retval->src_rate, retval->dst_rate) * pre_resample_channels;
  908. retval->resampler_padding = (float *)SDL_calloc(retval->resampler_padding_samples ? retval->resampler_padding_samples : 1, sizeof(float));
  909. if (!retval->resampler_padding) {
  910. SDL_FreeAudioStream(retval);
  911. SDL_OutOfMemory();
  912. return NULL;
  913. }
  914. retval->staging_buffer_size = ((retval->resampler_padding_samples / retval->pre_resample_channels) * retval->src_sample_frame_size);
  915. if (retval->staging_buffer_size > 0) {
  916. retval->staging_buffer = (Uint8 *)SDL_malloc(retval->staging_buffer_size);
  917. if (!retval->staging_buffer) {
  918. SDL_FreeAudioStream(retval);
  919. SDL_OutOfMemory();
  920. return NULL;
  921. }
  922. }
  923. /* Not resampling? It's an easy conversion (and maybe not even that!) */
  924. if (src_rate == dst_rate) {
  925. retval->cvt_before_resampling.needed = SDL_FALSE;
  926. if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, src_format, src_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) {
  927. SDL_FreeAudioStream(retval);
  928. return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */
  929. }
  930. } else {
  931. /* Don't resample at first. Just get us to Float32 format. */
  932. /* !!! FIXME: convert to int32 on devices without hardware float. */
  933. if (SDL_BuildAudioCVT(&retval->cvt_before_resampling, src_format, src_channels, src_rate, AUDIO_F32SYS, pre_resample_channels, src_rate) < 0) {
  934. SDL_FreeAudioStream(retval);
  935. return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */
  936. }
  937. #ifdef HAVE_LIBSAMPLERATE_H
  938. SetupLibSampleRateResampling(retval);
  939. #endif
  940. if (!retval->resampler_func) {
  941. retval->resampler_state = SDL_calloc(retval->resampler_padding_samples, sizeof(float));
  942. if (!retval->resampler_state) {
  943. SDL_FreeAudioStream(retval);
  944. SDL_OutOfMemory();
  945. return NULL;
  946. }
  947. retval->resampler_func = SDL_ResampleAudioStream;
  948. retval->reset_resampler_func = SDL_ResetAudioStreamResampler;
  949. retval->cleanup_resampler_func = SDL_CleanupAudioStreamResampler;
  950. }
  951. /* Convert us to the final format after resampling. */
  952. if (SDL_BuildAudioCVT(&retval->cvt_after_resampling, AUDIO_F32SYS, pre_resample_channels, dst_rate, dst_format, dst_channels, dst_rate) < 0) {
  953. SDL_FreeAudioStream(retval);
  954. return NULL; /* SDL_BuildAudioCVT should have called SDL_SetError. */
  955. }
  956. }
  957. retval->queue = SDL_NewDataQueue(packetlen, (size_t)packetlen * 2);
  958. if (!retval->queue) {
  959. SDL_FreeAudioStream(retval);
  960. return NULL; /* SDL_NewDataQueue should have called SDL_SetError. */
  961. }
  962. return retval;
  963. }
  964. static int SDL_AudioStreamPutInternal(SDL_AudioStream *stream, const void *buf, int len, int *maxputbytes)
  965. {
  966. int buflen = len;
  967. int workbuflen;
  968. Uint8 *workbuf;
  969. Uint8 *resamplebuf = NULL;
  970. int resamplebuflen = 0;
  971. int neededpaddingbytes;
  972. int paddingbytes;
  973. /* !!! FIXME: several converters can take advantage of SIMD, but only
  974. !!! FIXME: if the data is aligned to 16 bytes. EnsureStreamBufferSize()
  975. !!! FIXME: guarantees the buffer will align, but the
  976. !!! FIXME: converters will iterate over the data backwards if
  977. !!! FIXME: the output grows, and this means we won't align if buflen
  978. !!! FIXME: isn't a multiple of 16. In these cases, we should chop off
  979. !!! FIXME: a few samples at the end and convert them separately. */
  980. /* no padding prepended on first run. */
  981. neededpaddingbytes = stream->resampler_padding_samples * sizeof(float);
  982. paddingbytes = stream->first_run ? 0 : neededpaddingbytes;
  983. stream->first_run = SDL_FALSE;
  984. /* Make sure the work buffer can hold all the data we need at once... */
  985. workbuflen = buflen;
  986. if (stream->cvt_before_resampling.needed) {
  987. workbuflen *= stream->cvt_before_resampling.len_mult;
  988. }
  989. if (stream->dst_rate != stream->src_rate) {
  990. /* resamples can't happen in place, so make space for second buf. */
  991. const int framesize = stream->pre_resample_channels * sizeof(float);
  992. const int frames = workbuflen / framesize;
  993. resamplebuflen = ((int)SDL_ceil(frames * stream->rate_incr)) * framesize;
  994. #if DEBUG_AUDIOSTREAM
  995. SDL_Log("AUDIOSTREAM: will resample %d bytes to %d (ratio=%.6f)\n", workbuflen, resamplebuflen, stream->rate_incr);
  996. #endif
  997. workbuflen += resamplebuflen;
  998. }
  999. if (stream->cvt_after_resampling.needed) {
  1000. /* !!! FIXME: buffer might be big enough already? */
  1001. workbuflen *= stream->cvt_after_resampling.len_mult;
  1002. }
  1003. workbuflen += neededpaddingbytes;
  1004. #if DEBUG_AUDIOSTREAM
  1005. SDL_Log("AUDIOSTREAM: Putting %d bytes of preconverted audio, need %d byte work buffer\n", buflen, workbuflen);
  1006. #endif
  1007. workbuf = EnsureStreamBufferSize(stream, workbuflen);
  1008. if (!workbuf) {
  1009. return -1; /* probably out of memory. */
  1010. }
  1011. resamplebuf = workbuf; /* default if not resampling. */
  1012. SDL_memcpy(workbuf + paddingbytes, buf, buflen);
  1013. if (stream->cvt_before_resampling.needed) {
  1014. stream->cvt_before_resampling.buf = workbuf + paddingbytes;
  1015. stream->cvt_before_resampling.len = buflen;
  1016. if (SDL_ConvertAudio(&stream->cvt_before_resampling) == -1) {
  1017. return -1; /* uhoh! */
  1018. }
  1019. buflen = stream->cvt_before_resampling.len_cvt;
  1020. #if DEBUG_AUDIOSTREAM
  1021. SDL_Log("AUDIOSTREAM: After initial conversion we have %d bytes\n", buflen);
  1022. #endif
  1023. }
  1024. if (stream->dst_rate != stream->src_rate) {
  1025. /* save off some samples at the end; they are used for padding now so
  1026. the resampler is coherent and then used at the start of the next
  1027. put operation. Prepend last put operation's padding, too. */
  1028. /* prepend prior put's padding. :P */
  1029. if (paddingbytes) {
  1030. SDL_memcpy(workbuf, stream->resampler_padding, paddingbytes);
  1031. buflen += paddingbytes;
  1032. }
  1033. /* save off the data at the end for the next run. */
  1034. SDL_memcpy(stream->resampler_padding, workbuf + (buflen - neededpaddingbytes), neededpaddingbytes);
  1035. resamplebuf = workbuf + buflen; /* skip to second piece of workbuf. */
  1036. SDL_assert(buflen >= neededpaddingbytes);
  1037. if (buflen > neededpaddingbytes) {
  1038. buflen = stream->resampler_func(stream, workbuf, buflen - neededpaddingbytes, resamplebuf, resamplebuflen);
  1039. } else {
  1040. buflen = 0;
  1041. }
  1042. #if DEBUG_AUDIOSTREAM
  1043. SDL_Log("AUDIOSTREAM: After resampling we have %d bytes\n", buflen);
  1044. #endif
  1045. }
  1046. if (stream->cvt_after_resampling.needed && (buflen > 0)) {
  1047. stream->cvt_after_resampling.buf = resamplebuf;
  1048. stream->cvt_after_resampling.len = buflen;
  1049. if (SDL_ConvertAudio(&stream->cvt_after_resampling) == -1) {
  1050. return -1; /* uhoh! */
  1051. }
  1052. buflen = stream->cvt_after_resampling.len_cvt;
  1053. #if DEBUG_AUDIOSTREAM
  1054. SDL_Log("AUDIOSTREAM: After final conversion we have %d bytes\n", buflen);
  1055. #endif
  1056. }
  1057. #if DEBUG_AUDIOSTREAM
  1058. SDL_Log("AUDIOSTREAM: Final output is %d bytes\n", buflen);
  1059. #endif
  1060. if (maxputbytes) {
  1061. const int maxbytes = *maxputbytes;
  1062. if (buflen > maxbytes) {
  1063. buflen = maxbytes;
  1064. }
  1065. *maxputbytes -= buflen;
  1066. }
  1067. /* resamplebuf holds the final output, even if we didn't resample. */
  1068. return buflen ? SDL_WriteToDataQueue(stream->queue, resamplebuf, buflen) : 0;
  1069. }
  1070. int SDL_AudioStreamPut(SDL_AudioStream *stream, const void *buf, int len)
  1071. {
  1072. /* !!! FIXME: several converters can take advantage of SIMD, but only
  1073. !!! FIXME: if the data is aligned to 16 bytes. EnsureStreamBufferSize()
  1074. !!! FIXME: guarantees the buffer will align, but the
  1075. !!! FIXME: converters will iterate over the data backwards if
  1076. !!! FIXME: the output grows, and this means we won't align if buflen
  1077. !!! FIXME: isn't a multiple of 16. In these cases, we should chop off
  1078. !!! FIXME: a few samples at the end and convert them separately. */
  1079. #if DEBUG_AUDIOSTREAM
  1080. SDL_Log("AUDIOSTREAM: wants to put %d preconverted bytes\n", buflen);
  1081. #endif
  1082. if (!stream) {
  1083. return SDL_InvalidParamError("stream");
  1084. }
  1085. if (!buf) {
  1086. return SDL_InvalidParamError("buf");
  1087. }
  1088. if (len == 0) {
  1089. return 0; /* nothing to do. */
  1090. }
  1091. if ((len % stream->src_sample_frame_size) != 0) {
  1092. return SDL_SetError("Can't add partial sample frames");
  1093. }
  1094. if (!stream->cvt_before_resampling.needed &&
  1095. (stream->dst_rate == stream->src_rate) &&
  1096. !stream->cvt_after_resampling.needed) {
  1097. #if DEBUG_AUDIOSTREAM
  1098. SDL_Log("AUDIOSTREAM: no conversion needed at all, queueing %d bytes.\n", len);
  1099. #endif
  1100. return SDL_WriteToDataQueue(stream->queue, buf, len);
  1101. }
  1102. while (len > 0) {
  1103. int amount;
  1104. /* If we don't have a staging buffer or we're given enough data that
  1105. we don't need to store it for later, skip the staging process.
  1106. */
  1107. if (!stream->staging_buffer_filled && len >= stream->staging_buffer_size) {
  1108. return SDL_AudioStreamPutInternal(stream, buf, len, NULL);
  1109. }
  1110. /* If there's not enough data to fill the staging buffer, just save it */
  1111. if ((stream->staging_buffer_filled + len) < stream->staging_buffer_size) {
  1112. SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, len);
  1113. stream->staging_buffer_filled += len;
  1114. return 0;
  1115. }
  1116. /* Fill the staging buffer, process it, and continue */
  1117. amount = (stream->staging_buffer_size - stream->staging_buffer_filled);
  1118. SDL_assert(amount > 0);
  1119. SDL_memcpy(stream->staging_buffer + stream->staging_buffer_filled, buf, amount);
  1120. stream->staging_buffer_filled = 0;
  1121. if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, NULL) < 0) {
  1122. return -1;
  1123. }
  1124. buf = (void *)((Uint8 *)buf + amount);
  1125. len -= amount;
  1126. }
  1127. return 0;
  1128. }
  1129. int SDL_AudioStreamFlush(SDL_AudioStream *stream)
  1130. {
  1131. if (!stream) {
  1132. return SDL_InvalidParamError("stream");
  1133. }
  1134. #if DEBUG_AUDIOSTREAM
  1135. SDL_Log("AUDIOSTREAM: flushing! staging_buffer_filled=%d bytes\n", stream->staging_buffer_filled);
  1136. #endif
  1137. /* shouldn't use a staging buffer if we're not resampling. */
  1138. SDL_assert((stream->dst_rate != stream->src_rate) || (stream->staging_buffer_filled == 0));
  1139. if (stream->staging_buffer_filled > 0) {
  1140. /* push the staging buffer + silence. We need to flush out not just
  1141. the staging buffer, but the piece that the stream was saving off
  1142. for right-side resampler padding. */
  1143. const SDL_bool first_run = stream->first_run;
  1144. const int filled = stream->staging_buffer_filled;
  1145. int actual_input_frames = filled / stream->src_sample_frame_size;
  1146. if (!first_run) {
  1147. actual_input_frames += stream->resampler_padding_samples / stream->pre_resample_channels;
  1148. }
  1149. if (actual_input_frames > 0) { /* don't bother if nothing to flush. */
  1150. /* This is how many bytes we're expecting without silence appended. */
  1151. int flush_remaining = ((int)SDL_ceil(actual_input_frames * stream->rate_incr)) * stream->dst_sample_frame_size;
  1152. #if DEBUG_AUDIOSTREAM
  1153. SDL_Log("AUDIOSTREAM: flushing with padding to get max %d bytes!\n", flush_remaining);
  1154. #endif
  1155. SDL_memset(stream->staging_buffer + filled, '\0', stream->staging_buffer_size - filled);
  1156. if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, &flush_remaining) < 0) {
  1157. return -1;
  1158. }
  1159. /* we have flushed out (or initially filled) the pending right-side
  1160. resampler padding, but we need to push more silence to guarantee
  1161. the staging buffer is fully flushed out, too. */
  1162. SDL_memset(stream->staging_buffer, '\0', filled);
  1163. if (SDL_AudioStreamPutInternal(stream, stream->staging_buffer, stream->staging_buffer_size, &flush_remaining) < 0) {
  1164. return -1;
  1165. }
  1166. }
  1167. }
  1168. stream->staging_buffer_filled = 0;
  1169. stream->first_run = SDL_TRUE;
  1170. return 0;
  1171. }
  1172. /* get converted/resampled data from the stream */
  1173. int SDL_AudioStreamGet(SDL_AudioStream *stream, void *buf, int len)
  1174. {
  1175. #if DEBUG_AUDIOSTREAM
  1176. SDL_Log("AUDIOSTREAM: want to get %d converted bytes\n", len);
  1177. #endif
  1178. if (!stream) {
  1179. return SDL_InvalidParamError("stream");
  1180. }
  1181. if (!buf) {
  1182. return SDL_InvalidParamError("buf");
  1183. }
  1184. if (len <= 0) {
  1185. return 0; /* nothing to do. */
  1186. }
  1187. if ((len % stream->dst_sample_frame_size) != 0) {
  1188. return SDL_SetError("Can't request partial sample frames");
  1189. }
  1190. return (int)SDL_ReadFromDataQueue(stream->queue, buf, len);
  1191. }
  1192. /* number of converted/resampled bytes available */
  1193. int SDL_AudioStreamAvailable(SDL_AudioStream *stream)
  1194. {
  1195. return stream ? (int)SDL_CountDataQueue(stream->queue) : 0;
  1196. }
  1197. void SDL_AudioStreamClear(SDL_AudioStream *stream)
  1198. {
  1199. if (!stream) {
  1200. SDL_InvalidParamError("stream");
  1201. } else {
  1202. SDL_ClearDataQueue(stream->queue, (size_t)stream->packetlen * 2);
  1203. if (stream->reset_resampler_func) {
  1204. stream->reset_resampler_func(stream);
  1205. }
  1206. stream->first_run = SDL_TRUE;
  1207. stream->staging_buffer_filled = 0;
  1208. }
  1209. }
  1210. /* dispose of a stream */
  1211. void SDL_FreeAudioStream(SDL_AudioStream *stream)
  1212. {
  1213. if (stream) {
  1214. if (stream->cleanup_resampler_func) {
  1215. stream->cleanup_resampler_func(stream);
  1216. }
  1217. SDL_FreeDataQueue(stream->queue);
  1218. SDL_free(stream->staging_buffer);
  1219. SDL_free(stream->work_buffer_base);
  1220. SDL_free(stream->resampler_padding);
  1221. SDL_free(stream);
  1222. }
  1223. }
  1224. /* vi: set ts=4 sw=4 expandtab: */