Disable Effects at runtime or Add Remove Patch Cables

Status
Not open for further replies.

vangalvin

Member
I am working on a little project for my son and would like to have multiple effects that can be switched on and off.
at any time there will only be one effect between the ADC and the DAC / USB / PWM

It looks like there is no way to swap around the patchleads at runtime and I cant see any way to enable/disable the effects such as Flange, Bitcrusher, Reverb etc...

I was also not sure how to deal with the ADC being feed in to the effects, do you just run a patch lead from the ADC to each of the effects? it would make it so much easier if there was a spliter that would take one input and allow you to output it to multiple effects and be able to turn off each out port. Or even a way to disable a patch lead at runtime.

Any suggestions would be most welcome
 
Playing a bit with the audio design tool, you'll discover that you might draw a patch cord from one ADC to multiple effects. Then, you would place a patch cord from each effect output towards a mixer block which allows you to enable/disable the different effects by setting the mixer's respective channel gain either to a value >0 to enable or = 0 at runtime to disable the corresponding effect. Using an additional patch cord from the ADC directly towards a mixer channel allows you to bypass the whole thing or to create a dry/wet thing.
 
2018-12-30 12_37_24-Start.png
Use a mixer!


Edit: OK, Theremingenieur was faster..
 
Or even a way to disable a patch lead at runtime.

This was added to library, but it's still experimental and undocumented. You probably shouldn't try to use it at this point, unless you've able to dig into the library code to find out how it works.

But you can add the "amp" before an effect. Just set the gain to 0 to turn off its data output. The mixer does the same, if all its channels are 0 gain.
 
Playing a bit with the audio design tool, you'll discover that you might draw a patch cord from one ADC to multiple effects. Then, you would place a patch cord from each effect output towards a mixer block which allows you to enable/disable the different effects by setting the mixer's respective channel gain either to a value >0 to enable or = 0 at runtime to disable the corresponding effect. Using an additional patch cord from the ADC directly towards a mixer channel allows you to bypass the whole thing or to create a dry/wet thing.

Thanks guys, This is what I ended up doing.
https://imgur.com/a/PZD9htb

I was not sure if using a single input to multiple effects would cause issues in respect to taking up more processing power as power. If the signal is not present on the input of the effect then the effect is not run from what I have read freeing up some of the audio memory.

@PaulStoffregen I may try the audio amp option and see if that further reduces the memory usage.

For testing purposes I have added a waveform so i can check the audio path and make sure it is getting to the destination.
 
Here is what I ended up with, Its still a work in progress but so far it seems to be working OK.
now to add in the control's
ucR9VvM.jpg

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>


#define CHORUS_DELAY_LENGTH (16*AUDIO_BLOCK_SAMPLES)
short c_delayline[CHORUS_DELAY_LENGTH];
int n_chorus = 2;


// GUItool: begin automatically generated code
AudioSynthWaveform       waveform1;      //xy=64,67
AudioInputAnalog         adc1;           //xy=67,28
AudioMixer4              mixer1;         //xy=196,59
AudioEffectDelay         delay1;         //xy=309,88
AudioEffectReverb        reverb1;        //xy=479,72
AudioEffectChorus        chorus1;        //xy=480,137
AudioEffectBitcrusher    bitcrusher1;    //xy=490,104
AudioMixer4              mixer2;         //xy=715,43
AudioMixer4              mixer3;         //xy=716,104
AudioMixer4              mixer4;         //xy=716,165
AudioMixer4              mixer5;         //xy=717,226
AudioMixer4              mixer6;         //xy=861,119
AudioEffectDelay         delay2;         //xy=989,117
AudioOutputUSB           usb1;           //xy=990,41
AudioConnection          patchCord1(waveform1, 0, mixer1, 1);
AudioConnection          patchCord2(adc1, 0, mixer1, 0);
AudioConnection          patchCord3(mixer1, delay1);
AudioConnection          patchCord4(delay1, 0, mixer2, 0);
AudioConnection          patchCord5(delay1, 1, mixer2, 1);
AudioConnection          patchCord6(delay1, 2, reverb1, 0);
AudioConnection          patchCord7(delay1, 3, bitcrusher1, 0);
AudioConnection          patchCord8(delay1, 4, chorus1, 0);
AudioConnection          patchCord9(reverb1, 0, mixer2, 2);
AudioConnection          patchCord10(chorus1, 0, mixer3, 0);
AudioConnection          patchCord11(bitcrusher1, 0, mixer2, 3);
AudioConnection          patchCord12(mixer2, 0, mixer6, 0);
AudioConnection          patchCord13(mixer3, 0, mixer6, 1);
AudioConnection          patchCord14(mixer4, 0, mixer6, 2);
AudioConnection          patchCord15(mixer5, 0, mixer6, 3);
AudioConnection          patchCord16(mixer6, delay2);
AudioConnection          patchCord17(delay2, 0, usb1, 0);
AudioConnection          patchCord18(delay2, 1, usb1, 1);
// GUItool: end automatically generated code


