Sending voice data via SYSEX when voice is changed.

Adding master volume and changing master volume when SYSEX master volume is triggered.
pull/247/head
Holger Wirtz 3 years ago
parent 0b75186c5a
commit 7666793cc5
  1. BIN
      src/.mididevice.cpp.swp
  2. 5
      src/mididevice.cpp
  3. 2
      src/mididevice.h
  4. 104
      src/minidexed.cpp
  5. 3
      src/minidexed.h

Binary file not shown.

@ -170,9 +170,9 @@ void CMIDIDevice::MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsign
// GLOBAL MIDI SYSEX // GLOBAL MIDI SYSEX
if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[3] == 0x04 && pMessage[4] == 0x01 && pMessage[nLength-1] == MIDI_SYSTEM_EXCLUSIVE_END) // MASTER VOLUME if (pMessage[0] == MIDI_SYSTEM_EXCLUSIVE_BEGIN && pMessage[3] == 0x04 && pMessage[4] == 0x01 && pMessage[nLength-1] == MIDI_SYSTEM_EXCLUSIVE_END) // MASTER VOLUME
{ {
float32_t nMasterVolume=(pMessage[5] & (pMessage[6]<<7))/(1<<14); float32_t nMasterVolume=((pMessage[5] & 0x7c) & ((pMessage[6] & 0x7c) <<7))/(1<<14);
LOGNOTE("Master volume: %f",nMasterVolume); LOGNOTE("Master volume: %f",nMasterVolume);
// TODO: Handle global master volume m_pSynthesizer->setMasterVolume(nMasterVolume);
} }
else else
{ {
@ -427,7 +427,6 @@ void CMIDIDevice::HandleSystemExclusive(const uint8_t* pMessage, const size_t nL
// load sysex-data into voice memory // load sysex-data into voice memory
LOGDBG("One Voice bulk upload"); LOGDBG("One Voice bulk upload");
m_pSynthesizer->loadVoiceParameters(pMessage,nTG); m_pSynthesizer->loadVoiceParameters(pMessage,nTG);
break; break;
case 200: case 200:
LOGDBG("Bank bulk upload."); LOGDBG("Bank bulk upload.");

@ -49,12 +49,12 @@ public:
u8 GetChannel (unsigned nTG) const; u8 GetChannel (unsigned nTG) const;
virtual void Send (const u8 *pMessage, size_t nLength, unsigned nCable = 0) {} virtual void Send (const u8 *pMessage, size_t nLength, unsigned nCable = 0) {}
virtual void SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG);
protected: protected:
void MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable = 0); void MIDIMessageHandler (const u8 *pMessage, size_t nLength, unsigned nCable = 0);
void AddDevice (const char *pDeviceName); void AddDevice (const char *pDeviceName);
void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG); void HandleSystemExclusive(const uint8_t* pMessage, const size_t nLength, const unsigned nCable, const uint8_t nTG);
void SendSystemExclusiveVoice(uint8_t nVoice, const unsigned nCable, uint8_t nTG);
private: private:
CMiniDexed *m_pSynthesizer; CMiniDexed *m_pSynthesizer;
CConfig *m_pConfig; CConfig *m_pConfig;

