Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 19 of 19

Thread: Switch the Teensy audio shield between a mic input and playing wav files

  1. #1
    Junior Member
    Join Date
    Jul 2021
    Posts
    11

    Switch the Teensy audio shield between a mic input and playing wav files

    I would like to switch the Teensy audio shield between a mic input and playing wav files off the SD Card...or the mic and synth waveforms.
    I'm not a coder so much, more of a beginner. I have tried altering some existing sketches with no luck.
    thanks, steve

  2. #2
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Perhaps use a mixer with the mic input and synth waveforms as inputs, allowing switching/crossfading between these sources?

  3. #3
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    But can I have a mic input and SD card wav files and switch between them. I tried combining a mic input sketch with a play SD card sketch and no luck. My coding skills are minimal and with teensy audio even less so.

  4. #4
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Yes, you use a mixer to combine them as I said. You can choose whatever combination you like - the mixer is just an audio mixer with
    control inputs from 0 to 1 representing the range of movement in a physical audio mixer's fader(s).

  5. #5
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    I found this sketch that does what I want...which is to switch between mic input and the wav files on the SD card. Pardon my coding ignorance, but I'm having trouble figuring out how it works. I have to push all three buttons to switch to the mic. I take it this "mode" is determining which input is selected...I would like to borrow the mic and SD parts of this sketch and just have something simple like a switch....if HIGH, mic input, if LOW, SD wav files play. I think I can just modify this sketch and eliminate the parts I don't need and make it switch between the mic input and the SD card audio files.
    // Audio Tutorial Kit Tester
    //
    // http://www.pjrc.com/store/audio_tutorial_kit.html
    //
    // Easily test all the tutorial hardware by only listening and pressing buttons.
    // 1: listen for microphone (any button press moves to #2)
    // 2: listen for SD card playing (any button press moves to #2)
    // 3: test 3 buttons and 3 knobs (press all 3 buttons to go back to step #1)
    //
    // After test is completed, EEPROM storage is used to remember the hardware is good
    // Good hardware will begin at #3, which corresponds to the first tutorial example

    #include <Audio.h>
    #include <SD.h>
    #include <Bounce.h>
    #include <EEPROM.h>
    #include "AudioSampleButton1.h"
    #include "AudioSampleButton2.h"
    #include "AudioSampleButton3.h"
    #include "AudioSampleKnob1.h"
    #include "AudioSampleKnob2.h"
    #include "AudioSampleKnob3.h"
    #include "AudioSampleNosdcard.h"

    AudioInputI2S i2s1;
    AudioSynthWaveform waveform1;
    AudioPlaySdWav playSdWav1;
    AudioPlayMemory sample1;
    AudioMixer4 mixer1;
    AudioMixer4 mixer2;
    AudioOutputI2S i2s2;
    AudioConnection patchCord1(i2s1, 0, mixer1, 0);
    AudioConnection patchCord2(i2s1, 0, mixer2, 0);
    AudioConnection patchCord3(playSdWav1, 0, mixer1, 1);
    AudioConnection patchCord4(playSdWav1, 1, mixer2, 1);
    AudioConnection patchCord5(waveform1, 0, mixer1, 2);
    AudioConnection patchCord6(waveform1, 0, mixer2, 2);
    AudioConnection patchCord7(sample1, 0, mixer1, 3);
    AudioConnection patchCord8(sample1, 0, mixer2, 3);
    AudioConnection patchCord9(mixer1, 0, i2s2, 0);
    AudioConnection patchCordA(mixer2, 0, i2s2, 1);
    AudioControlSGTL5000 sgtl5000_1;

    Bounce button0 = Bounce(0, 15);
    Bounce button1 = Bounce(1, 15);
    Bounce button2 = Bounce(2, 15);

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

    // 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

    int mode;
    int count=1;
    int a1=0, a2=0, a3=0;
    bool anybutton=false;
    bool sdcardinit=true;
    bool playsamples=false;

    void setup() {
    mode = EEPROM.read(400);
    AudioMemory(20);
    pinMode(0, INPUT_PULLUP);
    pinMode(1, INPUT_PULLUP);
    pinMode(2, INPUT_PULLUP);
    Serial.begin(115200);
    SPI.setMOSI(SDCARD_MOSI_PIN);
    SPI.setSCK(SDCARD_SCK_PIN);
    sgtl5000_1.enable();
    sgtl5000_1.volume(0.5);
    sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
    sgtl5000_1.micGain(36);
    mixer1.gain(0, 0);
    mixer1.gain(1, 0);
    mixer1.gain(2, 0);
    mixer1.gain(3, 0.4);
    mixer2.gain(0, 0);
    mixer2.gain(1, 0);
    mixer2.gain(2, 0);
    mixer2.gain(3, 0.4);
    waveform1.begin(WAVEFORM_SINE);
    delay(1000);
    button0.update();
    button1.update();
    button2.update();
    a1 = analogRead(A1);
    a2 = analogRead(A2);
    a3 = analogRead(A3);
    }

    void update() {
    static int state=0;

    button0.update();
    button1.update();
    button2.update();
    anybutton = false;
    if (button0.fallingEdge()) {
    anybutton = true;
    Serial.println("Button (pin 0) Press");
    if (playsamples) sample1.play(AudioSampleButton1);
    }
    if (button1.fallingEdge()) {
    anybutton = true;
    Serial.println("Button (pin 1) Press");
    if (playsamples) sample1.play(AudioSampleButton2);
    }
    if (button2.fallingEdge()) {
    anybutton = true;
    Serial.println("Button (pin 2) Press");
    if (playsamples) sample1.play(AudioSampleButton3);
    }
    if (button0.risingEdge()) {
    Serial.println("Button (pin 0) Release");
    }
    if (button1.risingEdge()) {
    Serial.println("Button (pin 1) Release");
    }
    if (button2.risingEdge()) {
    Serial.println("Button (pin 2) Release");
    }
    if (state == 0) {
    int a = analogRead(A1);
    if (a > a1 + 50 || a < a1 - 50) {
    Serial.print("Knob (pin A1) = ");
    Serial.println(a);
    if (playsamples && !sample1.isPlaying()) sample1.play(AudioSampleKnob1);
    a1 = a;
    }
    state = 1;
    } else if (state == 1) {
    int a = analogRead(A2);
    if (a > a2 + 50 || a < a2 - 50) {
    Serial.print("Knob (pin A2) = ");
    Serial.println(a);
    if (playsamples && !sample1.isPlaying()) sample1.play(AudioSampleKnob2);
    a2 = a;
    }
    state = 2;
    } else {
    int a = analogRead(A3);
    if (a > a3 + 50 || a < a3 - 50) {
    Serial.print("Knob (pin A3) = ");
    Serial.println(a);
    if (playsamples && !sample1.isPlaying()) sample1.play(AudioSampleKnob3);
    a3 = a;
    }
    state = 0;
    }
    }

    elapsedMillis msec=0;

    void loop() {
    update();

    // Test microphone
    if (mode == 255) {
    playsamples = true;
    mixer1.gain(0, 1.0);
    mixer2.gain(0, 1.0);
    if (anybutton) {
    mixer1.gain(0, 0);
    mixer2.gain(0, 0);
    if (sdcardinit) {
    if (!(SD.begin(SDCARD_CS_PIN))) {
    while (1) {
    Serial.println("Unable to access the SD card");
    if (playsamples) sample1.play(AudioSampleNosdcard);
    delay(3500);
    }
    }
    sdcardinit = false;
    }
    mode = 123;
    }

    // Play WAV file (test SD card, sound quality)
    } else if (mode == 123) {
    mixer1.gain(1, 0.75);
    mixer2.gain(1, 0.75);
    if (playSdWav1.isPlaying() == false) {
    Serial.println("Start playing");
    playSdWav1.play("SDTEST2.WAV");
    delay(10); // wait for library to parse WAV info
    }
    if (anybutton) {
    playSdWav1.stop();
    mixer1.gain(1, 0);
    mixer2.gain(1, 0);
    mode = 45;
    EEPROM.write(400, mode);
    }

    // Beeping (test buttons & knobs)
    } else {
    mixer1.gain(2, 1.0);
    mixer2.gain(2, 1.0);
    if (mode == 45) {
    Serial.print("Beep #");
    Serial.println(count);
    count = count + 1;
    waveform1.frequency(440);
    waveform1.amplitude(0.35);
    msec = 0;
    mode = 46;
    } else if (mode == 46) {
    if (msec > 250) {
    waveform1.amplitude(0);
    msec = 0;
    mode = 47;
    }
    } else {
    if (msec > 1750) {
    mode = 45;
    }
    }
    if (button0.read() == LOW && button1.read() == LOW && button2.read() == LOW) {
    mixer1.gain(2, 0);
    mixer2.gain(2, 0);
    mode = 255;
    }
    }
    }

  6. #6
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Quote Originally Posted by stevex View Post
    I found this sketch that does what I want...which is to switch between mic input and the wav files on the SD card. Pardon my coding ignorance, but I'm having trouble figuring out how it works.
    It has various logic to set the mode variable, and then updates various mixer gains dependent on the mode.

  7. #7
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    416
    Quote Originally Posted by MarkT View Post
    It has various logic to set the mode variable, and then updates various mixer gains dependent on the mode.
    If you are able to find the QUOTE button above, why is it not possible for you to use the CODE button. Your code that you found becomes much more readable.
    See below:-
    Code:
    // Audio Tutorial Kit Tester
    //
    // http://www.pjrc.com/store/audio_tutorial_kit.html
    //
    // Easily test all the tutorial hardware by only listening and pressing buttons.
    // 1: listen for microphone (any button press moves to #2)
    // 2: listen for SD card playing (any button press moves to #2)
    // 3: test 3 buttons and 3 knobs (press all 3 buttons to go back to step #1)
    //
    // After test is completed, EEPROM storage is used to remember the hardware is good
    // Good hardware will begin at #3, which corresponds to the first tutorial example
    
    #include <Audio.h>
    #include <SD.h>
    #include <Bounce.h>
    #include <EEPROM.h>
    #include "AudioSampleButton1.h"
    #include "AudioSampleButton2.h"
    #include "AudioSampleButton3.h"
    #include "AudioSampleKnob1.h"
    #include "AudioSampleKnob2.h"
    #include "AudioSampleKnob3.h"
    #include "AudioSampleNosdcard.h"
    
    AudioInputI2S i2s1;
    AudioSynthWaveform waveform1;
    AudioPlaySdWav playSdWav1;
    AudioPlayMemory sample1;
    AudioMixer4 mixer1;
    AudioMixer4 mixer2;
    AudioOutputI2S i2s2;
    AudioConnection patchCord1(i2s1, 0, mixer1, 0);
    AudioConnection patchCord2(i2s1, 0, mixer2, 0);
    AudioConnection patchCord3(playSdWav1, 0, mixer1, 1);
    AudioConnection patchCord4(playSdWav1, 1, mixer2, 1);
    AudioConnection patchCord5(waveform1, 0, mixer1, 2);
    AudioConnection patchCord6(waveform1, 0, mixer2, 2);
    AudioConnection patchCord7(sample1, 0, mixer1, 3);
    AudioConnection patchCord8(sample1, 0, mixer2, 3);
    AudioConnection patchCord9(mixer1, 0, i2s2, 0);
    AudioConnection patchCordA(mixer2, 0, i2s2, 1);
    AudioControlSGTL5000 sgtl5000_1;
    
    Bounce button0 = Bounce(0, 15);
    Bounce button1 = Bounce(1, 15);
    Bounce button2 = Bounce(2, 15);
    
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN 10
    #define SDCARD_MOSI_PIN 7
    #define SDCARD_SCK_PIN 14
    
    // 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
    
    int mode;
    int count = 1;
    int a1 = 0, a2 = 0, a3 = 0;
    bool anybutton = false;
    bool sdcardinit = true;
    bool playsamples = false;
    
    void setup() {
    	mode = EEPROM.read(400);
    	AudioMemory(20);
    	pinMode(0, INPUT_PULLUP);
    	pinMode(1, INPUT_PULLUP);
    	pinMode(2, INPUT_PULLUP);
    	Serial.begin(115200);
    	SPI.setMOSI(SDCARD_MOSI_PIN);
    	SPI.setSCK(SDCARD_SCK_PIN);
    	sgtl5000_1.enable();
    	sgtl5000_1.volume(0.5);
    	sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
    	sgtl5000_1.micGain(36);
    	mixer1.gain(0, 0);
    	mixer1.gain(1, 0);
    	mixer1.gain(2, 0);
    	mixer1.gain(3, 0.4);
    	mixer2.gain(0, 0);
    	mixer2.gain(1, 0);
    	mixer2.gain(2, 0);
    	mixer2.gain(3, 0.4);
    	waveform1.begin(WAVEFORM_SINE);
    	delay(1000);
    	button0.update();
    	button1.update();
    	button2.update();
    	a1 = analogRead(A1);
    	a2 = analogRead(A2);
    	a3 = analogRead(A3);
    }
    
    void update() {
    	static int state = 0;
    
    	button0.update();
    	button1.update();
    	button2.update();
    	anybutton = false;
    	if (button0.fallingEdge()) {
    		anybutton = true;
    		Serial.println("Button (pin 0) Press");
    		if (playsamples) sample1.play(AudioSampleButton1);
    	}
    	if (button1.fallingEdge()) {
    		anybutton = true;
    		Serial.println("Button (pin 1) Press");
    		if (playsamples) sample1.play(AudioSampleButton2);
    	}
    	if (button2.fallingEdge()) {
    		anybutton = true;
    		Serial.println("Button (pin 2) Press");
    		if (playsamples) sample1.play(AudioSampleButton3);
    	}
    	if (button0.risingEdge()) {
    		Serial.println("Button (pin 0) Release");
    	}
    	if (button1.risingEdge()) {
    		Serial.println("Button (pin 1) Release");
    	}
    	if (button2.risingEdge()) {
    		Serial.println("Button (pin 2) Release");
    	}
    	if (state == 0) {
    		int a = analogRead(A1);
    		if (a > a1 + 50 || a < a1 - 50) {
    			Serial.print("Knob (pin A1) = ");
    			Serial.println(a);
    			if (playsamples && !sample1.isPlaying()) sample1.play(AudioSampleKnob1);
    			a1 = a;
    		}
    		state = 1;
    	}
    	else if (state == 1) {
    		int a = analogRead(A2);
    		if (a > a2 + 50 || a < a2 - 50) {
    			Serial.print("Knob (pin A2) = ");
    			Serial.println(a);
    			if (playsamples && !sample1.isPlaying()) sample1.play(AudioSampleKnob2);
    			a2 = a;
    		}
    		state = 2;
    	}
    	else {
    		int a = analogRead(A3);
    		if (a > a3 + 50 || a < a3 - 50) {
    			Serial.print("Knob (pin A3) = ");
    			Serial.println(a);
    			if (playsamples && !sample1.isPlaying()) sample1.play(AudioSampleKnob3);
    			a3 = a;
    		}
    		state = 0;
    	}
    }
    
    elapsedMillis msec = 0;
    
    void loop() {
    	update();
    
    	// Test microphone
    	if (mode == 255) {
    		playsamples = true;
    		mixer1.gain(0, 1.0);
    		mixer2.gain(0, 1.0);
    		if (anybutton) {
    			mixer1.gain(0, 0);
    			mixer2.gain(0, 0);
    			if (sdcardinit) {
    				if (!(SD.begin(SDCARD_CS_PIN))) {
    					while (1) {
    						Serial.println("Unable to access the SD card");
    						if (playsamples) sample1.play(AudioSampleNosdcard);
    						delay(3500);
    					}
    				}
    				sdcardinit = false;
    			}
    			mode = 123;
    		}
    
    		// Play WAV file (test SD card, sound quality)
    	}
    	else if (mode == 123) {
    		mixer1.gain(1, 0.75);
    		mixer2.gain(1, 0.75);
    		if (playSdWav1.isPlaying() == false) {
    			Serial.println("Start playing");
    			playSdWav1.play("SDTEST2.WAV");
    			delay(10); // wait for library to parse WAV info
    		}
    		if (anybutton) {
    			playSdWav1.stop();
    			mixer1.gain(1, 0);
    			mixer2.gain(1, 0);
    			mode = 45;
    			EEPROM.write(400, mode);
    		}
    
    		// Beeping (test buttons & knobs)
    	}
    	else {
    		mixer1.gain(2, 1.0);
    		mixer2.gain(2, 1.0);
    		if (mode == 45) {
    			Serial.print("Beep #");
    			Serial.println(count);
    			count = count + 1;
    			waveform1.frequency(440);
    			waveform1.amplitude(0.35);
    			msec = 0;
    			mode = 46;
    		}
    		else if (mode == 46) {
    			if (msec > 250) {
    				waveform1.amplitude(0);
    				msec = 0;
    				mode = 47;
    			}
    		}
    		else {
    			if (msec > 1750) {
    				mode = 45;
    			}
    		}
    		if (button0.read() == LOW && button1.read() == LOW && button2.read() == LOW) {
    			mixer1.gain(2, 0);
    			mixer2.gain(2, 0);
    			mode = 255;
    		}
    	}
    }

  8. #8
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    I did post the code in between the code things...it must have been something with my browser blocking it.

    test

    Code:
    /*
      Blink
    
      Turns an LED on for one second, then off for one second, repeatedly.
    
      Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
      it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
      the correct LED pin independent of which board is used.
      If you want to know what pin the on-board LED is connected to on your Arduino
      model, check the Technical Specs of your board at:
      https://www.arduino.cc/en/Main/Products
    
      modified 8 May 2014
      by Scott Fitzgerald
      modified 2 Sep 2016
      by Arturo Guadalupi
      modified 8 Sep 2016
      by Colby Newman
    
      This example code is in the public domain.
    
      http://www.arduino.cc/en/Tutorial/Blink
    */
    
    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);                       // wait for a second
    }

  9. #9
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    Quote Originally Posted by MarkT View Post
    It has various logic to set the mode variable, and then updates various mixer gains dependent on the mode.
    I do get that generally how it works, although I'm having trouble simplifying it...

  10. #10
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    416
    Quote Originally Posted by stevex View Post
    I did post the code in between the code things...it must have been something with my browser blocking it.

    test

    Code:
    /*
      Blink
    
      Turns an LED on for one second, then off for one second, repeatedly.
    
      Most Arduinos have an on-board LED you can control. On the UNO, MEGA and ZERO
      it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN is set to
      the correct LED pin independent of which board is used.
      If you want to know what pin the on-board LED is connected to on your Arduino
      model, check the Technical Specs of your board at:
      https://www.arduino.cc/en/Main/Products
    
      modified 8 May 2014
      by Scott Fitzgerald
      modified 2 Sep 2016
      by Arturo Guadalupi
      modified 8 Sep 2016
      by Colby Newman
    
      This example code is in the public domain.
    
      http://www.arduino.cc/en/Tutorial/Blink
    */
    
    // the setup function runs once when you press reset or power the board
    void setup() {
      // initialize digital pin LED_BUILTIN as an output.
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);                       // wait for a second
    }
    It's easy to get the cursor in the wrong place when pasting between the [CODE.../CODE]" identifiers. I find the easier way is to highlight the section of code, then press the CODE button. The code is then top and tailed with the correct entry.

  11. #11
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    Quote Originally Posted by stevex View Post
    I do get that generally how it works, although I'm having trouble simplifying it...
    I cannot get the mic input and the SD card wav files to work in the same sketch. All I want to do is switch between them.

  12. #12
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Forum rule is there for a reason... Post your current code and explain what's not working?

  13. #13
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    ok, here is the mixer sketch from the audio tutorial. It plays two wav files from the SD card on the audio shield. With pot A3 I can switch between the files.
    I have a mic connected to the audio shield and I would like to switch away from the wav files and have a mic input. When I add a is2s input to the mixers I don't know how to implement switching the output to the mic in the void loop. I can get the mic to work by itself without the wav files with the microphone check sketch in the audio tutorials. I get the Audio System Design Tool, but I must be missing some syntax or something in setup? In the void loop, how do I say I want to stop the wav file and switch to the mic input. I would think it's an if statement, but not sure how to go about it.


    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 2-2: Mixers & Playing Multiple Sounds
    
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioPlaySdWav           playSdWav1;     //xy=89,32
    AudioPlaySdWav           playSdWav2;     //xy=89,108
    AudioMixer4              mixer2;         //xy=268,123
    AudioMixer4              mixer1;         //xy=279,50
    AudioOutputI2S           i2s1;           //xy=537,49
    AudioConnection          patchCord1(playSdWav1, 0, mixer1, 0);
    AudioConnection          patchCord2(playSdWav1, 1, mixer2, 0);
    AudioConnection          patchCord3(playSdWav2, 0, mixer1, 1);
    AudioConnection          patchCord4(playSdWav2, 1, mixer2, 1);
    AudioConnection          patchCord5(mixer2, 0, i2s1, 1);
    AudioConnection          patchCord6(mixer1, 0, i2s1, 0);
    AudioControlSGTL5000     sgtl5000_1;     //xy=469,142
    // GUItool: end automatically generated code
    
    
    
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN    10
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    
    // 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
    
    
    int analogThreshold = 512;
    
    void setup() {
      Serial.begin(9600);
      AudioMemory(8);
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.8);
      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);
        }
      }
      pinMode(13, OUTPUT); // LED on pin 13
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.5);
      mixer2.gain(0, 0.5);
      mixer2.gain(1, 0.5);
      delay(1000);
    }
    
    void loop() {
      if (playSdWav1.isPlaying() == false) {
        Serial.println("Start playing 1");
        playSdWav1.play("CM.000.WAV");
        delay(10); // wait for library to parse WAV info
      }
      if (playSdWav2.isPlaying() == false) {
        Serial.println("Start playing 2");
        playSdWav2.play("SDTEST1.WAV");
        delay(10); // wait for library to parse WAV info
      }
      // uncomment this code to allow Knob A3 to pan between songs
      
    //  int knob = analogRead(A3);  // knob = 0 to 1023
    //  float gain1 = (float)knob / 1023.0;
    //  float gain2 = 1.0 - gain1;
    //  mixer1.gain(0, gain1);
    //  mixer1.gain(1, gain2);
    //  mixer2.gain(0, gain1);
    //  mixer2.gain(1, gain2);
    
    
    
      int knob = analogRead(A3);  // knob = 0 to 1023
      float gain1 = (knob <= analogThreshold);
      float gain2 = (knob >= analogThreshold);
      mixer1.gain(0, gain1);
      mixer1.gain(1, gain2);
      mixer2.gain(0, gain1);
      mixer2.gain(1, gain2);
     
    }

  14. #14
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Add an AudioInputI2S and connect it to channels 2 on both mixer1 and mixer2.

    Initialize the sgtl5000 to use microphone input and configure the mic gain as necessary. By turning the channel 2 gains
    on mixers between 0 and 1 you can drop in the mic channel or mute it.

  15. #15
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    ok finally I got both the mic input and the SD wav file from the SD card to play at the same time. Amazing.
    Now how do I get it to switch between the mic input and the SD wave file playing. (I know this may be a stupid question, but I think I'm having problem with syntax (I guess))
    I also need an array of wav files, so I can play 4-6 different ones. I'll need a button for both of these but the Bounce and update are not so clear to me. I'm still in the copy and paste phase of coding so my attempts are not always successful.



    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1;           //xy=196,92
    AudioPlaySdWav           playWav1;     //xy=214,43
    AudioMixer4              mixer2;         //xy=379,222
    AudioMixer4              mixer1;         //xy=386,121
    AudioOutputI2S           i2s2;           //xy=559,86
    AudioConnection          patchCord1(i2s1, 0, mixer1, 1);
    AudioConnection          patchCord2(i2s1, 0, mixer2, 1);
    AudioConnection          patchCord3(playWav1, 0, mixer1, 0);
    AudioConnection          patchCord4(playWav1, 1, mixer2, 0);
    AudioConnection          patchCord5(mixer2, 0, i2s2, 1);
    AudioConnection          patchCord6(mixer1, 0, i2s2, 0);
    AudioControlSGTL5000     sgtl5000_1;     //xy=553,148
    // GUItool: end automatically generated code
    
    
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN    10
    #define SDCARD_MOSI_PIN  7
    #define SDCARD_SCK_PIN   14
    
    
    
    void setup() {
      Serial.begin(9600);
    
    
      AudioMemory(8);
    
    
      sgtl5000_1.enable();
      sgtl5000_1.volume(0.7);
      sgtl5000_1.inputSelect(AUDIO_INPUT_MIC);
      sgtl5000_1.micGain(40);
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        // stop here, but print a message repetitively
        while (1) {
          Serial.println("Unable to access the SD card");
          delay(500);
          
    
    
        }
        mixer1.gain(0, 0.5);
          mixer1.gain(1, 0.5);
          mixer2.gain(0, 0.5);
          mixer2.gain(1, 0.5);
      }
    }
    
    void playFile(const char *filename)
    {
      Serial.print("Playing file: ");
      Serial.println(filename);
    
      // Start playing the file.  This sketch continues to
      // run while the file plays.
      playWav1.play(filename);
    
      // A brief delay for the library read WAV info
      delay(25);
    
      // Simply wait for the file to finish playing.
      while (playWav1.isPlaying()) {
        // uncomment these lines if you audio shield
        // has the optional volume pot soldered
        float vol = analogRead(15);
        vol = vol / 1024;
        sgtl5000_1.volume(vol);
      }
    }
    
    
    void loop() {
      playFile("CM.000.WAV");  // filenames are always uppercase 8.3 format
      delay(500);
      //  playFile("SDTEST2.WAV");
      //  delay(500);
      //  playFile("SDTEST3.WAV");
      //  delay(500);
      //  playFile("SDTEST4.WAV");
      //  delay(1500);
    }

  16. #16
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    OMG. I found what I was looking for on YouTube. My coding skills with Teensy audio are lacking and I was having a hard time making things work. Thank you all for your help. I hope to study this and figure out how it works exactly. This sketch has mic input as well as start, stop, next track, previous track, and volume. Perfect. I'm sorry if I was a pain. Getting help by writing back and forth is a chore, especially when this side is somewhat clueless.

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Bounce.h>
    
    // create audio component objects
    AudioPlaySdWav           playWav1;           // SD card wav file player
    AudioInputI2S            audioInput;         // audio shield input, mic or line-in selectable
    AudioMixer4              mixer1;             // mixers to combine wav file and audio shield inputs
    AudioMixer4              mixer2;
    
    // Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
    AudioOutputI2S           audioOutput;
    //AudioOutputSPDIF       audioOutput;
    //AudioOutputAnalog      audioOutput;
    
    // wire up the interfaces between audio components with patch cords
    // mixer inputs
    AudioConnection          patchCord1(playWav1, 0, mixer1, 0);          // left  channels into mixer 1
    AudioConnection          patchCord2(audioInput, 0, mixer1, 1);
    
    AudioConnection          patchCord3(playWav1, 1, mixer2, 0);          // right channels into mixer 2
    AudioConnection          patchCord4(audioInput, 1, mixer2, 1);
    
    // mixer outputs
    AudioConnection          patchCord5(mixer1, 0, audioOutput, 0);
    AudioConnection          patchCord6(mixer2, 0, audioOutput, 1);
    
    // object to allow control of the SGTL5000 audio shield settings
    AudioControlSGTL5000     audioShield;
    
    // buttons and potentiometers
    #define pot0             A1
    #define pot1             A2
    #define pot2             A3
    #define button0          0
    #define button1          1
    #define button2          2
    //#define button3          27
    
    // attach button debouncers to input buttons
    Bounce db_button0 = Bounce(button0, 30);
    Bounce db_button1 = Bounce(button1, 30);
    Bounce db_button2 = Bounce(button2, 30);
    //Bounce db_button3 = Bounce(button3, 30);
    
    // choose mic or line input for audio shield input path
    const int inputChSelect = AUDIO_INPUT_MIC;
    //const int inputChSelect = AUDIO_INPUT_LINEIN;
    
    // audio shield volume
    int masterVolume        = 0;
    
    // uncomment one set of SD card SPI pins to use
    // Use these with the Teensy Audio Shield
    #define SDCARD_CS_PIN     10
    #define SDCARD_MOSI_PIN   7
    #define SDCARD_SCK_PIN    14
    
    
    
    // wav filenames on SD card for playback
    char *wavFiles[]       = {"CM.000.WAV", "SDTEST1.WAV", "SDTEST2.WAV", "SDTEST3.WAV", "SDTEST4.WAV"};
    byte wavNum            = 0;      // current wav file index playing from array list
    bool wavIsPlaying      = false;  // track if a wav file is currently playing or not
    
    void setup() {
      Serial.begin(9600);
      Serial.println("SD Player Demo\n");
    
      // buttons are inputs with pullups
      pinMode(button0, INPUT_PULLUP);
      pinMode(button1, INPUT_PULLUP);
      pinMode(button2, INPUT_PULLUP);
      //pinMode(button3, INPUT_PULLUP);
    
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(8);
    
      // comment these out if not using the audio adaptor board.
      Serial.print("init audio shield...");
      audioShield.enable();
      audioShield.inputSelect(inputChSelect);  // select mic or line-in for audio shield input source
      audioShield.volume(0.5);
      Serial.println("done.");
    
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.5);
      mixer1.gain(2, 0);
      mixer1.gain(3, 0);
    
      mixer2.gain(0, 0.5);
      mixer2.gain(1, 0.5);
      mixer2.gain(2, 0);
      mixer2.gain(3, 0);
    
      Serial.print("init SD card...");
      SPI.setMOSI(SDCARD_MOSI_PIN);
      SPI.setSCK(SDCARD_SCK_PIN);
      if (!(SD.begin(SDCARD_CS_PIN))) {
        // stop here, but print a message
        Serial.println("Unable to access the SD card.  Program halted.");
        while (1);
      }
      Serial.println("done.");
      Serial.println("Waiting for control input...");
    
      // reset audio resource usage stats.
      // useful if tracking max usage in main program
      AudioProcessorUsageMaxReset();
      AudioMemoryUsageMaxReset();
    }
    
    void playFile(const char *filename)
    {
      Serial.print("Start playing file: ");
      Serial.println(filename);
    
      // start playing the file.
      // sketch continues to run while the file plays.
      playWav1.play(filename);
    
      // A brief delay for the library to read WAV header info
      delay(5);
    }
    
    
    void loop() {
    
      // auto select next wav file if current file finishes playing
      // and if playback is enabled
      if ((!(playWav1.isPlaying())) && (wavIsPlaying)) {
        wavNum++;
        if (wavNum > 4) {
          wavNum = 0;
        }
        playFile(wavFiles[wavNum]);
      }
    
      // read volume control pot and set audio shield volume if required
      int vol = analogRead(pot0);
      if (vol != masterVolume) {
        masterVolume = vol;
        audioShield.volume((float)vol / 1023);  // audio shield headphone out volume (optional)
        mixer1.gain(0, (float)vol / 1023);      // software mixer input channel volume
        mixer1.gain(1, (float)vol / 1023);
        mixer2.gain(0, (float)vol / 1023);
        mixer2.gain(1, (float)vol / 1023);
      }
    
      // update the button debounce status so falling edges
      // can be detected and processed
      db_button0.update();
      db_button1.update();
      db_button2.update();
      //db_button3.update();
    
      // button 0 pressed - toggle playback start/stop for current wav file
      if (db_button0.fallingEdge()) {
        if (playWav1.isPlaying()) {
          playWav1.stop();
          wavIsPlaying = false;
          Serial.println("Playback stopped\n");
        }
        else {
          playFile(wavFiles[wavNum]);
          wavIsPlaying = true;
          Serial.println("Playback started");
        }
        //Serial.print("Audio memory usage max: ");
        //Serial.println(AudioMemoryUsageMax());
      }
    
      // button 1 pressed - skip track forward
      if (db_button1.fallingEdge()) {
        Serial.println("Skip track forward");
        if (wavNum == 4)
          wavNum = 0;
        else
          wavNum++;
        playFile(wavFiles[wavNum]);
        wavIsPlaying = true;
      }
    
      // button 2 pressed - skip track backward
      if (db_button2.fallingEdge()) {
        Serial.println("Skip track backward");
        if (wavNum == 0)
          wavNum = 4;
        else
          wavNum--;
        playFile(wavFiles[wavNum]);
        wavIsPlaying = true;
      }
    
    }

  17. #17
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    You seem to be turning wav file volume on at the same time as microphone volome on, rather than cross-fading -
    I thought you wanted to cross-fade between them?

  18. #18
    Junior Member
    Join Date
    Jul 2021
    Posts
    11
    Quote Originally Posted by MarkT View Post
    You seem to be turning wav file volume on at the same time as microphone volome on, rather than cross-fading -
    I thought you wanted to cross-fade between them?
    Well, not crossfade so much...what I wanted it to do is to be able to switch between the mic input and the wav files on the SD card. With this sketch the mic is always live, but I can stop the wav files from playing, so the mic can be heard. It's pretty close to what I originally had in mind, so i think it's fine. I can always update it later as i learn more. I appreciate the help. I am more used to the Arduino than the Teensy. This is my first attempt at using a Teensy. It is much better with audio...I'm usually running motors on an Arduino rather than this sort of thing.

  19. #19
    Senior Member
    Join Date
    Jul 2020
    Posts
    1,246
    Well, not crossfade so much...what I wanted it to do is to be able to switch between the mic input and the wav files on the SD card.
    That's what I mean - in software you can crossfade instantly as well as gradually.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •