( still Newbie) question about audio flow and mixing/audio behavior.

Status
Not open for further replies.

Danny123

Member
Hi Team,

Ive got a smal test project going on, and its not quite clear to me, on how to handle the behavior that its giving me (or the results, and that has more to do with my skills than the teensy :))

what i try to achieve is a audio mixer with left input and right input (audio) aswel as a L&R audio output. seperated from eachother.

with button1 i trigger the left side to active, as for button2 the right. this works fine with no specialties.

but i wanted to make the left side overruling the right side, so if i press button1, the right side should remain off (or silent or low, bassicly do nothing because the left side is active).

the question is : how to go forward from here? and what to learn or take further notice of?
ive tried allot, and this code is the most basic version that works like a normal mixer with no specials or extra's.
ive tryed bouncing the buttons, worked with millis, even made the leftinput to a interrupt that it must be the master channel. but not getting the correct result and leads to no audio, or crackling audio of both sides,

to simplify its purpose of function : if button1 is pressed > turn on mixer1 and turn on led1(leftoutput)
if button2 is pressed > turn on mixer2 and turn on led2(Rightoutput)
but if button1 is active turn mixer2 en Led2(rightoutput) low (off) even if button2 is pressed.

Thnx in advance
Yours
Danny

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

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=299,207
AudioMixer4              mixer2;         //xy=503,273
AudioMixer4              mixer1;         //xy=504,130
AudioOutputI2S           i2s2;           //xy=676,193
AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
AudioConnection          patchCord2(i2s1, 1, mixer2, 0);
AudioConnection          patchCord3(mixer2, 0, i2s2, 1);
AudioConnection          patchCord4(mixer1, 0, i2s2, 0);
AudioControlSGTL5000     sgtl5000_1;     //xy=745,489
// GUItool: end automatically generated code



const int ledPin =  LED_BUILTIN;// the number of the LED pin
int ledState3 = LOW;             // ledState used to set the LED
unsigned long previousMillis3 = 0;        // will store last time LED was updated
const long interval = 1000;           // interval at which to blink (milliseconds)

const int leftInput = 0; //pinout op de Teensy
const int leftOutput = 1; //pinout op de Teensy
const int rightInput = 2; //pinout op de Teensy
const int rightOutput = 3; //pinout op de Teensy


void setup() {

  pinMode(ledPin, OUTPUT);

  pinMode (leftInput, INPUT_PULLUP);
  pinMode (leftOutput, OUTPUT);
  pinMode (rightInput, INPUT_PULLUP);
  pinMode (rightOutput, OUTPUT);
  digitalWrite(leftOutput, LOW);
  digitalWrite(rightOutput, LOW);

  AudioMemory(10);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.6);
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);

  mixer1.gain(0, 0.0); //audio input 1
  mixer2.gain(0, 0.0); //audio input 3

  delay(500);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void controleLed () {
  unsigned long currentMillis3 = millis();
  if (currentMillis3 - previousMillis3 >= interval) {
    previousMillis3 = currentMillis3;
    if (ledState3 == LOW) {
      ledState3 = HIGH;
    } else {
      ledState3 = LOW;
    }
    digitalWrite(ledPin, ledState3);
  }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {
  controleLed ();

  if (digitalRead(leftInput) == LOW) {
    digitalWrite(leftOutput, HIGH);
    mixer1.gain(0, 0.6); //audio input 1
    
  }

  if (digitalRead(leftInput) == HIGH) {
    digitalWrite(leftOutput, LOW);
    mixer1.gain(0, 0.0); //audio input 1
  }


  if (digitalRead(rightInput) == LOW) {
    digitalWrite(rightOutput, HIGH);
    mixer2.gain(0, 0.6); //audio input 1
  }

  if (digitalRead(rightInput) == HIGH) {
    digitalWrite(rightOutput, LOW);
    mixer2.gain(0, 0.0); //audio input 1
  }
}
 
I think you need to detect the button _changing_ state, not continually use its current state, and thus trigger the
action when its pressed only.

Then you simply need the state change code to set the gains for both left and right, as you don't want L and R
to be independently controlled as with the current code.

So left button pressed, set left gain 0.6, right gain 0.0, and vice versa?
 
Hi Mark, thnx for the answer,
its a bit difficult, because if the left side stops its audio (or button released) and the right side was or is active (but was called off by the overruling of the left side) it has to be active right away again.

so is it possible that the LOW statement is giving me these audio-artefacts?? and that perhaps a detection with say Falling OR Fallingedge and then do a certain action would be a better sollution?
i dont know how to explain it a bit, but if i am correct and the sketch is so called "polling" couldt this then cause the hearable crackling in the audiosignal? because the teensy contiously reads its pin-statement high or low, together with a second command? (but offcoarse it cant do these at the same time)

or is it perhaps a better idea to make the rightside function in the loop (as a normal operation mode) and give the leftside a sort of interrupt function?

thnx in advance
(o ps, using the T4.0 + audiobreakoutboard)
 
you can build a truth table
where LOW state of the buttons mean that it's pressed ie. active low
Code:
Lbtn  Rbtn  L  R    
-------------------
0      0    1  0
0      1    1  0
1      0    0  1
1      1    0  0

then you read states like this
Code:
void loop()
{
     // digitalRead returns a byte (uint8_t) 
    byte Rbtn = digitalRead(rightInput); 
    byte Lbtn = digitalRead(leftInput); 

    if ((Rbtn == 0) && (Lbtn == 1))
    {
         digitalWrite(rightOutput, HIGH);
         mixer2.gain(0, 0.6); //audio input 1
    }
    else
    {
          digitalWrite(rightOutput, LOW);
          mixer2.gain(0, 0.0); //audio input 1
    }

    if (Ltbn == 0) // don't matter what state Rbtn have
    {
         digitalWrite(leftOutput, HIGH);
         mixer1.gain(0, 0.6); //audio input 1
    }
    else
    {
          digitalWrite(leftOutput, LOW);
          mixer1.gain(0, 0.0); //audio input 1
    }
}
but I think it could be better if you used two AudioEffectFade
in that way you can define a smooth translation between on and off

using AudioEffectFade:
fadeIn(milliseconds);
fadeOut(milliseconds);
 
Last edited:
its a bit difficult, because if the left side stops its audio (or button released) and the right side was or is active (but was called off by the overruling of the left side) it has to be active right away again.
Can you set down your desired button behaviour as a state-machine? That will make the coding straightforward as
all the detail is in getting the state transitions as you want them - every part of the behaviour becomes explicit
in such a diagram if you consider what should happen for every input event in every state.

Interrupts are completely not relevant - that's for urgent (microsecond) hardware response, not UI.
 
to analyze if a audio signal is active you can use
AudioAnalyzeRMS rms1;
connected to the left input signal

by polling it with rms1.available(); and then read the RMS value with rms1.read(); to compare that to a level that you can define as off
 
Hi Team, I've think i found out what was going on, and how to solve the isseus i was running in at.
I think first a thanks to MarkT, the first replay got me thinking, and pointed me to the right direction. and found a solution that i didnt try before. to check the falling/rising edges of the buttons and take actions from there, in stead of keeping the button LOW.
also implemented it with the Bounce-lib to make it a bit more stable, and the first test was an great succes. this gives me a great foundation to carry on from here. Thnx :) i guess a simple way to describe my issue is that wenn u use youre finger to turn off the bathroom-lights, where "LOW" is keeping youre finger on the button wenn the lights are allready off and u mis a hand to do other things, and and buttonstate-checking lets it describe as flicking the bathroomlight switchs to off and u have youre hand free again for other things (if this is a bit of a correct explaination of what happens ;-)) briljant-briljant this quest, it took me a week to finaly let it go and ask.