@ -363,6 +363,7 @@ void CMiniDexed::ProgramChange (unsigned nProgram, unsigned nTG)
assert (m_pTG[nTG]); assert (m_pTG[nTG]);
m_pTG[nTG]->loadVoiceParameters (Buffer); m_pTG[nTG]->loadVoiceParameters (Buffer);
m_SerialMIDI.SendSystemExclusiveVoice(nProgram,0,nTG);
m_UI.ParameterChanged (); m_UI.ParameterChanged ();
} }
@ -867,56 +868,70 @@ void CMiniDexed::ProcessSound (void)
} }
// BEGIN TG mixing // BEGIN TG mixing
for (uint8_t i = 0; i < CConfig::ToneGenerators; i++) float32_t tmp_float[nFrames*2];
int16_t tmp_int[nFrames*2];
if(nMasterVolume > 0.0)
{ {
tg_mixer->doAddMix(i,m_OutputLevel[i]); for (uint8_t i = 0; i < CConfig::ToneGenerators; i++)
reverb_send_mixer->doAddMix(i,m_OutputLevel[i]); {
} tg_mixer->doAddMix(i,m_OutputLevel[i]);
// END TG mixing reverb_send_mixer->doAddMix(i,m_OutputLevel[i]);
}
// END TG mixing
// BEGIN create SampleBuffer for holding audio data // BEGIN create SampleBuffer for holding audio data
float32_t SampleBuffer[2][nFrames]; float32_t SampleBuffer[2][nFrames];
// END create SampleBuffer for holding audio data // END create SampleBuffer for holding audio data
// get the mix of all TGs // get the mix of all TGs
tg_mixer->getMix(SampleBuffer[indexL], SampleBuffer[indexR]); tg_mixer->getMix(SampleBuffer[indexL], SampleBuffer[indexR]);
// BEGIN adding reverb // BEGIN adding reverb
if (m_nParameter[ParameterReverbEnable]) if (m_nParameter[ParameterReverbEnable])
{ {
float32_t ReverbBuffer[2][nFrames]; float32_t ReverbBuffer[2][nFrames];
float32_t ReverbSendBuffer[2][nFrames]; float32_t ReverbSendBuffer[2][nFrames];
arm_fill_f32(0.0f, ReverbBuffer[indexL], nFrames); arm_fill_f32(0.0f, ReverbBuffer[indexL], nFrames);
arm_fill_f32(0.0f, ReverbBuffer[indexR], nFrames); arm_fill_f32(0.0f, ReverbBuffer[indexR], nFrames);
arm_fill_f32(0.0f, ReverbSendBuffer[indexR], nFrames); arm_fill_f32(0.0f, ReverbSendBuffer[indexR], nFrames);
arm_fill_f32(0.0f, ReverbSendBuffer[indexL], nFrames); arm_fill_f32(0.0f, ReverbSendBuffer[indexL], nFrames);
m_ReverbSpinLock.Acquire (); m_ReverbSpinLock.Acquire ();
reverb_send_mixer->getMix(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR]); reverb_send_mixer->getMix(ReverbSendBuffer[indexL], ReverbSendBuffer[indexR]);
reverb->doReverb(ReverbSendBuffer[indexL],ReverbSendBuffer[indexR],ReverbBuffer[indexL], ReverbBuffer[indexR],nFrames); reverb->doReverb(ReverbSendBuffer[indexL],ReverbSendBuffer[indexR],ReverbBuffer[indexL], ReverbBuffer[indexR],nFrames);
// scale down and add left reverb buffer by reverb level // scale down and add left reverb buffer by reverb level
arm_scale_f32(ReverbBuffer[indexL], reverb->get_level(), ReverbBuffer[indexL], nFrames); arm_scale_f32(ReverbBuffer[indexL], reverb->get_level(), ReverbBuffer[indexL], nFrames);
arm_add_f32(SampleBuffer[indexL], ReverbBuffer[indexL], SampleBuffer[indexL], nFrames); arm_add_f32(SampleBuffer[indexL], ReverbBuffer[indexL], SampleBuffer[indexL], nFrames);
// scale down and add right reverb buffer by reverb level // scale down and add right reverb buffer by reverb level
arm_scale_f32(ReverbBuffer[indexR], reverb->get_level(), ReverbBuffer[indexR], nFrames); arm_scale_f32(ReverbBuffer[indexR], reverb->get_level(), ReverbBuffer[indexR], nFrames);
arm_add_f32(SampleBuffer[indexR], ReverbBuffer[indexR], SampleBuffer[indexR], nFrames); arm_add_f32(SampleBuffer[indexR], ReverbBuffer[indexR], SampleBuffer[indexR], nFrames);
m_ReverbSpinLock.Release (); m_ReverbSpinLock.Release ();
} }
// END adding reverb // END adding reverb
// Convert dual float array (left, right) to single int16 array (left/right) // Convert dual float array (left, right) to single int16 array (left/right)
float32_t tmp_float[nFrames*2]; for(uint16_t i=0; i<nFrames;i++)
int16_t tmp_int[nFrames*2]; {
for(uint16_t i=0; i<nFrames;i++) if(nMasterVolume >0.0 && nMasterVolume <1.0)
{ {
tmp_float[i*2]=SampleBuffer[indexL][i]; tmp_float[i*2]=SampleBuffer[indexL][i] * nMasterVolume;
tmp_float[(i*2)+1]=SampleBuffer[indexR][i]; tmp_float[(i*2)+1]=SampleBuffer[indexR][i] * nMasterVolume;
}
else if(nMasterVolume == 1.0)
{
tmp_float[i*2]=SampleBuffer[indexL][i];
tmp_float[(i*2)+1]=SampleBuffer[indexR][i];
}
}
arm_float_to_q15(tmp_float,tmp_int,nFrames*2);
} }
arm_float_to_q15(tmp_float,tmp_int,nFrames*2); else
arm_fill_q15(0, tmp_int, nFrames * 2);
if (m_pSoundDevice->Write (tmp_int, sizeof(tmp_int)) != (int) sizeof(tmp_int)) if (m_pSoundDevice->Write (tmp_int, sizeof(tmp_int)) != (int) sizeof(tmp_int))
{ {
@ -1183,3 +1198,14 @@ void CMiniDexed::getSysExVoiceDump(uint8_t* dest, uint8_t nTG)
dest[161] = checksum & 0x7f; // Checksum dest[161] = checksum & 0x7f; // Checksum
dest[162] = 0xF7; // SysEx end dest[162] = 0xF7; // SysEx end
} }
void CMiniDexed::setMasterVolume (float32_t vol)
{
if(vol < 0.0)
vol = 0.0;
else if(vol > 1.0)
vol = 1.0;
nMasterVolume=vol;
}

@ -150,6 +150,7 @@ public:
std::string GetVoiceName (unsigned nTG); std::string GetVoiceName (unsigned nTG);
bool SavePerformance (void); bool SavePerformance (void);
void setMasterVolume (float32_t vol);
private: private:
int16_t ApplyNoteLimits (int16_t pitch, unsigned nTG); // returns < 0 to ignore note int16_t ApplyNoteLimits (int16_t pitch, unsigned nTG); // returns < 0 to ignore note
@ -195,6 +196,8 @@ private:
unsigned m_nReverbSend[CConfig::ToneGenerators]; unsigned m_nReverbSend[CConfig::ToneGenerators];
float32_t nMasterVolume;
CUserInterface m_UI; CUserInterface m_UI;
CSysExFileLoader m_SysExFileLoader; CSysExFileLoader m_SysExFileLoader;
CPerformanceConfig m_PerformanceConfig; CPerformanceConfig m_PerformanceConfig;

Loading…
Cancel
Save