1
0

Sndmix.cpp 90 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752
  1. /*
  2. * Sndmix.cpp
  3. * -----------
  4. * Purpose: Pattern playback, effect processing
  5. * Notes : (currently none)
  6. * Authors: Olivier Lapicque
  7. * OpenMPT Devs
  8. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  9. */
  10. #include "stdafx.h"
  11. #include "Sndfile.h"
  12. #include "MixerLoops.h"
  13. #include "MIDIEvents.h"
  14. #include "Tables.h"
  15. #ifdef MODPLUG_TRACKER
  16. #include "../mptrack/TrackerSettings.h"
  17. #endif // MODPLUG_TRACKER
  18. #ifndef NO_PLUGINS
  19. #include "plugins/PlugInterface.h"
  20. #endif // NO_PLUGINS
  21. #include "OPL.h"
  22. OPENMPT_NAMESPACE_BEGIN
  23. // Log tables for pre-amp
  24. // Pre-amp (or more precisely: Pre-attenuation) depends on the number of channels,
  25. // Which this table takes care of.
  26. static constexpr uint8 PreAmpTable[16] =
  27. {
  28. 0x60, 0x60, 0x60, 0x70, // 0-7
  29. 0x80, 0x88, 0x90, 0x98, // 8-15
  30. 0xA0, 0xA4, 0xA8, 0xAC, // 16-23
  31. 0xB0, 0xB4, 0xB8, 0xBC, // 24-31
  32. };
  33. #ifndef NO_AGC
  34. static constexpr uint8 PreAmpAGCTable[16] =
  35. {
  36. 0x60, 0x60, 0x60, 0x64,
  37. 0x68, 0x70, 0x78, 0x80,
  38. 0x84, 0x88, 0x8C, 0x90,
  39. 0x92, 0x94, 0x96, 0x98,
  40. };
  41. #endif
  42. void CSoundFile::SetMixerSettings(const MixerSettings &mixersettings)
  43. {
  44. SetPreAmp(mixersettings.m_nPreAmp); // adjust agc
  45. bool reset = false;
  46. if(
  47. (mixersettings.gdwMixingFreq != m_MixerSettings.gdwMixingFreq)
  48. ||
  49. (mixersettings.gnChannels != m_MixerSettings.gnChannels)
  50. ||
  51. (mixersettings.MixerFlags != m_MixerSettings.MixerFlags))
  52. reset = true;
  53. m_MixerSettings = mixersettings;
  54. InitPlayer(reset);
  55. }
  56. void CSoundFile::SetResamplerSettings(const CResamplerSettings &resamplersettings)
  57. {
  58. m_Resampler.m_Settings = resamplersettings;
  59. m_Resampler.UpdateTables();
  60. InitAmigaResampler();
  61. }
  62. void CSoundFile::InitPlayer(bool bReset)
  63. {
  64. if(bReset)
  65. {
  66. ResetMixStat();
  67. m_dryLOfsVol = m_dryROfsVol = 0;
  68. m_surroundLOfsVol = m_surroundROfsVol = 0;
  69. InitAmigaResampler();
  70. }
  71. m_Resampler.UpdateTables();
  72. #ifndef NO_REVERB
  73. m_Reverb.Initialize(bReset, m_RvbROfsVol, m_RvbLOfsVol, m_MixerSettings.gdwMixingFreq);
  74. #endif
  75. #ifndef NO_DSP
  76. m_Surround.Initialize(bReset, m_MixerSettings.gdwMixingFreq);
  77. #endif
  78. #ifndef NO_DSP
  79. m_MegaBass.Initialize(bReset, m_MixerSettings.gdwMixingFreq);
  80. #endif
  81. #ifndef NO_EQ
  82. m_EQ.Initialize(bReset, m_MixerSettings.gdwMixingFreq);
  83. #endif
  84. #ifndef NO_AGC
  85. m_AGC.Initialize(bReset, m_MixerSettings.gdwMixingFreq);
  86. #endif
  87. #ifndef NO_DSP
  88. m_BitCrush.Initialize(bReset, m_MixerSettings.gdwMixingFreq);
  89. #endif
  90. if(m_opl)
  91. {
  92. m_opl->Initialize(m_MixerSettings.gdwMixingFreq);
  93. }
  94. }
  95. bool CSoundFile::FadeSong(uint32 msec)
  96. {
  97. samplecount_t nsamples = Util::muldiv(msec, m_MixerSettings.gdwMixingFreq, 1000);
  98. if (nsamples <= 0) return false;
  99. if (nsamples > 0x100000) nsamples = 0x100000;
  100. m_PlayState.m_nBufferCount = nsamples;
  101. int32 nRampLength = static_cast<int32>(m_PlayState.m_nBufferCount);
  102. // Ramp everything down
  103. for (uint32 noff=0; noff < m_nMixChannels; noff++)
  104. {
  105. ModChannel &pramp = m_PlayState.Chn[m_PlayState.ChnMix[noff]];
  106. pramp.newRightVol = pramp.newLeftVol = 0;
  107. pramp.leftRamp = -pramp.leftVol * (1 << VOLUMERAMPPRECISION) / nRampLength;
  108. pramp.rightRamp = -pramp.rightVol * (1 << VOLUMERAMPPRECISION) / nRampLength;
  109. pramp.rampLeftVol = pramp.leftVol * (1 << VOLUMERAMPPRECISION);
  110. pramp.rampRightVol = pramp.rightVol * (1 << VOLUMERAMPPRECISION);
  111. pramp.nRampLength = nRampLength;
  112. pramp.dwFlags.set(CHN_VOLUMERAMP);
  113. }
  114. return true;
  115. }
  116. // Apply stereo separation factor on an interleaved stereo/quad stream.
  117. // count = Number of stereo sample pairs to process
  118. // separation = -256...256 (negative values = swap L/R, 0 = mono, 128 = normal)
  119. static void ApplyStereoSeparation(mixsample_t *mixBuf, std::size_t count, int32 separation)
  120. {
  121. #ifdef MPT_INTMIXER
  122. const mixsample_t factor_num = separation; // 128 =^= 1.0f
  123. const mixsample_t factor_den = MixerSettings::StereoSeparationScale; // 128
  124. const mixsample_t normalize_den = 2; // mid/side pre/post normalization
  125. const mixsample_t mid_den = normalize_den;
  126. const mixsample_t side_num = factor_num;
  127. const mixsample_t side_den = factor_den * normalize_den;
  128. #else
  129. const float normalize_factor = 0.5f; // cumulative mid/side normalization factor (1/sqrt(2))*(1/sqrt(2))
  130. const float factor = static_cast<float>(separation) / static_cast<float>(MixerSettings::StereoSeparationScale); // sep / 128
  131. const float mid_factor = normalize_factor;
  132. const float side_factor = factor * normalize_factor;
  133. #endif
  134. for(std::size_t i = 0; i < count; i++)
  135. {
  136. mixsample_t l = mixBuf[0];
  137. mixsample_t r = mixBuf[1];
  138. mixsample_t m = l + r;
  139. mixsample_t s = l - r;
  140. #ifdef MPT_INTMIXER
  141. m /= mid_den;
  142. s = Util::muldiv(s, side_num, side_den);
  143. #else
  144. m *= mid_factor;
  145. s *= side_factor;
  146. #endif
  147. l = m + s;
  148. r = m - s;
  149. mixBuf[0] = l;
  150. mixBuf[1] = r;
  151. mixBuf += 2;
  152. }
  153. }
  154. static void ApplyStereoSeparation(mixsample_t *SoundFrontBuffer, mixsample_t *SoundRearBuffer, std::size_t channels, std::size_t countChunk, int32 separation)
  155. {
  156. if(separation == MixerSettings::StereoSeparationScale)
  157. { // identity
  158. return;
  159. }
  160. if(channels >= 2) ApplyStereoSeparation(SoundFrontBuffer, countChunk, separation);
  161. if(channels >= 4) ApplyStereoSeparation(SoundRearBuffer , countChunk, separation);
  162. }
  163. void CSoundFile::ProcessInputChannels(IAudioSource &source, std::size_t countChunk)
  164. {
  165. for(std::size_t channel = 0; channel < NUMMIXINPUTBUFFERS; ++channel)
  166. {
  167. std::fill(&(MixInputBuffer[channel][0]), &(MixInputBuffer[channel][countChunk]), 0);
  168. }
  169. mixsample_t * buffers[NUMMIXINPUTBUFFERS];
  170. for(std::size_t channel = 0; channel < NUMMIXINPUTBUFFERS; ++channel)
  171. {
  172. buffers[channel] = MixInputBuffer[channel];
  173. }
  174. source.Process(mpt::audio_span_planar(buffers, m_MixerSettings.NumInputChannels, countChunk));
  175. }
  176. // Read one tick but skip all expensive rendering options
  177. CSoundFile::samplecount_t CSoundFile::ReadOneTick()
  178. {
  179. const auto origMaxMixChannels = m_MixerSettings.m_nMaxMixChannels;
  180. m_MixerSettings.m_nMaxMixChannels = 0;
  181. while(m_PlayState.m_nBufferCount)
  182. {
  183. auto framesToRender = std::min(m_PlayState.m_nBufferCount, samplecount_t(MIXBUFFERSIZE));
  184. CreateStereoMix(framesToRender);
  185. m_PlayState.m_nBufferCount -= framesToRender;
  186. m_PlayState.m_lTotalSampleCount += framesToRender;
  187. }
  188. m_MixerSettings.m_nMaxMixChannels = origMaxMixChannels;
  189. if(ReadNote())
  190. return m_PlayState.m_nBufferCount;
  191. else
  192. return 0;
  193. }
  194. CSoundFile::samplecount_t CSoundFile::Read(samplecount_t count, IAudioTarget &target, IAudioSource &source, std::optional<std::reference_wrapper<IMonitorOutput>> outputMonitor, std::optional<std::reference_wrapper<IMonitorInput>> inputMonitor)
  195. {
  196. MPT_ASSERT_ALWAYS(m_MixerSettings.IsValid());
  197. samplecount_t countRendered = 0;
  198. samplecount_t countToRender = count;
  199. while(!m_SongFlags[SONG_ENDREACHED] && countToRender > 0)
  200. {
  201. // Update Channel Data
  202. if(!m_PlayState.m_nBufferCount)
  203. {
  204. // Last tick or fade completely processed, find out what to do next
  205. if(m_SongFlags[SONG_FADINGSONG])
  206. {
  207. // Song was faded out
  208. m_SongFlags.set(SONG_ENDREACHED);
  209. } else if(ReadNote())
  210. {
  211. // Render next tick (normal progress)
  212. MPT_ASSERT(m_PlayState.m_nBufferCount > 0);
  213. #ifdef MODPLUG_TRACKER
  214. // Save pattern cue points for WAV rendering here (if we reached a new pattern, that is.)
  215. if(m_PatternCuePoints != nullptr && (m_PatternCuePoints->empty() || m_PlayState.m_nCurrentOrder != m_PatternCuePoints->back().order))
  216. {
  217. PatternCuePoint cue;
  218. cue.offset = countRendered;
  219. cue.order = m_PlayState.m_nCurrentOrder;
  220. cue.processed = false; // We don't know the base offset in the file here. It has to be added in the main conversion loop.
  221. m_PatternCuePoints->push_back(cue);
  222. }
  223. #endif
  224. } else
  225. {
  226. // No new pattern data
  227. #ifdef MODPLUG_TRACKER
  228. if((m_nMaxOrderPosition) && (m_PlayState.m_nCurrentOrder >= m_nMaxOrderPosition))
  229. {
  230. m_SongFlags.set(SONG_ENDREACHED);
  231. }
  232. #endif // MODPLUG_TRACKER
  233. if(IsRenderingToDisc())
  234. {
  235. // Disable song fade when rendering or when requested in libopenmpt.
  236. m_SongFlags.set(SONG_ENDREACHED);
  237. } else
  238. { // end of song reached, fade it out
  239. if(FadeSong(FADESONGDELAY)) // sets m_nBufferCount xor returns false
  240. { // FadeSong sets m_nBufferCount here
  241. MPT_ASSERT(m_PlayState.m_nBufferCount > 0);
  242. m_SongFlags.set(SONG_FADINGSONG);
  243. } else
  244. {
  245. m_SongFlags.set(SONG_ENDREACHED);
  246. }
  247. }
  248. }
  249. }
  250. if(m_SongFlags[SONG_ENDREACHED])
  251. {
  252. // Mix done.
  253. // If we decide to continue the mix (possible in libopenmpt), the tick count
  254. // is valid right now (0), meaning that no new row data will be processed.
  255. // This would effectively prolong the last played row.
  256. m_PlayState.m_nTickCount = m_PlayState.TicksOnRow();
  257. break;
  258. }
  259. MPT_ASSERT(m_PlayState.m_nBufferCount > 0); // assert that we have actually something to do
  260. const samplecount_t countChunk = std::min({ static_cast<samplecount_t>(MIXBUFFERSIZE), static_cast<samplecount_t>(m_PlayState.m_nBufferCount), static_cast<samplecount_t>(countToRender) });
  261. if(m_MixerSettings.NumInputChannels > 0)
  262. {
  263. ProcessInputChannels(source, countChunk);
  264. }
  265. if(inputMonitor)
  266. {
  267. mixsample_t *buffers[NUMMIXINPUTBUFFERS];
  268. for(std::size_t channel = 0; channel < NUMMIXINPUTBUFFERS; ++channel)
  269. {
  270. buffers[channel] = MixInputBuffer[channel];
  271. }
  272. inputMonitor->get().Process(mpt::audio_span_planar<const mixsample_t>(buffers, m_MixerSettings.NumInputChannels, countChunk));
  273. }
  274. CreateStereoMix(countChunk);
  275. if(m_opl)
  276. {
  277. m_opl->Mix(MixSoundBuffer, countChunk, m_OPLVolumeFactor * m_nVSTiVolume / 48);
  278. }
  279. #ifndef NO_REVERB
  280. m_Reverb.Process(MixSoundBuffer, ReverbSendBuffer, m_RvbROfsVol, m_RvbLOfsVol, countChunk);
  281. #endif // NO_REVERB
  282. #ifndef NO_PLUGINS
  283. if(m_loadedPlugins)
  284. {
  285. ProcessPlugins(countChunk);
  286. }
  287. #endif // NO_PLUGINS
  288. if(m_MixerSettings.gnChannels == 1)
  289. {
  290. MonoFromStereo(MixSoundBuffer, countChunk);
  291. }
  292. if(m_PlayConfig.getGlobalVolumeAppliesToMaster())
  293. {
  294. ProcessGlobalVolume(countChunk);
  295. }
  296. if(m_MixerSettings.m_nStereoSeparation != MixerSettings::StereoSeparationScale)
  297. {
  298. ProcessStereoSeparation(countChunk);
  299. }
  300. if(m_MixerSettings.DSPMask)
  301. {
  302. ProcessDSP(countChunk);
  303. }
  304. if(m_MixerSettings.gnChannels == 4)
  305. {
  306. InterleaveFrontRear(MixSoundBuffer, MixRearBuffer, countChunk);
  307. }
  308. if(outputMonitor)
  309. {
  310. outputMonitor->get().Process(mpt::audio_span_interleaved<const mixsample_t>(MixSoundBuffer, m_MixerSettings.gnChannels, countChunk));
  311. }
  312. target.Process(mpt::audio_span_interleaved<mixsample_t>(MixSoundBuffer, m_MixerSettings.gnChannels, countChunk));
  313. // Buffer ready
  314. countRendered += countChunk;
  315. countToRender -= countChunk;
  316. m_PlayState.m_nBufferCount -= countChunk;
  317. m_PlayState.m_lTotalSampleCount += countChunk;
  318. #ifdef MODPLUG_TRACKER
  319. if(IsRenderingToDisc())
  320. {
  321. // Stop playback on F00 if no more voices are active.
  322. // F00 sets the tick count to 65536 in FT2, so it just generates a reaaaally long row.
  323. // Usually this command can be found at the end of a song to effectively stop playback.
  324. // Since we don't want to render hours of silence, we are going to check if there are
  325. // still any channels playing, and if that is no longer the case, we stop playback at
  326. // the end of the next tick.
  327. if(m_PlayState.m_nMusicSpeed == uint16_max && (m_nMixStat == 0 || m_PlayState.m_nGlobalVolume == 0) && GetType() == MOD_TYPE_XM && !m_PlayState.m_nBufferCount)
  328. {
  329. m_SongFlags.set(SONG_ENDREACHED);
  330. }
  331. }
  332. #endif // MODPLUG_TRACKER
  333. }
  334. // mix done
  335. return countRendered;
  336. }
  337. void CSoundFile::ProcessDSP(uint32 countChunk)
  338. {
  339. #ifndef NO_DSP
  340. if(m_MixerSettings.DSPMask & SNDDSP_SURROUND)
  341. {
  342. m_Surround.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels);
  343. }
  344. #endif // NO_DSP
  345. #ifndef NO_DSP
  346. if(m_MixerSettings.DSPMask & SNDDSP_MEGABASS)
  347. {
  348. m_MegaBass.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels);
  349. }
  350. #endif // NO_DSP
  351. #ifndef NO_EQ
  352. if(m_MixerSettings.DSPMask & SNDDSP_EQ)
  353. {
  354. m_EQ.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels);
  355. }
  356. #endif // NO_EQ
  357. #ifndef NO_AGC
  358. if(m_MixerSettings.DSPMask & SNDDSP_AGC)
  359. {
  360. m_AGC.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels);
  361. }
  362. #endif // NO_AGC
  363. #ifndef NO_DSP
  364. if(m_MixerSettings.DSPMask & SNDDSP_BITCRUSH)
  365. {
  366. m_BitCrush.Process(MixSoundBuffer, MixRearBuffer, countChunk, m_MixerSettings.gnChannels);
  367. }
  368. #endif // NO_DSP
  369. #if defined(NO_DSP) && defined(NO_EQ) && defined(NO_AGC)
  370. MPT_UNREFERENCED_PARAMETER(countChunk);
  371. #endif
  372. }
  373. /////////////////////////////////////////////////////////////////////////////
  374. // Handles navigation/effects
  375. bool CSoundFile::ProcessRow()
  376. {
  377. while(++m_PlayState.m_nTickCount >= m_PlayState.TicksOnRow())
  378. {
  379. const auto [ignoreRow, patternTransition] = NextRow(m_PlayState, m_SongFlags[SONG_BREAKTOROW]);
  380. #ifdef MODPLUG_TRACKER
  381. if(patternTransition)
  382. {
  383. HandlePatternTransitionEvents();
  384. }
  385. // "Lock row" editing feature
  386. if(m_lockRowStart != ROWINDEX_INVALID && (m_PlayState.m_nRow < m_lockRowStart || m_PlayState.m_nRow > m_lockRowEnd) && !IsRenderingToDisc())
  387. {
  388. m_PlayState.m_nRow = m_lockRowStart;
  389. }
  390. // "Lock order" editing feature
  391. if(Order().IsPositionLocked(m_PlayState.m_nCurrentOrder) && !IsRenderingToDisc())
  392. {
  393. m_PlayState.m_nCurrentOrder = m_lockOrderStart;
  394. }
  395. #else
  396. MPT_UNUSED_VARIABLE(patternTransition);
  397. #endif // MODPLUG_TRACKER
  398. // Check if pattern is valid
  399. if(!m_SongFlags[SONG_PATTERNLOOP])
  400. {
  401. m_PlayState.m_nPattern = (m_PlayState.m_nCurrentOrder < Order().size()) ? Order()[m_PlayState.m_nCurrentOrder] : Order.GetInvalidPatIndex();
  402. if (m_PlayState.m_nPattern < Patterns.Size() && !Patterns[m_PlayState.m_nPattern].IsValid()) m_PlayState.m_nPattern = Order.GetIgnoreIndex();
  403. while (m_PlayState.m_nPattern >= Patterns.Size())
  404. {
  405. // End of song?
  406. if ((m_PlayState.m_nPattern == Order.GetInvalidPatIndex()) || (m_PlayState.m_nCurrentOrder >= Order().size()))
  407. {
  408. ORDERINDEX restartPosOverride = Order().GetRestartPos();
  409. if(restartPosOverride == 0 && m_PlayState.m_nCurrentOrder <= Order().size() && m_PlayState.m_nCurrentOrder > 0)
  410. {
  411. // Subtune detection. Subtunes are separated by "---" order items, so if we're in a
  412. // subtune and there's no restart position, we go to the first order of the subtune
  413. // (i.e. the first order after the previous "---" item)
  414. for(ORDERINDEX ord = m_PlayState.m_nCurrentOrder - 1; ord > 0; ord--)
  415. {
  416. if(Order()[ord] == Order.GetInvalidPatIndex())
  417. {
  418. // Jump back to first order of this subtune
  419. restartPosOverride = ord + 1;
  420. break;
  421. }
  422. }
  423. }
  424. // If channel resetting is disabled in MPT, we will emulate a pattern break (and we always do it if we're not in MPT)
  425. #ifdef MODPLUG_TRACKER
  426. if(!(TrackerSettings::Instance().m_dwPatternSetup & PATTERN_RESETCHANNELS))
  427. #endif // MODPLUG_TRACKER
  428. {
  429. m_SongFlags.set(SONG_BREAKTOROW);
  430. }
  431. if (restartPosOverride == 0 && !m_SongFlags[SONG_BREAKTOROW])
  432. {
  433. //rewbs.instroVSTi: stop all VSTi at end of song, if looping.
  434. StopAllVsti();
  435. m_PlayState.m_nMusicSpeed = m_nDefaultSpeed;
  436. m_PlayState.m_nMusicTempo = m_nDefaultTempo;
  437. m_PlayState.m_nGlobalVolume = m_nDefaultGlobalVolume;
  438. for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++)
  439. {
  440. auto &chn = m_PlayState.Chn[i];
  441. if(chn.dwFlags[CHN_ADLIB] && m_opl)
  442. {
  443. m_opl->NoteCut(i);
  444. }
  445. chn.dwFlags.set(CHN_NOTEFADE | CHN_KEYOFF);
  446. chn.nFadeOutVol = 0;
  447. if(i < m_nChannels)
  448. {
  449. chn.nGlobalVol = ChnSettings[i].nVolume;
  450. chn.nVolume = ChnSettings[i].nVolume;
  451. chn.nPan = ChnSettings[i].nPan;
  452. chn.nPanSwing = chn.nVolSwing = 0;
  453. chn.nCutSwing = chn.nResSwing = 0;
  454. chn.nOldVolParam = 0;
  455. chn.oldOffset = 0;
  456. chn.nOldHiOffset = 0;
  457. chn.nPortamentoDest = 0;
  458. if(!chn.nLength)
  459. {
  460. chn.dwFlags = ChnSettings[i].dwFlags;
  461. chn.nLoopStart = 0;
  462. chn.nLoopEnd = 0;
  463. chn.pModInstrument = nullptr;
  464. chn.pModSample = nullptr;
  465. }
  466. }
  467. }
  468. }
  469. //Handle Repeat position
  470. m_PlayState.m_nCurrentOrder = restartPosOverride;
  471. m_SongFlags.reset(SONG_BREAKTOROW);
  472. //If restart pos points to +++, move along
  473. while(m_PlayState.m_nCurrentOrder < Order().size() && Order()[m_PlayState.m_nCurrentOrder] == Order.GetIgnoreIndex())
  474. {
  475. m_PlayState.m_nCurrentOrder++;
  476. }
  477. //Check for end of song or bad pattern
  478. if (m_PlayState.m_nCurrentOrder >= Order().size()
  479. || !Order().IsValidPat(m_PlayState.m_nCurrentOrder))
  480. {
  481. m_visitedRows.Initialize(true);
  482. return false;
  483. }
  484. } else
  485. {
  486. m_PlayState.m_nCurrentOrder++;
  487. }
  488. if (m_PlayState.m_nCurrentOrder < Order().size())
  489. m_PlayState.m_nPattern = Order()[m_PlayState.m_nCurrentOrder];
  490. else
  491. m_PlayState.m_nPattern = Order.GetInvalidPatIndex();
  492. if (m_PlayState.m_nPattern < Patterns.Size() && !Patterns[m_PlayState.m_nPattern].IsValid())
  493. m_PlayState.m_nPattern = Order.GetIgnoreIndex();
  494. }
  495. m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder;
  496. #ifdef MODPLUG_TRACKER
  497. if ((m_nMaxOrderPosition) && (m_PlayState.m_nCurrentOrder >= m_nMaxOrderPosition)) return false;
  498. #endif // MODPLUG_TRACKER
  499. }
  500. // Weird stuff?
  501. if (!Patterns.IsValidPat(m_PlayState.m_nPattern))
  502. return false;
  503. // Did we jump to an invalid row?
  504. if (m_PlayState.m_nRow >= Patterns[m_PlayState.m_nPattern].GetNumRows()) m_PlayState.m_nRow = 0;
  505. // Has this row been visited before? We might want to stop playback now.
  506. // But: We will not mark the row as modified if the song is not in loop mode but
  507. // the pattern loop (editor flag, not to be confused with the pattern loop effect)
  508. // flag is set - because in that case, the module would stop after the first pattern loop...
  509. const bool overrideLoopCheck = (m_nRepeatCount != -1) && m_SongFlags[SONG_PATTERNLOOP];
  510. if(!overrideLoopCheck && m_visitedRows.Visit(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow, m_PlayState.Chn, ignoreRow))
  511. {
  512. if(m_nRepeatCount)
  513. {
  514. // repeat count == -1 means repeat infinitely.
  515. if(m_nRepeatCount > 0)
  516. {
  517. m_nRepeatCount--;
  518. }
  519. // Forget all but the current row.
  520. m_visitedRows.Initialize(true);
  521. m_visitedRows.Visit(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow, m_PlayState.Chn, ignoreRow);
  522. } else
  523. {
  524. #ifdef MODPLUG_TRACKER
  525. // Let's check again if this really is the end of the song.
  526. // The visited rows vector might have been screwed up while editing...
  527. // This is of course not possible during rendering to WAV, so we ignore that case.
  528. bool isReallyAtEnd = IsRenderingToDisc();
  529. if(!isReallyAtEnd)
  530. {
  531. for(const auto &t : GetLength(eNoAdjust, GetLengthTarget(true)))
  532. {
  533. if(t.lastOrder == m_PlayState.m_nCurrentOrder && t.lastRow == m_PlayState.m_nRow)
  534. {
  535. isReallyAtEnd = true;
  536. break;
  537. }
  538. }
  539. }
  540. if(isReallyAtEnd)
  541. {
  542. // This is really the song's end!
  543. m_visitedRows.Initialize(true);
  544. return false;
  545. } else
  546. {
  547. // Ok, this is really dirty, but we have to update the visited rows vector...
  548. GetLength(eAdjustOnlyVisitedRows, GetLengthTarget(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow));
  549. }
  550. #else
  551. if(m_SongFlags[SONG_PLAYALLSONGS])
  552. {
  553. // When playing all subsongs consecutively, first search for any hidden subsongs...
  554. if(!m_visitedRows.GetFirstUnvisitedRow(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow, true))
  555. {
  556. // ...and then try the next sequence.
  557. m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder = 0;
  558. m_PlayState.m_nNextRow = m_PlayState.m_nRow = 0;
  559. if(Order.GetCurrentSequenceIndex() >= Order.GetNumSequences() - 1)
  560. {
  561. Order.SetSequence(0);
  562. m_visitedRows.Initialize(true);
  563. return false;
  564. }
  565. Order.SetSequence(Order.GetCurrentSequenceIndex() + 1);
  566. m_visitedRows.Initialize(true);
  567. }
  568. // When jumping to the next subsong, stop all playing notes from the previous song...
  569. const auto muteFlag = CSoundFile::GetChannelMuteFlag();
  570. for(CHANNELINDEX i = 0; i < MAX_CHANNELS; i++)
  571. m_PlayState.Chn[i].Reset(ModChannel::resetSetPosFull, *this, i, muteFlag);
  572. StopAllVsti();
  573. // ...and the global playback information.
  574. m_PlayState.m_nMusicSpeed = m_nDefaultSpeed;
  575. m_PlayState.m_nMusicTempo = m_nDefaultTempo;
  576. m_PlayState.m_nGlobalVolume = m_nDefaultGlobalVolume;
  577. m_PlayState.m_nNextOrder = m_PlayState.m_nCurrentOrder;
  578. m_PlayState.m_nNextRow = m_PlayState.m_nRow;
  579. if(Order().size() > m_PlayState.m_nCurrentOrder)
  580. m_PlayState.m_nPattern = Order()[m_PlayState.m_nCurrentOrder];
  581. m_visitedRows.Visit(m_PlayState.m_nCurrentOrder, m_PlayState.m_nRow, m_PlayState.Chn, ignoreRow);
  582. if (!Patterns.IsValidPat(m_PlayState.m_nPattern))
  583. return false;
  584. } else
  585. {
  586. m_visitedRows.Initialize(true);
  587. return false;
  588. }
  589. #endif // MODPLUG_TRACKER
  590. }
  591. }
  592. SetupNextRow(m_PlayState, m_SongFlags[SONG_PATTERNLOOP]);
  593. // Reset channel values
  594. ModCommand *m = Patterns[m_PlayState.m_nPattern].GetpModCommand(m_PlayState.m_nRow, 0);
  595. for (ModChannel *pChn = m_PlayState.Chn, *pEnd = pChn + m_nChannels; pChn != pEnd; pChn++, m++)
  596. {
  597. // First, handle some quirks that happen after the last tick of the previous row...
  598. if(m_playBehaviour[KST3PortaAfterArpeggio]
  599. && pChn->nCommand == CMD_ARPEGGIO // Previous row state!
  600. && (m->command == CMD_PORTAMENTOUP || m->command == CMD_PORTAMENTODOWN))
  601. {
  602. // In ST3, a portamento immediately following an arpeggio continues where the arpeggio left off.
  603. // Test case: PortaAfterArp.s3m
  604. pChn->nPeriod = GetPeriodFromNote(pChn->nArpeggioLastNote, pChn->nFineTune, pChn->nC5Speed);
  605. }
  606. if(m_playBehaviour[kMODOutOfRangeNoteDelay]
  607. && !m->IsNote()
  608. && pChn->rowCommand.IsNote()
  609. && pChn->rowCommand.command == CMD_MODCMDEX && (pChn->rowCommand.param & 0xF0) == 0xD0
  610. && (pChn->rowCommand.param & 0x0Fu) >= m_PlayState.m_nMusicSpeed)
  611. {
  612. // In ProTracker, a note triggered by an out-of-range note delay can be heard on the next row
  613. // if there is no new note on that row.
  614. // Test case: NoteDelay-NextRow.mod
  615. pChn->nPeriod = GetPeriodFromNote(pChn->rowCommand.note, pChn->nFineTune, 0);
  616. }
  617. if(m_playBehaviour[kMODTempoOnSecondTick] && !m_playBehaviour[kMODVBlankTiming] && m_PlayState.m_nMusicSpeed == 1 && pChn->rowCommand.command == CMD_TEMPO)
  618. {
  619. // ProTracker sets the tempo after the first tick. This block handles the case of one tick per row.
  620. // Test case: TempoChange.mod
  621. m_PlayState.m_nMusicTempo = TEMPO(std::max(ModCommand::PARAM(1), pChn->rowCommand.param), 0);
  622. }
  623. pChn->rowCommand = *m;
  624. pChn->rightVol = pChn->newRightVol;
  625. pChn->leftVol = pChn->newLeftVol;
  626. pChn->dwFlags.reset(CHN_VIBRATO | CHN_TREMOLO);
  627. if(!m_playBehaviour[kITVibratoTremoloPanbrello]) pChn->nPanbrelloOffset = 0;
  628. pChn->nCommand = CMD_NONE;
  629. pChn->m_plugParamValueStep = 0;
  630. }
  631. // Now that we know which pattern we're on, we can update time signatures (global or pattern-specific)
  632. UpdateTimeSignature();
  633. if(ignoreRow)
  634. {
  635. m_PlayState.m_nTickCount = m_PlayState.m_nMusicSpeed;
  636. continue;
  637. }
  638. break;
  639. }
  640. // Should we process tick0 effects?
  641. if (!m_PlayState.m_nMusicSpeed) m_PlayState.m_nMusicSpeed = 1;
  642. //End of row? stop pattern step (aka "play row").
  643. #ifdef MODPLUG_TRACKER
  644. if (m_PlayState.m_nTickCount >= m_PlayState.TicksOnRow() - 1)
  645. {
  646. if(m_SongFlags[SONG_STEP])
  647. {
  648. m_SongFlags.reset(SONG_STEP);
  649. m_SongFlags.set(SONG_PAUSED);
  650. }
  651. }
  652. #endif // MODPLUG_TRACKER
  653. if (m_PlayState.m_nTickCount)
  654. {
  655. m_SongFlags.reset(SONG_FIRSTTICK);
  656. if(!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))
  657. && (GetType() != MOD_TYPE_MOD || m_SongFlags[SONG_PT_MODE]) // Fix infinite loop in "GamerMan " by MrGamer, which was made with FT2
  658. && m_PlayState.m_nTickCount < m_PlayState.TicksOnRow())
  659. {
  660. // Emulate first tick behaviour if Row Delay is set.
  661. // Test cases: PatternDelaysRetrig.it, PatternDelaysRetrig.s3m, PatternDelaysRetrig.xm, PatternDelaysRetrig.mod
  662. if(!(m_PlayState.m_nTickCount % (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay)))
  663. {
  664. m_SongFlags.set(SONG_FIRSTTICK);
  665. }
  666. }
  667. } else
  668. {
  669. m_SongFlags.set(SONG_FIRSTTICK);
  670. m_SongFlags.reset(SONG_BREAKTOROW);
  671. }
  672. // Update Effects
  673. return ProcessEffects();
  674. }
  675. std::pair<bool, bool> CSoundFile::NextRow(PlayState &playState, const bool breakRow) const
  676. {
  677. // When having an EEx effect on the same row as a Dxx jump, the target row is not played in ProTracker.
  678. // Test case: DelayBreak.mod (based on condom_corruption by Travolta)
  679. const bool ignoreRow = playState.m_nPatternDelay > 1 && breakRow && GetType() == MOD_TYPE_MOD;
  680. // Done with the last row of the pattern or jumping somewhere else (could also be a result of pattern loop to row 0, but that doesn't matter here)
  681. const bool patternTransition = playState.m_nNextRow == 0 || breakRow;
  682. if(patternTransition && GetType() == MOD_TYPE_S3M)
  683. {
  684. // Reset pattern loop start
  685. // Test case: LoopReset.s3m
  686. for(CHANNELINDEX i = 0; i < GetNumChannels(); i++)
  687. {
  688. playState.Chn[i].nPatternLoop = 0;
  689. }
  690. }
  691. playState.m_nPatternDelay = 0;
  692. playState.m_nFrameDelay = 0;
  693. playState.m_nTickCount = 0;
  694. playState.m_nRow = playState.m_nNextRow;
  695. playState.m_nCurrentOrder = playState.m_nNextOrder;
  696. return {ignoreRow, patternTransition};
  697. }
  698. void CSoundFile::SetupNextRow(PlayState &playState, const bool patternLoop) const
  699. {
  700. playState.m_nNextRow = playState.m_nRow + 1;
  701. if(playState.m_nNextRow >= Patterns[playState.m_nPattern].GetNumRows())
  702. {
  703. if(!patternLoop)
  704. playState.m_nNextOrder = playState.m_nCurrentOrder + 1;
  705. playState.m_nNextRow = 0;
  706. // FT2 idiosyncrasy: When E60 is used on a pattern row x, the following pattern also starts from row x
  707. // instead of the beginning of the pattern, unless there was a Bxx or Dxx effect.
  708. if(m_playBehaviour[kFT2LoopE60Restart])
  709. {
  710. playState.m_nNextRow = playState.m_nextPatStartRow;
  711. playState.m_nextPatStartRow = 0;
  712. }
  713. }
  714. }
  715. ////////////////////////////////////////////////////////////////////////////////////////////
  716. // Channel effect processing
  717. // Calculate delta for Vibrato / Tremolo / Panbrello effect
  718. int CSoundFile::GetVibratoDelta(int type, int position) const
  719. {
  720. // IT compatibility: IT has its own, more precise tables
  721. if(m_playBehaviour[kITVibratoTremoloPanbrello])
  722. {
  723. position &= 0xFF;
  724. switch(type & 0x03)
  725. {
  726. case 0: // Sine
  727. default:
  728. return ITSinusTable[position];
  729. case 1: // Ramp down
  730. return 64 - (position + 1) / 2;
  731. case 2: // Square
  732. return position < 128 ? 64 : 0;
  733. case 3: // Random
  734. return mpt::random<int, 7>(AccessPRNG()) - 0x40;
  735. }
  736. } else if(GetType() & (MOD_TYPE_DIGI | MOD_TYPE_DBM))
  737. {
  738. // Other waveforms are not supported.
  739. static constexpr int8 DBMSinus[] =
  740. {
  741. 33, 52, 69, 84, 96, 107, 116, 122, 125, 127, 125, 122, 116, 107, 96, 84,
  742. 69, 52, 33, 13, -8, -31, -54, -79, -104,-128, -104, -79, -54, -31, -8, 13,
  743. };
  744. return DBMSinus[(position / 2u) & 0x1F];
  745. } else
  746. {
  747. position &= 0x3F;
  748. switch(type & 0x03)
  749. {
  750. case 0: // Sine
  751. default:
  752. return ModSinusTable[position];
  753. case 1: // Ramp down
  754. return (position < 32 ? 0 : 255) - position * 4;
  755. case 2: // Square
  756. return position < 32 ? 127 : -127;
  757. case 3: // Random
  758. return ModRandomTable[position];
  759. }
  760. }
  761. }
  762. void CSoundFile::ProcessVolumeSwing(ModChannel &chn, int &vol) const
  763. {
  764. if(m_playBehaviour[kITSwingBehaviour])
  765. {
  766. vol += chn.nVolSwing;
  767. Limit(vol, 0, 64);
  768. } else if(m_playBehaviour[kMPTOldSwingBehaviour])
  769. {
  770. vol += chn.nVolSwing;
  771. Limit(vol, 0, 256);
  772. } else
  773. {
  774. chn.nVolume += chn.nVolSwing;
  775. Limit(chn.nVolume, 0, 256);
  776. vol = chn.nVolume;
  777. chn.nVolSwing = 0;
  778. }
  779. }
  780. void CSoundFile::ProcessPanningSwing(ModChannel &chn) const
  781. {
  782. if(m_playBehaviour[kITSwingBehaviour] || m_playBehaviour[kMPTOldSwingBehaviour])
  783. {
  784. chn.nRealPan = chn.nPan + chn.nPanSwing;
  785. Limit(chn.nRealPan, 0, 256);
  786. } else
  787. {
  788. chn.nPan += chn.nPanSwing;
  789. Limit(chn.nPan, 0, 256);
  790. chn.nPanSwing = 0;
  791. chn.nRealPan = chn.nPan;
  792. }
  793. }
  794. void CSoundFile::ProcessTremolo(ModChannel &chn, int &vol) const
  795. {
  796. if (chn.dwFlags[CHN_TREMOLO])
  797. {
  798. if(m_SongFlags.test_all(SONG_FIRSTTICK | SONG_PT_MODE))
  799. {
  800. // ProTracker doesn't apply tremolo nor advance on the first tick.
  801. // Test case: VibratoReset.mod
  802. return;
  803. }
  804. // IT compatibility: Why would you not want to execute tremolo at volume 0?
  805. if(vol > 0 || m_playBehaviour[kITVibratoTremoloPanbrello])
  806. {
  807. // IT compatibility: We don't need a different attenuation here because of the different tables we're going to use
  808. const uint8 attenuation = ((GetType() & (MOD_TYPE_XM | MOD_TYPE_MOD)) || m_playBehaviour[kITVibratoTremoloPanbrello]) ? 5 : 6;
  809. int delta = GetVibratoDelta(chn.nTremoloType, chn.nTremoloPos);
  810. if((chn.nTremoloType & 0x03) == 1 && m_playBehaviour[kFT2MODTremoloRampWaveform])
  811. {
  812. // FT2 compatibility: Tremolo ramp down / triangle implementation is weird and affected by vibrato position (copypaste bug)
  813. // Test case: TremoloWaveforms.xm, TremoloVibrato.xm
  814. uint8 ramp = (chn.nTremoloPos * 4u) & 0x7F;
  815. // Volume-colum vibrato gets executed first in FT2, so we may need to advance the vibrato position first
  816. uint32 vibPos = chn.nVibratoPos;
  817. if(!m_SongFlags[SONG_FIRSTTICK] && chn.dwFlags[CHN_VIBRATO])
  818. vibPos += chn.nVibratoSpeed;
  819. if((vibPos & 0x3F) >= 32)
  820. ramp ^= 0x7F;
  821. if((chn.nTremoloPos & 0x3F) >= 32)
  822. delta = -ramp;
  823. else
  824. delta = ramp;
  825. }
  826. if(GetType() != MOD_TYPE_DMF)
  827. {
  828. vol += (delta * chn.nTremoloDepth) / (1 << attenuation);
  829. } else
  830. {
  831. // Tremolo in DMF always attenuates by a percentage of the current note volume
  832. vol -= (vol * chn.nTremoloDepth * (64 - delta)) / (128 * 64);
  833. }
  834. }
  835. if(!m_SongFlags[SONG_FIRSTTICK] || ((GetType() & (MOD_TYPE_IT|MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS]))
  836. {
  837. // IT compatibility: IT has its own, more precise tables
  838. if(m_playBehaviour[kITVibratoTremoloPanbrello])
  839. chn.nTremoloPos += 4 * chn.nTremoloSpeed;
  840. else
  841. chn.nTremoloPos += chn.nTremoloSpeed;
  842. }
  843. }
  844. }
  845. void CSoundFile::ProcessTremor(CHANNELINDEX nChn, int &vol)
  846. {
  847. ModChannel &chn = m_PlayState.Chn[nChn];
  848. if(m_playBehaviour[kFT2Tremor])
  849. {
  850. // FT2 Compatibility: Weird XM tremor.
  851. // Test case: Tremor.xm
  852. if(chn.nTremorCount & 0x80)
  853. {
  854. if(!m_SongFlags[SONG_FIRSTTICK] && chn.nCommand == CMD_TREMOR)
  855. {
  856. chn.nTremorCount &= ~0x20;
  857. if(chn.nTremorCount == 0x80)
  858. {
  859. // Reached end of off-time
  860. chn.nTremorCount = (chn.nTremorParam >> 4) | 0xC0;
  861. } else if(chn.nTremorCount == 0xC0)
  862. {
  863. // Reached end of on-time
  864. chn.nTremorCount = (chn.nTremorParam & 0x0F) | 0x80;
  865. } else
  866. {
  867. chn.nTremorCount--;
  868. }
  869. chn.dwFlags.set(CHN_FASTVOLRAMP);
  870. }
  871. if((chn.nTremorCount & 0xE0) == 0x80)
  872. {
  873. vol = 0;
  874. }
  875. }
  876. } else if(chn.nCommand == CMD_TREMOR)
  877. {
  878. // IT compatibility 12. / 13.: Tremor
  879. if(m_playBehaviour[kITTremor])
  880. {
  881. if((chn.nTremorCount & 0x80) && chn.nLength)
  882. {
  883. if (chn.nTremorCount == 0x80)
  884. chn.nTremorCount = (chn.nTremorParam >> 4) | 0xC0;
  885. else if (chn.nTremorCount == 0xC0)
  886. chn.nTremorCount = (chn.nTremorParam & 0x0F) | 0x80;
  887. else
  888. chn.nTremorCount--;
  889. }
  890. if((chn.nTremorCount & 0xC0) == 0x80)
  891. vol = 0;
  892. } else
  893. {
  894. uint8 ontime = chn.nTremorParam >> 4;
  895. uint8 n = ontime + (chn.nTremorParam & 0x0F); // Total tremor cycle time (On + Off)
  896. if ((!(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))) || m_SongFlags[SONG_ITOLDEFFECTS])
  897. {
  898. n += 2;
  899. ontime++;
  900. }
  901. uint8 tremcount = chn.nTremorCount;
  902. if(!(GetType() & MOD_TYPE_XM))
  903. {
  904. if (tremcount >= n) tremcount = 0;
  905. if (tremcount >= ontime) vol = 0;
  906. chn.nTremorCount = tremcount + 1;
  907. } else
  908. {
  909. if(m_SongFlags[SONG_FIRSTTICK])
  910. {
  911. // tremcount is only 0 on the first tremor tick after triggering a note.
  912. if(tremcount > 0)
  913. {
  914. tremcount--;
  915. }
  916. } else
  917. {
  918. chn.nTremorCount = tremcount + 1;
  919. }
  920. if (tremcount % n >= ontime) vol = 0;
  921. }
  922. }
  923. chn.dwFlags.set(CHN_FASTVOLRAMP);
  924. }
  925. #ifndef NO_PLUGINS
  926. // Plugin tremor
  927. if(chn.nCommand == CMD_TREMOR && chn.pModInstrument && chn.pModInstrument->nMixPlug
  928. && !chn.pModInstrument->dwFlags[INS_MUTE]
  929. && !chn.dwFlags[CHN_MUTE | CHN_SYNCMUTE]
  930. && ModCommand::IsNote(chn.nLastNote))
  931. {
  932. const ModInstrument *pIns = chn.pModInstrument;
  933. IMixPlugin *pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin;
  934. if(pPlugin)
  935. {
  936. const bool isPlaying = pPlugin->IsNotePlaying(chn.nLastNote, nChn);
  937. if(vol == 0 && isPlaying)
  938. pPlugin->MidiCommand(*pIns, chn.nLastNote + NOTE_MAX_SPECIAL, 0, nChn);
  939. else if(vol != 0 && !isPlaying)
  940. pPlugin->MidiCommand(*pIns, chn.nLastNote, static_cast<uint16>(chn.nVolume), nChn);
  941. }
  942. }
  943. #endif // NO_PLUGINS
  944. }
  945. bool CSoundFile::IsEnvelopeProcessed(const ModChannel &chn, EnvelopeType env) const
  946. {
  947. if(chn.pModInstrument == nullptr)
  948. {
  949. return false;
  950. }
  951. const InstrumentEnvelope &insEnv = chn.pModInstrument->GetEnvelope(env);
  952. // IT Compatibility: S77/S79/S7B do not disable the envelope, they just pause the counter
  953. // Test cases: s77.it, EnvLoops.xm, PanSustainRelease.xm
  954. bool playIfPaused = m_playBehaviour[kITEnvelopePositionHandling] || m_playBehaviour[kFT2PanSustainRelease];
  955. return ((chn.GetEnvelope(env).flags[ENV_ENABLED] || (insEnv.dwFlags[ENV_ENABLED] && playIfPaused))
  956. && !insEnv.empty());
  957. }
  958. void CSoundFile::ProcessVolumeEnvelope(ModChannel &chn, int &vol) const
  959. {
  960. if(IsEnvelopeProcessed(chn, ENV_VOLUME))
  961. {
  962. const ModInstrument *pIns = chn.pModInstrument;
  963. if(m_playBehaviour[kITEnvelopePositionHandling] && chn.VolEnv.nEnvPosition == 0)
  964. {
  965. // If the envelope is disabled at the very same moment as it is triggered, we do not process anything.
  966. return;
  967. }
  968. const int envpos = chn.VolEnv.nEnvPosition - (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0);
  969. // Get values in [0, 256]
  970. int envval = pIns->VolEnv.GetValueFromPosition(envpos, 256);
  971. // if we are in the release portion of the envelope,
  972. // rescale envelope factor so that it is proportional to the release point
  973. // and release envelope beginning.
  974. if(pIns->VolEnv.nReleaseNode != ENV_RELEASE_NODE_UNSET
  975. && chn.VolEnv.nEnvValueAtReleaseJump != NOT_YET_RELEASED)
  976. {
  977. int envValueAtReleaseJump = chn.VolEnv.nEnvValueAtReleaseJump;
  978. int envValueAtReleaseNode = pIns->VolEnv[pIns->VolEnv.nReleaseNode].value * 4;
  979. //If we have just hit the release node, force the current env value
  980. //to be that of the release node. This works around the case where
  981. // we have another node at the same position as the release node.
  982. if(envpos == pIns->VolEnv[pIns->VolEnv.nReleaseNode].tick)
  983. envval = envValueAtReleaseNode;
  984. if(m_playBehaviour[kLegacyReleaseNode])
  985. {
  986. // Old, hard to grasp release node behaviour (additive)
  987. int relativeVolumeChange = (envval - envValueAtReleaseNode) * 2;
  988. envval = envValueAtReleaseJump + relativeVolumeChange;
  989. } else
  990. {
  991. // New behaviour, truly relative to release node
  992. if(envValueAtReleaseNode > 0)
  993. envval = envValueAtReleaseJump * envval / envValueAtReleaseNode;
  994. else
  995. envval = 0;
  996. }
  997. }
  998. vol = (vol * Clamp(envval, 0, 512)) / 256;
  999. }
  1000. }
  1001. void CSoundFile::ProcessPanningEnvelope(ModChannel &chn) const
  1002. {
  1003. if(IsEnvelopeProcessed(chn, ENV_PANNING))
  1004. {
  1005. const ModInstrument *pIns = chn.pModInstrument;
  1006. if(m_playBehaviour[kITEnvelopePositionHandling] && chn.PanEnv.nEnvPosition == 0)
  1007. {
  1008. // If the envelope is disabled at the very same moment as it is triggered, we do not process anything.
  1009. return;
  1010. }
  1011. const int envpos = chn.PanEnv.nEnvPosition - (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0);
  1012. // Get values in [-32, 32]
  1013. const int envval = pIns->PanEnv.GetValueFromPosition(envpos, 64) - 32;
  1014. int pan = chn.nRealPan;
  1015. if(pan >= 128)
  1016. {
  1017. pan += (envval * (256 - pan)) / 32;
  1018. } else
  1019. {
  1020. pan += (envval * (pan)) / 32;
  1021. }
  1022. chn.nRealPan = Clamp(pan, 0, 256);
  1023. }
  1024. }
  1025. int CSoundFile::ProcessPitchFilterEnvelope(ModChannel &chn, int32 &period) const
  1026. {
  1027. if(IsEnvelopeProcessed(chn, ENV_PITCH))
  1028. {
  1029. const ModInstrument *pIns = chn.pModInstrument;
  1030. if(m_playBehaviour[kITEnvelopePositionHandling] && chn.PitchEnv.nEnvPosition == 0)
  1031. {
  1032. // If the envelope is disabled at the very same moment as it is triggered, we do not process anything.
  1033. return -1;
  1034. }
  1035. const int envpos = chn.PitchEnv.nEnvPosition - (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0);
  1036. // Get values in [-256, 256]
  1037. #ifdef MODPLUG_TRACKER
  1038. const int32 range = ENVELOPE_MAX;
  1039. const int32 amp = 512;
  1040. #else
  1041. // TODO: AMS2 envelopes behave differently when linear slides are off - emulate with 15 * (-128...127) >> 6
  1042. // Copy over vibrato behaviour for that?
  1043. const int32 range = GetType() == MOD_TYPE_AMS ? uint8_max : ENVELOPE_MAX;
  1044. int32 amp;
  1045. switch(GetType())
  1046. {
  1047. case MOD_TYPE_AMS: amp = 64; break;
  1048. case MOD_TYPE_MDL: amp = 192; break;
  1049. default: amp = 512;
  1050. }
  1051. #endif
  1052. const int envval = pIns->PitchEnv.GetValueFromPosition(envpos, amp, range) - amp / 2;
  1053. if(chn.PitchEnv.flags[ENV_FILTER])
  1054. {
  1055. // Filter Envelope: controls cutoff frequency
  1056. return SetupChannelFilter(chn, !chn.dwFlags[CHN_FILTER], envval);
  1057. } else
  1058. {
  1059. // Pitch Envelope
  1060. if(chn.HasCustomTuning())
  1061. {
  1062. if(chn.nFineTune != envval)
  1063. {
  1064. chn.nFineTune = mpt::saturate_cast<int16>(envval);
  1065. chn.m_CalculateFreq = true;
  1066. //Preliminary tests indicated that this behavior
  1067. //is very close to original(with 12TET) when finestep count
  1068. //is 15.
  1069. }
  1070. } else //Original behavior
  1071. {
  1072. const bool useFreq = PeriodsAreFrequencies();
  1073. const uint32 (&upTable)[256] = useFreq ? LinearSlideUpTable : LinearSlideDownTable;
  1074. const uint32 (&downTable)[256] = useFreq ? LinearSlideDownTable : LinearSlideUpTable;
  1075. int l = envval;
  1076. if(l < 0)
  1077. {
  1078. l = -l;
  1079. LimitMax(l, 255);
  1080. period = Util::muldiv(period, downTable[l], 65536);
  1081. } else
  1082. {
  1083. LimitMax(l, 255);
  1084. period = Util::muldiv(period, upTable[l], 65536);
  1085. }
  1086. } //End: Original behavior.
  1087. }
  1088. }
  1089. return -1;
  1090. }
  1091. void CSoundFile::IncrementEnvelopePosition(ModChannel &chn, EnvelopeType envType) const
  1092. {
  1093. ModChannel::EnvInfo &chnEnv = chn.GetEnvelope(envType);
  1094. if(chn.pModInstrument == nullptr || !chnEnv.flags[ENV_ENABLED])
  1095. {
  1096. return;
  1097. }
  1098. // Increase position
  1099. uint32 position = chnEnv.nEnvPosition + (m_playBehaviour[kITEnvelopePositionHandling] ? 0 : 1);
  1100. const InstrumentEnvelope &insEnv = chn.pModInstrument->GetEnvelope(envType);
  1101. if(insEnv.empty())
  1102. {
  1103. return;
  1104. }
  1105. bool endReached = false;
  1106. if(!m_playBehaviour[kITEnvelopePositionHandling])
  1107. {
  1108. // FT2-style envelope processing.
  1109. if(insEnv.dwFlags[ENV_LOOP])
  1110. {
  1111. // Normal loop active
  1112. uint32 end = insEnv[insEnv.nLoopEnd].tick;
  1113. if(!(GetType() & (MOD_TYPE_XM | MOD_TYPE_MT2))) end++;
  1114. // FT2 compatibility: If the sustain point is at the loop end and the sustain loop has been released, don't loop anymore.
  1115. // Test case: EnvLoops.xm
  1116. const bool escapeLoop = (insEnv.nLoopEnd == insEnv.nSustainEnd && insEnv.dwFlags[ENV_SUSTAIN] && chn.dwFlags[CHN_KEYOFF] && m_playBehaviour[kFT2EnvelopeEscape]);
  1117. if(position == end && !escapeLoop)
  1118. {
  1119. position = insEnv[insEnv.nLoopStart].tick;
  1120. }
  1121. }
  1122. if(insEnv.dwFlags[ENV_SUSTAIN] && !chn.dwFlags[CHN_KEYOFF])
  1123. {
  1124. // Envelope sustained
  1125. if(position == insEnv[insEnv.nSustainEnd].tick + 1u)
  1126. {
  1127. position = insEnv[insEnv.nSustainStart].tick;
  1128. // FT2 compatibility: If the panning envelope reaches its sustain point before key-off, it stays there forever.
  1129. // Test case: PanSustainRelease.xm
  1130. if(m_playBehaviour[kFT2PanSustainRelease] && envType == ENV_PANNING && !chn.dwFlags[CHN_KEYOFF])
  1131. {
  1132. chnEnv.flags.reset(ENV_ENABLED);
  1133. }
  1134. }
  1135. } else
  1136. {
  1137. // Limit to last envelope point
  1138. if(position > insEnv.back().tick)
  1139. {
  1140. // Env of envelope
  1141. position = insEnv.back().tick;
  1142. endReached = true;
  1143. }
  1144. }
  1145. } else
  1146. {
  1147. // IT envelope processing.
  1148. // Test case: EnvLoops.it
  1149. uint32 start, end;
  1150. // IT compatiblity: OpenMPT processes the key-off flag earlier than IT. Grab the flag from the previous tick instead.
  1151. // Test case: EnvOffLength.it
  1152. if(insEnv.dwFlags[ENV_SUSTAIN] && !chn.dwOldFlags[CHN_KEYOFF] && (chnEnv.nEnvValueAtReleaseJump == NOT_YET_RELEASED || m_playBehaviour[kReleaseNodePastSustainBug]))
  1153. {
  1154. // Envelope sustained
  1155. start = insEnv[insEnv.nSustainStart].tick;
  1156. end = insEnv[insEnv.nSustainEnd].tick + 1;
  1157. } else if(insEnv.dwFlags[ENV_LOOP])
  1158. {
  1159. // Normal loop active
  1160. start = insEnv[insEnv.nLoopStart].tick;
  1161. end = insEnv[insEnv.nLoopEnd].tick + 1;
  1162. } else
  1163. {
  1164. // Limit to last envelope point
  1165. start = end = insEnv.back().tick;
  1166. if(position > end)
  1167. {
  1168. // Env of envelope
  1169. endReached = true;
  1170. }
  1171. }
  1172. if(position >= end)
  1173. {
  1174. position = start;
  1175. }
  1176. }
  1177. if(envType == ENV_VOLUME && endReached)
  1178. {
  1179. // Special handling for volume envelopes at end of envelope
  1180. if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) || (chn.dwFlags[CHN_KEYOFF] && GetType() != MOD_TYPE_MDL))
  1181. {
  1182. chn.dwFlags.set(CHN_NOTEFADE);
  1183. }
  1184. if(insEnv.back().value == 0 && (chn.nMasterChn > 0 || (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))))
  1185. {
  1186. // Stop channel if the last envelope node is silent anyway.
  1187. chn.dwFlags.set(CHN_NOTEFADE);
  1188. chn.nFadeOutVol = 0;
  1189. chn.nRealVolume = 0;
  1190. chn.nCalcVolume = 0;
  1191. }
  1192. }
  1193. chnEnv.nEnvPosition = position + (m_playBehaviour[kITEnvelopePositionHandling] ? 1 : 0);
  1194. }
  1195. void CSoundFile::IncrementEnvelopePositions(ModChannel &chn) const
  1196. {
  1197. if (chn.isFirstTick && GetType() == MOD_TYPE_MED)
  1198. return;
  1199. IncrementEnvelopePosition(chn, ENV_VOLUME);
  1200. IncrementEnvelopePosition(chn, ENV_PANNING);
  1201. IncrementEnvelopePosition(chn, ENV_PITCH);
  1202. }
  1203. void CSoundFile::ProcessInstrumentFade(ModChannel &chn, int &vol) const
  1204. {
  1205. // FadeOut volume
  1206. if(chn.dwFlags[CHN_NOTEFADE] && chn.pModInstrument != nullptr)
  1207. {
  1208. const ModInstrument *pIns = chn.pModInstrument;
  1209. uint32 fadeout = pIns->nFadeOut;
  1210. if (fadeout)
  1211. {
  1212. chn.nFadeOutVol -= fadeout * 2;
  1213. if (chn.nFadeOutVol <= 0) chn.nFadeOutVol = 0;
  1214. vol = (vol * chn.nFadeOutVol) / 65536;
  1215. } else if (!chn.nFadeOutVol)
  1216. {
  1217. vol = 0;
  1218. }
  1219. }
  1220. }
  1221. void CSoundFile::ProcessPitchPanSeparation(int32 &pan, int note, const ModInstrument &instr)
  1222. {
  1223. if(!instr.nPPS || note == NOTE_NONE)
  1224. return;
  1225. // with PPS = 16 / PPC = C-5, E-6 will pan hard right (and D#6 will not)
  1226. int32 delta = (note - instr.nPPC - NOTE_MIN) * instr.nPPS / 2;
  1227. pan = Clamp(pan + delta, 0, 256);
  1228. }
  1229. void CSoundFile::ProcessPanbrello(ModChannel &chn) const
  1230. {
  1231. int pdelta = chn.nPanbrelloOffset;
  1232. if(chn.rowCommand.command == CMD_PANBRELLO)
  1233. {
  1234. uint32 panpos;
  1235. // IT compatibility: IT has its own, more precise tables
  1236. if(m_playBehaviour[kITVibratoTremoloPanbrello])
  1237. panpos = chn.nPanbrelloPos;
  1238. else
  1239. panpos = ((chn.nPanbrelloPos + 0x10) >> 2);
  1240. pdelta = GetVibratoDelta(chn.nPanbrelloType, panpos);
  1241. // IT compatibility: Sample-and-hold style random panbrello (tremolo and vibrato don't use this mechanism in IT)
  1242. // Test case: RandomWaveform.it
  1243. if(m_playBehaviour[kITSampleAndHoldPanbrello] && chn.nPanbrelloType == 3)
  1244. {
  1245. if(chn.nPanbrelloPos == 0 || chn.nPanbrelloPos >= chn.nPanbrelloSpeed)
  1246. {
  1247. chn.nPanbrelloPos = 0;
  1248. chn.nPanbrelloRandomMemory = static_cast<int8>(pdelta);
  1249. }
  1250. chn.nPanbrelloPos++;
  1251. pdelta = chn.nPanbrelloRandomMemory;
  1252. } else
  1253. {
  1254. chn.nPanbrelloPos += chn.nPanbrelloSpeed;
  1255. }
  1256. // IT compatibility: Panbrello effect is active until next note or panning command.
  1257. // Test case: PanbrelloHold.it
  1258. if(m_playBehaviour[kITPanbrelloHold])
  1259. {
  1260. chn.nPanbrelloOffset = static_cast<int8>(pdelta);
  1261. }
  1262. }
  1263. if(pdelta)
  1264. {
  1265. pdelta = ((pdelta * (int)chn.nPanbrelloDepth) + 2) / 8;
  1266. pdelta += chn.nRealPan;
  1267. chn.nRealPan = Clamp(pdelta, 0, 256);
  1268. }
  1269. }
  1270. void CSoundFile::ProcessArpeggio(CHANNELINDEX nChn, int32 &period, Tuning::NOTEINDEXTYPE &arpeggioSteps)
  1271. {
  1272. ModChannel &chn = m_PlayState.Chn[nChn];
  1273. #ifndef NO_PLUGINS
  1274. // Plugin arpeggio
  1275. if(chn.pModInstrument && chn.pModInstrument->nMixPlug
  1276. && !chn.pModInstrument->dwFlags[INS_MUTE]
  1277. && !chn.dwFlags[CHN_MUTE | CHN_SYNCMUTE])
  1278. {
  1279. const ModInstrument *pIns = chn.pModInstrument;
  1280. IMixPlugin *pPlugin = m_MixPlugins[pIns->nMixPlug - 1].pMixPlugin;
  1281. if(pPlugin)
  1282. {
  1283. uint8 step = 0;
  1284. const bool arpOnRow = (chn.rowCommand.command == CMD_ARPEGGIO);
  1285. const ModCommand::NOTE lastNote = ModCommand::IsNote(chn.nLastNote) ? static_cast<ModCommand::NOTE>(pIns->NoteMap[chn.nLastNote - NOTE_MIN]) : static_cast<ModCommand::NOTE>(NOTE_NONE);
  1286. if(arpOnRow)
  1287. {
  1288. switch(m_PlayState.m_nTickCount % 3)
  1289. {
  1290. case 1: step = chn.nArpeggio >> 4; break;
  1291. case 2: step = chn.nArpeggio & 0x0F; break;
  1292. }
  1293. chn.nArpeggioBaseNote = lastNote;
  1294. }
  1295. // Trigger new note:
  1296. // - If there's an arpeggio on this row and
  1297. // - the note to trigger is not the same as the previous arpeggio note or
  1298. // - a pattern note has just been triggered on this tick
  1299. // - If there's no arpeggio
  1300. // - but an arpeggio note is still active and
  1301. // - there's no note stop or new note that would stop it anyway
  1302. if((arpOnRow && chn.nArpeggioLastNote != chn.nArpeggioBaseNote + step && (!m_SongFlags[SONG_FIRSTTICK] || !chn.rowCommand.IsNote()))
  1303. || (!arpOnRow && chn.rowCommand.note == NOTE_NONE && chn.nArpeggioLastNote != NOTE_NONE))
  1304. SendMIDINote(nChn, chn.nArpeggioBaseNote + step, static_cast<uint16>(chn.nVolume));
  1305. // Stop note:
  1306. // - If some arpeggio note is still registered or
  1307. // - When starting an arpeggio on a row with no other note on it, stop some possibly still playing note.
  1308. if(chn.nArpeggioLastNote != NOTE_NONE)
  1309. SendMIDINote(nChn, chn.nArpeggioLastNote + NOTE_MAX_SPECIAL, 0);
  1310. else if(arpOnRow && m_SongFlags[SONG_FIRSTTICK] && !chn.rowCommand.IsNote() && ModCommand::IsNote(lastNote))
  1311. SendMIDINote(nChn, lastNote + NOTE_MAX_SPECIAL, 0);
  1312. if(chn.rowCommand.command == CMD_ARPEGGIO)
  1313. chn.nArpeggioLastNote = chn.nArpeggioBaseNote + step;
  1314. else
  1315. chn.nArpeggioLastNote = NOTE_NONE;
  1316. }
  1317. }
  1318. #endif // NO_PLUGINS
  1319. if(chn.nCommand == CMD_ARPEGGIO)
  1320. {
  1321. if(chn.HasCustomTuning())
  1322. {
  1323. switch(m_PlayState.m_nTickCount % 3)
  1324. {
  1325. case 0: arpeggioSteps = 0; break;
  1326. case 1: arpeggioSteps = chn.nArpeggio >> 4; break;
  1327. case 2: arpeggioSteps = chn.nArpeggio & 0x0F; break;
  1328. }
  1329. chn.m_CalculateFreq = true;
  1330. chn.m_ReCalculateFreqOnFirstTick = true;
  1331. } else
  1332. {
  1333. if(GetType() == MOD_TYPE_MT2 && m_SongFlags[SONG_FIRSTTICK])
  1334. {
  1335. // MT2 resets any previous portamento when an arpeggio occurs.
  1336. chn.nPeriod = period = GetPeriodFromNote(chn.nNote, chn.nFineTune, chn.nC5Speed);
  1337. }
  1338. if(m_playBehaviour[kITArpeggio])
  1339. {
  1340. //IT playback compatibility 01 & 02
  1341. // Pattern delay restarts tick counting. Not quite correct yet!
  1342. const uint32 tick = m_PlayState.m_nTickCount % (m_PlayState.m_nMusicSpeed + m_PlayState.m_nFrameDelay);
  1343. if(chn.nArpeggio != 0)
  1344. {
  1345. uint32 arpRatio = 65536;
  1346. switch(tick % 3)
  1347. {
  1348. case 1: arpRatio = LinearSlideUpTable[(chn.nArpeggio >> 4) * 16]; break;
  1349. case 2: arpRatio = LinearSlideUpTable[(chn.nArpeggio & 0x0F) * 16]; break;
  1350. }
  1351. if(PeriodsAreFrequencies())
  1352. period = Util::muldivr(period, arpRatio, 65536);
  1353. else
  1354. period = Util::muldivr(period, 65536, arpRatio);
  1355. }
  1356. } else if(m_playBehaviour[kFT2Arpeggio])
  1357. {
  1358. // FastTracker 2: Swedish tracker logic (TM) arpeggio
  1359. if(!m_SongFlags[SONG_FIRSTTICK])
  1360. {
  1361. // Arpeggio is added on top of current note, but cannot do it the IT way because of
  1362. // the behaviour in ArpeggioClamp.xm.
  1363. // Test case: ArpSlide.xm
  1364. uint32 note = 0;
  1365. // The fact that arpeggio behaves in a totally fucked up way at 16 ticks/row or more is that the arpeggio offset LUT only has 16 entries in FT2.
  1366. // At more than 16 ticks/row, FT2 reads into the vibrato table, which is placed right after the arpeggio table.
  1367. // Test case: Arpeggio.xm
  1368. int arpPos = m_PlayState.m_nMusicSpeed - (m_PlayState.m_nTickCount % m_PlayState.m_nMusicSpeed);
  1369. if(arpPos > 16)
  1370. arpPos = 2;
  1371. else if(arpPos == 16)
  1372. arpPos = 0;
  1373. else
  1374. arpPos %= 3;
  1375. switch(arpPos)
  1376. {
  1377. case 1: note = (chn.nArpeggio >> 4); break;
  1378. case 2: note = (chn.nArpeggio & 0x0F); break;
  1379. }
  1380. if(arpPos != 0)
  1381. {
  1382. // Arpeggio is added on top of current note, but cannot do it the IT way because of
  1383. // the behaviour in ArpeggioClamp.xm.
  1384. // Test case: ArpSlide.xm
  1385. note += GetNoteFromPeriod(period, chn.nFineTune, chn.nC5Speed);
  1386. period = GetPeriodFromNote(note, chn.nFineTune, chn.nC5Speed);
  1387. // FT2 compatibility: FT2 has a different note limit for Arpeggio.
  1388. // Test case: ArpeggioClamp.xm
  1389. if(note >= 108 + NOTE_MIN)
  1390. {
  1391. period = std::max(static_cast<uint32>(period), GetPeriodFromNote(108 + NOTE_MIN, 0, chn.nC5Speed));
  1392. }
  1393. }
  1394. }
  1395. }
  1396. // Other trackers
  1397. else
  1398. {
  1399. uint32 tick = m_PlayState.m_nTickCount;
  1400. // TODO other likely formats for MOD case: MED, OKT, etc
  1401. uint8 note = (GetType() != MOD_TYPE_MOD) ? chn.nNote : static_cast<uint8>(GetNoteFromPeriod(period, chn.nFineTune, chn.nC5Speed));
  1402. if(GetType() & (MOD_TYPE_DBM | MOD_TYPE_DIGI))
  1403. tick += 2;
  1404. switch(tick % 3)
  1405. {
  1406. case 1: note += (chn.nArpeggio >> 4); break;
  1407. case 2: note += (chn.nArpeggio & 0x0F); break;
  1408. }
  1409. if(note != chn.nNote || (GetType() & (MOD_TYPE_DBM | MOD_TYPE_DIGI | MOD_TYPE_STM)) || m_playBehaviour[KST3PortaAfterArpeggio])
  1410. {
  1411. if(m_SongFlags[SONG_PT_MODE])
  1412. {
  1413. // Weird arpeggio wrap-around in ProTracker.
  1414. // Test case: ArpWraparound.mod, and the snare sound in "Jim is dead" by doh.
  1415. if(note == NOTE_MIDDLEC + 24)
  1416. {
  1417. period = int32_max;
  1418. return;
  1419. } else if(note > NOTE_MIDDLEC + 24)
  1420. {
  1421. note -= 37;
  1422. }
  1423. }
  1424. period = GetPeriodFromNote(note, chn.nFineTune, chn.nC5Speed);
  1425. if(GetType() & (MOD_TYPE_DBM | MOD_TYPE_DIGI | MOD_TYPE_PSM | MOD_TYPE_STM | MOD_TYPE_OKT))
  1426. {
  1427. // The arpeggio note offset remains effective after the end of the current row in ScreamTracker 2.
  1428. // This fixes the flute lead in MORPH.STM by Skaven, pattern 27.
  1429. // Note that ScreamTracker 2.24 handles arpeggio slightly differently: It only considers the lower
  1430. // nibble, and switches to that note halfway through the row.
  1431. chn.nPeriod = period;
  1432. } else if(m_playBehaviour[KST3PortaAfterArpeggio])
  1433. {
  1434. chn.nArpeggioLastNote = note;
  1435. }
  1436. }
  1437. }
  1438. }
  1439. }
  1440. }
  1441. void CSoundFile::ProcessVibrato(CHANNELINDEX nChn, int32 &period, Tuning::RATIOTYPE &vibratoFactor)
  1442. {
  1443. ModChannel &chn = m_PlayState.Chn[nChn];
  1444. if(chn.dwFlags[CHN_VIBRATO])
  1445. {
  1446. const bool advancePosition = !m_SongFlags[SONG_FIRSTTICK] || ((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !(m_SongFlags[SONG_ITOLDEFFECTS]));
  1447. if(GetType() == MOD_TYPE_669)
  1448. {
  1449. if(chn.nVibratoPos % 2u)
  1450. {
  1451. period += chn.nVibratoDepth * 167; // Already multiplied by 4, and it seems like the real factor here is 669... how original =)
  1452. }
  1453. chn.nVibratoPos++;
  1454. return;
  1455. }
  1456. // IT compatibility: IT has its own, more precise tables and pre-increments the vibrato position
  1457. if(advancePosition && m_playBehaviour[kITVibratoTremoloPanbrello])
  1458. chn.nVibratoPos += 4 * chn.nVibratoSpeed;
  1459. int vdelta = GetVibratoDelta(chn.nVibratoType, chn.nVibratoPos);
  1460. if(chn.HasCustomTuning())
  1461. {
  1462. //Hack implementation: Scaling vibratofactor to [0.95; 1.05]
  1463. //using figure from above tables and vibratodepth parameter
  1464. vibratoFactor += 0.05f * (vdelta * chn.nVibratoDepth) / (128.0f * 60.0f);
  1465. chn.m_CalculateFreq = true;
  1466. chn.m_ReCalculateFreqOnFirstTick = false;
  1467. if(m_PlayState.m_nTickCount + 1 == m_PlayState.m_nMusicSpeed)
  1468. chn.m_ReCalculateFreqOnFirstTick = true;
  1469. } else
  1470. {
  1471. // Original behaviour
  1472. if(m_SongFlags.test_all(SONG_FIRSTTICK | SONG_PT_MODE) || ((GetType() & (MOD_TYPE_DIGI | MOD_TYPE_DBM)) && m_SongFlags[SONG_FIRSTTICK]))
  1473. {
  1474. // ProTracker doesn't apply vibrato nor advance on the first tick.
  1475. // Test case: VibratoReset.mod
  1476. return;
  1477. } else if((GetType() & (MOD_TYPE_XM | MOD_TYPE_MOD)) && (chn.nVibratoType & 0x03) == 1)
  1478. {
  1479. // FT2 compatibility: Vibrato ramp down table is upside down.
  1480. // Test case: VibratoWaveforms.xm
  1481. vdelta = -vdelta;
  1482. }
  1483. uint32 vdepth;
  1484. // IT compatibility: correct vibrato depth
  1485. if(m_playBehaviour[kITVibratoTremoloPanbrello])
  1486. {
  1487. // Yes, vibrato goes backwards with old effects enabled!
  1488. if(m_SongFlags[SONG_ITOLDEFFECTS])
  1489. {
  1490. // Test case: vibrato-oldfx.it
  1491. vdepth = 5;
  1492. } else
  1493. {
  1494. // Test case: vibrato.it
  1495. vdepth = 6;
  1496. vdelta = -vdelta;
  1497. }
  1498. } else
  1499. {
  1500. if(m_SongFlags[SONG_S3MOLDVIBRATO])
  1501. vdepth = 5;
  1502. else if(GetType() == MOD_TYPE_DTM)
  1503. vdepth = 8;
  1504. else if(GetType() & (MOD_TYPE_DBM | MOD_TYPE_MTM))
  1505. vdepth = 7;
  1506. else if((GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) && !m_SongFlags[SONG_ITOLDEFFECTS])
  1507. vdepth = 7;
  1508. else
  1509. vdepth = 6;
  1510. // ST3 compatibility: Do not distinguish between vibrato types in effect memory
  1511. // Test case: VibratoTypeChange.s3m
  1512. if(m_playBehaviour[kST3VibratoMemory] && chn.rowCommand.command == CMD_FINEVIBRATO)
  1513. vdepth += 2;
  1514. }
  1515. vdelta = (-vdelta * static_cast<int>(chn.nVibratoDepth)) / (1 << vdepth);
  1516. DoFreqSlide(chn, period, vdelta);
  1517. // Process MIDI vibrato for plugins:
  1518. #ifndef NO_PLUGINS
  1519. IMixPlugin *plugin = GetChannelInstrumentPlugin(m_PlayState.Chn[nChn]);
  1520. if(plugin != nullptr)
  1521. {
  1522. // If the Pitch Wheel Depth is configured correctly (so it's the same as the plugin's PWD),
  1523. // MIDI vibrato will sound identical to vibrato with linear slides enabled.
  1524. int8 pwd = 2;
  1525. if(chn.pModInstrument != nullptr)
  1526. {
  1527. pwd = chn.pModInstrument->midiPWD;
  1528. }
  1529. plugin->MidiVibrato(vdelta, pwd, nChn);
  1530. }
  1531. #endif // NO_PLUGINS
  1532. }
  1533. // Advance vibrato position - IT updates on every tick, unless "old effects" are enabled (in this case it only updates on non-first ticks like other trackers)
  1534. // IT compatibility: IT has its own, more precise tables and pre-increments the vibrato position
  1535. if(advancePosition && !m_playBehaviour[kITVibratoTremoloPanbrello])
  1536. chn.nVibratoPos += chn.nVibratoSpeed;
  1537. } else if(chn.dwOldFlags[CHN_VIBRATO])
  1538. {
  1539. // Stop MIDI vibrato for plugins:
  1540. #ifndef NO_PLUGINS
  1541. IMixPlugin *plugin = GetChannelInstrumentPlugin(m_PlayState.Chn[nChn]);
  1542. if(plugin != nullptr)
  1543. {
  1544. plugin->MidiVibrato(0, 0, nChn);
  1545. }
  1546. #endif // NO_PLUGINS
  1547. }
  1548. }
  1549. void CSoundFile::ProcessSampleAutoVibrato(ModChannel &chn, int32 &period, Tuning::RATIOTYPE &vibratoFactor, int &nPeriodFrac) const
  1550. {
  1551. // Sample Auto-Vibrato
  1552. if(chn.pModSample != nullptr && chn.pModSample->nVibDepth)
  1553. {
  1554. const ModSample *pSmp = chn.pModSample;
  1555. const bool hasTuning = chn.HasCustomTuning();
  1556. // In IT compatible mode, we use always frequencies, otherwise we use periods, which are upside down.
  1557. // In this context, the "up" tables refer to the tables that increase frequency, and the down tables are the ones that decrease frequency.
  1558. const bool useFreq = PeriodsAreFrequencies();
  1559. const uint32 (&upTable)[256] = useFreq ? LinearSlideUpTable : LinearSlideDownTable;
  1560. const uint32 (&downTable)[256] = useFreq ? LinearSlideDownTable : LinearSlideUpTable;
  1561. const uint32 (&fineUpTable)[16] = useFreq ? FineLinearSlideUpTable : FineLinearSlideDownTable;
  1562. const uint32 (&fineDownTable)[16] = useFreq ? FineLinearSlideDownTable : FineLinearSlideUpTable;
  1563. // IT compatibility: Autovibrato is so much different in IT that I just put this in a separate code block, to get rid of a dozen IsCompatibilityMode() calls.
  1564. if(m_playBehaviour[kITVibratoTremoloPanbrello] && !hasTuning && GetType() != MOD_TYPE_MT2)
  1565. {
  1566. if(!pSmp->nVibRate)
  1567. return;
  1568. // Schism's autovibrato code
  1569. /*
  1570. X86 Assembler from ITTECH.TXT:
  1571. 1) Mov AX, [SomeVariableNameRelatingToVibrato]
  1572. 2) Add AL, Rate
  1573. 3) AdC AH, 0
  1574. 4) AH contains the depth of the vibrato as a fine-linear slide.
  1575. 5) Mov [SomeVariableNameRelatingToVibrato], AX ; For the next cycle.
  1576. */
  1577. const int vibpos = chn.nAutoVibPos & 0xFF;
  1578. int adepth = chn.nAutoVibDepth; // (1)
  1579. adepth += pSmp->nVibSweep; // (2 & 3)
  1580. LimitMax(adepth, static_cast<int>(pSmp->nVibDepth * 256u));
  1581. chn.nAutoVibDepth = adepth; // (5)
  1582. adepth /= 256; // (4)
  1583. chn.nAutoVibPos += pSmp->nVibRate;
  1584. int vdelta;
  1585. switch(pSmp->nVibType)
  1586. {
  1587. case VIB_RANDOM:
  1588. vdelta = mpt::random<int, 7>(AccessPRNG()) - 0x40;
  1589. break;
  1590. case VIB_RAMP_DOWN:
  1591. vdelta = 64 - (vibpos + 1) / 2;
  1592. break;
  1593. case VIB_RAMP_UP:
  1594. vdelta = ((vibpos + 1) / 2) - 64;
  1595. break;
  1596. case VIB_SQUARE:
  1597. vdelta = vibpos < 128 ? 64 : 0;
  1598. break;
  1599. case VIB_SINE:
  1600. default:
  1601. vdelta = ITSinusTable[vibpos];
  1602. break;
  1603. }
  1604. vdelta = (vdelta * adepth) / 64;
  1605. uint32 l = std::abs(vdelta);
  1606. LimitMax(period, Util::MaxValueOfType(period) / 256);
  1607. period *= 256;
  1608. if(vdelta < 0)
  1609. {
  1610. vdelta = Util::muldiv(period, downTable[l / 4u], 0x10000) - period;
  1611. if (l & 0x03)
  1612. {
  1613. vdelta += Util::muldiv(period, fineDownTable[l & 0x03], 0x10000) - period;
  1614. }
  1615. } else
  1616. {
  1617. vdelta = Util::muldiv(period, upTable[l / 4u], 0x10000) - period;
  1618. if (l & 0x03)
  1619. {
  1620. vdelta += Util::muldiv(period, fineUpTable[l & 0x03], 0x10000) - period;
  1621. }
  1622. }
  1623. period = (period + vdelta) / 256;
  1624. nPeriodFrac = vdelta & 0xFF;
  1625. } else
  1626. {
  1627. // MPT's autovibrato code
  1628. if (pSmp->nVibSweep == 0 && !(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)))
  1629. {
  1630. chn.nAutoVibDepth = pSmp->nVibDepth * 256;
  1631. } else
  1632. {
  1633. // Calculate current autovibrato depth using vibsweep
  1634. if (GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))
  1635. {
  1636. chn.nAutoVibDepth += pSmp->nVibSweep * 2u;
  1637. } else
  1638. {
  1639. if(!chn.dwFlags[CHN_KEYOFF])
  1640. {
  1641. chn.nAutoVibDepth += (pSmp->nVibDepth * 256u) / pSmp->nVibSweep;
  1642. }
  1643. }
  1644. LimitMax(chn.nAutoVibDepth, static_cast<int>(pSmp->nVibDepth * 256u));
  1645. }
  1646. chn.nAutoVibPos += pSmp->nVibRate;
  1647. int vdelta;
  1648. switch(pSmp->nVibType)
  1649. {
  1650. case VIB_RANDOM:
  1651. vdelta = ModRandomTable[chn.nAutoVibPos & 0x3F];
  1652. chn.nAutoVibPos++;
  1653. break;
  1654. case VIB_RAMP_DOWN:
  1655. vdelta = ((0x40 - (chn.nAutoVibPos / 2u)) & 0x7F) - 0x40;
  1656. break;
  1657. case VIB_RAMP_UP:
  1658. vdelta = ((0x40 + (chn.nAutoVibPos / 2u)) & 0x7F) - 0x40;
  1659. break;
  1660. case VIB_SQUARE:
  1661. vdelta = (chn.nAutoVibPos & 128) ? +64 : -64;
  1662. break;
  1663. case VIB_SINE:
  1664. default:
  1665. if(GetType() != MOD_TYPE_MT2)
  1666. {
  1667. vdelta = -ITSinusTable[chn.nAutoVibPos & 0xFF];
  1668. } else
  1669. {
  1670. // Fix flat-sounding pads in "another worlds" by Eternal Engine.
  1671. // Vibrato starts at the maximum amplitude of the sine wave
  1672. // and the vibrato frequency never decreases below the original note's frequency.
  1673. vdelta = (-ITSinusTable[(chn.nAutoVibPos + 192) & 0xFF] + 64) / 2;
  1674. }
  1675. }
  1676. int n = (vdelta * chn.nAutoVibDepth) / 256;
  1677. if(hasTuning)
  1678. {
  1679. //Vib sweep is not taken into account here.
  1680. vibratoFactor += 0.05F * pSmp->nVibDepth * vdelta / 4096.0f; //4096 == 64^2
  1681. //See vibrato for explanation.
  1682. chn.m_CalculateFreq = true;
  1683. /*
  1684. Finestep vibrato:
  1685. const float autoVibDepth = pSmp->nVibDepth * val / 4096.0f; //4096 == 64^2
  1686. vibratoFineSteps += static_cast<CTuning::FINESTEPTYPE>(chn.pModInstrument->pTuning->GetFineStepCount() * autoVibDepth);
  1687. chn.m_CalculateFreq = true;
  1688. */
  1689. }
  1690. else //Original behavior
  1691. {
  1692. if (GetType() != MOD_TYPE_XM)
  1693. {
  1694. int df1, df2;
  1695. if (n < 0)
  1696. {
  1697. n = -n;
  1698. uint32 n1 = n / 256;
  1699. df1 = downTable[n1];
  1700. df2 = downTable[n1+1];
  1701. } else
  1702. {
  1703. uint32 n1 = n / 256;
  1704. df1 = upTable[n1];
  1705. df2 = upTable[n1+1];
  1706. }
  1707. n /= 4;
  1708. period = Util::muldiv(period, df1 + ((df2 - df1) * (n & 0x3F) / 64), 256);
  1709. nPeriodFrac = period & 0xFF;
  1710. period /= 256;
  1711. } else
  1712. {
  1713. period += (n / 64);
  1714. }
  1715. } //Original MPT behavior
  1716. }
  1717. }
  1718. }
  1719. void CSoundFile::ProcessRamping(ModChannel &chn) const
  1720. {
  1721. chn.leftRamp = chn.rightRamp = 0;
  1722. LimitMax(chn.newLeftVol, int32_max >> VOLUMERAMPPRECISION);
  1723. LimitMax(chn.newRightVol, int32_max >> VOLUMERAMPPRECISION);
  1724. if(chn.dwFlags[CHN_VOLUMERAMP] && (chn.leftVol != chn.newLeftVol || chn.rightVol != chn.newRightVol))
  1725. {
  1726. const bool rampUp = (chn.newLeftVol > chn.leftVol) || (chn.newRightVol > chn.rightVol);
  1727. int32 rampLength, globalRampLength, instrRampLength = 0;
  1728. rampLength = globalRampLength = (rampUp ? m_MixerSettings.GetVolumeRampUpSamples() : m_MixerSettings.GetVolumeRampDownSamples());
  1729. //XXXih: add real support for bidi ramping here
  1730. if(m_playBehaviour[kFT2VolumeRamping] && (GetType() & MOD_TYPE_XM))
  1731. {
  1732. // apply FT2-style super-soft volume ramping (5ms), overriding openmpt settings
  1733. rampLength = globalRampLength = Util::muldivr(5, m_MixerSettings.gdwMixingFreq, 1000);
  1734. }
  1735. if(chn.pModInstrument != nullptr && rampUp)
  1736. {
  1737. instrRampLength = chn.pModInstrument->nVolRampUp;
  1738. rampLength = instrRampLength ? (m_MixerSettings.gdwMixingFreq * instrRampLength / 100000) : globalRampLength;
  1739. }
  1740. const bool enableCustomRamp = (instrRampLength > 0);
  1741. if(!rampLength)
  1742. {
  1743. rampLength = 1;
  1744. }
  1745. int32 leftDelta = ((chn.newLeftVol - chn.leftVol) * (1 << VOLUMERAMPPRECISION));
  1746. int32 rightDelta = ((chn.newRightVol - chn.rightVol) * (1 << VOLUMERAMPPRECISION));
  1747. if(!enableCustomRamp)
  1748. {
  1749. // Extra-smooth ramping, unless we're forced to use the default values
  1750. if((chn.leftVol | chn.rightVol) && (chn.newLeftVol | chn.newRightVol) && !chn.dwFlags[CHN_FASTVOLRAMP])
  1751. {
  1752. rampLength = m_PlayState.m_nBufferCount;
  1753. Limit(rampLength, globalRampLength, int32(1 << (VOLUMERAMPPRECISION - 1)));
  1754. }
  1755. }
  1756. chn.leftRamp = leftDelta / rampLength;
  1757. chn.rightRamp = rightDelta / rampLength;
  1758. chn.leftVol = chn.newLeftVol - ((chn.leftRamp * rampLength) / (1 << VOLUMERAMPPRECISION));
  1759. chn.rightVol = chn.newRightVol - ((chn.rightRamp * rampLength) / (1 << VOLUMERAMPPRECISION));
  1760. if (chn.leftRamp|chn.rightRamp)
  1761. {
  1762. chn.nRampLength = rampLength;
  1763. } else
  1764. {
  1765. chn.dwFlags.reset(CHN_VOLUMERAMP);
  1766. chn.leftVol = chn.newLeftVol;
  1767. chn.rightVol = chn.newRightVol;
  1768. }
  1769. } else
  1770. {
  1771. chn.dwFlags.reset(CHN_VOLUMERAMP);
  1772. chn.leftVol = chn.newLeftVol;
  1773. chn.rightVol = chn.newRightVol;
  1774. }
  1775. chn.rampLeftVol = chn.leftVol * (1 << VOLUMERAMPPRECISION);
  1776. chn.rampRightVol = chn.rightVol * (1 << VOLUMERAMPPRECISION);
  1777. chn.dwFlags.reset(CHN_FASTVOLRAMP);
  1778. }
  1779. // Returns channel increment and frequency with FREQ_FRACBITS fractional bits
  1780. std::pair<SamplePosition, uint32> CSoundFile::GetChannelIncrement(const ModChannel &chn, uint32 period, int periodFrac) const
  1781. {
  1782. uint32 freq;
  1783. if(!chn.HasCustomTuning())
  1784. freq = GetFreqFromPeriod(period, chn.nC5Speed, periodFrac);
  1785. else
  1786. freq = chn.nPeriod;
  1787. const ModInstrument *ins = chn.pModInstrument;
  1788. if(int32 finetune = chn.microTuning; finetune != 0)
  1789. {
  1790. if(ins)
  1791. finetune *= ins->midiPWD;
  1792. if(finetune)
  1793. freq = mpt::saturate_round<uint32>(freq * std::pow(2.0, finetune / (12.0 * 256.0 * 128.0)));
  1794. }
  1795. // Applying Pitch/Tempo lock
  1796. if(ins && ins->pitchToTempoLock.GetRaw())
  1797. {
  1798. freq = Util::muldivr(freq, m_PlayState.m_nMusicTempo.GetRaw(), ins->pitchToTempoLock.GetRaw());
  1799. }
  1800. // Avoid increment to overflow and become negative with unrealisticly high frequencies.
  1801. LimitMax(freq, uint32(int32_max));
  1802. return {SamplePosition::Ratio(freq, m_MixerSettings.gdwMixingFreq << FREQ_FRACBITS), freq};
  1803. }
  1804. ////////////////////////////////////////////////////////////////////////////////////////////
  1805. // Handles envelopes & mixer setup
  1806. bool CSoundFile::ReadNote()
  1807. {
  1808. #ifdef MODPLUG_TRACKER
  1809. // Checking end of row ?
  1810. if(m_SongFlags[SONG_PAUSED])
  1811. {
  1812. m_PlayState.m_nTickCount = 0;
  1813. if (!m_PlayState.m_nMusicSpeed) m_PlayState.m_nMusicSpeed = 6;
  1814. if (!m_PlayState.m_nMusicTempo.GetRaw()) m_PlayState.m_nMusicTempo.Set(125);
  1815. } else
  1816. #endif // MODPLUG_TRACKER
  1817. {
  1818. if(!ProcessRow())
  1819. return false;
  1820. }
  1821. ////////////////////////////////////////////////////////////////////////////////////
  1822. if (m_PlayState.m_nMusicTempo.GetRaw() == 0) return false;
  1823. m_PlayState.m_nSamplesPerTick = GetTickDuration(m_PlayState);
  1824. m_PlayState.m_nBufferCount = m_PlayState.m_nSamplesPerTick;
  1825. // Master Volume + Pre-Amplification / Attenuation setup
  1826. uint32 nMasterVol;
  1827. {
  1828. CHANNELINDEX nchn32 = Clamp(m_nChannels, CHANNELINDEX(1), CHANNELINDEX(31));
  1829. uint32 mastervol;
  1830. if (m_PlayConfig.getUseGlobalPreAmp())
  1831. {
  1832. int realmastervol = m_MixerSettings.m_nPreAmp;
  1833. if (realmastervol > 0x80)
  1834. {
  1835. //Attenuate global pre-amp depending on num channels
  1836. realmastervol = 0x80 + ((realmastervol - 0x80) * (nchn32 + 4)) / 16;
  1837. }
  1838. mastervol = (realmastervol * (m_nSamplePreAmp)) / 64;
  1839. } else
  1840. {
  1841. //Preferred option: don't use global pre-amp at all.
  1842. mastervol = m_nSamplePreAmp;
  1843. }
  1844. if (m_PlayConfig.getUseGlobalPreAmp())
  1845. {
  1846. uint32 attenuation =
  1847. #ifndef NO_AGC
  1848. (m_MixerSettings.DSPMask & SNDDSP_AGC) ? PreAmpAGCTable[nchn32 / 2u] :
  1849. #endif
  1850. PreAmpTable[nchn32 / 2u];
  1851. if(attenuation < 1) attenuation = 1;
  1852. nMasterVol = (mastervol << 7) / attenuation;
  1853. } else
  1854. {
  1855. nMasterVol = mastervol;
  1856. }
  1857. }
  1858. ////////////////////////////////////////////////////////////////////////////////////
  1859. // Update channels data
  1860. m_nMixChannels = 0;
  1861. for (CHANNELINDEX nChn = 0; nChn < MAX_CHANNELS; nChn++)
  1862. {
  1863. ModChannel &chn = m_PlayState.Chn[nChn];
  1864. // FT2 Compatibility: Prevent notes to be stopped after a fadeout. This way, a portamento effect can pick up a faded instrument which is long enough.
  1865. // This occurs for example in the bassline (channel 11) of jt_burn.xm. I hope this won't break anything else...
  1866. // I also suppose this could decrease mixing performance a bit, but hey, which CPU can't handle 32 muted channels these days... :-)
  1867. if(chn.dwFlags[CHN_NOTEFADE] && (!(chn.nFadeOutVol|chn.leftVol|chn.rightVol)) && !m_playBehaviour[kFT2ProcessSilentChannels])
  1868. {
  1869. chn.nLength = 0;
  1870. chn.nROfs = chn.nLOfs = 0;
  1871. }
  1872. // Check for unused channel
  1873. if(chn.dwFlags[CHN_MUTE] || (nChn >= m_nChannels && !chn.nLength))
  1874. {
  1875. if(nChn < m_nChannels)
  1876. {
  1877. // Process MIDI macros on channels that are currently muted.
  1878. ProcessMacroOnChannel(nChn);
  1879. }
  1880. chn.nLeftVU = chn.nRightVU = 0;
  1881. continue;
  1882. }
  1883. // Reset channel data
  1884. chn.increment = SamplePosition(0);
  1885. chn.nRealVolume = 0;
  1886. chn.nCalcVolume = 0;
  1887. chn.nRampLength = 0;
  1888. //Aux variables
  1889. Tuning::RATIOTYPE vibratoFactor = 1;
  1890. Tuning::NOTEINDEXTYPE arpeggioSteps = 0;
  1891. const ModInstrument *pIns = chn.pModInstrument;
  1892. // Calc Frequency
  1893. int32 period = 0;
  1894. // Also process envelopes etc. when there's a plugin on this channel, for possible fake automation using volume and pan data.
  1895. // We only care about master channels, though, since automation only "happens" on them.
  1896. const bool samplePlaying = (chn.nPeriod && chn.nLength);
  1897. const bool plugAssigned = (nChn < m_nChannels) && (ChnSettings[nChn].nMixPlugin || (chn.pModInstrument != nullptr && chn.pModInstrument->nMixPlug));
  1898. if (samplePlaying || plugAssigned)
  1899. {
  1900. int vol = chn.nVolume;
  1901. int insVol = chn.nInsVol; // This is the "SV * IV" value in ITTECH.TXT
  1902. ProcessVolumeSwing(chn, m_playBehaviour[kITSwingBehaviour] ? insVol : vol);
  1903. ProcessPanningSwing(chn);
  1904. ProcessTremolo(chn, vol);
  1905. ProcessTremor(nChn, vol);
  1906. // Clip volume and multiply (extend to 14 bits)
  1907. Limit(vol, 0, 256);
  1908. vol <<= 6;
  1909. // Process Envelopes
  1910. if (pIns)
  1911. {
  1912. if(m_playBehaviour[kITEnvelopePositionHandling])
  1913. {
  1914. // In IT compatible mode, envelope position indices are shifted by one for proper envelope pausing,
  1915. // so we have to update the position before we actually process the envelopes.
  1916. // When using MPT behaviour, we get the envelope position for the next tick while we are still calculating the current tick,
  1917. // which then results in wrong position information when the envelope is paused on the next row.
  1918. // Test cases: s77.it
  1919. IncrementEnvelopePositions(chn);
  1920. }
  1921. ProcessVolumeEnvelope(chn, vol);
  1922. ProcessInstrumentFade(chn, vol);
  1923. ProcessPanningEnvelope(chn);
  1924. if(!m_playBehaviour[kITPitchPanSeparation] && chn.nNote != NOTE_NONE && chn.pModInstrument && chn.pModInstrument->nPPS != 0)
  1925. ProcessPitchPanSeparation(chn.nRealPan, chn.nNote, *chn.pModInstrument);
  1926. } else
  1927. {
  1928. // No Envelope: key off => note cut
  1929. if(chn.dwFlags[CHN_NOTEFADE]) // 1.41-: CHN_KEYOFF|CHN_NOTEFADE
  1930. {
  1931. chn.nFadeOutVol = 0;
  1932. vol = 0;
  1933. }
  1934. }
  1935. if(chn.isPaused)
  1936. vol = 0;
  1937. // vol is 14-bits
  1938. if (vol)
  1939. {
  1940. // IMPORTANT: chn.nRealVolume is 14 bits !!!
  1941. // -> Util::muldiv( 14+8, 6+6, 18); => RealVolume: 14-bit result (22+12-20)
  1942. if(chn.dwFlags[CHN_SYNCMUTE])
  1943. {
  1944. chn.nRealVolume = 0;
  1945. } else if (m_PlayConfig.getGlobalVolumeAppliesToMaster())
  1946. {
  1947. // Don't let global volume affect level of sample if
  1948. // Global volume is going to be applied to master output anyway.
  1949. chn.nRealVolume = Util::muldiv(vol * MAX_GLOBAL_VOLUME, chn.nGlobalVol * insVol, 1 << 20);
  1950. } else
  1951. {
  1952. chn.nRealVolume = Util::muldiv(vol * m_PlayState.m_nGlobalVolume, chn.nGlobalVol * insVol, 1 << 20);
  1953. }
  1954. }
  1955. chn.nCalcVolume = vol; // Update calculated volume for MIDI macros
  1956. // ST3 only clamps the final output period, but never the channel's internal period.
  1957. // Test case: PeriodLimit.s3m
  1958. if (chn.nPeriod < m_nMinPeriod
  1959. && GetType() != MOD_TYPE_S3M
  1960. && !PeriodsAreFrequencies())
  1961. {
  1962. chn.nPeriod = m_nMinPeriod;
  1963. } else if(chn.nPeriod >= m_nMaxPeriod && m_playBehaviour[kApplyUpperPeriodLimit] && !PeriodsAreFrequencies())
  1964. {
  1965. // ...but on the other hand, ST3's SoundBlaster driver clamps the maximum channel period.
  1966. // Test case: PeriodLimitUpper.s3m
  1967. chn.nPeriod = m_nMaxPeriod;
  1968. }
  1969. if(m_playBehaviour[kFT2Periods]) Clamp(chn.nPeriod, 1, 31999);
  1970. period = chn.nPeriod;
  1971. // When glissando mode is set to semitones, clamp to the next halftone.
  1972. if((chn.dwFlags & (CHN_GLISSANDO | CHN_PORTAMENTO)) == (CHN_GLISSANDO | CHN_PORTAMENTO)
  1973. && (!m_SongFlags[SONG_PT_MODE] || (chn.rowCommand.IsPortamento() && !m_SongFlags[SONG_FIRSTTICK])))
  1974. {
  1975. if(period != chn.cachedPeriod)
  1976. {
  1977. // Only recompute this whole thing in case the base period has changed.
  1978. chn.cachedPeriod = period;
  1979. chn.glissandoPeriod = GetPeriodFromNote(GetNoteFromPeriod(period, chn.nFineTune, chn.nC5Speed), chn.nFineTune, chn.nC5Speed);
  1980. }
  1981. period = chn.glissandoPeriod;
  1982. }
  1983. ProcessArpeggio(nChn, period, arpeggioSteps);
  1984. // Preserve Amiga freq limits.
  1985. // In ST3, the frequency is always clamped to periods 113 to 856, while in ProTracker,
  1986. // the limit is variable, depending on the finetune of the sample.
  1987. // The int32_max test is for the arpeggio wrap-around in ProcessArpeggio().
  1988. // Test case: AmigaLimits.s3m, AmigaLimitsFinetune.mod
  1989. if(m_SongFlags[SONG_AMIGALIMITS | SONG_PT_MODE] && period != int32_max)
  1990. {
  1991. int limitLow = 113 * 4, limitHigh = 856 * 4;
  1992. if(GetType() != MOD_TYPE_S3M)
  1993. {
  1994. const int tableOffset = XM2MODFineTune(chn.nFineTune) * 12;
  1995. limitLow = ProTrackerTunedPeriods[tableOffset + 11] / 2;
  1996. limitHigh = ProTrackerTunedPeriods[tableOffset] * 2;
  1997. // Amiga cannot actually keep up with lower periods
  1998. if(limitLow < 113 * 4) limitLow = 113 * 4;
  1999. }
  2000. Limit(period, limitLow, limitHigh);
  2001. Limit(chn.nPeriod, limitLow, limitHigh);
  2002. }
  2003. ProcessPanbrello(chn);
  2004. }
  2005. // IT Compatibility: Ensure that there is no pan swing, panbrello, panning envelopes, etc. applied on surround channels.
  2006. // Test case: surround-pan.it
  2007. if(chn.dwFlags[CHN_SURROUND] && !m_SongFlags[SONG_SURROUNDPAN] && m_playBehaviour[kITNoSurroundPan])
  2008. {
  2009. chn.nRealPan = 128;
  2010. }
  2011. // Now that all relevant envelopes etc. have been processed, we can parse the MIDI macro data.
  2012. ProcessMacroOnChannel(nChn);
  2013. // After MIDI macros have been processed, we can also process the pitch / filter envelope and other pitch-related things.
  2014. if(samplePlaying)
  2015. {
  2016. int cutoff = ProcessPitchFilterEnvelope(chn, period);
  2017. if(cutoff >= 0 && chn.dwFlags[CHN_ADLIB] && m_opl)
  2018. {
  2019. // Cutoff doubles as modulator intensity for FM instruments
  2020. m_opl->Volume(nChn, static_cast<uint8>(cutoff / 4), true);
  2021. }
  2022. }
  2023. if(chn.rowCommand.volcmd == VOLCMD_VIBRATODEPTH &&
  2024. (chn.rowCommand.command == CMD_VIBRATO || chn.rowCommand.command == CMD_VIBRATOVOL || chn.rowCommand.command == CMD_FINEVIBRATO))
  2025. {
  2026. if(GetType() == MOD_TYPE_XM)
  2027. {
  2028. // XM Compatibility: Vibrato should be advanced twice (but not added up) if both volume-column and effect column vibrato is present.
  2029. // Effect column vibrato parameter has precedence if non-zero.
  2030. // Test case: VibratoDouble.xm
  2031. if(!m_SongFlags[SONG_FIRSTTICK])
  2032. chn.nVibratoPos += chn.nVibratoSpeed;
  2033. } else if(GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT))
  2034. {
  2035. // IT Compatibility: Vibrato should be applied twice if both volume-colum and effect column vibrato is present.
  2036. // Volume column vibrato parameter has precedence if non-zero.
  2037. // Test case: VibratoDouble.it
  2038. Vibrato(chn, chn.rowCommand.vol);
  2039. ProcessVibrato(nChn, period, vibratoFactor);
  2040. }
  2041. }
  2042. // Plugins may also receive vibrato
  2043. ProcessVibrato(nChn, period, vibratoFactor);
  2044. if(samplePlaying)
  2045. {
  2046. int nPeriodFrac = 0;
  2047. ProcessSampleAutoVibrato(chn, period, vibratoFactor, nPeriodFrac);
  2048. // Final Period
  2049. // ST3 only clamps the final output period, but never the channel's internal period.
  2050. // Test case: PeriodLimit.s3m
  2051. if (period <= m_nMinPeriod)
  2052. {
  2053. if(m_playBehaviour[kST3LimitPeriod]) chn.nLength = 0; // Pattern 15 in watcha.s3m
  2054. period = m_nMinPeriod;
  2055. }
  2056. const bool hasTuning = chn.HasCustomTuning();
  2057. if(hasTuning)
  2058. {
  2059. if(chn.m_CalculateFreq || (chn.m_ReCalculateFreqOnFirstTick && m_PlayState.m_nTickCount == 0))
  2060. {
  2061. chn.RecalcTuningFreq(vibratoFactor, arpeggioSteps, *this);
  2062. if(!chn.m_CalculateFreq)
  2063. chn.m_ReCalculateFreqOnFirstTick = false;
  2064. else
  2065. chn.m_CalculateFreq = false;
  2066. }
  2067. }
  2068. auto [ninc, freq] = GetChannelIncrement(chn, period, nPeriodFrac);
  2069. #ifndef MODPLUG_TRACKER
  2070. ninc.MulDiv(m_nFreqFactor, 65536);
  2071. #endif // !MODPLUG_TRACKER
  2072. if(ninc.IsZero())
  2073. {
  2074. ninc.Set(0, 1);
  2075. }
  2076. chn.increment = ninc;
  2077. if((chn.dwFlags & (CHN_ADLIB | CHN_MUTE | CHN_SYNCMUTE)) == CHN_ADLIB && m_opl)
  2078. {
  2079. const bool doProcess = m_playBehaviour[kOPLFlexibleNoteOff] || !chn.dwFlags[CHN_NOTEFADE] || GetType() == MOD_TYPE_S3M;
  2080. if(doProcess && !(GetType() == MOD_TYPE_S3M && chn.dwFlags[CHN_KEYOFF]))
  2081. {
  2082. // In ST3, a sample rate of 8363 Hz is mapped to middle-C, which is 261.625 Hz in a tempered scale at A4 = 440.
  2083. // Hence, we have to translate our "sample rate" into pitch.
  2084. auto milliHertz = Util::muldivr_unsigned(freq, 261625, 8363 << FREQ_FRACBITS);
  2085. const bool keyOff = chn.dwFlags[CHN_KEYOFF] || (chn.dwFlags[CHN_NOTEFADE] && chn.nFadeOutVol == 0);
  2086. if(!m_playBehaviour[kOPLNoteStopWith0Hz] || !keyOff)
  2087. m_opl->Frequency(nChn, milliHertz, keyOff, m_playBehaviour[kOPLBeatingOscillators]);
  2088. }
  2089. if(doProcess)
  2090. {
  2091. // Scale volume to OPL range (0...63).
  2092. m_opl->Volume(nChn, static_cast<uint8>(Util::muldivr_unsigned(chn.nCalcVolume * chn.nGlobalVol * chn.nInsVol, 63, 1 << 26)), false);
  2093. chn.nRealPan = m_opl->Pan(nChn, chn.nRealPan) * 128 + 128;
  2094. }
  2095. // Deallocate OPL channels for notes that are most definitely never going to play again.
  2096. if(const auto *ins = chn.pModInstrument; ins != nullptr
  2097. && (ins->VolEnv.dwFlags & (ENV_ENABLED | ENV_LOOP | ENV_SUSTAIN)) == ENV_ENABLED
  2098. && !ins->VolEnv.empty()
  2099. && chn.GetEnvelope(ENV_VOLUME).nEnvPosition >= ins->VolEnv.back().tick
  2100. && ins->VolEnv.back().value == 0)
  2101. {
  2102. m_opl->NoteCut(nChn);
  2103. if(!m_playBehaviour[kOPLNoResetAtEnvelopeEnd])
  2104. chn.dwFlags.reset(CHN_ADLIB);
  2105. chn.dwFlags.set(CHN_NOTEFADE);
  2106. chn.nFadeOutVol = 0;
  2107. } else if(m_playBehaviour[kOPLFlexibleNoteOff] && chn.dwFlags[CHN_NOTEFADE] && chn.nFadeOutVol == 0)
  2108. {
  2109. m_opl->NoteCut(nChn);
  2110. chn.dwFlags.reset(CHN_ADLIB);
  2111. }
  2112. }
  2113. }
  2114. // Increment envelope positions
  2115. if(pIns != nullptr && !m_playBehaviour[kITEnvelopePositionHandling])
  2116. {
  2117. // In IT and FT2 compatible mode, envelope positions are updated above.
  2118. // Test cases: s77.it, EnvLoops.xm
  2119. IncrementEnvelopePositions(chn);
  2120. }
  2121. // Volume ramping
  2122. chn.dwFlags.set(CHN_VOLUMERAMP, (chn.nRealVolume | chn.rightVol | chn.leftVol) != 0 && !chn.dwFlags[CHN_ADLIB]);
  2123. constexpr uint8 VUMETER_DECAY = 4;
  2124. chn.nLeftVU = (chn.nLeftVU > VUMETER_DECAY) ? (chn.nLeftVU - VUMETER_DECAY) : 0;
  2125. chn.nRightVU = (chn.nRightVU > VUMETER_DECAY) ? (chn.nRightVU - VUMETER_DECAY) : 0;
  2126. chn.newLeftVol = chn.newRightVol = 0;
  2127. chn.pCurrentSample = (chn.pModSample && chn.pModSample->HasSampleData() && chn.nLength && chn.IsSamplePlaying()) ? chn.pModSample->samplev() : nullptr;
  2128. if(chn.pCurrentSample || (chn.HasMIDIOutput() && !chn.dwFlags[CHN_KEYOFF | CHN_NOTEFADE]))
  2129. {
  2130. // Update VU-Meter (nRealVolume is 14-bit)
  2131. uint32 vul = (chn.nRealVolume * (256-chn.nRealPan)) / (1 << 14);
  2132. if (vul > 127) vul = 127;
  2133. if (chn.nLeftVU > 127) chn.nLeftVU = (uint8)vul;
  2134. vul /= 2;
  2135. if (chn.nLeftVU < vul) chn.nLeftVU = (uint8)vul;
  2136. uint32 vur = (chn.nRealVolume * chn.nRealPan) / (1 << 14);
  2137. if (vur > 127) vur = 127;
  2138. if (chn.nRightVU > 127) chn.nRightVU = (uint8)vur;
  2139. vur /= 2;
  2140. if (chn.nRightVU < vur) chn.nRightVU = (uint8)vur;
  2141. } else
  2142. {
  2143. // Note change but no sample
  2144. if (chn.nLeftVU > 128) chn.nLeftVU = 0;
  2145. if (chn.nRightVU > 128) chn.nRightVU = 0;
  2146. }
  2147. if (chn.pCurrentSample)
  2148. {
  2149. #ifdef MODPLUG_TRACKER
  2150. const uint32 kChnMasterVol = chn.dwFlags[CHN_EXTRALOUD] ? (uint32)m_PlayConfig.getNormalSamplePreAmp() : nMasterVol;
  2151. #else
  2152. const uint32 kChnMasterVol = nMasterVol;
  2153. #endif // MODPLUG_TRACKER
  2154. // Adjusting volumes
  2155. {
  2156. int32 pan = (m_MixerSettings.gnChannels >= 2) ? Clamp(chn.nRealPan, 0, 256) : 128;
  2157. int32 realvol;
  2158. if(m_PlayConfig.getUseGlobalPreAmp())
  2159. {
  2160. realvol = (chn.nRealVolume * kChnMasterVol) / 128;
  2161. } else
  2162. {
  2163. // Extra attenuation required here if we're bypassing pre-amp.
  2164. realvol = (chn.nRealVolume * kChnMasterVol) / 256;
  2165. }
  2166. const PanningMode panningMode = m_PlayConfig.getPanningMode();
  2167. if(panningMode == PanningMode::SoftPanning || (panningMode == PanningMode::Undetermined && (m_MixerSettings.MixerFlags & SNDMIX_SOFTPANNING)))
  2168. {
  2169. if(pan < 128)
  2170. {
  2171. chn.newLeftVol = (realvol * 128) / 256;
  2172. chn.newRightVol = (realvol * pan) / 256;
  2173. } else
  2174. {
  2175. chn.newLeftVol = (realvol * (256 - pan)) / 256;
  2176. chn.newRightVol = (realvol * 128) / 256;
  2177. }
  2178. } else if(panningMode == PanningMode::FT2Panning)
  2179. {
  2180. // FT2 uses square root panning. There is a 257-entry LUT for this,
  2181. // but FT2's internal panning ranges from 0 to 255 only, meaning that
  2182. // you can never truly achieve 100% right panning in FT2, only 100% left.
  2183. // Test case: FT2PanLaw.xm
  2184. LimitMax(pan, 255);
  2185. const int panL = pan > 0 ? XMPanningTable[256 - pan] : 65536;
  2186. const int panR = XMPanningTable[pan];
  2187. chn.newLeftVol = (realvol * panL) / 65536;
  2188. chn.newRightVol = (realvol * panR) / 65536;
  2189. } else
  2190. {
  2191. chn.newLeftVol = (realvol * (256 - pan)) / 256;
  2192. chn.newRightVol = (realvol * pan) / 256;
  2193. }
  2194. }
  2195. // Clipping volumes
  2196. //if (chn.nNewRightVol > 0xFFFF) chn.nNewRightVol = 0xFFFF;
  2197. //if (chn.nNewLeftVol > 0xFFFF) chn.nNewLeftVol = 0xFFFF;
  2198. if(chn.pModInstrument && Resampling::IsKnownMode(chn.pModInstrument->resampling))
  2199. {
  2200. // For defined resampling modes, use per-instrument resampling mode if set
  2201. chn.resamplingMode = chn.pModInstrument->resampling;
  2202. } else if(Resampling::IsKnownMode(m_nResampling))
  2203. {
  2204. chn.resamplingMode = m_nResampling;
  2205. } else if(m_SongFlags[SONG_ISAMIGA] && m_Resampler.m_Settings.emulateAmiga != Resampling::AmigaFilter::Off)
  2206. {
  2207. // Enforce Amiga resampler for Amiga modules
  2208. chn.resamplingMode = SRCMODE_AMIGA;
  2209. } else
  2210. {
  2211. // Default to global mixer settings
  2212. chn.resamplingMode = m_Resampler.m_Settings.SrcMode;
  2213. }
  2214. if(chn.increment.IsUnity() && !(chn.dwFlags[CHN_VIBRATO] || chn.nAutoVibDepth || chn.resamplingMode == SRCMODE_AMIGA))
  2215. {
  2216. // Exact sample rate match, do not interpolate at all
  2217. // - unless vibrato is applied, because in this case the constant enabling and disabling
  2218. // of resampling can introduce clicks (this is easily observable with a sine sample
  2219. // played at the mix rate).
  2220. chn.resamplingMode = SRCMODE_NEAREST;
  2221. }
  2222. const int extraAttenuation = m_PlayConfig.getExtraSampleAttenuation();
  2223. chn.newLeftVol /= (1 << extraAttenuation);
  2224. chn.newRightVol /= (1 << extraAttenuation);
  2225. // Dolby Pro-Logic Surround
  2226. if(chn.dwFlags[CHN_SURROUND] && m_MixerSettings.gnChannels == 2) chn.newRightVol = -chn.newRightVol;
  2227. // Checking Ping-Pong Loops
  2228. if(chn.dwFlags[CHN_PINGPONGFLAG]) chn.increment.Negate();
  2229. // Setting up volume ramp
  2230. ProcessRamping(chn);
  2231. // Adding the channel in the channel list
  2232. if(!chn.dwFlags[CHN_ADLIB])
  2233. {
  2234. m_PlayState.ChnMix[m_nMixChannels++] = nChn;
  2235. }
  2236. } else
  2237. {
  2238. chn.rightVol = chn.leftVol = 0;
  2239. chn.nLength = 0;
  2240. // Put the channel back into the mixer for end-of-sample pop reduction
  2241. if(chn.nLOfs || chn.nROfs)
  2242. m_PlayState.ChnMix[m_nMixChannels++] = nChn;
  2243. }
  2244. chn.dwOldFlags = chn.dwFlags;
  2245. }
  2246. // If there are more channels being mixed than allowed, order them by volume and discard the most quiet ones
  2247. if(m_nMixChannels >= m_MixerSettings.m_nMaxMixChannels)
  2248. {
  2249. std::partial_sort(std::begin(m_PlayState.ChnMix), std::begin(m_PlayState.ChnMix) + m_MixerSettings.m_nMaxMixChannels, std::begin(m_PlayState.ChnMix) + m_nMixChannels,
  2250. [this](CHANNELINDEX i, CHANNELINDEX j) { return (m_PlayState.Chn[i].nRealVolume > m_PlayState.Chn[j].nRealVolume); });
  2251. }
  2252. return true;
  2253. }
  2254. void CSoundFile::ProcessMacroOnChannel(CHANNELINDEX nChn)
  2255. {
  2256. ModChannel &chn = m_PlayState.Chn[nChn];
  2257. if(nChn < GetNumChannels())
  2258. {
  2259. // TODO evaluate per-plugin macros here
  2260. //ProcessMIDIMacro(m_PlayState, nChn, false, m_MidiCfg.Global[MIDIOUT_PAN]);
  2261. //ProcessMIDIMacro(m_PlayState, nChn, false, m_MidiCfg.Global[MIDIOUT_VOLUME]);
  2262. if((chn.rowCommand.command == CMD_MIDI && m_SongFlags[SONG_FIRSTTICK]) || chn.rowCommand.command == CMD_SMOOTHMIDI)
  2263. {
  2264. if(chn.rowCommand.param < 0x80)
  2265. ProcessMIDIMacro(m_PlayState, nChn, (chn.rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.SFx[chn.nActiveMacro], chn.rowCommand.param);
  2266. else
  2267. ProcessMIDIMacro(m_PlayState, nChn, (chn.rowCommand.command == CMD_SMOOTHMIDI), m_MidiCfg.Zxx[chn.rowCommand.param & 0x7F], chn.rowCommand.param);
  2268. }
  2269. }
  2270. }
  2271. #ifndef NO_PLUGINS
  2272. void CSoundFile::ProcessMidiOut(CHANNELINDEX nChn)
  2273. {
  2274. ModChannel &chn = m_PlayState.Chn[nChn];
  2275. // Do we need to process MIDI?
  2276. // For now there is no difference between mute and sync mute with VSTis.
  2277. if(chn.dwFlags[CHN_MUTE | CHN_SYNCMUTE] || !chn.HasMIDIOutput()) return;
  2278. // Get instrument info and plugin reference
  2279. const ModInstrument *pIns = chn.pModInstrument; // Can't be nullptr at this point, as we have valid MIDI output.
  2280. // No instrument or muted instrument?
  2281. if(pIns->dwFlags[INS_MUTE])
  2282. {
  2283. return;
  2284. }
  2285. // Check instrument plugins
  2286. const PLUGINDEX nPlugin = GetBestPlugin(m_PlayState, nChn, PrioritiseInstrument, RespectMutes);
  2287. IMixPlugin *pPlugin = nullptr;
  2288. if(nPlugin > 0 && nPlugin <= MAX_MIXPLUGINS)
  2289. {
  2290. pPlugin = m_MixPlugins[nPlugin - 1].pMixPlugin;
  2291. }
  2292. // Couldn't find a valid plugin
  2293. if(pPlugin == nullptr) return;
  2294. const ModCommand::NOTE note = chn.rowCommand.note;
  2295. // Check for volume commands
  2296. uint8 vol = 0xFF;
  2297. if(chn.rowCommand.volcmd == VOLCMD_VOLUME)
  2298. {
  2299. vol = std::min(chn.rowCommand.vol, uint8(64));
  2300. } else if(chn.rowCommand.command == CMD_VOLUME)
  2301. {
  2302. vol = std::min(chn.rowCommand.param, uint8(64));
  2303. }
  2304. const bool hasVolCommand = (vol != 0xFF);
  2305. if(m_playBehaviour[kMIDICCBugEmulation])
  2306. {
  2307. if(note != NOTE_NONE)
  2308. {
  2309. ModCommand::NOTE realNote = note;
  2310. if(ModCommand::IsNote(note))
  2311. realNote = pIns->NoteMap[note - NOTE_MIN];
  2312. SendMIDINote(nChn, realNote, static_cast<uint16>(chn.nVolume));
  2313. } else if(hasVolCommand)
  2314. {
  2315. pPlugin->MidiCC(MIDIEvents::MIDICC_Volume_Fine, vol, nChn);
  2316. }
  2317. return;
  2318. }
  2319. const uint32 defaultVolume = pIns->nGlobalVol;
  2320. //If new note, determine notevelocity to use.
  2321. if(note != NOTE_NONE)
  2322. {
  2323. int32 velocity = static_cast<int32>(4 * defaultVolume);
  2324. switch(pIns->pluginVelocityHandling)
  2325. {
  2326. case PLUGIN_VELOCITYHANDLING_CHANNEL:
  2327. velocity = chn.nVolume;
  2328. break;
  2329. default:
  2330. break;
  2331. }
  2332. int32 swing = chn.nVolSwing;
  2333. if(m_playBehaviour[kITSwingBehaviour]) swing *= 4;
  2334. velocity += swing;
  2335. Limit(velocity, 0, 256);
  2336. ModCommand::NOTE realNote = note;
  2337. if(ModCommand::IsNote(note))
  2338. realNote = pIns->NoteMap[note - NOTE_MIN];
  2339. // Experimental VST panning
  2340. //ProcessMIDIMacro(nChn, false, m_MidiCfg.Global[MIDIOUT_PAN], 0, nPlugin);
  2341. SendMIDINote(nChn, realNote, static_cast<uint16>(velocity));
  2342. }
  2343. const bool processVolumeAlsoOnNote = (pIns->pluginVelocityHandling == PLUGIN_VELOCITYHANDLING_VOLUME);
  2344. const bool hasNote = m_playBehaviour[kMIDIVolumeOnNoteOffBug] ? (note != NOTE_NONE) : ModCommand::IsNote(note);
  2345. if((hasVolCommand && !hasNote) || (hasNote && processVolumeAlsoOnNote))
  2346. {
  2347. switch(pIns->pluginVolumeHandling)
  2348. {
  2349. case PLUGIN_VOLUMEHANDLING_DRYWET:
  2350. if(hasVolCommand) pPlugin->SetDryRatio(1.0f - (2 * vol) / 127.0f);
  2351. else pPlugin->SetDryRatio(1.0f - (2 * defaultVolume) / 127.0f);
  2352. break;
  2353. case PLUGIN_VOLUMEHANDLING_MIDI:
  2354. if(hasVolCommand) pPlugin->MidiCC(MIDIEvents::MIDICC_Volume_Coarse, std::min(uint8(127), static_cast<uint8>(2 * vol)), nChn);
  2355. else pPlugin->MidiCC(MIDIEvents::MIDICC_Volume_Coarse, static_cast<uint8>(std::min(uint32(127), static_cast<uint32>(2 * defaultVolume))), nChn);
  2356. break;
  2357. default:
  2358. break;
  2359. }
  2360. }
  2361. }
  2362. #endif // NO_PLUGINS
  2363. template<int channels>
  2364. MPT_FORCEINLINE void ApplyGlobalVolumeWithRamping(int32 *SoundBuffer, int32 *RearBuffer, int32 lCount, int32 m_nGlobalVolume, int32 step, int32 &m_nSamplesToGlobalVolRampDest, int32 &m_lHighResRampingGlobalVolume)
  2365. {
  2366. const bool isStereo = (channels >= 2);
  2367. const bool hasRear = (channels >= 4);
  2368. for(int pos = 0; pos < lCount; ++pos)
  2369. {
  2370. if(m_nSamplesToGlobalVolRampDest > 0)
  2371. {
  2372. // Ramping required
  2373. m_lHighResRampingGlobalVolume += step;
  2374. SoundBuffer[0] = Util::muldiv(SoundBuffer[0], m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
  2375. if constexpr(isStereo) SoundBuffer[1] = Util::muldiv(SoundBuffer[1], m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION);
  2376. if constexpr(hasRear) RearBuffer[0] = Util::muldiv(RearBuffer[0] , m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION); else MPT_UNUSED_VARIABLE(RearBuffer);
  2377. if constexpr(hasRear) RearBuffer[1] = Util::muldiv(RearBuffer[1] , m_lHighResRampingGlobalVolume, MAX_GLOBAL_VOLUME << VOLUMERAMPPRECISION); else MPT_UNUSED_VARIABLE(RearBuffer);
  2378. m_nSamplesToGlobalVolRampDest--;
  2379. } else
  2380. {
  2381. SoundBuffer[0] = Util::muldiv(SoundBuffer[0], m_nGlobalVolume, MAX_GLOBAL_VOLUME);
  2382. if constexpr(isStereo) SoundBuffer[1] = Util::muldiv(SoundBuffer[1], m_nGlobalVolume, MAX_GLOBAL_VOLUME);
  2383. if constexpr(hasRear) RearBuffer[0] = Util::muldiv(RearBuffer[0] , m_nGlobalVolume, MAX_GLOBAL_VOLUME); else MPT_UNUSED_VARIABLE(RearBuffer);
  2384. if constexpr(hasRear) RearBuffer[1] = Util::muldiv(RearBuffer[1] , m_nGlobalVolume, MAX_GLOBAL_VOLUME); else MPT_UNUSED_VARIABLE(RearBuffer);
  2385. m_lHighResRampingGlobalVolume = m_nGlobalVolume << VOLUMERAMPPRECISION;
  2386. }
  2387. SoundBuffer += isStereo ? 2 : 1;
  2388. if constexpr(hasRear) RearBuffer += 2;
  2389. }
  2390. }
  2391. void CSoundFile::ProcessGlobalVolume(long lCount)
  2392. {
  2393. // should we ramp?
  2394. if(IsGlobalVolumeUnset())
  2395. {
  2396. // do not ramp if no global volume was set before (which is the case at song start), to prevent audible glitches when default volume is > 0 and it is set to 0 in the first row
  2397. m_PlayState.m_nGlobalVolumeDestination = m_PlayState.m_nGlobalVolume;
  2398. m_PlayState.m_nSamplesToGlobalVolRampDest = 0;
  2399. m_PlayState.m_nGlobalVolumeRampAmount = 0;
  2400. } else if(m_PlayState.m_nGlobalVolumeDestination != m_PlayState.m_nGlobalVolume)
  2401. {
  2402. // User has provided new global volume
  2403. // m_nGlobalVolume: the last global volume which got set e.g. by a pattern command
  2404. // m_nGlobalVolumeDestination: the current target of the ramping algorithm
  2405. const bool rampUp = m_PlayState.m_nGlobalVolume > m_PlayState.m_nGlobalVolumeDestination;
  2406. m_PlayState.m_nGlobalVolumeDestination = m_PlayState.m_nGlobalVolume;
  2407. m_PlayState.m_nSamplesToGlobalVolRampDest = m_PlayState.m_nGlobalVolumeRampAmount = rampUp ? m_MixerSettings.GetVolumeRampUpSamples() : m_MixerSettings.GetVolumeRampDownSamples();
  2408. }
  2409. // calculate ramping step
  2410. int32 step = 0;
  2411. if (m_PlayState.m_nSamplesToGlobalVolRampDest > 0)
  2412. {
  2413. // Still some ramping left to do.
  2414. int32 highResGlobalVolumeDestination = static_cast<int32>(m_PlayState.m_nGlobalVolumeDestination) << VOLUMERAMPPRECISION;
  2415. const long delta = highResGlobalVolumeDestination - m_PlayState.m_lHighResRampingGlobalVolume;
  2416. step = delta / static_cast<long>(m_PlayState.m_nSamplesToGlobalVolRampDest);
  2417. if(m_nMixLevels == MixLevels::v1_17RC2)
  2418. {
  2419. // Define max step size as some factor of user defined ramping value: the lower the value, the more likely the click.
  2420. // If step is too big (might cause click), extend ramp length.
  2421. // Warning: This increases the volume ramp length by EXTREME amounts (factors of 100 are easily reachable)
  2422. // compared to the user-defined setting, so this really should not be used!
  2423. int32 maxStep = std::max(int32(50), static_cast<int32>((10000 / (m_PlayState.m_nGlobalVolumeRampAmount + 1))));
  2424. while(std::abs(step) > maxStep)
  2425. {
  2426. m_PlayState.m_nSamplesToGlobalVolRampDest += m_PlayState.m_nGlobalVolumeRampAmount;
  2427. step = delta / static_cast<int32>(m_PlayState.m_nSamplesToGlobalVolRampDest);
  2428. }
  2429. }
  2430. }
  2431. // apply volume and ramping
  2432. if(m_MixerSettings.gnChannels == 1)
  2433. {
  2434. ApplyGlobalVolumeWithRamping<1>(MixSoundBuffer, MixRearBuffer, lCount, m_PlayState.m_nGlobalVolume, step, m_PlayState.m_nSamplesToGlobalVolRampDest, m_PlayState.m_lHighResRampingGlobalVolume);
  2435. } else if(m_MixerSettings.gnChannels == 2)
  2436. {
  2437. ApplyGlobalVolumeWithRamping<2>(MixSoundBuffer, MixRearBuffer, lCount, m_PlayState.m_nGlobalVolume, step, m_PlayState.m_nSamplesToGlobalVolRampDest, m_PlayState.m_lHighResRampingGlobalVolume);
  2438. } else if(m_MixerSettings.gnChannels == 4)
  2439. {
  2440. ApplyGlobalVolumeWithRamping<4>(MixSoundBuffer, MixRearBuffer, lCount, m_PlayState.m_nGlobalVolume, step, m_PlayState.m_nSamplesToGlobalVolRampDest, m_PlayState.m_lHighResRampingGlobalVolume);
  2441. }
  2442. }
  2443. void CSoundFile::ProcessStereoSeparation(long countChunk)
  2444. {
  2445. ApplyStereoSeparation(MixSoundBuffer, MixRearBuffer, m_MixerSettings.gnChannels, countChunk, m_MixerSettings.m_nStereoSeparation);
  2446. }
  2447. OPENMPT_NAMESPACE_END