@@ -126,6 +126,34 @@ void SamplerDevice::processMidiCc(uint8_t controller, uint8_t value, uint8_t cha
126126{
127127 std::lock_guard<std::mutex> lock { m_mutex };
128128
129+ if (controller == 121 ) { // Reset All Controllers
130+ m_globalPan = m_manualGlobalPan;
131+ m_globalVolume = m_manualGlobalVolume;
132+ m_globalCutoff = m_manualGlobalCutoff;
133+ m_globalHpfCutoff = m_manualGlobalHpfCutoff;
134+
135+ for (auto && sample : m_samples) {
136+ if (sample) {
137+ sample->pan = sample->manualPan ;
138+ sample->volume = sample->manualVolume ;
139+ sample->cutoff = sample->manualCutoff ;
140+ sample->hpfCutoff = sample->manualHpfCutoff ;
141+ }
142+ }
143+
144+ for (auto && voice : m_voices) {
145+ if (voice.active && voice.sample ) {
146+ voice.pan = m_globalPan;
147+ voice.volume = m_globalVolume;
148+ voice.cutoff = m_globalCutoff;
149+ voice.hpfCutoff = m_globalHpfCutoff;
150+ updateVoiceEffects (voice);
151+ }
152+ }
153+ emit dataChanged ();
154+ return ;
155+ }
156+
129157 if (m_channelMode) {
130158 // channel is 0-indexed (0-15)
131159 const size_t note = 36 + channel;
@@ -204,6 +232,33 @@ void SamplerDevice::processMidiAllNotesOff()
204232 voice.releasing = true ;
205233 }
206234 }
235+
236+ m_globalPan = m_manualGlobalPan;
237+ m_globalVolume = m_manualGlobalVolume;
238+ m_globalCutoff = m_manualGlobalCutoff;
239+ m_globalHpfCutoff = m_manualGlobalHpfCutoff;
240+
241+ for (auto && sample : m_samples) {
242+ if (sample) {
243+ sample->pan = sample->manualPan ;
244+ sample->volume = sample->manualVolume ;
245+ sample->cutoff = sample->manualCutoff ;
246+ sample->hpfCutoff = sample->manualHpfCutoff ;
247+ }
248+ }
249+
250+ // Update active voices to reflect the reset values
251+ for (auto && voice : m_voices) {
252+ if (voice.active && voice.sample ) {
253+ voice.pan = m_globalPan;
254+ voice.volume = m_globalVolume;
255+ voice.cutoff = m_globalCutoff;
256+ voice.hpfCutoff = m_globalHpfCutoff;
257+ updateVoiceEffects (voice);
258+ }
259+ }
260+
261+ emit dataChanged ();
207262}
208263
209264void SamplerDevice::processAudio (float * output, uint32_t nFrames, uint32_t sampleRate)
@@ -304,6 +359,10 @@ void SamplerDevice::loadSample(uint8_t note, const std::string & filePath)
304359 sample->data = std::move (data);
305360 sample->cutoff = 1 .0f ;
306361 sample->hpfCutoff = 0 .0f ;
362+ sample->manualPan = sample->pan ;
363+ sample->manualVolume = sample->volume ;
364+ sample->manualCutoff = sample->cutoff ;
365+ sample->manualHpfCutoff = sample->hpfCutoff ;
307366
308367 std::lock_guard<std::mutex> lock { m_mutex };
309368 m_samples.at (note) = std::move (sample);
@@ -359,6 +418,7 @@ void SamplerDevice::setSamplePan(uint8_t note, float pan)
359418 std::lock_guard<std::mutex> lock { m_mutex };
360419 if (m_samples.at (note)) {
361420 m_samples.at (note)->pan = std::clamp (pan, 0 .0f , 1 .0f );
421+ m_samples.at (note)->manualPan = m_samples.at (note)->pan ;
362422 for (auto && voice : m_voices) {
363423 if (voice.active && voice.note == note) {
364424 updateVoiceEffects (voice);
@@ -385,6 +445,7 @@ void SamplerDevice::setSampleVolume(uint8_t note, float volume)
385445 std::lock_guard<std::mutex> lock { m_mutex };
386446 if (m_samples.at (note)) {
387447 m_samples.at (note)->volume = std::clamp (volume, 0 .0f , 1 .0f );
448+ m_samples.at (note)->manualVolume = m_samples.at (note)->volume ;
388449 for (auto && voice : m_voices) {
389450 if (voice.active && voice.note == note) {
390451 updateVoiceEffects (voice);
@@ -411,6 +472,7 @@ void SamplerDevice::setSampleCutoff(uint8_t note, float cutoff)
411472 std::lock_guard<std::mutex> lock { m_mutex };
412473 if (m_samples.at (note)) {
413474 m_samples.at (note)->cutoff = std::clamp (cutoff, 0 .0f , 1 .0f );
475+ m_samples.at (note)->manualCutoff = m_samples.at (note)->cutoff ;
414476 for (auto && voice : m_voices) {
415477 if (voice.active && voice.note == note) {
416478 updateVoiceEffects (voice);
@@ -437,6 +499,7 @@ void SamplerDevice::setSampleHpfCutoff(uint8_t note, float cutoff)
437499 std::lock_guard<std::mutex> lock { m_mutex };
438500 if (m_samples.at (note)) {
439501 m_samples.at (note)->hpfCutoff = std::clamp (cutoff, 0 .0f , 1 .0f );
502+ m_samples.at (note)->manualHpfCutoff = m_samples.at (note)->hpfCutoff ;
440503 for (auto && voice : m_voices) {
441504 if (voice.active && voice.note == note) {
442505 updateVoiceEffects (voice);
@@ -506,10 +569,10 @@ void SamplerDevice::serializeToXml(QXmlStreamWriter & writer) const
506569 }();
507570
508571 writer.writeAttribute (Constants::NahdXml::xmlKeySamplePath (), path);
509- writer.writeAttribute (Constants::NahdXml::xmlKeyPan (), QString::number (std::round ((s->pan * 200 .0f ) - 100 .0f )));
510- writer.writeAttribute (Constants::NahdXml::xmlKeyVolume (), QString::number (std::round (s->volume * 100 .0f )));
511- writer.writeAttribute (Constants::NahdXml::xmlKeyCutoff (), QString::number (std::round (s->cutoff * 100 .0f )));
512- writer.writeAttribute (Constants::NahdXml::xmlKeyHpfCutoff (), QString::number (std::round (s->hpfCutoff * 100 .0f )));
572+ writer.writeAttribute (Constants::NahdXml::xmlKeyPan (), QString::number (std::round ((s->manualPan * 200 .0f ) - 100 .0f )));
573+ writer.writeAttribute (Constants::NahdXml::xmlKeyVolume (), QString::number (std::round (s->manualVolume * 100 .0f )));
574+ writer.writeAttribute (Constants::NahdXml::xmlKeyCutoff (), QString::number (std::round (s->manualCutoff * 100 .0f )));
575+ writer.writeAttribute (Constants::NahdXml::xmlKeyHpfCutoff (), QString::number (std::round (s->manualHpfCutoff * 100 .0f )));
513576 writer.writeEndElement ();
514577 }
515578 }
0 commit comments