Teens 4.0 + AudioShield Rev D - Connections inside of functions.

Status
Not open for further replies.

hvlmnns

Member
Hey,
My project requires dynamic routing of effects and mixers.
So the naive me tried to make the connections inside a function (setup in this case)
I just moved the two AudioConnections from global scope to the setup function.

But this breaks the library and I'm not hearing an output anymore.
Is there a way to make dynamic connections on the go?
Am I just missing a Audio.init() or something?

thx for the help,
hvlmnns

Code:
// Advanced Microcontroller-based Audio Workshop
//
// http://www.pjrc.com/store/audio_tutorial_kit.html
// https://hackaday.io/project/8292-microcontroller-audio-workshop-had-supercon-2015
//
// Part 1-3: First "Hello World" program, play a music file
//
// WAV files for this and other Tutorials are here:
// http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html

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

AudioPlaySdWav playSdWav1;
AudioOutputI2S i2s1;
AudioControlSGTL5000 sgtl5000_1;

// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 11
#define SDCARD_SCK_PIN 13

// Use these with the Teensy 3.5 & 3.6 SD card
//#define SDCARD_CS_PIN    BUILTIN_SDCARD
//#define SDCARD_MOSI_PIN  11  // not actually used
//#define SDCARD_SCK_PIN   13  // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN    4
//#define SDCARD_MOSI_PIN  11
//#define SDCARD_SCK_PIN   13

void setup()
{
  Serial.begin(9600);

  // THIS WAS OUTSIDE SETUP BEFORE
  AudioConnection patchCord1(playSdWav1, 0, i2s1, 0);
  AudioConnection patchCord2(playSdWav1, 1, i2s1, 1);
  // THIS WAS OUTSIDE SETUP BEFORE

  AudioMemory(8);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN)))
  {
    while (1)
    {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  delay(1000);
}

void loop()
{
  if (playSdWav1.isPlaying() == false)
  {
    Serial.println("Start playing");
    playSdWav1.play("SDTEST2.WAV");
    delay(10); // wait for library to parse WAV info
  }
  // do nothing while playing...
}
 
Usually the best approach is to use the mixer and amp with gain of 0.0 and 1.0. Zero gain is handled as turning off the flow of data, and gain of 1.0 passes data through without any math, so it really does act as a switch.

The AudioConnection objects do support .connect() and .disconnect(), but they're not designed to be created as local variables.
 
Can I easily modify them to be used as such?
I need my effects to be ordered b the user, and that's not possible if it's all hardwired on the global scope.

My end goal is to have 16 looped channels with 16 effects per channel.
So for me, I would prefer to work with structs and setup functions.
 
Can I easily modify them to be used as such?

All the source code is in the audio lib and core lib, so you certainly can try to modify it.

Whether that's considered "easily" really depends upon you - how good your programming skill is and what sort of tasks you consider easy versus difficult. ;)
 
I was aiming at: "is the library coded in a way to extend modify it".
If there are a lot of cross dependencies to the connections id rather ask for it as a feature implementation than doing it myself :D
 
To be specific. Since you are the main creator of that library i would kindly ask you to point me to a direction where and why the connection can't be changed in a local scope.
 
To be specific.

All the audio library depends on cores/AudioStream.cpp and the audio library. IMHO, you can only change scope of connections, if you understand how it is working now. I assume you are fluent in C++ so that would not be an issue for you.
 
I'm just concerned this might break stuff I'm not aware of since it was designed that way because of a reason I guess.
 
Before you dive into AudioStream.cpp, maybe try creating and destroying audio connections on the heap with C++ new / delete.

Again, do not create these objects on the stack (eg, local variables) as your code in msg #1. That is absolutely the wrong way!


I'm just concerned this might break stuff I'm not aware of since it was designed that way because of a reason I guess.

Oh, I'm sure you'll break plenty as you learn how things work. That's the normal way of things...
 
Code:
AudioPlaySdWav playSdWav1;
AudioPlaySdWav playSdWav2;
AudioOutputI2S i2s1;
AudioConnection *conn1 = new AudioConnection(playSdWav1, 0, i2s1, 0);
AudioConnection *conn2 = new AudioConnection(playSdWav1, 1, i2s1, 1);

void setup()
{
  Serial.begin(9600);
  delay(10000);
  // THIS WAS OUTSIDE SETUP BEFORE
  delete conn1;
  delete conn2;
  AudioConnection *conn1 = new AudioConnection(playSdWav2, 0, i2s1, 0);
  AudioConnection *conn2 = new AudioConnection(playSdWav2, 1, i2s1, 1);
  // THIS WAS OUTSIDE SETUP BEFORE
  delay(1000);

this does not work either.
 
Please follow the "Forum Rule" (in red at the top of every page) when something doesn't work. There could be many reasons why that code isn't working, but nobody can help if you don't show enough of the code.

But, to prove this does indeed work, here is a complete program you can copy into Arduino and run on your Teensy to see (hear) it in action.

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

AudioPlaySdWav playSdWav1;
AudioOutputI2S i2s1;
AudioControlSGTL5000 sgtl5000_1;

AudioConnection *patch1, *patch2;

#define SDCARD_CS_PIN 10

void setup()
{
  Serial.begin(9600);
  AudioMemory(8);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  delay(1000);
}

void loop()
{
  if (playSdWav1.isPlaying() == false) {
    Serial.println("Start playing");
    playSdWav1.play("SDTEST2.WAV");
    delay(10); // wait for library to parse WAV info
  }
  // while playing, demonstrate that we can create and destroy connections

  Serial.println("Create connections");
  patch1 = new AudioConnection(playSdWav1, 0, i2s1, 0);
  patch2 = new AudioConnection(playSdWav1, 1, i2s1, 1);
  delay(5000);  // 5 seconds with connections

  Serial.println("Destroy connections");
  delete patch1;
  delete patch2;
  delay(2000);  // 2 seconds without
  
}

Please, post complete programs when saying something doesn't work. We can help you much better that way.
 
Status
Not open for further replies.
Back
Top