diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cfb4d7a0..f653dbd7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,4 @@ +- Fixed crash when playing with a shared pipe https://github.com/GrandOrgue/grandorgue/issues/847 # 3.4.2 (2021-11-14) - Added ASIO logo to About splash screen https://github.com/GrandOrgue/grandorgue/issues/823 - Upgraded PortAudio Library to the latest stable release, v19.7.0. The upgraded library corrects PortAudio errors in GrandOrgue on macOS 11. diff --git a/src/grandorgue/GODefinitionFile.cpp b/src/grandorgue/GODefinitionFile.cpp index a07551f8f..d05452e00 100644 --- a/src/grandorgue/GODefinitionFile.cpp +++ b/src/grandorgue/GODefinitionFile.cpp @@ -1016,10 +1016,10 @@ void GODefinitionFile::SwitchSample(const GOSoundProvider *pipe, GO_SAMPLER* han m_soundengine->SwitchSample(pipe, handle); } -void GODefinitionFile::UpdateVelocity(GO_SAMPLER* handle, unsigned velocity) +void GODefinitionFile::UpdateVelocity(const GOSoundProvider* pipe, GO_SAMPLER* handle, unsigned velocity) { if (m_soundengine) - m_soundengine->UpdateVelocity(handle, velocity); + m_soundengine->UpdateVelocity(pipe, handle, velocity); } void GODefinitionFile::SendMidiMessage(GOMidiEvent& e) diff --git a/src/grandorgue/GODefinitionFile.h b/src/grandorgue/GODefinitionFile.h index 781cf61fa..887e2a82c 100644 --- a/src/grandorgue/GODefinitionFile.h +++ b/src/grandorgue/GODefinitionFile.h @@ -206,7 +206,7 @@ class GODefinitionFile : public GOEventDistributor, private GOPipeUpdateCallback GO_SAMPLER* StartSample(const GOSoundProvider *pipe, int sampler_group_id, unsigned audio_group, unsigned velocity, unsigned delay, uint64_t last_stop); uint64_t StopSample(const GOSoundProvider *pipe, GO_SAMPLER* handle); void SwitchSample(const GOSoundProvider *pipe, GO_SAMPLER* handle); - void UpdateVelocity(GO_SAMPLER* handle, unsigned velocity); + void UpdateVelocity(const GOSoundProvider* pipe, GO_SAMPLER* handle, unsigned velocity); void SendMidiMessage(GOMidiEvent& e); void SendMidiRecorderMessage(GOMidiEvent& e); diff --git a/src/grandorgue/GOSoundingPipe.cpp b/src/grandorgue/GOSoundingPipe.cpp index 3be59f0a3..94d8ff7d5 100644 --- a/src/grandorgue/GOSoundingPipe.cpp +++ b/src/grandorgue/GOSoundingPipe.cpp @@ -359,7 +359,7 @@ void GOSoundingPipe::Change(unsigned velocity, unsigned last_velocity) else if (m_Instances && !velocity) SetOff(); else if (m_Sampler && last_velocity != velocity) - m_organfile->UpdateVelocity(m_Sampler, velocity); + m_organfile->UpdateVelocity(GetSoundProvider(), m_Sampler, velocity); } void GOSoundingPipe::UpdateAmplitude() diff --git a/src/grandorgue/sound/GOSoundEngine.cpp b/src/grandorgue/sound/GOSoundEngine.cpp index d11192110..3e6dd39fc 100644 --- a/src/grandorgue/sound/GOSoundEngine.cpp +++ b/src/grandorgue/sound/GOSoundEngine.cpp @@ -654,12 +654,16 @@ void GOSoundEngine::SwitchSample(const GOSoundProvider *pipe, GO_SAMPLER* handle handle->new_attack = m_CurrentTime + handle->delay; } -void GOSoundEngine::UpdateVelocity(GO_SAMPLER* handle, unsigned velocity) +void GOSoundEngine::UpdateVelocity(const GOSoundProvider* pipe, GO_SAMPLER* handle, unsigned velocity) { assert(handle); handle->velocity = velocity; /* Concurrent update possible, as it just update a float */ - handle->fader.SetVelocityVolume(handle->pipe->GetVelocityVolume(handle->velocity)); + if (pipe && handle->pipe == pipe) + // we've just checked thar handle is still playing the same pipe + // may be handle is switched to another pipe after this checking + // but we don't want to lock it because this functionality is not so important + handle->fader.SetVelocityVolume(pipe->GetVelocityVolume(handle->velocity)); } const std::vector& GOSoundEngine::GetMeterInfo() diff --git a/src/grandorgue/sound/GOSoundEngine.h b/src/grandorgue/sound/GOSoundEngine.h index 69c15636c..e6b0ddf1d 100644 --- a/src/grandorgue/sound/GOSoundEngine.h +++ b/src/grandorgue/sound/GOSoundEngine.h @@ -106,7 +106,7 @@ class GOSoundEngine GO_SAMPLER* StartSample(const GOSoundProvider *pipe, int sampler_group_id, unsigned audio_group, unsigned velocity, unsigned delay, uint64_t last_stop); uint64_t StopSample(const GOSoundProvider *pipe, GO_SAMPLER* handle); void SwitchSample(const GOSoundProvider *pipe, GO_SAMPLER* handle); - void UpdateVelocity(GO_SAMPLER* handle, unsigned velocity); + void UpdateVelocity(const GOSoundProvider* pipe, GO_SAMPLER* handle, unsigned velocity); void GetAudioOutput(float *output_buffer, unsigned n_frames, unsigned audio_output, bool last); void NextPeriod();