Trying to Learn to Play WAV. files on Teensy 3.2 + Prop Shield

Status
Not open for further replies.

derplecbob

Active member
Hi
I have a teensy 3.2 soldered onto the prop shield with an 8omh 1.5 watt speaker soldered off the speaker end of the prop shield.
I'm trying to find the minimum amount of code I need to play a few wav files. That way I can add it into other code.
I'm not very good at coding and I'm new to playing audio so I apologize for the messy code


I got this first Code to play a tone so I know its working but the second code I tried to use to play a WAV file but its not working and I don't know why
Code:
#include <Audio.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveformSine   sine1;          //xy=180,469
//AudioSynthWaveformSineHires   sine1;
AudioOutputAnalog        dac1;           //xy=380,468
AudioConnection          patchCord1(sine1, dac1);
// GUItool: end automatically generated code

int freq = 1100;

void setup() {
  Serial.begin(9600);

  //dac1.analogReference(EXTERNAL);   // louder, default is 1.2v INTERNAL
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);//Enable Amplifier
  AudioMemory(12);
  sine1.amplitude(1.0);
  sine1.frequency(1000);

}

void loop()
{
  if (Serial.available()) {
    Serial.read();
    sine1.frequency(freq);
    Serial.println(freq);
    freq += 100;
  }
}


Second code
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav           playSdWav1;
AudioOutputAnalog        dac1;
AudioConnection          patchCord1(playSdWav1, 0,  dac1, 0);
AudioConnection          patchCord2(playSdWav1, 0,  dac1, 1);


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


void setup() {

 pinMode(5, OUTPUT);    // sound
 digitalWrite(5, HIGH); // turn on the amplifier
 delay(10);             // allow time to wake up

  

  
  Serial.begin(115200);
  AudioMemory(10);


  delay(1000);
}

void loop() {
 
    playSdWav1.play("SDTEST2.WAV");
    delay(1000); // wait for library to parse WAV info
}
 
Try this in the loop() code - from : ...\hardware\teensy\avr\libraries\Audio\examples\Tutorial\Part_1_03_Playing_Music\Part_1_03_Playing_Music.ino
Code:
void loop() {
  if (playSdWav1.isPlaying() == false) {
    Serial.println("Start playing");
    playSdWav1.play("SDTEST2.WAV");
    delay(10); // wait for library to parse WAV info
  }
  // do nothing while playing...
}

With the delay(1000) - the sound file will get started again about the time it starts in some fashion as loop() repeats after that delay - without regard to .isPlaying().

There is a PJRC Audio tutorial and that sample comes early in the presentation. Working through that may help ...
 
While far from elegant, you could just change the delay to be the length of your WAV file.

Code:
void loop() {
    playSdWav1.play("SDTEST2.WAV");
    delay(93200);  // wait for SDTEST2.WAV to completely play, approx 93.2 seconds
}

You did ask for "the minimum amount of code"...
 
The problem is you are using code to read files from the SD card reader. The Teensy 3.2 does not have a built-in micro SD card reader, and nor does the Prop shield.

You could get a Teensy 3.5 or 3.6 and use the Prop shield on that processor. You would have to solder a wire from the hole A14 fits into on the back of the Prop shield and attach it to pin A21 on the Teensy 3.5/3.6. Note, while the Teensy 4.1 also has a micro SD card reader, but it doesn't have a DAC (digital to analog converter) to play sounds.

You could also attach a micro SD card reader to the Teensy 3.2, but that is messy.

So the question becomes how do you use the Prop shield to play songs and other pre-recorded sounds with the Teensy 3.2. This will be a complex answer.

Without adding any hardware you can use the flash memory in the Teensy Prop shield to hold the recorded songs/sounds. However, until Teensy 1.54 is released, it is somewhat complicated to use. Some of the limitations in 1.53 are:

  • The Audio library currently only has an entry to play sounds from flash memory that are encoded with the mono 16-bit signed, little-endian, 44100 Hz, RAW format. You will need to convert the stereo WAV files to the mono RAW format. In theory once 1.54 is finished, you will be able to use the WAV player on flash files;
  • You will need to create a FAT filesystem on the flash memory and copy files to this filesystem; (and)
  • You will need to use a different sketch that plays RAW files from flash memory.

