diff --git a/src/libprojectM/Audio/PCM.cpp b/src/libprojectM/Audio/PCM.cpp index bc7c83c59a..1deea37ae4 100755 --- a/src/libprojectM/Audio/PCM.cpp +++ b/src/libprojectM/Audio/PCM.cpp @@ -1,5 +1,7 @@ #include "Audio/PCM.hpp" +#include + namespace libprojectM { namespace Audio { @@ -17,6 +19,7 @@ void PCM::AddToBuffer( return; } + std::lock_guard lock(m_pcmMutex); for (size_t i = 0; i < sampleCount; i++) { size_t const bufferOffset = (m_start + i) % AudioBufferSamples; @@ -48,9 +51,12 @@ void PCM::Add(int16_t const* const samples, uint32_t channels, size_t const coun void PCM::UpdateFrameAudioData(double secondsSinceLastFrame, uint32_t frame) { - // 1. Copy audio data from input buffer - CopyNewWaveformData(m_inputBufferL, m_waveformL); - CopyNewWaveformData(m_inputBufferR, m_waveformR); + // 1. Copy audio data from input buffer (lock to prevent tearing with audio thread writes) + { + std::lock_guard lock(m_pcmMutex); + CopyNewWaveformData(m_inputBufferL, m_waveformL); + CopyNewWaveformData(m_inputBufferR, m_waveformR); + } // 2. Update spectrum analyzer data for both channels UpdateSpectrum(m_waveformL, m_spectrumL); @@ -110,7 +116,7 @@ void PCM::UpdateSpectrum(const WaveformBuffer& waveformData, SpectrumBuffer& spe void PCM::CopyNewWaveformData(const WaveformBuffer& source, WaveformBuffer& destination) { - auto const bufferStartIndex = m_start.load(); + auto const bufferStartIndex = m_start; for (size_t i = 0; i < AudioBufferSamples; i++) { diff --git a/src/libprojectM/Audio/PCM.hpp b/src/libprojectM/Audio/PCM.hpp index 26871954da..7727f13ee3 100755 --- a/src/libprojectM/Audio/PCM.hpp +++ b/src/libprojectM/Audio/PCM.hpp @@ -15,9 +15,9 @@ #include -#include #include #include +#include namespace libprojectM { @@ -89,10 +89,12 @@ class PROJECTM_CXX_EXPORT PCM */ void CopyNewWaveformData(const WaveformBuffer& source, WaveformBuffer& destination); + std::mutex m_pcmMutex; //!< Protects the circular input buffer from concurrent access. + // External input buffer WaveformBuffer m_inputBufferL{0.f}; //!< Circular buffer for left-channel PCM data. WaveformBuffer m_inputBufferR{0.f}; //!< Circular buffer for right-channel PCM data. - std::atomic m_start{0}; //!< Circular buffer start index. + size_t m_start{0}; //!< Circular buffer start index. // Frame waveform data WaveformBuffer m_waveformL{0.f}; //!< Left-channel waveform data, aligned. Only the first WaveformSamples number of samples are valid.