Is it possible to frequently change the SGTL5000 input select from mic to line?

Status
Not open for further replies.
I am attempting to make a two channel recorder that can handle mic or line level. I need to be able to switch between the object AudioControlSGTL5000 from inputs AUDIO_INPUT_LINEIN and AUDIO_INPUT_MIC frequently because I am recording in real time. I attached my code. Should there be any technical issue with this? It's not working as is but it could be something else that I'm not catching.
Code:
#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <XPT2046_Touchscreen.h>
#include <ILI9341_t3.h>


AudioInputI2S            i2s2;           
AudioAnalyzePeak         peak1;  
AudioAnalyzePeak         peak2;   
AudioRecordQueue         queue1;         
AudioRecordQueue         queue2; 
AudioPlaySdRaw           playRaw1;       
AudioOutputI2S           i2s1;  
AudioMixer4              Channel1_mixer;
AudioMixer4              Channel2_mixer;        
AudioMixer4              Channel12_mixer;
AudioMixer4              Channel22_mixer;  
AudioConnection          patchCord1(i2s2, 0, Channel1_mixer, 0);
AudioConnection          patchCord12(i2s2, 0, Channel12_mixer, 0);
//AudioConnection          patchCord1(i2s2, 0, queue1, 0);
AudioConnection          patchCord2(i2s2, 0, peak1, 0);

AudioConnection          patchCord3(i2s2, 1, Channel2_mixer, 1);
//AudioConnection          patchCord32(i2s2, 1, Channel22_mixer, 1);
//AudioConnection          patchCord3(i2s2, 1, queue2, 0); 
AudioConnection          patchCord4(i2s2, 1, peak2, 0);
AudioConnection          patchCord5(playRaw1, 0, i2s1, 0);
AudioConnection          patchCord6(playRaw1, 1, i2s1, 1);
AudioConnection          patchCord7(Channel1_mixer, 0, queue1, 0); 
AudioConnection          patchCord8(Channel2_mixer, 1, queue2, 0);
AudioConnection          patchCord9(Channel22_mixer, 0, i2s1, 0); 
AudioConnection          patchCord10(Channel12_mixer, 0, i2s1, 1); 
AudioControlSGTL5000     sgtl5000_1;     

#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000

// The STMPE610 uses hardware SPI on the shield, and #8
#define STMPE_CS 8

// The display also uses hardware SPI, plus #9 & #10
#define TFT_RST 255
#define TFT_MOSI 7
#define TFT_SCLK 14
#define TFT_MISO 12
// For the Adafruit shield, these are the default.
#define TFT_DC 20
#define TFT_CS 21


// which input on the audio shield will be used?
const int myInput = AUDIO_INPUT_LINEIN;
const int myInput2 = AUDIO_INPUT_MIC;


// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN    10
#define SDCARD_MOSI_PIN  7
#define SDCARD_SCK_PIN   14

// PCB stuff
#define PCB_POT_1_CS     26
#define PCB_POT_2_CS     31
#define SPICLOCK         30000000


// Remember which mode we're doing
int recording = 0;  // 0=stopped, 1=recording, 2=playing
int playing = 0;
int play_tracks[2];

// The file where data is recorded
File frec, frec2;
int x;
int y;
int counter;
char curr_menu = 'R';
int was_touched_flag = 0;
int can_scroll_down = 0;
int can_scroll_up = 0;
char* files[26];
int pots[2];
int selbutton1 = 1;   //select button for line 1 
int selbutton2 = 1;   //select button for line 2 


int num_files = 0, scroll_offset = 0;
ILI9341_t3 tft(TFT_CS, TFT_DC, 255, TFT_MOSI, TFT_SCLK, TFT_MISO);
XPT2046_Touchscreen ts(STMPE_CS);
int tracks[4];
int pot_vals[48] = {4099, 5895, 4360, 3080, 2312, 1, 4374, 6954, 2837, 1550, 2328, 8806, 3374, 1041, 2086, 2614, 2622, 3419, 2376, 266, 1066, 1339, 1616, 1626, 1092, 276, 1388, 1402, 1134, 861, 582, 296, 900, 1222, 935, 637, 327, 670, 689, 356, 736, 382, 398, 415, 434, 456, 480, 508};


