soloud.cpp 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308
  1. /*
  2. SoLoud audio engine
  3. Copyright (c) 2013-2020 Jari Komppa
  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
  17. distribution.
  18. */
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <math.h> // sin
  22. #include <float.h> // _controlfp
  23. #include "soloud_internal.h"
  24. #include "soloud_thread.h"
  25. #include "soloud_fft.h"
  26. #ifdef SOLOUD_SSE_INTRINSICS
  27. #include <xmmintrin.h>
  28. #ifdef _M_IX86
  29. #include <emmintrin.h>
  30. #endif
  31. #endif
  32. //#define FLOATING_POINT_DEBUG
  33. #if !defined(WITH_SDL2) && !defined(WITH_SDL1) && !defined(WITH_PORTAUDIO) && \
  34. !defined(WITH_OPENAL) && !defined(WITH_XAUDIO2) && !defined(WITH_WINMM) && \
  35. !defined(WITH_WASAPI) && !defined(WITH_OSS) && !defined(WITH_SDL1_STATIC) && \
  36. !defined(WITH_SDL2_STATIC) && !defined(WITH_ALSA) && !defined(WITH_OPENSLES) && \
  37. !defined(WITH_NULL) && !defined(WITH_COREAUDIO) && !defined(WITH_VITA_HOMEBREW) &&\
  38. !defined(WITH_JACK) && !defined(WITH_NOSOUND) && !defined(WITH_MINIAUDIO)
  39. #error It appears you haven't enabled any of the back-ends. Please #define one or more of the WITH_ defines (or use premake) '
  40. #endif
  41. namespace SoLoud
  42. {
  43. AlignedFloatBuffer::AlignedFloatBuffer()
  44. {
  45. mBasePtr = 0;
  46. mData = 0;
  47. mFloats = 0;
  48. }
  49. result AlignedFloatBuffer::init(unsigned int aFloats)
  50. {
  51. delete[] mBasePtr;
  52. mBasePtr = 0;
  53. mData = 0;
  54. mFloats = aFloats;
  55. #ifndef SOLOUD_SSE_INTRINSICS
  56. mBasePtr = new unsigned char[aFloats * sizeof(float)];
  57. if (mBasePtr == NULL)
  58. return OUT_OF_MEMORY;
  59. mData = (float*)mBasePtr;
  60. #else
  61. mBasePtr = new unsigned char[aFloats * sizeof(float) + 16];
  62. if (mBasePtr == NULL)
  63. return OUT_OF_MEMORY;
  64. mData = (float *)(((size_t)mBasePtr + 15)&~15);
  65. #endif
  66. return SO_NO_ERROR;
  67. }
  68. void AlignedFloatBuffer::clear()
  69. {
  70. memset(mData, 0, sizeof(float) * mFloats);
  71. }
  72. AlignedFloatBuffer::~AlignedFloatBuffer()
  73. {
  74. delete[] mBasePtr;
  75. }
  76. TinyAlignedFloatBuffer::TinyAlignedFloatBuffer()
  77. {
  78. unsigned char * basePtr = &mActualData[0];
  79. mData = (float *)(((size_t)basePtr + 15)&~15);
  80. }
  81. Soloud::Soloud()
  82. {
  83. #ifdef FLOATING_POINT_DEBUG
  84. unsigned int u;
  85. u = _controlfp(0, 0);
  86. u = u & ~(_EM_INVALID | /*_EM_DENORMAL |*/ _EM_ZERODIVIDE | _EM_OVERFLOW /*| _EM_UNDERFLOW | _EM_INEXACT*/);
  87. _controlfp(u, _MCW_EM);
  88. #endif
  89. mResampler = SOLOUD_DEFAULT_RESAMPLER;
  90. mInsideAudioThreadMutex = false;
  91. mScratchSize = 0;
  92. mSamplerate = 0;
  93. mBufferSize = 0;
  94. mFlags = 0;
  95. mGlobalVolume = 0;
  96. mPlayIndex = 0;
  97. mBackendData = NULL;
  98. mAudioThreadMutex = NULL;
  99. mPostClipScaler = 0;
  100. mBackendCleanupFunc = NULL;
  101. mBackendPauseFunc = NULL;
  102. mBackendResumeFunc = NULL;
  103. mChannels = 2;
  104. mStreamTime = 0;
  105. mLastClockedTime = 0;
  106. mAudioSourceID = 1;
  107. mBackendString = 0;
  108. mBackendID = 0;
  109. mActiveVoiceDirty = true;
  110. mActiveVoiceCount = 0;
  111. int i;
  112. for (i = 0; i < VOICE_COUNT; i++)
  113. mActiveVoice[i] = 0;
  114. for (i = 0; i < FILTERS_PER_STREAM; i++)
  115. {
  116. mFilter[i] = NULL;
  117. mFilterInstance[i] = NULL;
  118. }
  119. for (i = 0; i < 256; i++)
  120. {
  121. mFFTData[i] = 0;
  122. mVisualizationWaveData[i] = 0;
  123. mWaveData[i] = 0;
  124. }
  125. for (i = 0; i < MAX_CHANNELS; i++)
  126. {
  127. mVisualizationChannelVolume[i] = 0;
  128. }
  129. for (i = 0; i < VOICE_COUNT; i++)
  130. {
  131. mVoice[i] = 0;
  132. }
  133. mVoiceGroup = 0;
  134. mVoiceGroupCount = 0;
  135. m3dPosition[0] = 0;
  136. m3dPosition[1] = 0;
  137. m3dPosition[2] = 0;
  138. m3dAt[0] = 0;
  139. m3dAt[1] = 0;
  140. m3dAt[2] = -1;
  141. m3dUp[0] = 0;
  142. m3dUp[1] = 1;
  143. m3dUp[2] = 0;
  144. m3dVelocity[0] = 0;
  145. m3dVelocity[1] = 0;
  146. m3dVelocity[2] = 0;
  147. m3dSoundSpeed = 343.3f;
  148. mMaxActiveVoices = 16;
  149. mHighestVoice = 0;
  150. mResampleData = NULL;
  151. mResampleDataOwner = NULL;
  152. for (i = 0; i < 3 * MAX_CHANNELS; i++)
  153. m3dSpeakerPosition[i] = 0;
  154. }
  155. Soloud::~Soloud()
  156. {
  157. // let's stop all sounds before deinit, so we don't mess up our mutexes
  158. stopAll();
  159. deinit();
  160. unsigned int i;
  161. for (i = 0; i < FILTERS_PER_STREAM; i++)
  162. {
  163. delete mFilterInstance[i];
  164. }
  165. for (i = 0; i < mVoiceGroupCount; i++)
  166. delete[] mVoiceGroup[i];
  167. delete[] mVoiceGroup;
  168. delete[] mResampleData;
  169. delete[] mResampleDataOwner;
  170. }
  171. void Soloud::deinit()
  172. {
  173. // Make sure no audio operation is currently pending
  174. lockAudioMutex_internal();
  175. unlockAudioMutex_internal();
  176. SOLOUD_ASSERT(!mInsideAudioThreadMutex);
  177. stopAll();
  178. if (mBackendCleanupFunc)
  179. mBackendCleanupFunc(this);
  180. mBackendCleanupFunc = 0;
  181. if (mAudioThreadMutex)
  182. Thread::destroyMutex(mAudioThreadMutex);
  183. mAudioThreadMutex = NULL;
  184. }
  185. result Soloud::init(unsigned int aFlags, unsigned int aBackend, unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aChannels)
  186. {
  187. if (aBackend >= BACKEND_MAX || aChannels == 3 || aChannels == 5 || aChannels == 7 || aChannels > MAX_CHANNELS)
  188. return INVALID_PARAMETER;
  189. deinit();
  190. mAudioThreadMutex = Thread::createMutex();
  191. mBackendID = 0;
  192. mBackendString = 0;
  193. int samplerate = 44100;
  194. int buffersize = 2048;
  195. int inited = 0;
  196. if (aSamplerate != Soloud::AUTO) samplerate = aSamplerate;
  197. if (aBufferSize != Soloud::AUTO) buffersize = aBufferSize;
  198. #if defined(WITH_SDL1_STATIC)
  199. if (!inited &&
  200. (aBackend == Soloud::SDL1 ||
  201. aBackend == Soloud::AUTO))
  202. {
  203. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  204. int ret = sdl1static_init(this, aFlags, samplerate, buffersize, aChannels);
  205. if (ret == 0)
  206. {
  207. inited = 1;
  208. mBackendID = Soloud::SDL1;
  209. }
  210. if (ret != 0 && aBackend != Soloud::AUTO)
  211. return ret;
  212. }
  213. #endif
  214. #if defined(WITH_SDL2_STATIC)
  215. if (!inited &&
  216. (aBackend == Soloud::SDL2 ||
  217. aBackend == Soloud::AUTO))
  218. {
  219. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  220. int ret = sdl2static_init(this, aFlags, samplerate, buffersize, aChannels);
  221. if (ret == 0)
  222. {
  223. inited = 1;
  224. mBackendID = Soloud::SDL2;
  225. }
  226. if (ret != 0 && aBackend != Soloud::AUTO)
  227. return ret;
  228. }
  229. #endif
  230. #if defined(WITH_SDL2)
  231. if (!inited &&
  232. (aBackend == Soloud::SDL2 ||
  233. aBackend == Soloud::AUTO))
  234. {
  235. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  236. int ret = sdl2_init(this, aFlags, samplerate, buffersize, aChannels);
  237. if (ret == 0)
  238. {
  239. inited = 1;
  240. mBackendID = Soloud::SDL2;
  241. }
  242. if (ret != 0 && aBackend != Soloud::AUTO)
  243. return ret;
  244. }
  245. #endif
  246. #if defined(WITH_SDL1)
  247. if (!inited &&
  248. (aBackend == Soloud::SDL1 ||
  249. aBackend == Soloud::AUTO))
  250. {
  251. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  252. int ret = sdl1_init(this, aFlags, samplerate, buffersize, aChannels);
  253. if (ret == 0)
  254. {
  255. inited = 1;
  256. mBackendID = Soloud::SDL1;
  257. }
  258. if (ret != 0 && aBackend != Soloud::AUTO)
  259. return ret;
  260. }
  261. #endif
  262. #if defined(WITH_MINIAUDIO)
  263. if (!inited &&
  264. (aBackend == Soloud::MINIAUDIO ||
  265. aBackend == Soloud::AUTO))
  266. {
  267. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  268. int ret = miniaudio_init(this, aFlags, samplerate, buffersize, aChannels);
  269. if (ret == 0)
  270. {
  271. inited = 1;
  272. mBackendID = Soloud::MINIAUDIO;
  273. }
  274. if (ret != 0 && aBackend != Soloud::AUTO)
  275. return ret;
  276. }
  277. #endif
  278. #if defined(WITH_PORTAUDIO)
  279. if (!inited &&
  280. (aBackend == Soloud::PORTAUDIO ||
  281. aBackend == Soloud::AUTO))
  282. {
  283. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  284. int ret = portaudio_init(this, aFlags, samplerate, buffersize, aChannels);
  285. if (ret == 0)
  286. {
  287. inited = 1;
  288. mBackendID = Soloud::PORTAUDIO;
  289. }
  290. if (ret != 0 && aBackend != Soloud::AUTO)
  291. return ret;
  292. }
  293. #endif
  294. #if defined(WITH_XAUDIO2)
  295. if (!inited &&
  296. (aBackend == Soloud::XAUDIO2 ||
  297. aBackend == Soloud::AUTO))
  298. {
  299. if (aBufferSize == Soloud::AUTO) buffersize = 4096;
  300. int ret = xaudio2_init(this, aFlags, samplerate, buffersize, aChannels);
  301. if (ret == 0)
  302. {
  303. inited = 1;
  304. mBackendID = Soloud::XAUDIO2;
  305. }
  306. if (ret != 0 && aBackend != Soloud::AUTO)
  307. return ret;
  308. }
  309. #endif
  310. #if defined(WITH_WINMM)
  311. if (!inited &&
  312. (aBackend == Soloud::WINMM ||
  313. aBackend == Soloud::AUTO))
  314. {
  315. if (aBufferSize == Soloud::AUTO) buffersize = 4096;
  316. int ret = winmm_init(this, aFlags, samplerate, buffersize, aChannels);
  317. if (ret == 0)
  318. {
  319. inited = 1;
  320. mBackendID = Soloud::WINMM;
  321. }
  322. if (ret != 0 && aBackend != Soloud::AUTO)
  323. return ret;
  324. }
  325. #endif
  326. #if defined(WITH_WASAPI)
  327. if (!inited &&
  328. (aBackend == Soloud::WASAPI ||
  329. aBackend == Soloud::AUTO))
  330. {
  331. if (aBufferSize == Soloud::AUTO) buffersize = 4096;
  332. if (aSamplerate == Soloud::AUTO) samplerate = 48000;
  333. int ret = wasapi_init(this, aFlags, samplerate, buffersize, aChannels);
  334. if (ret == 0)
  335. {
  336. inited = 1;
  337. mBackendID = Soloud::WASAPI;
  338. }
  339. if (ret != 0 && aBackend != Soloud::AUTO)
  340. return ret;
  341. }
  342. #endif
  343. #if defined(WITH_ALSA)
  344. if (!inited &&
  345. (aBackend == Soloud::ALSA ||
  346. aBackend == Soloud::AUTO))
  347. {
  348. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  349. int ret = alsa_init(this, aFlags, samplerate, buffersize, aChannels);
  350. if (ret == 0)
  351. {
  352. inited = 1;
  353. mBackendID = Soloud::ALSA;
  354. }
  355. if (ret != 0 && aBackend != Soloud::AUTO)
  356. return ret;
  357. }
  358. #endif
  359. #if defined(WITH_JACK)
  360. if (!inited &&
  361. (aBackend == Soloud::JACK ||
  362. aBackend == Soloud::AUTO))
  363. {
  364. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  365. int ret = jack_init(this, aFlags, samplerate, buffersize, aChannels);
  366. if (ret == 0)
  367. {
  368. inited = 1;
  369. mBackendID = Soloud::JACK;
  370. }
  371. if (ret != 0 && aBackend != Soloud::AUTO)
  372. return ret;
  373. }
  374. #endif
  375. #if defined(WITH_OSS)
  376. if (!inited &&
  377. (aBackend == Soloud::OSS ||
  378. aBackend == Soloud::AUTO))
  379. {
  380. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  381. int ret = oss_init(this, aFlags, samplerate, buffersize, aChannels);
  382. if (ret == 0)
  383. {
  384. inited = 1;
  385. mBackendID = Soloud::OSS;
  386. }
  387. if (ret != 0 && aBackend != Soloud::AUTO)
  388. return ret;
  389. }
  390. #endif
  391. #if defined(WITH_OPENAL)
  392. if (!inited &&
  393. (aBackend == Soloud::OPENAL ||
  394. aBackend == Soloud::AUTO))
  395. {
  396. if (aBufferSize == Soloud::AUTO) buffersize = 4096;
  397. int ret = openal_init(this, aFlags, samplerate, buffersize, aChannels);
  398. if (ret == 0)
  399. {
  400. inited = 1;
  401. mBackendID = Soloud::OPENAL;
  402. }
  403. if (ret != 0 && aBackend != Soloud::AUTO)
  404. return ret;
  405. }
  406. #endif
  407. #if defined(WITH_COREAUDIO)
  408. if (!inited &&
  409. (aBackend == Soloud::COREAUDIO ||
  410. aBackend == Soloud::AUTO))
  411. {
  412. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  413. int ret = coreaudio_init(this, aFlags, samplerate, buffersize, aChannels);
  414. if (ret == 0)
  415. {
  416. inited = 1;
  417. mBackendID = Soloud::COREAUDIO;
  418. }
  419. if (ret != 0 && aBackend != Soloud::AUTO)
  420. return ret;
  421. }
  422. #endif
  423. #if defined(WITH_OPENSLES)
  424. if (!inited &&
  425. (aBackend == Soloud::OPENSLES ||
  426. aBackend == Soloud::AUTO))
  427. {
  428. if (aBufferSize == Soloud::AUTO) buffersize = 4096;
  429. int ret = opensles_init(this, aFlags, samplerate, buffersize, aChannels);
  430. if (ret == 0)
  431. {
  432. inited = 1;
  433. mBackendID = Soloud::OPENSLES;
  434. }
  435. if (ret != 0 && aBackend != Soloud::AUTO)
  436. return ret;
  437. }
  438. #endif
  439. #if defined(WITH_VITA_HOMEBREW)
  440. if (!inited &&
  441. (aBackend == Soloud::VITA_HOMEBREW ||
  442. aBackend == Soloud::AUTO))
  443. {
  444. int ret = vita_homebrew_init(this, aFlags, samplerate, buffersize, aChannels);
  445. if (ret == 0)
  446. {
  447. inited = 1;
  448. mBackendID = Soloud::VITA_HOMEBREW;
  449. }
  450. if (ret != 0 && aBackend != Soloud::AUTO)
  451. return ret;
  452. }
  453. #endif
  454. #if defined(WITH_NOSOUND)
  455. if (!inited &&
  456. (aBackend == Soloud::NOSOUND ||
  457. aBackend == Soloud::AUTO))
  458. {
  459. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  460. int ret = nosound_init(this, aFlags, samplerate, buffersize, aChannels);
  461. if (ret == 0)
  462. {
  463. inited = 1;
  464. mBackendID = Soloud::NOSOUND;
  465. }
  466. if (ret != 0 && aBackend != Soloud::AUTO)
  467. return ret;
  468. }
  469. #endif
  470. #if defined(WITH_NULL)
  471. if (!inited &&
  472. (aBackend == Soloud::NULLDRIVER))
  473. {
  474. if (aBufferSize == Soloud::AUTO) buffersize = 2048;
  475. int ret = null_init(this, aFlags, samplerate, buffersize, aChannels);
  476. if (ret == 0)
  477. {
  478. inited = 1;
  479. mBackendID = Soloud::NULLDRIVER;
  480. }
  481. if (ret != 0)
  482. return ret;
  483. }
  484. #endif
  485. if (!inited && aBackend != Soloud::AUTO)
  486. return NOT_IMPLEMENTED;
  487. if (!inited)
  488. return UNKNOWN_ERROR;
  489. return 0;
  490. }
  491. result Soloud::pause()
  492. {
  493. if (mBackendPauseFunc)
  494. return mBackendPauseFunc(this);
  495. return NOT_IMPLEMENTED;
  496. }
  497. result Soloud::resume()
  498. {
  499. if (mBackendResumeFunc)
  500. return mBackendResumeFunc(this);
  501. return NOT_IMPLEMENTED;
  502. }
  503. void Soloud::postinit_internal(unsigned int aSamplerate, unsigned int aBufferSize, unsigned int aFlags, unsigned int aChannels)
  504. {
  505. mGlobalVolume = 1;
  506. mChannels = aChannels;
  507. mSamplerate = aSamplerate;
  508. mBufferSize = aBufferSize;
  509. mScratchSize = (aBufferSize + 15) & (~0xf); // round to the next div by 16
  510. if (mScratchSize < SAMPLE_GRANULARITY * 2) mScratchSize = SAMPLE_GRANULARITY * 2;
  511. if (mScratchSize < 4096) mScratchSize = 4096;
  512. mScratch.init(mScratchSize * MAX_CHANNELS);
  513. mOutputScratch.init(mScratchSize * MAX_CHANNELS);
  514. mResampleData = new float*[mMaxActiveVoices * 2];
  515. mResampleDataOwner = new AudioSourceInstance*[mMaxActiveVoices];
  516. mResampleDataBuffer.init(mMaxActiveVoices * 2 * SAMPLE_GRANULARITY * MAX_CHANNELS);
  517. unsigned int i;
  518. for (i = 0; i < mMaxActiveVoices * 2; i++)
  519. mResampleData[i] = mResampleDataBuffer.mData + (SAMPLE_GRANULARITY * MAX_CHANNELS * i);
  520. for (i = 0; i < mMaxActiveVoices; i++)
  521. mResampleDataOwner[i] = NULL;
  522. mFlags = aFlags;
  523. mPostClipScaler = 0.95f;
  524. switch (mChannels)
  525. {
  526. case 1:
  527. m3dSpeakerPosition[0 * 3 + 0] = 0;
  528. m3dSpeakerPosition[0 * 3 + 1] = 0;
  529. m3dSpeakerPosition[0 * 3 + 2] = 1;
  530. break;
  531. case 2:
  532. m3dSpeakerPosition[0 * 3 + 0] = 2;
  533. m3dSpeakerPosition[0 * 3 + 1] = 0;
  534. m3dSpeakerPosition[0 * 3 + 2] = 1;
  535. m3dSpeakerPosition[1 * 3 + 0] = -2;
  536. m3dSpeakerPosition[1 * 3 + 1] = 0;
  537. m3dSpeakerPosition[1 * 3 + 2] = 1;
  538. break;
  539. case 4:
  540. m3dSpeakerPosition[0 * 3 + 0] = 2;
  541. m3dSpeakerPosition[0 * 3 + 1] = 0;
  542. m3dSpeakerPosition[0 * 3 + 2] = 1;
  543. m3dSpeakerPosition[1 * 3 + 0] = -2;
  544. m3dSpeakerPosition[1 * 3 + 1] = 0;
  545. m3dSpeakerPosition[1 * 3 + 2] = 1;
  546. // I suppose technically the second pair should be straight left & right,
  547. // but I prefer moving them a bit back to mirror the front speakers.
  548. m3dSpeakerPosition[2 * 3 + 0] = 2;
  549. m3dSpeakerPosition[2 * 3 + 1] = 0;
  550. m3dSpeakerPosition[2 * 3 + 2] = -1;
  551. m3dSpeakerPosition[3 * 3 + 0] = -2;
  552. m3dSpeakerPosition[3 * 3 + 1] = 0;
  553. m3dSpeakerPosition[3 * 3 + 2] = -1;
  554. break;
  555. case 6:
  556. m3dSpeakerPosition[0 * 3 + 0] = 2;
  557. m3dSpeakerPosition[0 * 3 + 1] = 0;
  558. m3dSpeakerPosition[0 * 3 + 2] = 1;
  559. m3dSpeakerPosition[1 * 3 + 0] = -2;
  560. m3dSpeakerPosition[1 * 3 + 1] = 0;
  561. m3dSpeakerPosition[1 * 3 + 2] = 1;
  562. // center and subwoofer.
  563. m3dSpeakerPosition[2 * 3 + 0] = 0;
  564. m3dSpeakerPosition[2 * 3 + 1] = 0;
  565. m3dSpeakerPosition[2 * 3 + 2] = 1;
  566. // Sub should be "mix of everything". We'll handle it as a special case and make it a null vector.
  567. m3dSpeakerPosition[3 * 3 + 0] = 0;
  568. m3dSpeakerPosition[3 * 3 + 1] = 0;
  569. m3dSpeakerPosition[3 * 3 + 2] = 0;
  570. // I suppose technically the second pair should be straight left & right,
  571. // but I prefer moving them a bit back to mirror the front speakers.
  572. m3dSpeakerPosition[4 * 3 + 0] = 2;
  573. m3dSpeakerPosition[4 * 3 + 1] = 0;
  574. m3dSpeakerPosition[4 * 3 + 2] = -1;
  575. m3dSpeakerPosition[5 * 3 + 0] = -2;
  576. m3dSpeakerPosition[5 * 3 + 1] = 0;
  577. m3dSpeakerPosition[5 * 3 + 2] = -1;
  578. break;
  579. case 8:
  580. m3dSpeakerPosition[0 * 3 + 0] = 2;
  581. m3dSpeakerPosition[0 * 3 + 1] = 0;
  582. m3dSpeakerPosition[0 * 3 + 2] = 1;
  583. m3dSpeakerPosition[1 * 3 + 0] = -2;
  584. m3dSpeakerPosition[1 * 3 + 1] = 0;
  585. m3dSpeakerPosition[1 * 3 + 2] = 1;
  586. // center and subwoofer.
  587. m3dSpeakerPosition[2 * 3 + 0] = 0;
  588. m3dSpeakerPosition[2 * 3 + 1] = 0;
  589. m3dSpeakerPosition[2 * 3 + 2] = 1;
  590. // Sub should be "mix of everything". We'll handle it as a special case and make it a null vector.
  591. m3dSpeakerPosition[3 * 3 + 0] = 0;
  592. m3dSpeakerPosition[3 * 3 + 1] = 0;
  593. m3dSpeakerPosition[3 * 3 + 2] = 0;
  594. // side
  595. m3dSpeakerPosition[4 * 3 + 0] = 2;
  596. m3dSpeakerPosition[4 * 3 + 1] = 0;
  597. m3dSpeakerPosition[4 * 3 + 2] = 0;
  598. m3dSpeakerPosition[5 * 3 + 0] = -2;
  599. m3dSpeakerPosition[5 * 3 + 1] = 0;
  600. m3dSpeakerPosition[5 * 3 + 2] = 0;
  601. // back
  602. m3dSpeakerPosition[6 * 3 + 0] = 2;
  603. m3dSpeakerPosition[6 * 3 + 1] = 0;
  604. m3dSpeakerPosition[6 * 3 + 2] = -1;
  605. m3dSpeakerPosition[7 * 3 + 0] = -2;
  606. m3dSpeakerPosition[7 * 3 + 1] = 0;
  607. m3dSpeakerPosition[7 * 3 + 2] = -1;
  608. break;
  609. }
  610. }
  611. const char * Soloud::getErrorString(result aErrorCode) const
  612. {
  613. switch (aErrorCode)
  614. {
  615. case SO_NO_ERROR: return "No error";
  616. case INVALID_PARAMETER: return "Some parameter is invalid";
  617. case FILE_NOT_FOUND: return "File not found";
  618. case FILE_LOAD_FAILED: return "File found, but could not be loaded";
  619. case DLL_NOT_FOUND: return "DLL not found, or wrong DLL";
  620. case OUT_OF_MEMORY: return "Out of memory";
  621. case NOT_IMPLEMENTED: return "Feature not implemented";
  622. /*case UNKNOWN_ERROR: return "Other error";*/
  623. }
  624. return "Other error";
  625. }
  626. float * Soloud::getWave()
  627. {
  628. int i;
  629. lockAudioMutex_internal();
  630. for (i = 0; i < 256; i++)
  631. mWaveData[i] = mVisualizationWaveData[i];
  632. unlockAudioMutex_internal();
  633. return mWaveData;
  634. }
  635. float Soloud::getApproximateVolume(unsigned int aChannel)
  636. {
  637. if (aChannel > mChannels)
  638. return 0;
  639. float vol = 0;
  640. lockAudioMutex_internal();
  641. vol = mVisualizationChannelVolume[aChannel];
  642. unlockAudioMutex_internal();
  643. return vol;
  644. }
  645. float * Soloud::calcFFT()
  646. {
  647. lockAudioMutex_internal();
  648. float temp[1024];
  649. int i;
  650. for (i = 0; i < 256; i++)
  651. {
  652. temp[i*2] = mVisualizationWaveData[i];
  653. temp[i*2+1] = 0;
  654. temp[i+512] = 0;
  655. temp[i+768] = 0;
  656. }
  657. unlockAudioMutex_internal();
  658. SoLoud::FFT::fft1024(temp);
  659. for (i = 0; i < 256; i++)
  660. {
  661. float real = temp[i * 2];
  662. float imag = temp[i * 2 + 1];
  663. mFFTData[i] = (float)sqrt(real*real+imag*imag);
  664. }
  665. return mFFTData;
  666. }
  667. #if defined(SOLOUD_SSE_INTRINSICS)
  668. void Soloud::clip_internal(AlignedFloatBuffer &aBuffer, AlignedFloatBuffer &aDestBuffer, unsigned int aSamples, float aVolume0, float aVolume1)
  669. {
  670. float vd = (aVolume1 - aVolume0) / aSamples;
  671. float v = aVolume0;
  672. unsigned int i, j, c, d;
  673. unsigned int samplequads = (aSamples + 3) / 4; // rounded up
  674. // Clip
  675. if (mFlags & CLIP_ROUNDOFF)
  676. {
  677. float nb = -1.65f; __m128 negbound = _mm_load_ps1(&nb);
  678. float pb = 1.65f; __m128 posbound = _mm_load_ps1(&pb);
  679. float ls = 0.87f; __m128 linearscale = _mm_load_ps1(&ls);
  680. float cs = -0.1f; __m128 cubicscale = _mm_load_ps1(&cs);
  681. float nw = -0.9862875f; __m128 negwall = _mm_load_ps1(&nw);
  682. float pw = 0.9862875f; __m128 poswall = _mm_load_ps1(&pw);
  683. __m128 postscale = _mm_load_ps1(&mPostClipScaler);
  684. TinyAlignedFloatBuffer volumes;
  685. volumes.mData[0] = v;
  686. volumes.mData[1] = v + vd;
  687. volumes.mData[2] = v + vd + vd;
  688. volumes.mData[3] = v + vd + vd + vd;
  689. vd *= 4;
  690. __m128 vdelta = _mm_load_ps1(&vd);
  691. c = 0;
  692. d = 0;
  693. for (j = 0; j < mChannels; j++)
  694. {
  695. __m128 vol = _mm_load_ps(volumes.mData);
  696. for (i = 0; i < samplequads; i++)
  697. {
  698. //float f1 = origdata[c] * v; c++; v += vd;
  699. __m128 f = _mm_load_ps(&aBuffer.mData[c]);
  700. c += 4;
  701. f = _mm_mul_ps(f, vol);
  702. vol = _mm_add_ps(vol, vdelta);
  703. //float u1 = (f1 > -1.65f);
  704. __m128 u = _mm_cmpgt_ps(f, negbound);
  705. //float o1 = (f1 < 1.65f);
  706. __m128 o = _mm_cmplt_ps(f, posbound);
  707. //f1 = (0.87f * f1 - 0.1f * f1 * f1 * f1) * u1 * o1;
  708. __m128 lin = _mm_mul_ps(f, linearscale);
  709. __m128 cubic = _mm_mul_ps(f, f);
  710. cubic = _mm_mul_ps(cubic, f);
  711. cubic = _mm_mul_ps(cubic, cubicscale);
  712. f = _mm_add_ps(cubic, lin);
  713. //f1 = f1 * u1 + !u1 * -0.9862875f;
  714. __m128 lowmask = _mm_andnot_ps(u, negwall);
  715. __m128 ilowmask = _mm_and_ps(u, f);
  716. f = _mm_add_ps(lowmask, ilowmask);
  717. //f1 = f1 * o1 + !o1 * 0.9862875f;
  718. __m128 himask = _mm_andnot_ps(o, poswall);
  719. __m128 ihimask = _mm_and_ps(o, f);
  720. f = _mm_add_ps(himask, ihimask);
  721. // outdata[d] = f1 * postclip; d++;
  722. f = _mm_mul_ps(f, postscale);
  723. _mm_store_ps(&aDestBuffer.mData[d], f);
  724. d += 4;
  725. }
  726. }
  727. }
  728. else
  729. {
  730. float nb = -1.0f; __m128 negbound = _mm_load_ps1(&nb);
  731. float pb = 1.0f; __m128 posbound = _mm_load_ps1(&pb);
  732. __m128 postscale = _mm_load_ps1(&mPostClipScaler);
  733. TinyAlignedFloatBuffer volumes;
  734. volumes.mData[0] = v;
  735. volumes.mData[1] = v + vd;
  736. volumes.mData[2] = v + vd + vd;
  737. volumes.mData[3] = v + vd + vd + vd;
  738. vd *= 4;
  739. __m128 vdelta = _mm_load_ps1(&vd);
  740. c = 0;
  741. d = 0;
  742. for (j = 0; j < mChannels; j++)
  743. {
  744. __m128 vol = _mm_load_ps(volumes.mData);
  745. for (i = 0; i < samplequads; i++)
  746. {
  747. //float f1 = aBuffer.mData[c] * v; c++; v += vd;
  748. __m128 f = _mm_load_ps(&aBuffer.mData[c]);
  749. c += 4;
  750. f = _mm_mul_ps(f, vol);
  751. vol = _mm_add_ps(vol, vdelta);
  752. //f1 = (f1 <= -1) ? -1 : (f1 >= 1) ? 1 : f1;
  753. f = _mm_max_ps(f, negbound);
  754. f = _mm_min_ps(f, posbound);
  755. //aDestBuffer.mData[d] = f1 * mPostClipScaler; d++;
  756. f = _mm_mul_ps(f, postscale);
  757. _mm_store_ps(&aDestBuffer.mData[d], f);
  758. d += 4;
  759. }
  760. }
  761. }
  762. }
  763. #else // fallback code
  764. void Soloud::clip_internal(AlignedFloatBuffer &aBuffer, AlignedFloatBuffer &aDestBuffer, unsigned int aSamples, float aVolume0, float aVolume1)
  765. {
  766. float vd = (aVolume1 - aVolume0) / aSamples;
  767. float v = aVolume0;
  768. unsigned int i, j, c, d;
  769. unsigned int samplequads = (aSamples + 3) / 4; // rounded up
  770. // Clip
  771. if (mFlags & CLIP_ROUNDOFF)
  772. {
  773. c = 0;
  774. d = 0;
  775. for (j = 0; j < mChannels; j++)
  776. {
  777. v = aVolume0;
  778. for (i = 0; i < samplequads; i++)
  779. {
  780. float f1 = aBuffer.mData[c] * v; c++; v += vd;
  781. float f2 = aBuffer.mData[c] * v; c++; v += vd;
  782. float f3 = aBuffer.mData[c] * v; c++; v += vd;
  783. float f4 = aBuffer.mData[c] * v; c++; v += vd;
  784. f1 = (f1 <= -1.65f) ? -0.9862875f : (f1 >= 1.65f) ? 0.9862875f : (0.87f * f1 - 0.1f * f1 * f1 * f1);
  785. f2 = (f2 <= -1.65f) ? -0.9862875f : (f2 >= 1.65f) ? 0.9862875f : (0.87f * f2 - 0.1f * f2 * f2 * f2);
  786. f3 = (f3 <= -1.65f) ? -0.9862875f : (f3 >= 1.65f) ? 0.9862875f : (0.87f * f3 - 0.1f * f3 * f3 * f3);
  787. f4 = (f4 <= -1.65f) ? -0.9862875f : (f4 >= 1.65f) ? 0.9862875f : (0.87f * f4 - 0.1f * f4 * f4 * f4);
  788. aDestBuffer.mData[d] = f1 * mPostClipScaler; d++;
  789. aDestBuffer.mData[d] = f2 * mPostClipScaler; d++;
  790. aDestBuffer.mData[d] = f3 * mPostClipScaler; d++;
  791. aDestBuffer.mData[d] = f4 * mPostClipScaler; d++;
  792. }
  793. }
  794. }
  795. else
  796. {
  797. c = 0;
  798. d = 0;
  799. for (j = 0; j < mChannels; j++)
  800. {
  801. v = aVolume0;
  802. for (i = 0; i < samplequads; i++)
  803. {
  804. float f1 = aBuffer.mData[c] * v; c++; v += vd;
  805. float f2 = aBuffer.mData[c] * v; c++; v += vd;
  806. float f3 = aBuffer.mData[c] * v; c++; v += vd;
  807. float f4 = aBuffer.mData[c] * v; c++; v += vd;
  808. f1 = (f1 <= -1) ? -1 : (f1 >= 1) ? 1 : f1;
  809. f2 = (f2 <= -1) ? -1 : (f2 >= 1) ? 1 : f2;
  810. f3 = (f3 <= -1) ? -1 : (f3 >= 1) ? 1 : f3;
  811. f4 = (f4 <= -1) ? -1 : (f4 >= 1) ? 1 : f4;
  812. aDestBuffer.mData[d] = f1 * mPostClipScaler; d++;
  813. aDestBuffer.mData[d] = f2 * mPostClipScaler; d++;
  814. aDestBuffer.mData[d] = f3 * mPostClipScaler; d++;
  815. aDestBuffer.mData[d] = f4 * mPostClipScaler; d++;
  816. }
  817. }
  818. }
  819. }
  820. #endif
  821. #define FIXPOINT_FRAC_BITS 20
  822. #define FIXPOINT_FRAC_MUL (1 << FIXPOINT_FRAC_BITS)
  823. #define FIXPOINT_FRAC_MASK ((1 << FIXPOINT_FRAC_BITS) - 1)
  824. static float catmullrom(float t, float p0, float p1, float p2, float p3)
  825. {
  826. return 0.5f * (
  827. (2 * p1) +
  828. (-p0 + p2) * t +
  829. (2 * p0 - 5 * p1 + 4 * p2 - p3) * t * t +
  830. (-p0 + 3 * p1 - 3 * p2 + p3) * t * t * t
  831. );
  832. }
  833. static void resample_catmullrom(float* aSrc,
  834. float* aSrc1,
  835. float* aDst,
  836. int aSrcOffset,
  837. int aDstSampleCount,
  838. int aStepFixed)
  839. {
  840. int i;
  841. int pos = aSrcOffset;
  842. for (i = 0; i < aDstSampleCount; i++, pos += aStepFixed)
  843. {
  844. int p = pos >> FIXPOINT_FRAC_BITS;
  845. int f = pos & FIXPOINT_FRAC_MASK;
  846. float s0, s1, s2, s3;
  847. if (p < 3)
  848. {
  849. s3 = aSrc1[512 + p - 3];
  850. }
  851. else
  852. {
  853. s3 = aSrc[p - 3];
  854. }
  855. if (p < 2)
  856. {
  857. s2 = aSrc1[512 + p - 2];
  858. }
  859. else
  860. {
  861. s2 = aSrc[p - 2];
  862. }
  863. if (p < 1)
  864. {
  865. s1 = aSrc1[512 + p - 1];
  866. }
  867. else
  868. {
  869. s1 = aSrc[p - 1];
  870. }
  871. s0 = aSrc[p];
  872. aDst[i] = catmullrom(f / (float)FIXPOINT_FRAC_MUL, s3, s2, s1, s0);
  873. }
  874. }
  875. static void resample_linear(float* aSrc,
  876. float* aSrc1,
  877. float* aDst,
  878. int aSrcOffset,
  879. int aDstSampleCount,
  880. int aStepFixed)
  881. {
  882. int i;
  883. int pos = aSrcOffset;
  884. for (i = 0; i < aDstSampleCount; i++, pos += aStepFixed)
  885. {
  886. int p = pos >> FIXPOINT_FRAC_BITS;
  887. int f = pos & FIXPOINT_FRAC_MASK;
  888. #ifdef _DEBUG
  889. if (p >= SAMPLE_GRANULARITY || p < 0)
  890. {
  891. // This should never actually happen
  892. p = SAMPLE_GRANULARITY - 1;
  893. }
  894. #endif
  895. float s1 = aSrc1[SAMPLE_GRANULARITY - 1];
  896. float s2 = aSrc[p];
  897. if (p != 0)
  898. {
  899. s1 = aSrc[p - 1];
  900. }
  901. aDst[i] = s1 + (s2 - s1) * f * (1 / (float)FIXPOINT_FRAC_MUL);
  902. }
  903. }
  904. static void resample_point(float* aSrc,
  905. float* aSrc1,
  906. float* aDst,
  907. int aSrcOffset,
  908. int aDstSampleCount,
  909. int aStepFixed)
  910. {
  911. int i;
  912. int pos = aSrcOffset;
  913. for (i = 0; i < aDstSampleCount; i++, pos += aStepFixed)
  914. {
  915. int p = pos >> FIXPOINT_FRAC_BITS;
  916. aDst[i] = aSrc[p];
  917. }
  918. }
  919. void panAndExpand(AudioSourceInstance *aVoice, float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize, float *aScratch, unsigned int aChannels)
  920. {
  921. #ifdef SOLOUD_SSE_INTRINSICS
  922. SOLOUD_ASSERT(((size_t)aBuffer & 0xf) == 0);
  923. SOLOUD_ASSERT(((size_t)aScratch & 0xf) == 0);
  924. SOLOUD_ASSERT(((size_t)aBufferSize & 0xf) == 0);
  925. #endif
  926. float pan[MAX_CHANNELS]; // current speaker volume
  927. float pand[MAX_CHANNELS]; // destination speaker volume
  928. float pani[MAX_CHANNELS]; // speaker volume increment per sample
  929. unsigned int j, k;
  930. for (k = 0; k < aChannels; k++)
  931. {
  932. pan[k] = aVoice->mCurrentChannelVolume[k];
  933. pand[k] = aVoice->mChannelVolume[k] * aVoice->mOverallVolume;
  934. pani[k] = (pand[k] - pan[k]) / aSamplesToRead; // TODO: this is a bit inconsistent.. but it's a hack to begin with
  935. }
  936. int ofs = 0;
  937. switch (aChannels)
  938. {
  939. case 1: // Target is mono. Sum everything. (1->1, 2->1, 4->1, 6->1, 8->1)
  940. for (j = 0, ofs = 0; j < aVoice->mChannels; j++, ofs += aBufferSize)
  941. {
  942. pan[0] = aVoice->mCurrentChannelVolume[0];
  943. for (k = 0; k < aSamplesToRead; k++)
  944. {
  945. pan[0] += pani[0];
  946. aBuffer[k] += aScratch[ofs + k] * pan[0];
  947. }
  948. }
  949. break;
  950. case 2:
  951. switch (aVoice->mChannels)
  952. {
  953. case 8: // 8->2, just sum lefties and righties, add a bit of center and sub?
  954. for (j = 0; j < aSamplesToRead; j++)
  955. {
  956. pan[0] += pani[0];
  957. pan[1] += pani[1];
  958. float s1 = aScratch[j];
  959. float s2 = aScratch[aBufferSize + j];
  960. float s3 = aScratch[aBufferSize * 2 + j];
  961. float s4 = aScratch[aBufferSize * 3 + j];
  962. float s5 = aScratch[aBufferSize * 4 + j];
  963. float s6 = aScratch[aBufferSize * 5 + j];
  964. float s7 = aScratch[aBufferSize * 6 + j];
  965. float s8 = aScratch[aBufferSize * 7 + j];
  966. aBuffer[j + 0] += 0.2f * (s1 + s3 + s4 + s5 + s7) * pan[0];
  967. aBuffer[j + aBufferSize] += 0.2f * (s2 + s3 + s4 + s6 + s8) * pan[1];
  968. }
  969. break;
  970. case 6: // 6->2, just sum lefties and righties, add a bit of center and sub?
  971. for (j = 0; j < aSamplesToRead; j++)
  972. {
  973. pan[0] += pani[0];
  974. pan[1] += pani[1];
  975. float s1 = aScratch[j];
  976. float s2 = aScratch[aBufferSize + j];
  977. float s3 = aScratch[aBufferSize * 2 + j];
  978. float s4 = aScratch[aBufferSize * 3 + j];
  979. float s5 = aScratch[aBufferSize * 4 + j];
  980. float s6 = aScratch[aBufferSize * 5 + j];
  981. aBuffer[j + 0] += 0.3f * (s1 + s3 + s4 + s5) * pan[0];
  982. aBuffer[j + aBufferSize] += 0.3f * (s2 + s3 + s4 + s6) * pan[1];
  983. }
  984. break;
  985. case 4: // 4->2, just sum lefties and righties
  986. for (j = 0; j < aSamplesToRead; j++)
  987. {
  988. pan[0] += pani[0];
  989. pan[1] += pani[1];
  990. float s1 = aScratch[j];
  991. float s2 = aScratch[aBufferSize + j];
  992. float s3 = aScratch[aBufferSize * 2 + j];
  993. float s4 = aScratch[aBufferSize * 3 + j];
  994. aBuffer[j + 0] += 0.5f * (s1 + s3) * pan[0];
  995. aBuffer[j + aBufferSize] += 0.5f * (s2 + s4) * pan[1];
  996. }
  997. break;
  998. case 2: // 2->2
  999. #if defined(SOLOUD_SSE_INTRINSICS)
  1000. {
  1001. int c = 0;
  1002. //if ((aBufferSize & 3) == 0)
  1003. {
  1004. unsigned int samplequads = aSamplesToRead / 4; // rounded down
  1005. TinyAlignedFloatBuffer pan0;
  1006. pan0.mData[0] = pan[0] + pani[0];
  1007. pan0.mData[1] = pan[0] + pani[0] * 2;
  1008. pan0.mData[2] = pan[0] + pani[0] * 3;
  1009. pan0.mData[3] = pan[0] + pani[0] * 4;
  1010. TinyAlignedFloatBuffer pan1;
  1011. pan1.mData[0] = pan[1] + pani[1];
  1012. pan1.mData[1] = pan[1] + pani[1] * 2;
  1013. pan1.mData[2] = pan[1] + pani[1] * 3;
  1014. pan1.mData[3] = pan[1] + pani[1] * 4;
  1015. pani[0] *= 4;
  1016. pani[1] *= 4;
  1017. __m128 pan0delta = _mm_load_ps1(&pani[0]);
  1018. __m128 pan1delta = _mm_load_ps1(&pani[1]);
  1019. __m128 p0 = _mm_load_ps(pan0.mData);
  1020. __m128 p1 = _mm_load_ps(pan1.mData);
  1021. for (j = 0; j < samplequads; j++)
  1022. {
  1023. __m128 f0 = _mm_load_ps(aScratch + c);
  1024. __m128 c0 = _mm_mul_ps(f0, p0);
  1025. __m128 f1 = _mm_load_ps(aScratch + c + aBufferSize);
  1026. __m128 c1 = _mm_mul_ps(f1, p1);
  1027. __m128 o0 = _mm_load_ps(aBuffer + c);
  1028. __m128 o1 = _mm_load_ps(aBuffer + c + aBufferSize);
  1029. c0 = _mm_add_ps(c0, o0);
  1030. c1 = _mm_add_ps(c1, o1);
  1031. _mm_store_ps(aBuffer + c, c0);
  1032. _mm_store_ps(aBuffer + c + aBufferSize, c1);
  1033. p0 = _mm_add_ps(p0, pan0delta);
  1034. p1 = _mm_add_ps(p1, pan1delta);
  1035. c += 4;
  1036. }
  1037. }
  1038. // If buffer size or samples to read are not divisible by 4, handle leftovers
  1039. for (j = c; j < aSamplesToRead; j++)
  1040. {
  1041. pan[0] += pani[0];
  1042. pan[1] += pani[1];
  1043. float s1 = aScratch[j];
  1044. float s2 = aScratch[aBufferSize + j];
  1045. aBuffer[j + 0] += s1 * pan[0];
  1046. aBuffer[j + aBufferSize] += s2 * pan[1];
  1047. }
  1048. }
  1049. #else // fallback
  1050. for (j = 0; j < aSamplesToRead; j++)
  1051. {
  1052. pan[0] += pani[0];
  1053. pan[1] += pani[1];
  1054. float s1 = aScratch[j];
  1055. float s2 = aScratch[aBufferSize + j];
  1056. aBuffer[j + 0] += s1 * pan[0];
  1057. aBuffer[j + aBufferSize] += s2 * pan[1];
  1058. }
  1059. #endif
  1060. break;
  1061. case 1: // 1->2
  1062. #if defined(SOLOUD_SSE_INTRINSICS)
  1063. {
  1064. int c = 0;
  1065. //if ((aBufferSize & 3) == 0)
  1066. {
  1067. unsigned int samplequads = aSamplesToRead / 4; // rounded down
  1068. TinyAlignedFloatBuffer pan0;
  1069. pan0.mData[0] = pan[0] + pani[0];
  1070. pan0.mData[1] = pan[0] + pani[0] * 2;
  1071. pan0.mData[2] = pan[0] + pani[0] * 3;
  1072. pan0.mData[3] = pan[0] + pani[0] * 4;
  1073. TinyAlignedFloatBuffer pan1;
  1074. pan1.mData[0] = pan[1] + pani[1];
  1075. pan1.mData[1] = pan[1] + pani[1] * 2;
  1076. pan1.mData[2] = pan[1] + pani[1] * 3;
  1077. pan1.mData[3] = pan[1] + pani[1] * 4;
  1078. pani[0] *= 4;
  1079. pani[1] *= 4;
  1080. __m128 pan0delta = _mm_load_ps1(&pani[0]);
  1081. __m128 pan1delta = _mm_load_ps1(&pani[1]);
  1082. __m128 p0 = _mm_load_ps(pan0.mData);
  1083. __m128 p1 = _mm_load_ps(pan1.mData);
  1084. for (j = 0; j < samplequads; j++)
  1085. {
  1086. __m128 f = _mm_load_ps(aScratch + c);
  1087. __m128 c0 = _mm_mul_ps(f, p0);
  1088. __m128 c1 = _mm_mul_ps(f, p1);
  1089. __m128 o0 = _mm_load_ps(aBuffer + c);
  1090. __m128 o1 = _mm_load_ps(aBuffer + c + aBufferSize);
  1091. c0 = _mm_add_ps(c0, o0);
  1092. c1 = _mm_add_ps(c1, o1);
  1093. _mm_store_ps(aBuffer + c, c0);
  1094. _mm_store_ps(aBuffer + c + aBufferSize, c1);
  1095. p0 = _mm_add_ps(p0, pan0delta);
  1096. p1 = _mm_add_ps(p1, pan1delta);
  1097. c += 4;
  1098. }
  1099. }
  1100. // If buffer size or samples to read are not divisible by 4, handle leftovers
  1101. for (j = c; j < aSamplesToRead; j++)
  1102. {
  1103. pan[0] += pani[0];
  1104. pan[1] += pani[1];
  1105. float s = aScratch[j];
  1106. aBuffer[j + 0] += s * pan[0];
  1107. aBuffer[j + aBufferSize] += s * pan[1];
  1108. }
  1109. }
  1110. #else // fallback
  1111. for (j = 0; j < aSamplesToRead; j++)
  1112. {
  1113. pan[0] += pani[0];
  1114. pan[1] += pani[1];
  1115. float s = aScratch[j];
  1116. aBuffer[j + 0] += s * pan[0];
  1117. aBuffer[j + aBufferSize] += s * pan[1];
  1118. }
  1119. #endif
  1120. break;
  1121. }
  1122. break;
  1123. case 4:
  1124. switch (aVoice->mChannels)
  1125. {
  1126. case 8: // 8->4, add a bit of center, sub?
  1127. for (j = 0; j < aSamplesToRead; j++)
  1128. {
  1129. pan[0] += pani[0];
  1130. pan[1] += pani[1];
  1131. pan[2] += pani[2];
  1132. pan[3] += pani[3];
  1133. float s1 = aScratch[j];
  1134. float s2 = aScratch[aBufferSize + j];
  1135. float s3 = aScratch[aBufferSize * 2 + j];
  1136. float s4 = aScratch[aBufferSize * 3 + j];
  1137. float s5 = aScratch[aBufferSize * 4 + j];
  1138. float s6 = aScratch[aBufferSize * 5 + j];
  1139. float s7 = aScratch[aBufferSize * 6 + j];
  1140. float s8 = aScratch[aBufferSize * 7 + j];
  1141. float c = (s3 + s4) * 0.7f;
  1142. aBuffer[j + 0] += s1 * pan[0] + c;
  1143. aBuffer[j + aBufferSize] += s2 * pan[1] + c;
  1144. aBuffer[j + aBufferSize * 2] += 0.5f * (s5 + s7) * pan[2];
  1145. aBuffer[j + aBufferSize * 3] += 0.5f * (s6 + s8) * pan[3];
  1146. }
  1147. break;
  1148. case 6: // 6->4, add a bit of center, sub?
  1149. for (j = 0; j < aSamplesToRead; j++)
  1150. {
  1151. pan[0] += pani[0];
  1152. pan[1] += pani[1];
  1153. pan[2] += pani[2];
  1154. pan[3] += pani[3];
  1155. float s1 = aScratch[j];
  1156. float s2 = aScratch[aBufferSize + j];
  1157. float s3 = aScratch[aBufferSize * 2 + j];
  1158. float s4 = aScratch[aBufferSize * 3 + j];
  1159. float s5 = aScratch[aBufferSize * 4 + j];
  1160. float s6 = aScratch[aBufferSize * 5 + j];
  1161. float c = (s3 + s4) * 0.7f;
  1162. aBuffer[j + 0] += s1 * pan[0] + c;
  1163. aBuffer[j + aBufferSize] += s2 * pan[1] + c;
  1164. aBuffer[j + aBufferSize * 2] += s5 * pan[2];
  1165. aBuffer[j + aBufferSize * 3] += s6 * pan[3];
  1166. }
  1167. break;
  1168. case 4: // 4->4
  1169. for (j = 0; j < aSamplesToRead; j++)
  1170. {
  1171. pan[0] += pani[0];
  1172. pan[1] += pani[1];
  1173. pan[2] += pani[2];
  1174. pan[3] += pani[3];
  1175. float s1 = aScratch[j];
  1176. float s2 = aScratch[aBufferSize + j];
  1177. float s3 = aScratch[aBufferSize * 2 + j];
  1178. float s4 = aScratch[aBufferSize * 3 + j];
  1179. aBuffer[j + 0] += s1 * pan[0];
  1180. aBuffer[j + aBufferSize] += s2 * pan[1];
  1181. aBuffer[j + aBufferSize * 2] += s3 * pan[2];
  1182. aBuffer[j + aBufferSize * 3] += s4 * pan[3];
  1183. }
  1184. break;
  1185. case 2: // 2->4
  1186. for (j = 0; j < aSamplesToRead; j++)
  1187. {
  1188. pan[0] += pani[0];
  1189. pan[1] += pani[1];
  1190. pan[2] += pani[2];
  1191. pan[3] += pani[3];
  1192. float s1 = aScratch[j];
  1193. float s2 = aScratch[aBufferSize + j];
  1194. aBuffer[j + 0] += s1 * pan[0];
  1195. aBuffer[j + aBufferSize] += s2 * pan[1];
  1196. aBuffer[j + aBufferSize * 2] += s1 * pan[2];
  1197. aBuffer[j + aBufferSize * 3] += s2 * pan[3];
  1198. }
  1199. break;
  1200. case 1: // 1->4
  1201. for (j = 0; j < aSamplesToRead; j++)
  1202. {
  1203. pan[0] += pani[0];
  1204. pan[1] += pani[1];
  1205. pan[2] += pani[2];
  1206. pan[3] += pani[3];
  1207. float s = aScratch[j];
  1208. aBuffer[j + 0] += s * pan[0];
  1209. aBuffer[j + aBufferSize] += s * pan[1];
  1210. aBuffer[j + aBufferSize * 2] += s * pan[2];
  1211. aBuffer[j + aBufferSize * 3] += s * pan[3];
  1212. }
  1213. break;
  1214. }
  1215. break;
  1216. case 6:
  1217. switch (aVoice->mChannels)
  1218. {
  1219. case 8: // 8->6
  1220. for (j = 0; j < aSamplesToRead; j++)
  1221. {
  1222. pan[0] += pani[0];
  1223. pan[1] += pani[1];
  1224. pan[2] += pani[2];
  1225. pan[3] += pani[3];
  1226. pan[4] += pani[4];
  1227. pan[5] += pani[5];
  1228. float s1 = aScratch[j];
  1229. float s2 = aScratch[aBufferSize + j];
  1230. float s3 = aScratch[aBufferSize * 2 + j];
  1231. float s4 = aScratch[aBufferSize * 3 + j];
  1232. float s5 = aScratch[aBufferSize * 4 + j];
  1233. float s6 = aScratch[aBufferSize * 5 + j];
  1234. float s7 = aScratch[aBufferSize * 6 + j];
  1235. float s8 = aScratch[aBufferSize * 7 + j];
  1236. aBuffer[j + 0] += s1 * pan[0];
  1237. aBuffer[j + aBufferSize] += s2 * pan[1];
  1238. aBuffer[j + aBufferSize * 2] += s3 * pan[2];
  1239. aBuffer[j + aBufferSize * 3] += s4 * pan[3];
  1240. aBuffer[j + aBufferSize * 4] += 0.5f * (s5 + s7) * pan[4];
  1241. aBuffer[j + aBufferSize * 5] += 0.5f * (s6 + s8) * pan[5];
  1242. }
  1243. break;
  1244. case 6: // 6->6
  1245. for (j = 0; j < aSamplesToRead; j++)
  1246. {
  1247. pan[0] += pani[0];
  1248. pan[1] += pani[1];
  1249. pan[2] += pani[2];
  1250. pan[3] += pani[3];
  1251. pan[4] += pani[4];
  1252. pan[5] += pani[5];
  1253. float s1 = aScratch[j];
  1254. float s2 = aScratch[aBufferSize + j];
  1255. float s3 = aScratch[aBufferSize * 2 + j];
  1256. float s4 = aScratch[aBufferSize * 3 + j];
  1257. float s5 = aScratch[aBufferSize * 4 + j];
  1258. float s6 = aScratch[aBufferSize * 5 + j];
  1259. aBuffer[j + 0] += s1 * pan[0];
  1260. aBuffer[j + aBufferSize] += s2 * pan[1];
  1261. aBuffer[j + aBufferSize * 2] += s3 * pan[2];
  1262. aBuffer[j + aBufferSize * 3] += s4 * pan[3];
  1263. aBuffer[j + aBufferSize * 4] += s5 * pan[4];
  1264. aBuffer[j + aBufferSize * 5] += s6 * pan[5];
  1265. }
  1266. break;
  1267. case 4: // 4->6
  1268. for (j = 0; j < aSamplesToRead; j++)
  1269. {
  1270. pan[0] += pani[0];
  1271. pan[1] += pani[1];
  1272. pan[2] += pani[2];
  1273. pan[3] += pani[3];
  1274. pan[4] += pani[4];
  1275. pan[5] += pani[5];
  1276. float s1 = aScratch[j];
  1277. float s2 = aScratch[aBufferSize + j];
  1278. float s3 = aScratch[aBufferSize * 2 + j];
  1279. float s4 = aScratch[aBufferSize * 3 + j];
  1280. aBuffer[j + 0] += s1 * pan[0];
  1281. aBuffer[j + aBufferSize] += s2 * pan[1];
  1282. aBuffer[j + aBufferSize * 2] += 0.5f * (s1 + s2) * pan[2];
  1283. aBuffer[j + aBufferSize * 3] += 0.25f * (s1 + s2 + s3 + s4) * pan[3];
  1284. aBuffer[j + aBufferSize * 4] += s3 * pan[4];
  1285. aBuffer[j + aBufferSize * 5] += s4 * pan[5];
  1286. }
  1287. break;
  1288. case 2: // 2->6
  1289. for (j = 0; j < aSamplesToRead; j++)
  1290. {
  1291. pan[0] += pani[0];
  1292. pan[1] += pani[1];
  1293. pan[2] += pani[2];
  1294. pan[3] += pani[3];
  1295. pan[4] += pani[4];
  1296. pan[5] += pani[5];
  1297. float s1 = aScratch[j];
  1298. float s2 = aScratch[aBufferSize + j];
  1299. aBuffer[j + 0] += s1 * pan[0];
  1300. aBuffer[j + aBufferSize] += s2 * pan[1];
  1301. aBuffer[j + aBufferSize * 2] += 0.5f * (s1 + s2) * pan[2];
  1302. aBuffer[j + aBufferSize * 3] += 0.5f * (s1 + s2) * pan[3];
  1303. aBuffer[j + aBufferSize * 4] += s1 * pan[4];
  1304. aBuffer[j + aBufferSize * 5] += s2 * pan[5];
  1305. }
  1306. break;
  1307. case 1: // 1->6
  1308. for (j = 0; j < aSamplesToRead; j++)
  1309. {
  1310. pan[0] += pani[0];
  1311. pan[1] += pani[1];
  1312. pan[2] += pani[2];
  1313. pan[3] += pani[3];
  1314. pan[4] += pani[4];
  1315. pan[5] += pani[5];
  1316. float s = aScratch[j];
  1317. aBuffer[j + 0] += s * pan[0];
  1318. aBuffer[j + aBufferSize] += s * pan[1];
  1319. aBuffer[j + aBufferSize * 2] += s * pan[2];
  1320. aBuffer[j + aBufferSize * 3] += s * pan[3];
  1321. aBuffer[j + aBufferSize * 4] += s * pan[4];
  1322. aBuffer[j + aBufferSize * 5] += s * pan[5];
  1323. }
  1324. break;
  1325. }
  1326. break;
  1327. case 8:
  1328. switch (aVoice->mChannels)
  1329. {
  1330. case 8: // 8->8
  1331. for (j = 0; j < aSamplesToRead; j++)
  1332. {
  1333. pan[0] += pani[0];
  1334. pan[1] += pani[1];
  1335. pan[2] += pani[2];
  1336. pan[3] += pani[3];
  1337. pan[4] += pani[4];
  1338. pan[5] += pani[5];
  1339. pan[6] += pani[6];
  1340. pan[7] += pani[7];
  1341. float s1 = aScratch[j];
  1342. float s2 = aScratch[aBufferSize + j];
  1343. float s3 = aScratch[aBufferSize * 2 + j];
  1344. float s4 = aScratch[aBufferSize * 3 + j];
  1345. float s5 = aScratch[aBufferSize * 4 + j];
  1346. float s6 = aScratch[aBufferSize * 5 + j];
  1347. float s7 = aScratch[aBufferSize * 6 + j];
  1348. float s8 = aScratch[aBufferSize * 7 + j];
  1349. aBuffer[j + 0] += s1 * pan[0];
  1350. aBuffer[j + aBufferSize] += s2 * pan[1];
  1351. aBuffer[j + aBufferSize * 2] += s3 * pan[2];
  1352. aBuffer[j + aBufferSize * 3] += s4 * pan[3];
  1353. aBuffer[j + aBufferSize * 4] += s5 * pan[4];
  1354. aBuffer[j + aBufferSize * 5] += s6 * pan[5];
  1355. aBuffer[j + aBufferSize * 6] += s7 * pan[6];
  1356. aBuffer[j + aBufferSize * 7] += s8 * pan[7];
  1357. }
  1358. break;
  1359. case 6: // 6->8
  1360. for (j = 0; j < aSamplesToRead; j++)
  1361. {
  1362. pan[0] += pani[0];
  1363. pan[1] += pani[1];
  1364. pan[2] += pani[2];
  1365. pan[3] += pani[3];
  1366. pan[4] += pani[4];
  1367. pan[5] += pani[5];
  1368. pan[6] += pani[6];
  1369. pan[7] += pani[7];
  1370. float s1 = aScratch[j];
  1371. float s2 = aScratch[aBufferSize + j];
  1372. float s3 = aScratch[aBufferSize * 2 + j];
  1373. float s4 = aScratch[aBufferSize * 3 + j];
  1374. float s5 = aScratch[aBufferSize * 4 + j];
  1375. float s6 = aScratch[aBufferSize * 5 + j];
  1376. aBuffer[j + 0] += s1 * pan[0];
  1377. aBuffer[j + aBufferSize] += s2 * pan[1];
  1378. aBuffer[j + aBufferSize * 2] += s3 * pan[2];
  1379. aBuffer[j + aBufferSize * 3] += s4 * pan[3];
  1380. aBuffer[j + aBufferSize * 4] += 0.5f * (s5 + s1) * pan[4];
  1381. aBuffer[j + aBufferSize * 5] += 0.5f * (s6 + s2) * pan[5];
  1382. aBuffer[j + aBufferSize * 6] += s5 * pan[6];
  1383. aBuffer[j + aBufferSize * 7] += s6 * pan[7];
  1384. }
  1385. break;
  1386. case 4: // 4->8
  1387. for (j = 0; j < aSamplesToRead; j++)
  1388. {
  1389. pan[0] += pani[0];
  1390. pan[1] += pani[1];
  1391. pan[2] += pani[2];
  1392. pan[3] += pani[3];
  1393. pan[4] += pani[4];
  1394. pan[5] += pani[5];
  1395. pan[6] += pani[6];
  1396. pan[7] += pani[7];
  1397. float s1 = aScratch[j];
  1398. float s2 = aScratch[aBufferSize + j];
  1399. float s3 = aScratch[aBufferSize * 2 + j];
  1400. float s4 = aScratch[aBufferSize * 3 + j];
  1401. aBuffer[j + 0] += s1 * pan[0];
  1402. aBuffer[j + aBufferSize] += s2 * pan[1];
  1403. aBuffer[j + aBufferSize * 2] += 0.5f * (s1 + s2) * pan[2];
  1404. aBuffer[j + aBufferSize * 3] += 0.25f * (s1 + s2 + s3 + s4) * pan[3];
  1405. aBuffer[j + aBufferSize * 4] += 0.5f * (s1 + s3) * pan[4];
  1406. aBuffer[j + aBufferSize * 5] += 0.5f * (s2 + s4) * pan[5];
  1407. aBuffer[j + aBufferSize * 6] += s3 * pan[4];
  1408. aBuffer[j + aBufferSize * 7] += s4 * pan[5];
  1409. }
  1410. break;
  1411. case 2: // 2->8
  1412. for (j = 0; j < aSamplesToRead; j++)
  1413. {
  1414. pan[0] += pani[0];
  1415. pan[1] += pani[1];
  1416. pan[2] += pani[2];
  1417. pan[3] += pani[3];
  1418. pan[4] += pani[4];
  1419. pan[5] += pani[5];
  1420. pan[6] += pani[6];
  1421. pan[7] += pani[7];
  1422. float s1 = aScratch[j];
  1423. float s2 = aScratch[aBufferSize + j];
  1424. aBuffer[j + 0] += s1 * pan[0];
  1425. aBuffer[j + aBufferSize] += s2 * pan[1];
  1426. aBuffer[j + aBufferSize * 2] += 0.5f * (s1 + s2) * pan[2];
  1427. aBuffer[j + aBufferSize * 3] += 0.5f * (s1 + s2) * pan[3];
  1428. aBuffer[j + aBufferSize * 4] += s1 * pan[4];
  1429. aBuffer[j + aBufferSize * 5] += s2 * pan[5];
  1430. aBuffer[j + aBufferSize * 6] += s1 * pan[6];
  1431. aBuffer[j + aBufferSize * 7] += s2 * pan[7];
  1432. }
  1433. break;
  1434. case 1: // 1->8
  1435. for (j = 0; j < aSamplesToRead; j++)
  1436. {
  1437. pan[0] += pani[0];
  1438. pan[1] += pani[1];
  1439. pan[2] += pani[2];
  1440. pan[3] += pani[3];
  1441. pan[4] += pani[4];
  1442. pan[5] += pani[5];
  1443. pan[6] += pani[6];
  1444. pan[7] += pani[7];
  1445. float s = aScratch[j];
  1446. aBuffer[j + 0] += s * pan[0];
  1447. aBuffer[j + aBufferSize] += s * pan[1];
  1448. aBuffer[j + aBufferSize * 2] += s * pan[2];
  1449. aBuffer[j + aBufferSize * 3] += s * pan[3];
  1450. aBuffer[j + aBufferSize * 4] += s * pan[4];
  1451. aBuffer[j + aBufferSize * 5] += s * pan[5];
  1452. aBuffer[j + aBufferSize * 6] += s * pan[6];
  1453. aBuffer[j + aBufferSize * 7] += s * pan[7];
  1454. }
  1455. break;
  1456. }
  1457. break;
  1458. }
  1459. for (k = 0; k < aChannels; k++)
  1460. aVoice->mCurrentChannelVolume[k] = pand[k];
  1461. }
  1462. void Soloud::mixBus_internal(float *aBuffer, unsigned int aSamplesToRead, unsigned int aBufferSize, float *aScratch, unsigned int aBus, float aSamplerate, unsigned int aChannels, unsigned int aResampler)
  1463. {
  1464. unsigned int i, j;
  1465. // Clear accumulation buffer
  1466. for (i = 0; i < aSamplesToRead; i++)
  1467. {
  1468. for (j = 0; j < aChannels; j++)
  1469. {
  1470. aBuffer[i + j * aBufferSize] = 0;
  1471. }
  1472. }
  1473. // Accumulate sound sources
  1474. for (i = 0; i < mActiveVoiceCount; i++)
  1475. {
  1476. AudioSourceInstance *voice = mVoice[mActiveVoice[i]];
  1477. if (voice &&
  1478. voice->mBusHandle == aBus &&
  1479. !(voice->mFlags & AudioSourceInstance::PAUSED) &&
  1480. !(voice->mFlags & AudioSourceInstance::INAUDIBLE))
  1481. {
  1482. float step = voice->mSamplerate / aSamplerate;
  1483. // avoid step overflow
  1484. if (step > (1 << (32 - FIXPOINT_FRAC_BITS)))
  1485. step = 0;
  1486. unsigned int step_fixed = (int)floor(step * FIXPOINT_FRAC_MUL);
  1487. unsigned int outofs = 0;
  1488. if (voice->mDelaySamples)
  1489. {
  1490. if (voice->mDelaySamples > aSamplesToRead)
  1491. {
  1492. outofs = aSamplesToRead;
  1493. voice->mDelaySamples -= aSamplesToRead;
  1494. }
  1495. else
  1496. {
  1497. outofs = voice->mDelaySamples;
  1498. voice->mDelaySamples = 0;
  1499. }
  1500. // Clear scratch where we're skipping
  1501. unsigned int k;
  1502. for (k = 0; k < voice->mChannels; k++)
  1503. {
  1504. memset(aScratch + k * aBufferSize, 0, sizeof(float) * outofs);
  1505. }
  1506. }
  1507. while (step_fixed != 0 && outofs < aSamplesToRead)
  1508. {
  1509. if (voice->mLeftoverSamples == 0)
  1510. {
  1511. // Swap resample buffers (ping-pong)
  1512. float * t = voice->mResampleData[0];
  1513. voice->mResampleData[0] = voice->mResampleData[1];
  1514. voice->mResampleData[1] = t;
  1515. // Get a block of source data
  1516. int readcount = 0;
  1517. if (!voice->hasEnded() || voice->mFlags & AudioSourceInstance::LOOPING)
  1518. {
  1519. readcount = voice->getAudio(voice->mResampleData[0], SAMPLE_GRANULARITY, SAMPLE_GRANULARITY);
  1520. if (readcount < SAMPLE_GRANULARITY)
  1521. {
  1522. if (voice->mFlags & AudioSourceInstance::LOOPING)
  1523. {
  1524. while (readcount < SAMPLE_GRANULARITY && voice->seek(voice->mLoopPoint, mScratch.mData, mScratchSize) == SO_NO_ERROR)
  1525. {
  1526. voice->mLoopCount++;
  1527. int inc = voice->getAudio(voice->mResampleData[0] + readcount, SAMPLE_GRANULARITY - readcount, SAMPLE_GRANULARITY);
  1528. readcount += inc;
  1529. if (inc == 0) break;
  1530. }
  1531. }
  1532. }
  1533. }
  1534. // Clear remaining of the resample data if the full scratch wasn't used
  1535. if (readcount < SAMPLE_GRANULARITY)
  1536. {
  1537. unsigned int k;
  1538. for (k = 0; k < voice->mChannels; k++)
  1539. memset(voice->mResampleData[0] + readcount + SAMPLE_GRANULARITY * k, 0, sizeof(float) * (SAMPLE_GRANULARITY - readcount));
  1540. }
  1541. // If we go past zero, crop to zero (a bit of a kludge)
  1542. if (voice->mSrcOffset < SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL)
  1543. {
  1544. voice->mSrcOffset = 0;
  1545. }
  1546. else
  1547. {
  1548. // We have new block of data, move pointer backwards
  1549. voice->mSrcOffset -= SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL;
  1550. }
  1551. // Run the per-stream filters to get our source data
  1552. for (j = 0; j < FILTERS_PER_STREAM; j++)
  1553. {
  1554. if (voice->mFilter[j])
  1555. {
  1556. voice->mFilter[j]->filter(
  1557. voice->mResampleData[0],
  1558. SAMPLE_GRANULARITY,
  1559. SAMPLE_GRANULARITY,
  1560. voice->mChannels,
  1561. voice->mSamplerate,
  1562. mStreamTime);
  1563. }
  1564. }
  1565. }
  1566. else
  1567. {
  1568. voice->mLeftoverSamples = 0;
  1569. }
  1570. // Figure out how many samples we can generate from this source data.
  1571. // The value may be zero.
  1572. unsigned int writesamples = 0;
  1573. if (voice->mSrcOffset < SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL)
  1574. {
  1575. writesamples = ((SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL) - voice->mSrcOffset) / step_fixed + 1;
  1576. // avoid reading past the current buffer..
  1577. if (((writesamples * step_fixed + voice->mSrcOffset) >> FIXPOINT_FRAC_BITS) >= SAMPLE_GRANULARITY)
  1578. writesamples--;
  1579. }
  1580. // If this is too much for our output buffer, don't write that many:
  1581. if (writesamples + outofs > aSamplesToRead)
  1582. {
  1583. voice->mLeftoverSamples = (writesamples + outofs) - aSamplesToRead;
  1584. writesamples = aSamplesToRead - outofs;
  1585. }
  1586. // Call resampler to generate the samples, once per channel
  1587. if (writesamples)
  1588. {
  1589. for (j = 0; j < voice->mChannels; j++)
  1590. {
  1591. switch (aResampler)
  1592. {
  1593. case RESAMPLER_POINT:
  1594. resample_point(voice->mResampleData[0] + SAMPLE_GRANULARITY * j,
  1595. voice->mResampleData[1] + SAMPLE_GRANULARITY * j,
  1596. aScratch + aBufferSize * j + outofs,
  1597. voice->mSrcOffset,
  1598. writesamples,
  1599. /*voice->mSamplerate,
  1600. aSamplerate,*/
  1601. step_fixed);
  1602. break;
  1603. case RESAMPLER_CATMULLROM:
  1604. resample_catmullrom(voice->mResampleData[0] + SAMPLE_GRANULARITY * j,
  1605. voice->mResampleData[1] + SAMPLE_GRANULARITY * j,
  1606. aScratch + aBufferSize * j + outofs,
  1607. voice->mSrcOffset,
  1608. writesamples,
  1609. /*voice->mSamplerate,
  1610. aSamplerate,*/
  1611. step_fixed);
  1612. break;
  1613. default:
  1614. //case RESAMPLER_LINEAR:
  1615. resample_linear(voice->mResampleData[0] + SAMPLE_GRANULARITY * j,
  1616. voice->mResampleData[1] + SAMPLE_GRANULARITY * j,
  1617. aScratch + aBufferSize * j + outofs,
  1618. voice->mSrcOffset,
  1619. writesamples,
  1620. /*voice->mSamplerate,
  1621. aSamplerate,*/
  1622. step_fixed);
  1623. break;
  1624. }
  1625. }
  1626. }
  1627. // Keep track of how many samples we've written so far
  1628. outofs += writesamples;
  1629. // Move source pointer onwards (writesamples may be zero)
  1630. voice->mSrcOffset += writesamples * step_fixed;
  1631. }
  1632. // Handle panning and channel expansion (and/or shrinking)
  1633. panAndExpand(voice, aBuffer, aSamplesToRead, aBufferSize, aScratch, aChannels);
  1634. // clear voice if the sound is over
  1635. if (!(voice->mFlags & (AudioSourceInstance::LOOPING | AudioSourceInstance::DISABLE_AUTOSTOP)) && voice->hasEnded())
  1636. {
  1637. stopVoice_internal(mActiveVoice[i]);
  1638. }
  1639. }
  1640. else
  1641. if (voice &&
  1642. voice->mBusHandle == aBus &&
  1643. !(voice->mFlags & AudioSourceInstance::PAUSED) &&
  1644. (voice->mFlags & AudioSourceInstance::INAUDIBLE) &&
  1645. (voice->mFlags & AudioSourceInstance::INAUDIBLE_TICK))
  1646. {
  1647. // Inaudible but needs ticking. Do minimal work (keep counters up to date and ask audiosource for data)
  1648. float step = voice->mSamplerate / aSamplerate;
  1649. int step_fixed = (int)floor(step * FIXPOINT_FRAC_MUL);
  1650. unsigned int outofs = 0;
  1651. if (voice->mDelaySamples)
  1652. {
  1653. if (voice->mDelaySamples > aSamplesToRead)
  1654. {
  1655. outofs = aSamplesToRead;
  1656. voice->mDelaySamples -= aSamplesToRead;
  1657. }
  1658. else
  1659. {
  1660. outofs = voice->mDelaySamples;
  1661. voice->mDelaySamples = 0;
  1662. }
  1663. }
  1664. while (step_fixed != 0 && outofs < aSamplesToRead)
  1665. {
  1666. if (voice->mLeftoverSamples == 0)
  1667. {
  1668. // Swap resample buffers (ping-pong)
  1669. float * t = voice->mResampleData[0];
  1670. voice->mResampleData[0] = voice->mResampleData[1];
  1671. voice->mResampleData[1] = t;
  1672. // Get a block of source data
  1673. int readcount = 0;
  1674. if (!voice->hasEnded() || voice->mFlags & AudioSourceInstance::LOOPING)
  1675. {
  1676. readcount = voice->getAudio(voice->mResampleData[0], SAMPLE_GRANULARITY, SAMPLE_GRANULARITY);
  1677. if (readcount < SAMPLE_GRANULARITY)
  1678. {
  1679. if (voice->mFlags & AudioSourceInstance::LOOPING)
  1680. {
  1681. while (readcount < SAMPLE_GRANULARITY && voice->seek(voice->mLoopPoint, mScratch.mData, mScratchSize) == SO_NO_ERROR)
  1682. {
  1683. voice->mLoopCount++;
  1684. readcount += voice->getAudio(voice->mResampleData[0] + readcount, SAMPLE_GRANULARITY - readcount, SAMPLE_GRANULARITY);
  1685. }
  1686. }
  1687. }
  1688. }
  1689. // If we go past zero, crop to zero (a bit of a kludge)
  1690. if (voice->mSrcOffset < SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL)
  1691. {
  1692. voice->mSrcOffset = 0;
  1693. }
  1694. else
  1695. {
  1696. // We have new block of data, move pointer backwards
  1697. voice->mSrcOffset -= SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL;
  1698. }
  1699. // Skip filters
  1700. }
  1701. else
  1702. {
  1703. voice->mLeftoverSamples = 0;
  1704. }
  1705. // Figure out how many samples we can generate from this source data.
  1706. // The value may be zero.
  1707. unsigned int writesamples = 0;
  1708. if (voice->mSrcOffset < SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL)
  1709. {
  1710. writesamples = ((SAMPLE_GRANULARITY * FIXPOINT_FRAC_MUL) - voice->mSrcOffset) / step_fixed + 1;
  1711. // avoid reading past the current buffer..
  1712. if (((writesamples * step_fixed + voice->mSrcOffset) >> FIXPOINT_FRAC_BITS) >= SAMPLE_GRANULARITY)
  1713. writesamples--;
  1714. }
  1715. // If this is too much for our output buffer, don't write that many:
  1716. if (writesamples + outofs > aSamplesToRead)
  1717. {
  1718. voice->mLeftoverSamples = (writesamples + outofs) - aSamplesToRead;
  1719. writesamples = aSamplesToRead - outofs;
  1720. }
  1721. // Skip resampler
  1722. // Keep track of how many samples we've written so far
  1723. outofs += writesamples;
  1724. // Move source pointer onwards (writesamples may be zero)
  1725. voice->mSrcOffset += writesamples * step_fixed;
  1726. }
  1727. // clear voice if the sound is over
  1728. if (!(voice->mFlags & (AudioSourceInstance::LOOPING | AudioSourceInstance::DISABLE_AUTOSTOP)) && voice->hasEnded())
  1729. {
  1730. stopVoice_internal(mActiveVoice[i]);
  1731. }
  1732. }
  1733. }
  1734. }
  1735. void Soloud::mapResampleBuffers_internal()
  1736. {
  1737. SOLOUD_ASSERT(mMaxActiveVoices < 256);
  1738. char live[256];
  1739. memset(live, 0, mMaxActiveVoices);
  1740. unsigned int i, j;
  1741. for (i = 0; i < mMaxActiveVoices; i++)
  1742. {
  1743. for (j = 0; j < mMaxActiveVoices; j++)
  1744. {
  1745. if (mResampleDataOwner[i] && mResampleDataOwner[i] == mVoice[mActiveVoice[j]])
  1746. {
  1747. live[i] |= 1; // Live channel
  1748. live[j] |= 2; // Live voice
  1749. }
  1750. }
  1751. }
  1752. for (i = 0; i < mMaxActiveVoices; i++)
  1753. {
  1754. if (!(live[i] & 1) && mResampleDataOwner[i]) // For all dead channels with owners..
  1755. {
  1756. mResampleDataOwner[i]->mResampleData[0] = 0;
  1757. mResampleDataOwner[i]->mResampleData[1] = 0;
  1758. mResampleDataOwner[i] = 0;
  1759. }
  1760. }
  1761. int latestfree = 0;
  1762. for (i = 0; i < mActiveVoiceCount; i++)
  1763. {
  1764. if (!(live[i] & 2) && mVoice[mActiveVoice[i]]) // For all live voices with no channel..
  1765. {
  1766. int found = -1;
  1767. for (j = latestfree; found == -1 && j < mMaxActiveVoices; j++)
  1768. {
  1769. if (mResampleDataOwner[j] == 0)
  1770. {
  1771. found = j;
  1772. }
  1773. }
  1774. SOLOUD_ASSERT(found != -1);
  1775. mResampleDataOwner[found] = mVoice[mActiveVoice[i]];
  1776. mResampleDataOwner[found]->mResampleData[0] = mResampleData[found * 2 + 0];
  1777. mResampleDataOwner[found]->mResampleData[1] = mResampleData[found * 2 + 1];
  1778. memset(mResampleDataOwner[found]->mResampleData[0], 0, sizeof(float) * SAMPLE_GRANULARITY * MAX_CHANNELS);
  1779. memset(mResampleDataOwner[found]->mResampleData[1], 0, sizeof(float) * SAMPLE_GRANULARITY * MAX_CHANNELS);
  1780. latestfree = found + 1;
  1781. }
  1782. }
  1783. }
  1784. void Soloud::calcActiveVoices_internal()
  1785. {
  1786. // TODO: consider whether we need to re-evaluate the active voices all the time.
  1787. // It is a must when new voices are started, but otherwise we could get away
  1788. // with postponing it sometimes..
  1789. mActiveVoiceDirty = false;
  1790. // Populate
  1791. unsigned int i, candidates, mustlive;
  1792. candidates = 0;
  1793. mustlive = 0;
  1794. for (i = 0; i < mHighestVoice; i++)
  1795. {
  1796. if (mVoice[i] && (!(mVoice[i]->mFlags & (AudioSourceInstance::INAUDIBLE | AudioSourceInstance::PAUSED)) || (mVoice[i]->mFlags & AudioSourceInstance::INAUDIBLE_TICK)))
  1797. {
  1798. mActiveVoice[candidates] = i;
  1799. candidates++;
  1800. if (mVoice[i]->mFlags & AudioSourceInstance::INAUDIBLE_TICK)
  1801. {
  1802. mActiveVoice[candidates - 1] = mActiveVoice[mustlive];
  1803. mActiveVoice[mustlive] = i;
  1804. mustlive++;
  1805. }
  1806. }
  1807. }
  1808. // Check for early out
  1809. if (candidates <= mMaxActiveVoices)
  1810. {
  1811. // everything is audible, early out
  1812. mActiveVoiceCount = candidates;
  1813. mapResampleBuffers_internal();
  1814. return;
  1815. }
  1816. mActiveVoiceCount = mMaxActiveVoices;
  1817. if (mustlive >= mMaxActiveVoices)
  1818. {
  1819. // Oopsie. Well, nothing to sort, since the "must live" voices already
  1820. // ate all our active voice slots.
  1821. // This is a potentially an error situation, but we have no way to report
  1822. // error from here. And asserting could be bad, too.
  1823. return;
  1824. }
  1825. // If we get this far, there's nothing to it: we'll have to sort the voices to find the most audible.
  1826. // Iterative partial quicksort:
  1827. int left = 0, stack[24], pos = 0, right;
  1828. int len = candidates - mustlive;
  1829. unsigned int *data = mActiveVoice + mustlive;
  1830. int k = mActiveVoiceCount;
  1831. for (;;)
  1832. {
  1833. for (; left + 1 < len; len++)
  1834. {
  1835. if (pos == 24) len = stack[pos = 0];
  1836. int pivot = data[left];
  1837. float pivotvol = mVoice[pivot]->mOverallVolume;
  1838. stack[pos++] = len;
  1839. for (right = left - 1;;)
  1840. {
  1841. do
  1842. {
  1843. right++;
  1844. }
  1845. while (mVoice[data[right]]->mOverallVolume > pivotvol);
  1846. do
  1847. {
  1848. len--;
  1849. }
  1850. while (pivotvol > mVoice[data[len]]->mOverallVolume);
  1851. if (right >= len) break;
  1852. int temp = data[right];
  1853. data[right] = data[len];
  1854. data[len] = temp;
  1855. }
  1856. }
  1857. if (pos == 0) break;
  1858. if (left >= k) break;
  1859. left = len;
  1860. len = stack[--pos];
  1861. }
  1862. // TODO: should the rest of the voices be flagged INAUDIBLE?
  1863. mapResampleBuffers_internal();
  1864. }
  1865. void Soloud::mix_internal(unsigned int aSamples, unsigned int aStride)
  1866. {
  1867. #ifdef FLOATING_POINT_DEBUG
  1868. // This needs to be done in the audio thread as well..
  1869. static int done = 0;
  1870. if (!done)
  1871. {
  1872. unsigned int u;
  1873. u = _controlfp(0, 0);
  1874. u = u & ~(_EM_INVALID | /*_EM_DENORMAL |*/ _EM_ZERODIVIDE | _EM_OVERFLOW /*| _EM_UNDERFLOW | _EM_INEXACT*/);
  1875. _controlfp(u, _MCW_EM);
  1876. done = 1;
  1877. }
  1878. #endif
  1879. #ifdef _MCW_DN
  1880. {
  1881. static bool once = false;
  1882. if (!once)
  1883. {
  1884. once = true;
  1885. if (!(mFlags & NO_FPU_REGISTER_CHANGE))
  1886. {
  1887. _controlfp(_DN_FLUSH, _MCW_DN);
  1888. }
  1889. }
  1890. }
  1891. #endif
  1892. #ifdef SOLOUD_SSE_INTRINSICS
  1893. {
  1894. static bool once = false;
  1895. if (!once)
  1896. {
  1897. once = true;
  1898. // Set denorm clear to zero (CTZ) and denorms are zero (DAZ) flags on.
  1899. // This causes all math to consider really tiny values as zero, which
  1900. // helps performance. I'd rather use constants from the sse headers,
  1901. // but for some reason the DAZ value is not defined there(!)
  1902. if (!(mFlags & NO_FPU_REGISTER_CHANGE))
  1903. {
  1904. _mm_setcsr(_mm_getcsr() | 0x8040);
  1905. }
  1906. }
  1907. }
  1908. #endif
  1909. float buffertime = aSamples / (float)mSamplerate;
  1910. float globalVolume[2];
  1911. mStreamTime += buffertime;
  1912. mLastClockedTime = 0;
  1913. globalVolume[0] = mGlobalVolume;
  1914. if (mGlobalVolumeFader.mActive)
  1915. {
  1916. mGlobalVolume = mGlobalVolumeFader.get(mStreamTime);
  1917. }
  1918. globalVolume[1] = mGlobalVolume;
  1919. lockAudioMutex_internal();
  1920. // Process faders. May change scratch size.
  1921. int i;
  1922. for (i = 0; i < (signed)mHighestVoice; i++)
  1923. {
  1924. if (mVoice[i] && !(mVoice[i]->mFlags & AudioSourceInstance::PAUSED))
  1925. {
  1926. float volume[2];
  1927. mVoice[i]->mActiveFader = 0;
  1928. if (mGlobalVolumeFader.mActive > 0)
  1929. {
  1930. mVoice[i]->mActiveFader = 1;
  1931. }
  1932. mVoice[i]->mStreamTime += buffertime;
  1933. mVoice[i]->mStreamPosition += (double)buffertime * (double)mVoice[i]->mOverallRelativePlaySpeed;
  1934. // TODO: this is actually unstable, because mStreamTime depends on the relative
  1935. // play speed.
  1936. if (mVoice[i]->mRelativePlaySpeedFader.mActive > 0)
  1937. {
  1938. float speed = mVoice[i]->mRelativePlaySpeedFader.get(mVoice[i]->mStreamTime);
  1939. setVoiceRelativePlaySpeed_internal(i, speed);
  1940. }
  1941. volume[0] = mVoice[i]->mOverallVolume;
  1942. if (mVoice[i]->mVolumeFader.mActive > 0)
  1943. {
  1944. mVoice[i]->mSetVolume = mVoice[i]->mVolumeFader.get(mVoice[i]->mStreamTime);
  1945. mVoice[i]->mActiveFader = 1;
  1946. updateVoiceVolume_internal(i);
  1947. mActiveVoiceDirty = true;
  1948. }
  1949. volume[1] = mVoice[i]->mOverallVolume;
  1950. if (mVoice[i]->mPanFader.mActive > 0)
  1951. {
  1952. float pan = mVoice[i]->mPanFader.get(mVoice[i]->mStreamTime);
  1953. setVoicePan_internal(i, pan);
  1954. mVoice[i]->mActiveFader = 1;
  1955. }
  1956. if (mVoice[i]->mPauseScheduler.mActive)
  1957. {
  1958. mVoice[i]->mPauseScheduler.get(mVoice[i]->mStreamTime);
  1959. if (mVoice[i]->mPauseScheduler.mActive == -1)
  1960. {
  1961. mVoice[i]->mPauseScheduler.mActive = 0;
  1962. setVoicePause_internal(i, 1);
  1963. }
  1964. }
  1965. if (mVoice[i]->mStopScheduler.mActive)
  1966. {
  1967. mVoice[i]->mStopScheduler.get(mVoice[i]->mStreamTime);
  1968. if (mVoice[i]->mStopScheduler.mActive == -1)
  1969. {
  1970. mVoice[i]->mStopScheduler.mActive = 0;
  1971. stopVoice_internal(i);
  1972. }
  1973. }
  1974. }
  1975. }
  1976. if (mActiveVoiceDirty)
  1977. calcActiveVoices_internal();
  1978. mixBus_internal(mOutputScratch.mData, aSamples, aStride, mScratch.mData, 0, (float)mSamplerate, mChannels, mResampler);
  1979. for (i = 0; i < FILTERS_PER_STREAM; i++)
  1980. {
  1981. if (mFilterInstance[i])
  1982. {
  1983. mFilterInstance[i]->filter(mOutputScratch.mData, aSamples, aStride, mChannels, (float)mSamplerate, mStreamTime);
  1984. }
  1985. }
  1986. unlockAudioMutex_internal();
  1987. // Note: clipping channels*aStride, not channels*aSamples, so we're possibly clipping some unused data.
  1988. // The buffers should be large enough for it, we just may do a few bytes of unneccessary work.
  1989. clip_internal(mOutputScratch, mScratch, aStride, globalVolume[0], globalVolume[1]);
  1990. if (mFlags & ENABLE_VISUALIZATION)
  1991. {
  1992. for (i = 0; i < MAX_CHANNELS; i++)
  1993. {
  1994. mVisualizationChannelVolume[i] = 0;
  1995. }
  1996. if (aSamples > 255)
  1997. {
  1998. for (i = 0; i < 256; i++)
  1999. {
  2000. int j;
  2001. mVisualizationWaveData[i] = 0;
  2002. for (j = 0; j < (signed)mChannels; j++)
  2003. {
  2004. float sample = mScratch.mData[i + j * aStride];
  2005. float absvol = (float)fabs(sample);
  2006. if (mVisualizationChannelVolume[j] < absvol)
  2007. mVisualizationChannelVolume[j] = absvol;
  2008. mVisualizationWaveData[i] += sample;
  2009. }
  2010. }
  2011. }
  2012. else
  2013. {
  2014. // Very unlikely failsafe branch
  2015. for (i = 0; i < 256; i++)
  2016. {
  2017. int j;
  2018. mVisualizationWaveData[i] = 0;
  2019. for (j = 0; j < (signed)mChannels; j++)
  2020. {
  2021. float sample = mScratch.mData[(i % aSamples) + j * aStride];
  2022. float absvol = (float)fabs(sample);
  2023. if (mVisualizationChannelVolume[j] < absvol)
  2024. mVisualizationChannelVolume[j] = absvol;
  2025. mVisualizationWaveData[i] += sample;
  2026. }
  2027. }
  2028. }
  2029. }
  2030. }
  2031. void Soloud::mix(float *aBuffer, unsigned int aSamples)
  2032. {
  2033. unsigned int stride = (aSamples + 15) & ~0xf;
  2034. mix_internal(aSamples, stride);
  2035. interlace_samples_float(mScratch.mData, aBuffer, aSamples, mChannels, stride);
  2036. }
  2037. void Soloud::mixSigned16(short *aBuffer, unsigned int aSamples)
  2038. {
  2039. unsigned int stride = (aSamples + 15) & ~0xf;
  2040. mix_internal(aSamples, stride);
  2041. interlace_samples_s16(mScratch.mData, aBuffer, aSamples, mChannels, stride);
  2042. }
  2043. void interlace_samples_float(const float *aSourceBuffer, float *aDestBuffer, unsigned int aSamples, unsigned int aChannels, unsigned int aStride)
  2044. {
  2045. // 111222 -> 121212
  2046. unsigned int i, j, c;
  2047. c = 0;
  2048. for (j = 0; j < aChannels; j++)
  2049. {
  2050. c = j * aStride;
  2051. for (i = j; i < aSamples * aChannels; i += aChannels)
  2052. {
  2053. aDestBuffer[i] = aSourceBuffer[c];
  2054. c++;
  2055. }
  2056. }
  2057. }
  2058. void interlace_samples_s16(const float *aSourceBuffer, short *aDestBuffer, unsigned int aSamples, unsigned int aChannels, unsigned int aStride)
  2059. {
  2060. // 111222 -> 121212
  2061. unsigned int i, j, c;
  2062. c = 0;
  2063. for (j = 0; j < aChannels; j++)
  2064. {
  2065. c = j * aStride;
  2066. for (i = j; i < aSamples * aChannels; i += aChannels)
  2067. {
  2068. aDestBuffer[i] = (short)(aSourceBuffer[c] * 0x7fff);
  2069. c++;
  2070. }
  2071. }
  2072. }
  2073. void Soloud::lockAudioMutex_internal()
  2074. {
  2075. if (mAudioThreadMutex)
  2076. {
  2077. Thread::lockMutex(mAudioThreadMutex);
  2078. }
  2079. SOLOUD_ASSERT(!mInsideAudioThreadMutex);
  2080. mInsideAudioThreadMutex = true;
  2081. }
  2082. void Soloud::unlockAudioMutex_internal()
  2083. {
  2084. SOLOUD_ASSERT(mInsideAudioThreadMutex);
  2085. mInsideAudioThreadMutex = false;
  2086. if (mAudioThreadMutex)
  2087. {
  2088. Thread::unlockMutex(mAudioThreadMutex);
  2089. }
  2090. }
  2091. };