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

Status
Not open for further replies.

stevex

Member
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
 
Perhaps use a mixer with the mic input and synth waveforms as inputs, allowing switching/crossfading between these sources?
 
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.
 
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).
 
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.
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;
}
}
}
 
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.
 
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;
		}
	}
}
 
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
}
 
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.
 
Forum rule is there for a reason... Post your current code and explain what's not working?
 
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);
 
}
 
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.
 
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);
}
 
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;
  }

}
 
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?
 
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.
 
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.
 
Status
Not open for further replies.
Back
Top