In order to convert files to the RAW format, the normal answer is to use Audacity (or possibly use sox if you are comfortable with command line tools):


To download files to the flash memory, when 1.54 is fully completed, you should in theory be able to run a script and when you connect the Teensy, it will allow you to connect the Teensy as a USB removable disk drive and copy the files directly from your system. However, that is a work in progress, and things are rapidly changing. In 1.53 and earlier, the tool I used was TeensyTransfer written by FrankB.


Here is a sketch I've used to play 4 different sounds with the prop shield:

Code:
// Converted from the WavFilePlay from the Teensy release:
// hardware/teensy/avr/libraries/Audio/examples/WavFilePlayer/WavFilePlayer.ino
//
// Simple RAW file player example for the prop shield to use the Analog DAC
// and prop shield amplifier to play mono sounds.
//         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// On the prop shield, pin 6 selects the serial flash memory controller,
// and pin 5 enables the amplifier.
//
// This example code is in the public domain.

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

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=149,388
AudioMixer4              mixer1;         //xy=445,386
AudioOutputAnalog        dac1;           //xy=591,379
AudioConnection          patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection          patchCord2(mixer1, dac1);
// GUItool: end automatically generated code

#define PROP_AMP_ENABLE		5
#define FLASH_CHIP_SELECT	6
#define VOLUME_POT		A1

void setup() {
  Serial.begin(9600);

  // wait up to 3 seconds for the Serial device to become available
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 3000))
    ;

  Serial.println ("Start prop shield RAW player");

  // Enable the amplifier on the prop shield
  pinMode(PROP_AMP_ENABLE, OUTPUT);
  digitalWrite(PROP_AMP_ENABLE, HIGH);

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

  // Set initial volume (comment if using a potentiometer on A1 below)
  mixer1.gain(0, 0.5f);

  // uncomment these lines if you have a potentiometer or trimpot
  // on the pin A1 to control the volume, and comment out the
  // above line
  // float vol = analogRead(VOLUME_POT);
  // mixer1.gain(0, vol / 1024.0f);

  // Start SerialFlash
  if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
    while (1)
      {
	Serial.println ("Cannot access SPI Flash chip");
	delay (1000);
      }
  }
}

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.
  playFlashRaw1.play(filename);

  // A brief delay for the library read RAW info
  delay(5);

  // Simply wait for the file to finish playing.
  while (playFlashRaw1.isPlaying()) {
    // uncomment these lines if you have a potentiometer or trimpot
    // on the pin A1 to control the volume
    // float vol = analogRead(VOLUME_POT);
    // mixer1.gain(0, vol / 1024.0f);
  }
}


void loop() {
  playFile("SDTEST1.RAW");  // filenames are always uppercase 8.3 format
  delay(500);
  playFile("SDTEST2.RAW");
  delay(500);
  playFile("SDTEST3.RAW");
  delay(500);
  playFile("SDTEST4.RAW");
  delay(1500);
}

Here is a zip file of some Halloween sounds that I converted to RAW along with the original WAV files:
 
Last edited:
Thank you all so much!

The problem is you are using code to read files from the SD card reader. The Teensy 3.2 does not have a built-in micro SD card reader, and nor does the Prop shield.

You could get a Teensy 3.5 or 3.6 and use the Prop shield on that processor. You would have to solder a wire from the hole A14 fits into on the back of the Prop shield and attach it to pin A21 on the Teensy 3.5/3.6. Note, while the Teensy 4.1 also has a micro SD card reader, but it doesn't have a DAC (digital to analog converter) to play sounds.

You could also attach a micro SD card reader to the Teensy 3.2, but that is messy.

So the question becomes how do you use the Prop shield to play songs and other pre-recorded sounds with the Teensy 3.2. This will be a complex answer.