void setup() {
  Channel12_mixer.gain(0,3);
  Channel22_mixer.gain(3,0);
  pinMode(32,OUTPUT);
  digitalWrite(32, HIGH);
  

  play_tracks[0] = 0;
  play_tracks[1] = 0;
  tracks[0] = 0;
  tracks[1] = 0;
  tracks[2] = 0;
  tracks[3] = 0;
  Serial.begin(9600);
  while(!Serial); // Wait for the serial to work
  tft.begin();
  if (!ts.begin()) {
    Serial.print("TS not connected.");
    while (1);
  }
  display_top();
  display_record_menu();

  // Audio connections require memory, and the record queue
  // uses this memory to buffer incoming audio.
  AudioMemory(60);

  // Enable the audio shield, select input, and enable output
  sgtl5000_1.enable();
  //sgtl5000_1.inputSelect(myInput);
  sgtl5000_1.volume(0.4);
  sgtl5000_1.micGain(30); 

  // Initialize the SD card
  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here if no SD card, but print a message
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
 // Enable the audio shield, select input, and enable output
  pinMode(A17,INPUT);
  pinMode(A18,INPUT);
  pots[0] = analogRead(A17);
  pots[1] = analogRead(A18);
  Serial.println(pots[0] / 333.0);
  Serial.println(pots[1] / 333.0);
  Channel1_mixer.gain(0, pots[0] / 333.0);
  Channel2_mixer.gain(1, pots[1] / 333.0);
  Channel12_mixer.gain(0, pots[0] / 333.0);
  Channel22_mixer.gain(1, pots[1] / 333.0);
}


void loop() {
//  Serial.println(analogRead(A17));
//  delay(2000);
  TS_Point p = ts.getPoint();
    if (!ts.bufferEmpty() && ts.touched()) {
        delay(150);
        //Serial.print(p.x); Serial.println(p.y);
        flag_resp(p.x,p.y);
        //need to add button in flag response to check for selbutton1 and selbutton 2 
    }

  // If we're playing or recording, carry on...
  if (recording) {
    continueRecording();
  }
  if (playing) {
    continuePlaying();
  }
  if (abs(pots[0] - analogRead(A17)) > 23) {
    pots[0] = analogRead(A17);
    Serial.println(pots[0] / 333.0);
    //Channel1_mixer.gain(0, pots[0]);
    Channel12_mixer.gain(0, pots[0] / 333.0);    
    Channel1_mixer.gain(0, pots[0] / 333.0);
  }
  if (abs(pots[1] - analogRead(A18)) > 23) {
    pots[1] = analogRead(A18);
    Serial.println(pots[1] / 333.0);
    // Channel2_mixer.gain(1, pots[0] / 333.0);
    Channel22_mixer.gain(1, pots[1] / 333.0);
    Channel2_mixer.gain(1, pots[1] / 333.0);
  }
  
  
}


void startRecording() {
  Serial.println("startRecording");

  //check for flag if file 1 or file 2 has been pressed 
  Serial.println(tracks[0]);
  Serial.println(tracks[1]);
  if (tracks[0]){
    if (selbutton1 == 0){
      sgtl5000_1.inputSelect(myInput);  //line level 
    }
    else{
      sgtl5000_1.inputSelect(myInput2); //mic level 
    }
  if (SD.exists("RECORD.RAW")) {
    // The SD library writes new data to the end of the
    // file, so to start a new recording, the old file
    // must be deleted before new data is written.
    SD.remove("RECORD.RAW");
  }
     frec = SD.open("RECORD.RAW", FILE_WRITE);
     if (frec) {
      queue1.begin();
      recording = 1;
    } else {
       tft.fillRoundRect(105, 45, 120, 60, 5, ILI9341_RED);
        tft.setCursor(135, 65);
        tft.println("SD CARD ERR");
        delayMicroseconds(2000000);
        display_record_menu();  }
  }
 
  if (tracks[1]){
    if (selbutton2 == 0){
      sgtl5000_1.inputSelect(myInput);  //line level 
    }
    else{
      sgtl5000_1.inputSelect(myInput2); //mic level 
    }
  if (SD.exists("RECORD1.RAW")) {
    SD.remove("RECORD1.RAW");
  }
     frec2 = SD.open("RECORD1.RAW", FILE_WRITE);
     if (frec2) {
      
      Serial.println("in Record1");
      queue2.begin();
      recording = 1;
    } else {
      Serial.println("hey");
       tft.fillRoundRect(105, 45, 120, 60, 5, ILI9341_RED);
        tft.setCursor(135, 65);
        tft.println("SD CARD ERR");
        delayMicroseconds(2000000);
        display_record_menu();  
      }
  }
}

