Compare commits

...

2 Commits

  1. 99
      MicroMDAEPiano.ino
  2. 120
      mod-delay.cpp
  3. 89
      mod-delay.h

@ -28,6 +28,7 @@
#include <MIDI.h>
#include <EEPROM.h>
#include <limits.h>
#include "mod-delay.h"
#include "mdaEPiano.h"
#ifdef USE_XFADE_DATA
#include "mdaEPianoDataXfade.h"
@ -45,7 +46,6 @@
#include "LiquidCrystalPlus_I2C.h"
#include "UI.h"
//*************************************************************************************************
//* GLOBAL VARIABLES
//*************************************************************************************************
@ -59,27 +59,37 @@ AudioEffectFreeverb freeverb_r;
AudioEffectFreeverb freeverb_l;
AudioMixer4 mixer_r;
AudioMixer4 mixer_l;
AudioSynthWaveform delaySweep_r;
AudioSynthWaveform delaySweep_l;
AudioEffectModDelay modulatedDelay_r;
AudioEffectModDelay modulatedDelay_l;
AudioConnection patchCord0(queue_r, peak_r);
AudioConnection patchCord1(queue_l, peak_l);
AudioConnection patchCord4(queue_r, freeverb_r);
AudioConnection patchCord5(queue_l, freeverb_l);
AudioConnection patchCord6(queue_r, 0, mixer_r, 0);
AudioConnection patchCord7(queue_l, 0, mixer_l, 0);
AudioConnection patchCord8(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord9(freeverb_l, 0, mixer_l, 1);
AudioConnection patchCord6(queue_r, modulatedDelay_r);
AudioConnection patchCord7(queue_l, modulatedDelay_l);
AudioConnection patchCord8(queue_r, 0, mixer_r, 0);
AudioConnection patchCord9(queue_l, 0, mixer_l, 0);
AudioConnection patchCord10(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord11(freeverb_l, 0, mixer_l, 1);
AudioConnection patchCord12(modulatedDelay_r, 0, mixer_r, 2);
AudioConnection patchCord13(modulatedDelay_l, 0, mixer_l, 2);
AudioConnection patchCord14(delaySweep_r, 0, modulatedDelay_r, 1);
AudioConnection patchCord15(delaySweep_l, 0, modulatedDelay_l, 1);
#ifdef TEENSY_AUDIO_BOARD
AudioOutputI2S i2s1;
AudioConnection patchCord110(mixer_r, 0, i2s1, 0);
AudioConnection patchCord111(mixer_l, 0, i2s1, 1);
AudioConnection patchCord18(mixer_r, 0, i2s1, 0);
AudioConnection patchCord19(mixer_l, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1;
#else
AudioOutputPT8211 pt8211_1;
AudioAmplifier volume_r;
AudioAmplifier volume_l;
AudioConnection patchCord10(mixer_r, volume_r);
AudioConnection patchCord11(mixer_l, volume_l);
AudioConnection patchCord12(volume_r, 0, pt8211_1, 1);
AudioConnection patchCord13(volume_l, 0, pt8211_1, 0);
AudioConnection patchCord18(mixer_r, volume_r);
AudioConnection patchCord19(mixer_l, volume_l);
AudioConnection patchCord20(volume_r, 0, pt8211_1, 1);
AudioConnection patchCord21(volume_l, 0, pt8211_1, 0);
#endif
// Objects
@ -114,8 +124,12 @@ const uint16_t audio_block_time_us = 1000000 / (SAMPLE_RATE / AUDIO_BLOCK_SAMPLE
elapsedMillis cpu_mem_millis;
#endif
enum MDA_EP_PARAM { DECAY, RELEASE, HARDNESS, TREBLE, PAN_TREM, LFO_RATE, VELOCITY_SENSE, STEREO, MAX_POLY, TUNE, DETUNE, OVERDRIVE };
const int32_t delayBufferLength = 1000;
int16_t delayBuf_r[delayBufferLength];
int16_t delayBuf_l[delayBufferLength];
float modFreq = 0.7;
enum MDA_EP_PARAM { DECAY, RELEASE, HARDNESS, TREBLE, PAN_TREM, LFO_RATE, VELOCITY_SENSE, STEREO, MAX_POLY, TUNE, DETUNE, OVERDRIVE };
//*************************************************************************************************
//* SETUP FUNCTION
@ -127,26 +141,26 @@ void setup()
Serial.begin(SERIAL_SPEED);
delay(220);
/*
// LCD display setup
lcd.init();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
lcd.noAutoscroll();
lcd.clear();
lcd.display();
lcd.show(0, 0, 20, " MicroMDAEPiano");
lcd.show(1, 0, 16, "(c)parasiTstudio");
// Encoder setup
enc[0].write(INITIAL_ENC_L_VALUE);
enc_val[0] = enc[0].read();
enc[1].write(INITIAL_ENC_R_VALUE);
enc_val[1] = enc[1].read();
but[0].update();
but[1].update();
*/
/*
// LCD display setup
lcd.init();
lcd.blink_off();
lcd.cursor_off();
lcd.backlight();
lcd.noAutoscroll();
lcd.clear();
lcd.display();
lcd.show(0, 0, 20, " MicroMDAEPiano");
lcd.show(1, 0, 16, "(c)parasiTstudio");
// Encoder setup
enc[0].write(INITIAL_ENC_L_VALUE);
enc_val[0] = enc[0].read();
enc[1].write(INITIAL_ENC_R_VALUE);
enc_val[1] = enc[1].read();
but[0].update();
but[1].update();
*/
// Debug output
Serial.println(F("MicroMDAEPiano based on https://sourceforge.net/projects/mda-vst"));
@ -183,6 +197,8 @@ void setup()
#endif
// start audio card
AudioNoInterrupts();
AudioMemory(AUDIO_MEM);
#ifdef TEENSY_AUDIO_BOARD
@ -223,10 +239,21 @@ void setup()
freeverb_l.roomsize(0.2);
freeverb_r.damping(0.5);
freeverb_l.damping(0.5);
mixer_r.gain(0, 0.7);
mixer_l.gain(0, 0.7);
mixer_r.gain(1, 0.3);
mixer_l.gain(1, 0.3);
modulatedDelay_r.setbuf(delayBufferLength, delayBuf_r);
modulatedDelay_l.setbuf(delayBufferLength, delayBuf_l);
delaySweep_r.begin(0.1, modFreq, WAVEFORM_SINE);
delaySweep_l.begin(0.1, modFreq, WAVEFORM_SINE);
//delaySweep_l.phase(180.0);
mixer_r.gain(0, 0.5);
mixer_l.gain(0, 0.5);
mixer_r.gain(1, 0.2);
mixer_l.gain(1, 0.2);
mixer_r.gain(2, 0.5);
mixer_l.gain(2, 0.5);
AudioInterrupts();
Serial.println(F("<setup end>"));

@ -0,0 +1,120 @@
/* Modulated delay line
Inspired by;
http://musicdsp.org/showArchiveComment.php?ArchiveID=154
But details changed for Teensy Audio.
No feedback within the class, just done externally
so we can add filters and stuff to the loop.
Delay time is a signal input to the block, and functions from 0 to 0x7fff,
scaling the delay time accordingly.
*/
/*
Copyright (c) 2016, Byron Jacquot, SparkFun Electronics
SparkFun code, firmware, and software is released under
the MIT License(http://opensource.org/licenses/MIT).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice, development funding notice, and this permission
notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "mod-delay.h"
#define INTERPOLATE (1)
void AudioEffectModDelay::update(void)
{
audio_block_t *audioblock, *controlblockDelay;
int16_t *data, *end, *ctrlDelay;
int32_t extract_index;
#ifdef INTERPOLATE
int32_t interp_delta;
int32_t next;
int16_t calc;
#endif
if (buffer_length == 0)
return;
audioblock = receiveWritable(0);
if (!audioblock) return;
controlblockDelay = receiveReadOnly(1);
if (!controlblockDelay) {
release(audioblock);
return;
}
data = audioblock->data;
end = audioblock->data + AUDIO_BLOCK_SAMPLES;
ctrlDelay = controlblockDelay->data;
do
{
delayline_p[insert_index] = *data;
insert_index++;
if (insert_index >= buffer_length)
{
insert_index = 0;
}
#ifdef INTERPOLATE
interp_delta = (buffer_length * (*ctrlDelay));
delay_delta = (interp_delta >> 15); // MSB's for delay len
interp_delta &= 0x7fff; //LSBs for interp distance
#else
delay_delta = (buffer_length * (*ctrlDelay)) >> 15;
#endif
extract_index = insert_index - delay_delta;
if (extract_index < 0)
{
extract_index = buffer_length + extract_index;
}
#ifdef INTERPOLATE
// Use the fractional part to interpolate between samples
next = extract_index + 1;
if (next >= buffer_length)
{
next = 0;
}
calc = delayline_p[next] - delayline_p[extract_index];
calc = (calc * interp_delta ) >> 15;
calc += delayline_p[extract_index];
*data = calc;
#else
*data = delayline_p[extract_index];
#endif
data++;
ctrlDelay++;
} while (data < end);
transmit(audioblock);
release(audioblock);
release(controlblockDelay);
}

@ -0,0 +1,89 @@
/* Modulated delay line
Inspired by;
http://musicdsp.org/showArchiveComment.php?ArchiveID=154
But details changed for Teensy Audio.
No feedback within the class, just done externally
so we can add filters and stuff to the loop.
Delay time is a signal input to the block, and functions from 0 to 0x7fff,
scaling the delay time accordingly.
*/
/*
Copyright (c) 2016, Byron Jacquot, SparkFun Electronics
SparkFun code, firmware, and software is released under
the MIT License(http://opensource.org/licenses/MIT).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice, development funding notice, and this permission
notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/* from https://forum.pjrc.com/threads/46793-Anyone-Doing-Pitch-Shifting */
#pragma once
#ifndef _mod_delay_h_
#define _mod_delay_h_
#include "AudioStream.h"
#include <Arduino.h>
class AudioEffectModDelay: public AudioStream
{
public:
AudioEffectModDelay (void) : AudioStream(2, inputQueueArray)
{
buffer_length = 0;
}
virtual void update(void);
// Set the parameters
void setbuf(int32_t delay_len, int16_t* delay_buf )
{
delayline_p = delay_buf;
insert_index = 0;
buffer_length = delay_len;
memset(delayline_p, 0, buffer_length);
};
void inspect(void)
{
Serial.print(insert_index, HEX);
Serial.print(' ');
Serial.print(delay_delta, HEX);
Serial.print(' ');
Serial.println(buffer_length, HEX);
};
private:
audio_block_t *inputQueueArray[2];
int16_t *delayline_p;
int32_t insert_index;
int32_t buffer_length;
int32_t delay_delta;
};
#endif
Loading…
Cancel
Save