From f03e3887213a2e3ad4f049d80d66edfa24318561 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 28 Apr 2025 21:10:07 +0200 Subject: [PATCH 1/4] Fix operator enable/disable (#896) Enable/disable operators, closes #872 by calling m_pSynthesizer->setOPMask --- src/mididevice.cpp | 22 ++++++++++++++-------- updater.py | 4 ++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index d657103..0695245 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -718,14 +718,20 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL default: if(sysex_return >= 300 && sysex_return < 500) { - LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); - m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); - switch(pMessage[4] + ((pMessage[3] & 0x03) * 128)) - { - case 134: - m_pSynthesizer->notesOff(0,nTG); - break; - } + uint8_t param = pMessage[4] + ((pMessage[3] & 0x03) * 128); + if(param == 155) { + LOGDBG("Operators enabled: %d%d%d%d%d%d", (pMessage[5] & 0x20) ? 1 : 0, (pMessage[5] & 0x10) ? 1 : 0, (pMessage[5] & 0x08) ? 1 : 0, (pMessage[5] & 0x04) ? 1 : 0, (pMessage[5] & 0x02) ? 1 : 0, (pMessage[5] & 0x01) ? 1 : 0); + m_pSynthesizer->setOPMask(pMessage[5], nTG); + } else { + LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); + m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); + switch(pMessage[4] + ((pMessage[3] & 0x03) * 128)) + { + case 134: + m_pSynthesizer->notesOff(0,nTG); + break; + } + } } else if(sysex_return >= 500 && sysex_return < 600) { diff --git a/updater.py b/updater.py index a88228c..30e6749 100644 --- a/updater.py +++ b/updater.py @@ -1,5 +1,5 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- # Updater for MiniDexed From e6aab619206d779bde2f34be6af315a1e8f91097 Mon Sep 17 00:00:00 2001 From: probonopd Date: Mon, 28 Apr 2025 22:19:54 +0200 Subject: [PATCH 2/4] Simplify code structure As suggested by @soyersoyer in https://github.com/probonopd/MiniDexed/pull/896#issuecomment-2836244015 --- src/mididevice.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/mididevice.cpp b/src/mididevice.cpp index 0695245..576821f 100644 --- a/src/mididevice.cpp +++ b/src/mididevice.cpp @@ -715,23 +715,22 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL //TODO: add code for storing a bank bulk upload LOGNOTE("Currently code for storing a bulk bank upload is missing!"); break; + case 455: + // Parameter 155 + 300 added by Synth_Dexed = 455 + LOGDBG("Operators enabled: %d%d%d%d%d%d", (pMessage[5] & 0x20) ? 1 : 0, (pMessage[5] & 0x10) ? 1 : 0, (pMessage[5] & 0x08) ? 1 : 0, (pMessage[5] & 0x04) ? 1 : 0, (pMessage[5] & 0x02) ? 1 : 0, (pMessage[5] & 0x01) ? 1 : 0); + m_pSynthesizer->setOPMask(pMessage[5], nTG); + break; default: if(sysex_return >= 300 && sysex_return < 500) { - uint8_t param = pMessage[4] + ((pMessage[3] & 0x03) * 128); - if(param == 155) { - LOGDBG("Operators enabled: %d%d%d%d%d%d", (pMessage[5] & 0x20) ? 1 : 0, (pMessage[5] & 0x10) ? 1 : 0, (pMessage[5] & 0x08) ? 1 : 0, (pMessage[5] & 0x04) ? 1 : 0, (pMessage[5] & 0x02) ? 1 : 0, (pMessage[5] & 0x01) ? 1 : 0); - m_pSynthesizer->setOPMask(pMessage[5], nTG); - } else { - LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); - m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); - switch(pMessage[4] + ((pMessage[3] & 0x03) * 128)) - { - case 134: - m_pSynthesizer->notesOff(0,nTG); - break; - } - } + LOGDBG("SysEx voice parameter change: Parameter %d value: %d",pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5]); + m_pSynthesizer->setVoiceDataElement(pMessage[4] + ((pMessage[3] & 0x03) * 128), pMessage[5],nTG); + switch(pMessage[4] + ((pMessage[3] & 0x03) * 128)) + { + case 134: + m_pSynthesizer->notesOff(0,nTG); + break; + } } else if(sysex_return >= 500 && sysex_return < 600) { From 1199230c73d023a2e90ba077dc2bf08b2735ebb8 Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 29 Apr 2025 08:09:55 +0200 Subject: [PATCH 3/4] BREAKING CHANGE: Load default performances from performance/001_Default (#895) BREAKING CHANGE: Load default performances from performance/001_Default rather than performance/ Closes #893, #894 --- src/performanceconfig.cpp | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/performanceconfig.cpp b/src/performanceconfig.cpp index d0ce2de..dfff8a9 100644 --- a/src/performanceconfig.cpp +++ b/src/performanceconfig.cpp @@ -33,7 +33,6 @@ LOGMODULE ("Performance"); #define PERFORMANCE_DIR "performance" #define DEFAULT_PERFORMANCE_FILENAME "performance.ini" #define DEFAULT_PERFORMANCE_NAME "Default" -#define DEFAULT_PERFORMANCE_BANK_NAME "Default" CPerformanceConfig::CPerformanceConfig (FATFS *pFileSystem) : m_Properties (DEFAULT_PERFORMANCE_FILENAME, pFileSystem) @@ -1168,10 +1167,6 @@ bool CPerformanceConfig::ListPerformanceBanks() } unsigned nNumBanks = 0; - - // Add in the default performance directory as the first bank - m_PerformanceBankName[0] = DEFAULT_PERFORMANCE_BANK_NAME; - nNumBanks = 1; m_nLastPerformanceBank = 0; // List directories with names in format 01_Perf Bank Name @@ -1277,10 +1272,7 @@ std::string CPerformanceConfig::GetPerformanceBankName(unsigned nBankID) { return m_PerformanceBankName[nBankID]; } - else - { - return DEFAULT_PERFORMANCE_BANK_NAME; - } + return ""; } std::string CPerformanceConfig::AddPerformanceBankDirName(unsigned nBankID) @@ -1290,12 +1282,6 @@ std::string CPerformanceConfig::AddPerformanceBankDirName(unsigned nBankID) { // Performance Banks directories in format "001_Bank Name" std::string Index; - if (nBankID == 0) - { - // Legacy: Bank 1 is the default performance directory - return ""; - } - if (nBankID < 9) { Index = "00" + std::to_string(nBankID+1); From 5b24bbd84b11f6aedddefb5e4e30c9a23ec8b91b Mon Sep 17 00:00:00 2001 From: probonopd Date: Tue, 29 Apr 2025 22:33:06 +0200 Subject: [PATCH 4/4] Patch Synth_Dexed to fix glissando/portamento detune (#897) Patch Synth_Dexed, addresses #889 --- .github/workflows/build.yml | 10 +++++ src/patches/dx7note.patch | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 src/patches/dx7note.patch diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3f3a2fd..c4030af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,6 +39,11 @@ jobs: wget -q https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz tar xf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz + # Patch Synth_Dexed until the fix is merged upstream; see https://github.com/probonopd/MiniDexed/issues/889 + - name: Patch Synth_Dexed + run: | + ( cd Synth_Dexed ; patch -p1 < ../src/patches/dx7note.patch ) + - name: Build for Raspberry Pi 5 (64-bit) run: | set -ex @@ -124,6 +129,11 @@ jobs: wget -q https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-arm-none-eabi.tar.xz tar xf gcc-arm-10.3-2021.07-x86_64-arm-none-eabi.tar.xz + # Patch Synth_Dexed until the fix is merged upstream; see https://github.com/probonopd/MiniDexed/issues/889 + - name: Patch Synth_Dexed + run: | + ( cd Synth_Dexed ; patch -p1 < ../src/patches/dx7note.patch ) + - name: Build for Raspberry Pi 2 (32-bit) run: | set -ex diff --git a/src/patches/dx7note.patch b/src/patches/dx7note.patch new file mode 100644 index 0000000..a4a151c --- /dev/null +++ b/src/patches/dx7note.patch @@ -0,0 +1,81 @@ +diff --git a/src/dx7note.cpp b/src/dx7note.cpp +index b5ed6db..2a07836 100644 +--- a/src/dx7note.cpp ++++ b/src/dx7note.cpp +@@ -184,11 +184,14 @@ void Dx7Note::init(const uint8_t patch[156], int midinote, int velocity, int src + int32_t freq = osc_freq(midinote, mode, coarse, fine, detune); + opMode[op] = mode; + basepitch_[op] = freq; +- porta_curpitch_[op] = freq; + ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3]; + +- if (porta >= 0) ++ // Always set porta_curpitch_ to basepitch_ if no portamento transition ++ if (porta < 0 || porta >= 128 || srcnote == midinote) { ++ porta_curpitch_[op] = freq; ++ } else { + porta_curpitch_[op] = osc_freq(srcnote, mode, coarse, fine, detune); ++ } + } + for (int i = 0; i < 4; i++) { + rates[i] = patch[126 + i]; +@@ -253,13 +256,17 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co + + int32_t basepitch = basepitch_[op]; + +- if ( opMode[op] ) ++ if (opMode[op]) { + params_[op].freq = Freqlut::lookup(basepitch + pitch_base); +- else { +- if ( porta_rateindex_ >= 0 ) { +- basepitch = porta_curpitch_[op]; +- if ( porta_gliss_ ) +- basepitch = logfreq_round2semi(basepitch); ++ } else { ++ // If portamento is enabled but there is no transition, use basepitch_ ++ if (porta_rateindex_ >= 0) { ++ if (porta_curpitch_[op] != basepitch_[op]) { ++ basepitch = porta_curpitch_[op]; ++ if (porta_gliss_) ++ basepitch = logfreq_round2semi(basepitch); ++ } ++ // else: no transition, use basepitch_ as is + } + params_[op].freq = Freqlut::lookup(basepitch + pitch_mod); + } +@@ -280,7 +287,7 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co + + // ==== PORTAMENTO ==== + int porta = porta_rateindex_; +- if ( porta >= 0 ) { ++ if (porta >= 0) { + int32_t rate = Porta::rates[porta]; + for (int op = 0; op < 6; op++) { + int32_t cur = porta_curpitch_[op]; +@@ -289,7 +296,8 @@ void Dx7Note::compute(int32_t *buf, int32_t lfo_val, int32_t lfo_delay, const Co + bool going_up = cur < dst; + int32_t newpitch = cur + (going_up ? +rate : -rate); + +- if ( going_up ? (cur > dst) : (cur < dst) ) ++ // Clamp to destination if we would overshoot/undershoot ++ if ((going_up && newpitch > dst) || (!going_up && newpitch < dst)) + newpitch = dst; + + porta_curpitch_[op] = newpitch; +@@ -317,10 +325,15 @@ void Dx7Note::update(const uint8_t patch[156], int midinote, int velocity, int p + int detune = patch[off + 20]; + int32_t freq = osc_freq(midinote, mode, coarse, fine, detune); + basepitch_[op] = freq; +- porta_curpitch_[op] = freq; + ampmodsens_[op] = ampmodsenstab[patch[off + 14] & 3]; + opMode[op] = mode; + ++ // Always set porta_curpitch_ to basepitch_ if no portamento transition ++ if (porta < 0 || porta >= 128) { ++ porta_curpitch_[op] = freq; ++ } ++ // else: porta_curpitch_ will be handled by portamento logic ++ + for (int i = 0; i < 4; i++) { + rates[i] = patch[off + i]; + levels[i] = patch[off + 4 + i];