PDA

View Full Version : Apply EQ on different channels in I2S_QUAD



madzo0omadz
05-02-2016, 05:09 AM
Hi guys,

I've been using the Teensy 3.2 along with two Audio shields, following the Quad tutorial shown below:
https://www.sparkfun.com/news/2055

So now I have 2xLineIn, 2xLineOut/headphone. I am trying to apply an Eqalizer for each Line In and output all 4 channels in one Line out. The problem I'm having is that I can't apply independent equalizers to each LineIn. For example, say I have two soundtracks that I want to mix into one, before mixing them I want to apply Bass Booster on music stream 1 and a vocal booster on music stream 2. When I run the code below, it applies Bass Booster to one LineOut(headphone1) and a Vocal Booster to another LineOut(headphone2) and not to the individual input streams themselves. Any idea if this is possible to do on Teensy Quad Audio?

Here is the code:

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


// GUItool: begin automatically generated code
AudioInputI2SQuad i2s_quad1; //xy=377,202
AudioMixer4 mixer1; //xy=629,160
AudioMixer4 mixer2; //xy=631,254
AudioOutputI2SQuad i2s_quad2; //xy=822,214
AudioConnection patchCord1(i2s_quad1, 0, mixer1, 0);
AudioConnection patchCord2(i2s_quad1, 1, mixer2, 0);
AudioConnection patchCord3(i2s_quad1, 2, mixer1, 1);
AudioConnection patchCord4(i2s_quad1, 3, mixer2, 1);
AudioConnection patchCord5(mixer1, 0, i2s_quad2, 0);//change this to 2 to switch to lower headphone jack
AudioConnection patchCord6(mixer2, 0, i2s_quad2, 1);//change this to 3 to switch to lower headphone jack
AudioControlSGTL5000 sgtl5000_1; //xy=162,36
AudioControlSGTL5000 sgtl5000_2; //xy=492,44
// GUItool: end automatically generated code

const int myInput = AUDIO_INPUT_LINEIN;
//const int myInput = AUDIO_INPUT_MIC;


void setup() {
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(50);

// Enable the first audio shield (Music Stream 1), select input, and enable output
sgtl5000_1.setAddress(LOW);
sgtl5000_1.enable();
sgtl5000_1.inputSelect(myInput);
sgtl5000_1.volume(0.75); //0.75
sgtl5000_1.audioPreProcessorEnable();
sgtl5000_1.audioPostProcessorEnable();

// Enable the second audio shield (Music Stream 2), select input, and enable output
sgtl5000_2.setAddress(HIGH);
sgtl5000_2.enable();
sgtl5000_2.inputSelect(myInput);
sgtl5000_2.volume(0.75);
sgtl5000_2.audioPreProcessorEnable();
sgtl5000_2.audioPostProcessorEnable();

//Notes: mixer 1 = left ear, mixer 2 = right ear
// mixer1/2 channel 0 is music stream 1, channel 1 is music stream 2
}


//switch between different Equalizer modes:
int mode=2;

void loop() {
if (mode == 1) {
//Bass boost Stream 1, Bass reducer on Stream 2; mode 1
//gains
mixer1.gain(0,0.75);
mixer2.gain(0,0.75);
mixer1.gain(1,0.75);
mixer2.gain(1,0.75);

//Change Equalizer

//Music Stream 1 (upper Teensy Audio board); add bass boost to it
sgtl5000_1.eqSelect(3);
sgtl5000_1.eqBands(1,1,-1,0,0);

//Music Stream 2 (Lower Teensy Audio board); remove bass from it
sgtl5000_2.eqSelect(3);
sgtl5000_2.eqBands(-1,-1,1,-1,-1);

}

}

Ardaudio
05-02-2016, 11:07 AM
My guess is that you can't have audioPreProcessorEnable() and audioPostProcessorEnable() active at the same time for the same sgtl5000.

As you call them in sequence, only the Post is active. I suggest you try the same code without the audioPostProcessorEnable()

WMXZ
05-02-2016, 11:58 AM
My guess is that you can't have audioPreProcessorEnable() and audioPostProcessorEnable() active at the same time for the same sgtl5000.

As you call them in sequence, only the Post is active. I suggest you try the same code without the audioPostProcessorEnable()

when using I2S_Quad, there are two different audio boards and consequently two different SGTL5000s.
So it should be possible to control the signal processing of the two audio boards independently.

Ardaudio
05-02-2016, 12:16 PM
I'm sorry. Probably, I wasn’t very clear in what I wrote.

I was referring to these two lines of code

sgtl5000_1.audioPreProcessorEnable();
sgtl5000_1.audioPostProcessorEnable();

and these two

sgtl5000_2.audioPreProcessorEnable();
sgtl5000_2.audioPostProcessorEnable();

As I said, I may be wrong but I suspect the audioPostProcessorEnable() nullifies the audioPreProcessorEnable() that is called just before.

In other words, calling
sgtl5000_1.audioPreProcessorEnable();
sgtl5000_1.audioPostProcessorEnable();

is functionally equivalent to:
sgtl5000_1.audioPostProcessorEnable();

PaulStoffregen
05-02-2016, 12:36 PM
You could do preprocessing on 2 channels in one SGTL5000 and postprocessing on 2 channels in the other. But you can't have both on the same chip, because there's only 1 digital signal processor unit inside each SGTL5000.

If you check out the SGTL5000 datasheet, you'll see the chip has a number of ways to route the signals internally. Rob Soles wrote much of the SGTL5000 support code. One of the really challenging parts, which changed several times in the early audio lib days, was how to represent such complex configurable hardware as something worthy of Arduino's simplicity. Very early versions closely mirrored the SGTL5000 registers. That was simplified to a "route" function that let you reprogram the chip's internal routing. But even that was quite complex and required understanding the chip's internal signal structure. When it came time to write the documentation (which the many SGTL5000 functions too most of my time...), I decided to further simplify the API. While you could do various routing stuff, really the only 2 scenarios that made sense where multiple routes to use the signal processor for preprocessing of input before Teensy gets the data, or postprocessing Teensy's output before it gets to the DAC.

Hopefully this has made the SGTL5000 object easier to understand and use. But perhaps along the way we lost the view that it's really just one signal processing unit inside a chip with flexible signal routing?

madzo0omadz
06-26-2016, 02:01 AM
Hey guys, thank you so much for the great input. All I had to do was enable the "Pre-Processor" and adjust the incoming signal before mixing the channels. Just to spread the tips of using this amazing Audio shield, here is a work around that I did in case the solution above doesn't work for your Audio application:
7471

I pretty much added different filters to the inputs, each filter I'd define its cutoff frequency and if it's a bass pass, a treble pass or mid-range pass and then build up the augmented sound through mixing the sounds desired. I do not recommend this method except as a last resort if the pre-made functions by Paul didn't work for you.