void setup() {
  Serial.begin(115200);
  AudioMemory(30);


mixer1.gain(0, 0);  //ADC1 connected to this port
mixer1.gain(1, 0);  //waveform1
mixer1.gain(2, 0);  //not used
mixer1.gain(3, 0);  //not used


mixer2.gain(0, 0);  //from Delay1 (0)
mixer2.gain(1, 0);  //from delay1 (1)
mixer2.gain(2, 0);  //from reverb1
mixer2.gain(3, 0);  //from bitcrush


mixer3.gain(0, 0);  //not used
mixer3.gain(1, 0);  //not used
mixer3.gain(2, 0);  //not used
mixer3.gain(3, 0);  //not used


mixer4.gain(0, 0);  //not used
mixer4.gain(1, 0);  //not used
mixer4.gain(2, 0);  //not used
mixer4.gain(3, 0);  //not used


mixer5.gain(0, 0);  //not used
mixer5.gain(1, 0);  //not used
mixer5.gain(2, 0);  //not used
mixer5.gain(3, 0);  //not used


mixer6.gain(0, 0);  //from mixer2
mixer6.gain(1, 0);  //from mixer3
mixer6.gain(2, 0);  //from mixer4
mixer6.gain(3, 0);  //from mixer5


//input from mixer1
delay1.disable(0); // direct to mixer2
delay1.disable(1); // direct to mixer2
delay1.disable(2); // to reverb1
delay1.disable(3); // to bitcrusher1
delay1.disable(4);
delay1.disable(5);
delay1.disable(6);
delay1.disable(7); // to notefreq1


//input from mixer6
delay2.disable(0); // to USB1 - R
delay2.disable(1); // to USB1 - L
delay2.disable(2); //not used
delay2.disable(3); //not used
delay2.disable(4); //not used
delay2.disable(5); //not used
delay2.disable(6); //not used
delay2.disable(7); //not used


//  AudioProcessorUsageMaxReset();
//  AudioMemoryUsageMaxReset();
  delay(300);
//  waveform1.begin(WAVEFORM_SINE);
//  waveform1.frequency(440);
//  waveform1.amplitude(0.99);
}


void playSine(){
  waveform1.begin(WAVEFORM_SINE);
  waveform1.frequency(440);
  waveform1.amplitude(0.99);
}


void disableAll(){
    mixer1.gain(0, 0);  //ADC
    mixer1.gain(1, 0);  //waveform1
    mixer1.gain(2, 0);  //not used
    mixer1.gain(3, 0);  //not used


    delay1.disable(0); //direct to mixer2
    delay1.disable(1); //direct to mixer2
    delay1.disable(2); //to reverb1
    delay1.disable(3); //to bitcrusher1
    delay1.disable(4);
    delay1.disable(5);
    delay1.disable(6); //to notefreq1


    mixer2.gain(0, 0);  //ADC
    mixer2.gain(1, 0);  //waveform1
    mixer2.gain(2, 0);  //not used
    mixer2.gain(3, 0);  //not used


    mixer3.gain(0, 0);  //ADC
    mixer3.gain(1, 0);  //waveform1
    mixer3.gain(2, 0);  //not used
    mixer3.gain(3, 0);  //not used    


    mixer4.gain(0, 0);  //ADC
    mixer4.gain(1, 0);  //waveform1
    mixer4.gain(2, 0);  //not used
    mixer4.gain(3, 0);  //not used    


    mixer5.gain(0, 0);  //ADC
    mixer5.gain(1, 0);  //waveform1
    mixer5.gain(2, 0);  //not used
    mixer5.gain(3, 0);  //not used    


    mixer6.gain(0, 0);  //from mixer2
    mixer6.gain(1, 0);  //from mixer3
    mixer6.gain(2, 0);  //from mixer4
    mixer6.gain(3, 0);  //from mixer5


    delay2.disable(0); //to usb1 - R
    delay2.disable(1); //to usb1 - L
    delay2.disable(2); //not used
    delay2.disable(3); //not used
    delay2.disable(4); //not used
    delay2.disable(5); //not used
    delay2.disable(6); //not used
}