Other question that ive got, (@ ManickSan)
is about the Fade-ins/outs

using AudioEffectFade:
fadeIn(milliseconds);
fadeOut(milliseconds);

is this usable everytime one of the audio mixers become true or active? just to avoid pops and clicks at the start of ending of the audio-path.

thnx
 
You are toggling the "state" when pressing buttons?

The Fade Effect make sure that the signal don't get from zero to max at a short time,
to describe it better (when the pop most notable):
if the input signal is at it's maximum and you just turn the signal on you get a sudden rise of the output signal and this can be heard as a pop or click
there could be other reasons as well
but I think it's best just to try it and see if it helps.

When working with a physical mixer u fade in/out the mixers with the sliders,
and the buttons should have some pop/click suppression stuff
 
Hi Manicksan,
if i understand your question correct, now i use the Toggle, first i only used the digitalRead/Write to give a LOW or HIGH command, so at first this works or it looks like it works, when a test is been done with leds, but when using audio with it, it gives a hearable crackling noise, i did had a couple of lucky shots with it, that it did as i wanted, but somewhere i couldnt believe it was the correct way for my project, and when i started to get a bit deeper, and wanted to add additional actions, it only became worse.

I wil try the audio-fades, this is a briljant thing to do, just to clean it up a bit and avoid the plops :) (is there a special library needed or is standard available?)

Thnx
 
So basically ive got the code up&running,
but encountert an issue in audio routing, and i am not sure if i am asking it to do something impossible, or something that the hardware simply cant handle.

Ive added a timerfunction (millis) on the left input button, that if the button has been released, an 5 second timer gets triggert, if in this period the right button is pressed, i wanted to route the audio both to the left and right outputs.

So ive made an loopback function in the pjrc-audio disign tool, from the mixer2 output to the mixer1(1) input,
so that the audio from the mixer 2, is hearable on both speakers instead of only the right one.
(if ptt-timer && rightintput == true) than do : mixer1.gain(1,0.6)

Did some small and simple tests, but it didnt do this smoothly, and with crackling audio as a result,

is this even possible? or (i hope) am i overlooking somthing?

Thnx in advance
Danny
 
Pfoe,,,, got it,,

in the pjrc-audio tool, i also could draw a second line from the i2s1 to mixer input one, and made this active when the timer is on, this lets the right-side stream its audio flawlessly to the left side,
(still learning every day with this)

if i may thnk for pointing me to the right direction, sometimes just asking the question clears the mind, and one finds the solution not much later :)

Thnx
Danny
(and hopefully to hear every one again @ the next round of questions)
 
Status
Not open for further replies.
Back
Top