Without adding any hardware you can use the flash memory in the Teensy Prop shield to hold the recorded songs/sounds. However, until Teensy 1.54 is released, it is somewhat complicated to use. Some of the limitations in 1.53 are:

  • The Audio library currently only has an entry to play sounds from flash memory that are encoded with the mono 16-bit signed, little-endian, 44100 Hz, RAW format. You will need to convert the stereo WAV files to the mono RAW format. In theory once 1.54 is finished, you will be able to use the WAV player on flash files;
  • You will need to create a FAT filesystem on the flash memory and copy files to this filesystem; (and)
  • You will need to use a different sketch that plays RAW files from flash memory.

In order to convert files to the RAW format, the normal answer is to use Audacity (or possibly use sox if you are comfortable with command line tools):


To download files to the flash memory, when 1.54 is fully completed, you should in theory be able to run a script and when you connect the Teensy, it will allow you to connect the Teensy as a USB removable disk drive and copy the files directly from your system. However, that is a work in progress, and things are rapidly changing. In 1.53 and earlier, the tool I used was TeensyTransfer written by FrankB.


Here is a sketch I've used to play 4 different sounds with the prop shield:

Code:
// Converted from the WavFilePlay from the Teensy release:
// hardware/teensy/avr/libraries/Audio/examples/WavFilePlayer/WavFilePlayer.ino
//
// Simple RAW file player example for the prop shield to use the Analog DAC
// and prop shield amplifier to play mono sounds.
//         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// On the prop shield, pin 6 selects the serial flash memory controller,
// and pin 5 enables the amplifier.
//
// This example code is in the public domain.

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

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=149,388
AudioMixer4              mixer1;         //xy=445,386
AudioOutputAnalog        dac1;           //xy=591,379
AudioConnection          patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection          patchCord2(mixer1, dac1);
// GUItool: end automatically generated code

#define PROP_AMP_ENABLE		5
#define FLASH_CHIP_SELECT	6
#define VOLUME_POT		A1

void setup() {
  Serial.begin(9600);

  // wait up to 3 seconds for the Serial device to become available
  long unsigned debug_start = millis ();
  while (!Serial && ((millis () - debug_start) <= 3000))
    ;

  Serial.println ("Start prop shield RAW player");

  // Enable the amplifier on the prop shield
  pinMode(PROP_AMP_ENABLE, OUTPUT);
  digitalWrite(PROP_AMP_ENABLE, HIGH);

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

  // Set initial volume (comment if using a potentiometer on A1 below)
  mixer1.gain(0, 0.5f);

  // uncomment these lines if you have a potentiometer or trimpot
  // on the pin A1 to control the volume, and comment out the
  // above line
  // float vol = analogRead(VOLUME_POT);
  // mixer1.gain(0, vol / 1024.0f);

  // Start SerialFlash
  if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
    while (1)
      {
	Serial.println ("Cannot access SPI Flash chip");
	delay (1000);
      }
  }
}

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.
  playFlashRaw1.play(filename);

  // A brief delay for the library read RAW info
  delay(5);

  // Simply wait for the file to finish playing.
  while (playFlashRaw1.isPlaying()) {
    // uncomment these lines if you have a potentiometer or trimpot
    // on the pin A1 to control the volume
    // float vol = analogRead(VOLUME_POT);
    // mixer1.gain(0, vol / 1024.0f);
  }
}


void loop() {
  playFile("SDTEST1.RAW");  // filenames are always uppercase 8.3 format
  delay(500);
  playFile("SDTEST2.RAW");
  delay(500);
  playFile("SDTEST3.RAW");
  delay(500);
  playFile("SDTEST4.RAW");
  delay(1500);
}

Here is a zip file of some Halloween sounds that I converted to RAW along with the original WAV files:

And thank you Michael, you've helped me tremendously. I now have a lot to think about.
Do you know when 1.54 might come out?
Thanks again
 
And thank you Michael, you've helped me tremendously. I now have a lot to think about.
Do you know when 1.54 might come out?
Thanks again

Well that is a Paul question, but from afar I see we are making progress, but I'm not sure how long it will take before the things gel. There are several threads with the various parts being discussed.
 
Status
Not open for further replies.
Back
Top