changing patchcords in the loop?

Status
Not open for further replies.

manatee

Active member
Hello,

Is it possible to change patchcord connections during loop?
If so, how would i do this?

Thanks in advance!
 
Use connect() & disconnect() on existing audio connection objects by adhering to the following:

Instantiate all possible AudioConnections needed in the project(in the global scope, as usual). Multiple sources to one destination is ok.
In Setup() disconnect all AudioConnections except the ones that will never change, before enabling the audio engine.
In loop() connect and disconnect all you want while still following the connection rules & guidelines.
Code:
#include <Audio.h>

AudioSynthWaveformSine   sine4;
AudioSynthWaveformSine   sine1;
AudioSynthWaveformSine   sine2;
AudioSynthWaveformSine   sine3;
AudioMixer4              mixer1;
AudioMixer4              mixer2;
AudioOutputI2S           i2s1;
AudioOutputAnalogStereo  dacs1;
AudioConnection          patchCord1(sine1, 0, mixer1, 0);
AudioConnection          patchCord2(sine2, 0, mixer1, 0);
AudioConnection          patchCord3(sine3, 0, mixer1, 0);
AudioConnection          patchCord4(sine4, 0, mixer1, 0);
AudioConnection          patchCord5(sine4, 0, mixer2, 3);
AudioConnection          patchCord50(mixer1, 0, i2s1, 0);
AudioConnection          patchCord51(mixer2, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;

void setup() {
  
  patchCord1.disconnect();
  patchCord2.disconnect();
  patchCord3.disconnect();
  patchCord4.disconnect();
  patchCord5.disconnect();
  
  AudioMemory(10);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  sine1.frequency(500);
	sine1.amplitude(1.0);
  sine2.frequency(1000);
	sine2.amplitude(1.0);
  sine3.frequency(1500);
	sine3.amplitude(1.0);
  sine4.frequency(2000);
	sine4.amplitude(1.0);

}
const uint t = 1250; 
void loop() {
  patchCord1.connect();
  delay(t);
  patchCord1.disconnect();
  patchCord5.disconnect();
  patchCord2.connect();
  delay(t);
  patchCord2.disconnect();
  patchCord3.connect();
  delay(t);
  patchCord3.disconnect();
  patchCord4.connect();
  patchCord5.connect();
  delay(t);
  patchCord4.disconnect();
  
}
Or dynamically create/delete audio connection objects at runtime.
Code:
#include <Audio.h>

AudioSynthWaveformSine   sine1;
AudioSynthWaveformSine   sine2;
AudioSynthWaveformSine   sine3;
AudioSynthWaveformSine   sine4;
AudioMixer4              mixer1;
AudioOutputI2S           i2s1;
AudioConnection*         patchCord1;
AudioConnection          patchCord50(mixer1, 0, i2s1, 0);
AudioConnection          patchCord51(mixer1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;

void setup() {
  
  AudioMemory(10);
  // delay(2000);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  sine1.frequency(500);
	sine1.amplitude(1.0);
  sine2.frequency(1000);
	sine2.amplitude(1.0);
  sine3.frequency(1500);
	sine3.amplitude(1.0);
  sine4.frequency(2000);
	sine4.amplitude(1.0);

  patchCord1 = new AudioConnection(sine1, 0, mixer1, 0);
}

const uint t = 1250; 
void loop() {
  delay(t);
  delete patchCord1;
  patchCord1 = new AudioConnection(sine2, 0, mixer1, 0);
  delay(t);
  delete patchCord1;
  patchCord1 = new AudioConnection(sine3, 0, mixer1, 0);
  delay(t);
  delete patchCord1;
  patchCord1 = new AudioConnection(sine4, 0, mixer1, 0);
  delay(t);
  delete patchCord1;
  patchCord1 = new AudioConnection(sine1, 0, mixer1, 0);
  
}
 
Thank you for your reply!Your code ran smoothly.

I thought i understood how it works but i'm getting glitchy/distorted sinewaves with this simple switch case code based on your code.

I have a push button on pin 10 and six leds to flag each switch case.
Any ideia what i'm doing wrong?

Thanks in advance!


Code:
#include <Bounce.h>
#include <Audio.h>

AudioSynthWaveformSine   sine1;
AudioSynthWaveformSine   sine2;
AudioSynthWaveformSine   sine3;
AudioSynthWaveformSine   sine4;
AudioMixer4              mixer1;
AudioOutputI2S           i2s1;
AudioConnection*         patchCord1;
AudioConnection          patchCord50(mixer1, 0, i2s1, 0);
AudioConnection          patchCord51(mixer1, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;

const int mode = 10;

Bounce pushbutton = Bounce(mode, 10);

byte previousState = HIGH;         // what state was the button last time
unsigned int count = 1;            // how many times has it changed to low
unsigned long countAt = 0;         // when count changed
unsigned int countPrinted = 0;     // last count printed

const int ledPin1 =  5; 
const int ledPin2 =  6; 
const int ledPin3 =  9; 
const int ledPin4 =  2; 
const int ledPin5 =  3; 
const int ledPin6 =  4; 


void setup() {

  pinMode(mode, INPUT);
  
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin5, OUTPUT);
  pinMode(ledPin6, OUTPUT);  
  
  AudioMemory(10);
  
  // delay(2000);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  sine1.frequency(500);
  sine1.amplitude(1.0);
  sine2.frequency(1000);
  sine2.amplitude(1.0);
  sine3.frequency(1500);
  sine3.amplitude(1.0);
  sine4.frequency(2000);
  sine4.amplitude(1.0);

  patchCord1 = new AudioConnection(sine1, 0, mixer1, 0);
  
}

  
void loop() {

  if (pushbutton.update()) {
    if (pushbutton.fallingEdge()) {
      count = count + 1;
      countAt = millis();
    }
  } else {
    if (count != countPrinted) {
      unsigned long nowMillis = millis();
      if (nowMillis - countAt > 100) {
        countPrinted = count;
      }
    }
  }

  if (count ==7){
    count =1;}

    switch (count) {
      case 1:
        digitalWrite(ledPin1, HIGH);
        digitalWrite(ledPin6, LOW); 
  
  delete patchCord1;
  patchCord1 = new AudioConnection(sine2, 0, mixer1, 0);
        
        break;
        
      case 2:
        digitalWrite(ledPin2, HIGH);
        digitalWrite(ledPin1, LOW); 

  delete patchCord1;
  patchCord1 = new AudioConnection(sine3, 0, mixer1, 0);
       
        break;
      
      case 3:
      
        digitalWrite(ledPin3, HIGH); 
        digitalWrite(ledPin2, LOW); 
  
  delete patchCord1;
  patchCord1 = new AudioConnection(sine4, 0, mixer1, 0);
      
        break;
      
      case 4:
      
        digitalWrite(ledPin4, HIGH); 
        digitalWrite(ledPin3, LOW); 

  delete patchCord1;
  patchCord1 = new AudioConnection(sine1, 0, mixer1, 0);
      
        break;
      
      case 5:
        digitalWrite(ledPin5, HIGH); 
        digitalWrite(ledPin4, LOW); 
      
        break;
      
      case 6:
        digitalWrite(ledPin6, HIGH); 
        digitalWrite(ledPin5, LOW); 
      
        break;
    }
  
}
 
Last edited by a moderator:
Your switch statement is being executed every iteration of the loop which means you are constantly un-patching patching the cord.
The switch statement should only be executed once for every button press!
 
I wonder if it’s really necessary to create all the AudioConnection objects that way? I think you could create an array of pointers:

AudioConnection *cables[16]; // 16, for example

And create the connections as needed using ‘new’.

My interest in Teensy is mostly about building synth devices, and it seems people mostly use the Audio system Design Tool, which is quite handy, but gets awkward, for instance, when you try to make a polyphonic synth with more than a few voices.

A more flexible mixer would be nice, too.

In general, attempting to build something where you must create unique names at compile time doesn’t scale well, and is kind of the reason for arrays, structs, and classes.
 
In my experience gcc does a particularly poor job of handling heap fragmentation. I would avoid new/delete (as well as malloc()/free()) as much as possible unless you are absolutely certain that you will be deallocating objects in exactly the reverse order of allocating them.
 
Fragmentation is a different issue from imbalanced new/delete and malloc/free. And dynamic memory is handled by the library, not GCC itself.

Yes, fragmentation can be an issue, but sloppy programming causing memory leaks is more common.

But my point was more about the problems using statically defined and individually named objects, in an application where things naturally group together (e.g. a voice can be considered one or more oscillators, filter, envelope, maybe mixer, working as one) . Much cleaner to create a class for Voice, and an array of those for polyphony. Which gets to the question, how to manage the interconnections?

Manually creating all possible connections becomes impractical beyond a small level of polyphony.

And even if you distrust dynamic memory when used arbitrarily over the runtime of a program, that doesn’t mean it’s not safe to use during initialization, to create the mesh of connections programmatically .
 
Status
Not open for further replies.
Back
Top