void loop() {
if (Serial.available()){
  char c = Serial.read();


//Serial.println(int(c));


switch(int(c)){
  case 114: //ascii r
    Serial.println("sine on right");
    AudioNoInterrupts();
    disableAll();
    mixer1.gain(0, 0);  //ADC
    mixer1.gain(1, 1);  //waveform1
    delay1.delay(0, 0); //right
    mixer2.gain(0, 1);  //from delay1
    mixer6.gain(0, 1);  //from mixer6
    delay2.delay(0, 0); //to usb1 - right
    AudioInterrupts();  
    playSine(); //Start up the sine
  break;


  case 108: //ascii l 
    Serial.println("sine on left");
    AudioNoInterrupts();
    disableAll();
    mixer1.gain(0, 0);  //ADC
    mixer1.gain(1, 1);  //waveform1
    delay1.delay(1, 0);
    mixer2.gain(1, 1);  //from delay1
    mixer6.gain(0, 1);  //from mixer6
    delay2.delay(1, 0);
    AudioInterrupts();
    playSine(); //Start up the sine
  break;


  case 98:
    Serial.println("sine on both channels");
    AudioNoInterrupts();
    disableAll();
    mixer1.gain(0, 0);  //ADC
    mixer1.gain(1, 1);  //waveform1
    delay1.delay(0, 0);
    delay1.delay(1, 0);
    mixer2.gain(0, 1);  //from delay1
    mixer2.gain(1, 1);  //from delay1
    mixer6.gain(0, 1);  //from mixer6
    delay2.delay(0, 0);
    delay2.delay(1, 0);
    AudioInterrupts();
    playSine(); //Start up the sine
  break;


  case 97: //ascii a
    Serial.println("Reverb on both channels");
    AudioNoInterrupts();
    disableAll();
    mixer1.gain(0, 0);  //adc1
    mixer1.gain(1, 1);  //waveform1
    delay1.delay(2, 0); //To Reverb In
    mixer2.gain(2, 1);  //From Reverb Out
    mixer6.gain(0, 1);  //from mixer6
    delay2.delay(0, 0); //to USB R
    delay2.delay(1, 0); //to USB L
    reverb1.reverbTime(0.1);
    AudioInterrupts();
    playSine(); //Start up the sine
  break;


  case 99: //ascii c
    Serial.println("Bitcrusher on both channels");
    AudioNoInterrupts();
    disableAll();
    mixer1.gain(0, 0);  //adc1
    mixer1.gain(1, 1);  //waveform1
    delay1.delay(3, 0); //To bitcrusher1 In
    mixer2.gain(3, 1);  //Bitcrusher1 out
    mixer6.gain(0, 1);  //from mixer6
    delay2.delay(0, 0); //to USB R
    delay2.delay(1, 0); //to USB L
    bitcrusher1.bits(4);
    bitcrusher1.sampleRate(44100);
    AudioInterrupts();
    playSine(); //Start up the sine  
  break;


  case 109: //asci m
    Serial.println("Bitcrusher on both channels");
    AudioNoInterrupts();
    disableAll();
    mixer1.gain(0, 0);  //adc1
    mixer1.gain(1, 1);  //waveform1
    delay1.delay(4, 0); //to notefreq1
    mixer3.gain(0, 1);  //Bitcrusher1 out
    mixer6.gain(1, 1);  //from mixer6
    delay2.delay(0, 0); //to USB R
    delay2.delay(1, 0); //to USB L
    chorus1.begin(c_delayline,CHORUS_DELAY_LENGTH,n_chorus);
    chorus1.voices(n_chorus);
    AudioInterrupts();
    playSine(); //Start up the sine
    
  break;


  case 101: //ascii e
      AudioNoInterrupts();
      disableAll();
      AudioInterrupts();
  break;
}//switch


}//serial.available
}//loop
 
Status
Not open for further replies.
Back
Top