void continueRecording() {
  //if first track is enabled 
  if (tracks[0]){
    if (selbutton1 == 0){
      sgtl5000_1.inputSelect(myInput);  //line level 
    }
    else{
      sgtl5000_1.inputSelect(myInput2); //mic level 
    }
    if (queue1.available() >= 2) {
      byte buffer[512];
      memcpy(buffer, queue1.readBuffer(), 256);
      queue1.freeBuffer();
      memcpy(buffer+256, queue1.readBuffer(), 256);
      queue1.freeBuffer();
      // write all 512 bytes to the SD card
      elapsedMicros usec = 0;
      frec.write(buffer, 512);
    }
  }
  //If 2nd track is enabled 
  if (tracks[1]){
    if (selbutton2 == 0){
      sgtl5000_1.inputSelect(myInput);  //line level 
    }
    else{
      sgtl5000_1.inputSelect(myInput2); //mic level 
    }
    //Serial.println("ContinueRecording for track 2");
    if (queue2.available() >= 2) {
    byte buffer[512];
    memcpy(buffer, queue2.readBuffer(), 256);
    queue2.freeBuffer();
    memcpy(buffer+256, queue2.readBuffer(), 256);
    queue2.freeBuffer();
    // write all 512 bytes to the SD card
    elapsedMicros usec = 0;
    frec2.write(buffer, 512);
    }
  }
}

void stopRecording() {
  Serial.println("stopRecording");
  queue1.end();
  queue2.end(); 
  Serial.println(tracks[0]);
  Serial.println(tracks[1]);
  if (recording) {
    Serial.println("Entered if");
    if (tracks[0]){
      if (selbutton1 == 0){
        sgtl5000_1.inputSelect(myInput);  //line level 
       }
      else{
      sgtl5000_1.inputSelect(myInput2); //mic level 
      }
    while (queue1.available() > 0) {
      frec.write((byte*)queue1.readBuffer(), 256);
      queue1.freeBuffer();
    }
    frec.close();
    }
    if (tracks[1]){
      if (selbutton2 == 0){
        sgtl5000_1.inputSelect(myInput);  //line level 
       }
      else{
      sgtl5000_1.inputSelect(myInput2); //mic level 
      }
     Serial.println("Ending recording"); 
    while (queue2.available() > 0) {
      frec.write((byte*)queue2.readBuffer(), 256);
      queue2.freeBuffer();
    }
    frec2.close();
    }
  recording = 0;
}
}

void startPlaying() {
  Serial.println("startPlaying");
  if (play_tracks[0])
    playRaw1.play("RECORD.RAW");
  if (play_tracks[1])
    playRaw1.play("RECORD1.RAW");
  playing = 1;
}

void continuePlaying() {
  if (!playRaw1.isPlaying()) {
    playRaw1.stop();
    playing = 0;
  }
}

void stopPlaying() {
  Serial.println("stopPlaying");
  if (playing) playRaw1.stop();
  playing = 0;
}
 
So firstly there's not a problem with switching between the inputs frequently.

I haven't tested your code, but from just looking at it I'm scratching my head about a few of your decisions...

Channel22_mixer.gain(1, pots[1] / 333.0);

so pots[1] is returning a value of between 0-1024, you're dividing by 333.0, what are you hoping to achieve? How does the maths look in your head?

I would have done: NormalisedPot = POT_READING / 1024.0 that gives you a range 0-1, then you scale to what you want, so if you wanted a 0-3 range, all you'd need to do is multiply the normalisedPot value, it maybe a few cycles more expensive but for the sake of sanity it's sometimes handy.

Back to 1024 / 333.0 in the gain column, I could be wrong, but I thought the gain was from 0-1, you're returning 3.0750750750750758 which is a nice number, I don't know why you picked it, but it does have a certain charm to it. So you have a gain of 3 if your pot reads 1024, which may clip or distort the hardware.

Another note would be

if (abs(pots[0] - analogRead(A17)) > 23)

why have you got an absolute expression, I could be wrong, but from what I understand you'd normally use abs to chop off the negative part of sine wave and make it always return a positive number, have you used abs to always return a positive number? You seem to be comparing the pot against itself, I don't understand the logic, is the intention a way of checking whether your pot has gone beyond a certain threshold or is it to filter out unusually noisey pot readings?
 
also put Serial.Println debugging line inside the if's and the else function:

if (tracks[1]){
if (selbutton2 == 0){
sgtl5000_1.inputSelect(myInput); //line level
}
else{
sgtl5000_1.inputSelect(myInput2); //mic level
}

I suspect it'll just be executing those instructions every time the loop goes round. Use a bool to store a state "hasChanged" or something like that.
 
Status
Not open for further replies.
Back
Top