| 26 | static constexpr int SAMPLE_INDEX_FULL = -1; |
| 27 | |
| 28 | void CSound::Mix(short *pFinalOut, unsigned Frames) |
| 29 | { |
| 30 | Frames = minimum(Frames, m_MaxFrames); |
| 31 | mem_zero(m_pMixBuffer, Frames * 2 * sizeof(int)); |
| 32 | |
| 33 | // acquire lock while we are mixing |
| 34 | m_SoundLock.lock(); |
| 35 | |
| 36 | const int MasterVol = m_SoundVolume.load(std::memory_order_relaxed); |
| 37 | |
| 38 | for(auto &Voice : m_aVoices) |
| 39 | { |
| 40 | if(!Voice.m_pSample) |
| 41 | continue; |
| 42 | |
| 43 | // mix voice |
| 44 | int *pOut = m_pMixBuffer; |
| 45 | |
| 46 | const int Step = Voice.m_pSample->m_Channels; // setup input sources |
| 47 | short *pInL = &Voice.m_pSample->m_pData[Voice.m_Tick * Step]; |
| 48 | short *pInR = &Voice.m_pSample->m_pData[Voice.m_Tick * Step + 1]; |
| 49 | |
| 50 | unsigned End = Voice.m_pSample->m_NumFrames - Voice.m_Tick; |
| 51 | |
| 52 | int VolumeR = round_truncate(Voice.m_pChannel->m_Vol * (Voice.m_Vol / 255.0f)); |
| 53 | int VolumeL = VolumeR; |
| 54 | |
| 55 | // make sure that we don't go outside the sound data |
| 56 | if(Frames < End) |
| 57 | End = Frames; |
| 58 | |
| 59 | // check if we have a mono sound |
| 60 | if(Voice.m_pSample->m_Channels == 1) |
| 61 | pInR = pInL; |
| 62 | |
| 63 | // volume calculation |
| 64 | if(Voice.m_Flags & ISound::FLAG_POS && Voice.m_pChannel->m_Pan) |
| 65 | { |
| 66 | // TODO: we should respect the channel panning value |
| 67 | const vec2 Delta = Voice.m_Position - vec2(m_ListenerPositionX.load(std::memory_order_relaxed), m_ListenerPositionY.load(std::memory_order_relaxed)); |
| 68 | vec2 Falloff = vec2(0.0f, 0.0f); |
| 69 | |
| 70 | float RangeX = 0.0f; // for panning |
| 71 | bool InVoiceField = false; |
| 72 | |
| 73 | switch(Voice.m_Shape) |
| 74 | { |
| 75 | case ISound::SHAPE_CIRCLE: |
| 76 | { |
| 77 | const float Radius = Voice.m_Circle.m_Radius; |
| 78 | RangeX = Radius; |
| 79 | |
| 80 | const float Dist = length(Delta); |
| 81 | if(Dist < Radius) |
| 82 | { |
| 83 | InVoiceField = true; |
| 84 | |
| 85 | // falloff |
no test coverage detected