|
|
@ -9,15 +9,9 @@ |
|
|
|
|
|
|
|
|
|
|
|
namespace BAGuitar { |
|
|
|
namespace BAGuitar { |
|
|
|
|
|
|
|
|
|
|
|
constexpr int MIDI_NUM_PARAMS = 4; |
|
|
|
|
|
|
|
constexpr int MIDI_CHANNEL = 0; |
|
|
|
constexpr int MIDI_CHANNEL = 0; |
|
|
|
constexpr int MIDI_CONTROL = 1; |
|
|
|
constexpr int MIDI_CONTROL = 1; |
|
|
|
|
|
|
|
|
|
|
|
constexpr int MIDI_BYPASS = 0; |
|
|
|
|
|
|
|
constexpr int MIDI_DELAY = 1; |
|
|
|
|
|
|
|
constexpr int MIDI_FEEDBACK = 2; |
|
|
|
|
|
|
|
constexpr int MIDI_MIX = 3; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// BOSS DM-3 Filters
|
|
|
|
// BOSS DM-3 Filters
|
|
|
|
constexpr unsigned NUM_IIR_STAGES = 4; |
|
|
|
constexpr unsigned NUM_IIR_STAGES = 4; |
|
|
|
constexpr unsigned IIR_COEFF_SHIFT = 2; |
|
|
|
constexpr unsigned IIR_COEFF_SHIFT = 2; |
|
|
@ -200,13 +194,40 @@ void AudioEffectAnalogDelay::delay(size_t delaySamples) |
|
|
|
m_delaySamples= delaySamples; |
|
|
|
m_delaySamples= delaySamples; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::m_preProcessing(audio_block_t *out, audio_block_t *dry, audio_block_t *wet) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if ( out && dry && wet) { |
|
|
|
|
|
|
|
alphaBlend(out, dry, wet, m_feedback); |
|
|
|
|
|
|
|
m_iir->process(out->data, out->data, AUDIO_BLOCK_SAMPLES); |
|
|
|
|
|
|
|
} else if (dry) { |
|
|
|
|
|
|
|
memcpy(out->data, dry->data, sizeof(int16_t) * AUDIO_BLOCK_SAMPLES); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::m_postProcessing(audio_block_t *out, audio_block_t *dry, audio_block_t *wet) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!out) return; // no valid output buffer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( out && dry && wet) { |
|
|
|
|
|
|
|
// Simulate the LPF IIR nature of the analog systems
|
|
|
|
|
|
|
|
//m_iir->process(wet->data, wet->data, AUDIO_BLOCK_SAMPLES);
|
|
|
|
|
|
|
|
alphaBlend(out, dry, wet, m_mix); |
|
|
|
|
|
|
|
} else if (dry) { |
|
|
|
|
|
|
|
memcpy(out->data, dry->data, sizeof(int16_t) * AUDIO_BLOCK_SAMPLES); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Set the output volume
|
|
|
|
|
|
|
|
gainAdjust(out, out, m_volume, 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::processMidi(int channel, int control, int value) |
|
|
|
void AudioEffectAnalogDelay::processMidi(int channel, int control, int value) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
float val = (float)value / 127.0f; |
|
|
|
float val = (float)value / 127.0f; |
|
|
|
|
|
|
|
|
|
|
|
if ((m_midiConfig[MIDI_DELAY][MIDI_CHANNEL] == channel) && |
|
|
|
if ((m_midiConfig[DELAY][MIDI_CHANNEL] == channel) && |
|
|
|
(m_midiConfig[MIDI_DELAY][MIDI_CONTROL] == control)) { |
|
|
|
(m_midiConfig[DELAY][MIDI_CONTROL] == control)) { |
|
|
|
// Delay
|
|
|
|
// Delay
|
|
|
|
m_maxDelaySamples = m_memory->getSlot()->size(); |
|
|
|
m_maxDelaySamples = m_memory->getSlot()->size(); |
|
|
|
Serial.println(String("AudioEffectAnalogDelay::delay: ") + val + String(" out of ") + m_maxDelaySamples); |
|
|
|
Serial.println(String("AudioEffectAnalogDelay::delay: ") + val + String(" out of ") + m_maxDelaySamples); |
|
|
@ -214,75 +235,47 @@ void AudioEffectAnalogDelay::processMidi(int channel, int control, int value) |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((m_midiConfig[MIDI_BYPASS][MIDI_CHANNEL] == channel) && |
|
|
|
if ((m_midiConfig[BYPASS][MIDI_CHANNEL] == channel) && |
|
|
|
(m_midiConfig[MIDI_BYPASS][MIDI_CONTROL] == control)) { |
|
|
|
(m_midiConfig[BYPASS][MIDI_CONTROL] == control)) { |
|
|
|
// Bypass
|
|
|
|
// Bypass
|
|
|
|
if (value >= 65) { bypass(false); Serial.println(String("AudioEffectAnalogDelay::not bypassed -> ON") + value); } |
|
|
|
if (value >= 65) { bypass(false); Serial.println(String("AudioEffectAnalogDelay::not bypassed -> ON") + value); } |
|
|
|
else { bypass(true); Serial.println(String("AudioEffectAnalogDelay::bypassed -> OFF") + value); } |
|
|
|
else { bypass(true); Serial.println(String("AudioEffectAnalogDelay::bypassed -> OFF") + value); } |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((m_midiConfig[MIDI_FEEDBACK][MIDI_CHANNEL] == channel) && |
|
|
|
if ((m_midiConfig[FEEDBACK][MIDI_CHANNEL] == channel) && |
|
|
|
(m_midiConfig[MIDI_FEEDBACK][MIDI_CONTROL] == control)) { |
|
|
|
(m_midiConfig[FEEDBACK][MIDI_CONTROL] == control)) { |
|
|
|
// Feedback
|
|
|
|
// Feedback
|
|
|
|
Serial.println(String("AudioEffectAnalogDelay::feedback: ") + val); |
|
|
|
Serial.println(String("AudioEffectAnalogDelay::feedback: ") + val); |
|
|
|
feedback(val); |
|
|
|
feedback(val); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((m_midiConfig[MIDI_MIX][MIDI_CHANNEL] == channel) && |
|
|
|
if ((m_midiConfig[MIX][MIDI_CHANNEL] == channel) && |
|
|
|
(m_midiConfig[MIDI_MIX][MIDI_CONTROL] == control)) { |
|
|
|
(m_midiConfig[MIX][MIDI_CONTROL] == control)) { |
|
|
|
// Mix
|
|
|
|
// Mix
|
|
|
|
Serial.println(String("AudioEffectAnalogDelay::mix: ") + val); |
|
|
|
Serial.println(String("AudioEffectAnalogDelay::mix: ") + val); |
|
|
|
mix(val); |
|
|
|
mix(val); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
if ((m_midiConfig[VOLUME][MIDI_CHANNEL] == channel) && |
|
|
|
void AudioEffectAnalogDelay::mapMidiDelay(int control, int channel) |
|
|
|
(m_midiConfig[VOLUME][MIDI_CONTROL] == control)) { |
|
|
|
{ |
|
|
|
// Volume
|
|
|
|
m_midiConfig[MIDI_DELAY][MIDI_CHANNEL] = channel; |
|
|
|
Serial.println(String("AudioEffectAnalogDelay::volume: ") + val); |
|
|
|
m_midiConfig[MIDI_DELAY][MIDI_CONTROL] = control; |
|
|
|
volume(val); |
|
|
|
} |
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::mapMidiBypass(int control, int channel) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_midiConfig[MIDI_BYPASS][MIDI_CHANNEL] = channel; |
|
|
|
|
|
|
|
m_midiConfig[MIDI_BYPASS][MIDI_CONTROL] = control; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::mapMidiFeedback(int control, int channel) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_midiConfig[MIDI_FEEDBACK][MIDI_CHANNEL] = channel; |
|
|
|
|
|
|
|
m_midiConfig[MIDI_FEEDBACK][MIDI_CONTROL] = control; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::mapMidiMix(int control, int channel) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
m_midiConfig[MIDI_MIX][MIDI_CHANNEL] = channel; |
|
|
|
|
|
|
|
m_midiConfig[MIDI_MIX][MIDI_CONTROL] = control; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::m_preProcessing(audio_block_t *out, audio_block_t *dry, audio_block_t *wet) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if ( out && dry && wet) { |
|
|
|
|
|
|
|
alphaBlend(out, dry, wet, m_feedback); |
|
|
|
|
|
|
|
m_iir->process(out->data, out->data, AUDIO_BLOCK_SAMPLES); |
|
|
|
|
|
|
|
} else if (dry) { |
|
|
|
|
|
|
|
memcpy(out->data, dry->data, sizeof(int16_t) * AUDIO_BLOCK_SAMPLES); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void AudioEffectAnalogDelay::m_postProcessing(audio_block_t *out, audio_block_t *dry, audio_block_t *wet) |
|
|
|
void AudioEffectAnalogDelay::mapMidiControl(int parameter, int midiCC, int midiChannel) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if ( out && dry && wet) { |
|
|
|
if (parameter >= NUM_CONTROLS) { |
|
|
|
// Simulate the LPF IIR nature of the analog systems
|
|
|
|
return ; // Invalid midi parameter
|
|
|
|
//m_iir->process(wet->data, wet->data, AUDIO_BLOCK_SAMPLES);
|
|
|
|
|
|
|
|
alphaBlend(out, dry, wet, m_mix); |
|
|
|
|
|
|
|
} else if (dry) { |
|
|
|
|
|
|
|
memcpy(out->data, dry->data, sizeof(int16_t) * AUDIO_BLOCK_SAMPLES); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
m_midiConfig[parameter][MIDI_CHANNEL] = midiChannel; |
|
|
|
|
|
|
|
m_midiConfig[parameter][MIDI_CONTROL] = midiCC; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|