MP3-Player Lib, with example

Yes, fn is pointing to valid MP3 content.
I have both a "next" and "previous" button and I can cycle back & forth between two files that play just fine. If I cycle too many times the player locks up and no longer responds to buttons. Any serial debugging statements stop printing.
 
Smells like a race condition. :eek:
I can't verify it or anything myself right now, because I'm way too deep in work here.
 
I think I've corrected the problem. I've used my Next/Prev button ~30 times now without an issue.
I added the line:
if (o->playing != codec_playing) return;
to the top of decodeMp3() in play_sd_mp3.cpp.
I also had to move the
playing = codec_playing;
line in play() to be before decodeMP3() is called instead of one of the last lines in play().

I've attached my updated version of play_sd_mp3.cpp
 

Attachments

  • play_sd_mp3.cpp
    7.9 KB · Views: 282
Is there any updates to this thread on MP3 library (i.e. does this now work with the audio.h library or something different)? Can it work with Paul's FFT function from the audio library? On a different note, has anyone attempted to read audio files directly from the USB "debug" port on the Teesny 3.2 or 3.5? It would be alot easier for users to plug in a USB thumb drive with music files rather than the SD card. If not does anyone know if such a audio board exists with USB interface?
 
Is there any updates to this thread on MP3 library (i.e. does this now work with the audio.h library or something different)? Can it work with Paul's FFT function from the audio library? On a different note, has anyone attempted to read audio files directly from the USB "debug" port on the Teesny 3.2 or 3.5? It would be alot easier for users to plug in a USB thumb drive with music files rather than the SD card. If not does anyone know if such a audio board exists with USB interface?

It always worked with the audiolibrary and every part of it.
 
Hello!

Thank for the giant work! The library really rocks!
But is there a way to play 2 mp3 files simultaniously? I need to mix 2 mp3 files using mixer audio object from Teensy audio library. But when I try to play 2 mp3 files or 1 mp3+ 1 aac only one file plays.
 
No sorry, the time I wrote it, the Teensy 3.2 was the biggest model, with the most memory. But it was not enough to play two files simultanously.
 
No sorry, the time I wrote it, the Teensy 3.2 was the biggest model, with the most memory. But it was not enough to play two files simultanously.
Do you plan update your library to support multiple file decoding for teensy 3.5-3.6? It would be really useful function!
 
Hello everyone and I'm sorry for barging in like that as a new member.

First off thank you Frank for your excellent work! My project would be dead in the water without it.

However, if anyone knows, is it possible to use the SD card slot of the Teensy 4.1 instead the one of the audio board? My sketch does find the sd card but does not seem to pass the file to the decoder (using the SDFat library, not SD). Maybe I'm just blind and the solution is easy.

My thought is it's a bit of a waste to send data from the audio board down to the Teensy and then back up. Also read speeds seem to be faster from the on-board sd slot. I looked through the library but I can't find a reason why it would not work. Then again, I'm not that experienced.

Thank you very much for your input.
 
Hello everyone and I'm sorry for barging in like that as a new member.

First off thank you Frank for your excellent work! My project would be dead in the water without it.

However, if anyone knows, is it possible to use the SD card slot of the Teensy 4.1 instead the one of the audio board? My sketch does find the sd card but does not seem to pass the file to the decoder (using the SDFat library, not SD). Maybe I'm just blind and the solution is easy.
You might want to post your code exactly and mention what version of teensy dunio you are using. If you are using Teensy Dunio 1.56, it should just work, assuming you use BUILTIN_SDCARD for the SD card CS pin instead of using 10 (which is the CS card for the audio shield). Note, Teensy Dunio 1.56 uses SDfat underneath, so make sure you eliminate any private copies of SDfat that you have and use the normal SD method to open the file.

Here is a simple wavplayer that I have in my sources that was modified to run on the Teensy 4.1:
Code:
// Simple WAV file player example
//
// Three types of output may be used, by configuring the code below.
//
//   1: Digital I2S - Normally used with the audio shield:
//         http://www.pjrc.com/store/teensy3_audio.html
//
//   2: Digital S/PDIF - Connect pin 22 to a S/PDIF transmitter
//         https://www.oshpark.com/shared_projects/KcDBKHta
//
//   3: Analog DAC - Connect the DAC pin to an amplified speaker
//         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// To configure the output type, first uncomment one of the three
// output objects.  If not using the audio shield, comment out
// the sgtl5000_1 lines in setup(), so it does not wait forever
// trying to configure the SGTL5000 codec chip.
//
// The SD card may connect to different pins, depending on the
// hardware you are using.  Uncomment or configure the SD card
// pins to match your hardware.
//
// Data files to put on your SD card can be downloaded here:
//   http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
//
// This example code is in the public domain.

// This example has been modified to run on the Teensy 3.5, 3.6, and Teensy
// 4.1, using the built-in SD card reader.

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

AudioPlaySdWav           playWav1;
// Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
AudioOutputI2S           audioOutput;
//AudioOutputSPDIF       audioOutput;
//AudioOutputAnalog      audioOutput;
//On Teensy LC, use this for the Teensy Audio Shield:
//AudioOutputI2Sslave    audioOutput;

AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);
AudioControlSGTL5000     sgtl5000_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 (& Teensy 4.1)
#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() {
  Serial.begin(9600);

  // 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.
  // This may wait forever if the SDA & SCL pins lack
  // pullup resistors
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  // These are needed on the Teensy 3.5 and 3.6, but not on the Teensy 4.1
  //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);
    }
  }
}

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 your audio shield has the optional volume
    // potentiometer soldered to it, and you want to use it to control the volume. 
    //float vol = analogRead(15) / 1024.0f;
    //sgtl5000_1.volume(vol);
  }
}


void loop() {
  // In older Teensydunio filenames are always uppercase 8.3 format
  // In newer Teensydunio, you can use VFAT filenames (i.e. mixed case and longer names).
  playFile("SDTEST1.WAV");
  delay(500);
  playFile("SDTEST2.WAV");
  delay(500);
  playFile("SDTEST3.WAV");
  delay(500);
  playFile("SDTEST4.WAV");
  delay(1500);
}

My thought is it's a bit of a waste to send data from the audio board down to the Teensy and then back up. Also read speeds seem to be faster from the on-board sd slot. I looked through the library but I can't find a reason why it would not work. Then again, I'm not that experienced.
The data is always going to go down to the Teensy from the SD card. The only way it would not transfer the data to the Teensy is if you have a separate processor that handles playing the sound (such as the dfplayer). There the Teensy would just send commands to the remote board.
 
Just as I was about to give up for the day and go to bed :D

Thank you thank you thank you thank you!!!. Yes, I was not defining the correct pins. Than's all it was. Here's my test sketch, pretty much like yours:


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

#include <play_sd_mp3.h>


// GUItool: begin automatically generated code
AudioPlaySdMp3           playMp31;       //xy=154,78
AudioOutputI2S           i2s1;           //xy=334,89
AudioConnection          patchCord1(playMp31, 0, i2s1, 0);
AudioConnection          patchCord2(playMp31, 1, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=240,153
// GUItool: end automatically generated code

// Use these with the Teensy 3.5 & 3.6 SD card (& Teensy 4.1)
#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11  // not actually used
#define SDCARD_SCK_PIN   13  // not actually used

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

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

  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);

  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);
    }
  }
}

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

  // Simply wait for the file to finish playing.
  while (playMp31.isPlaying()) {
    // uncomment these lines if your audio shield
    // has the optional volume pot soldered
    //float vol = analogRead(15);
    //vol = vol / 1024;
    // sgtl5000_1.volume(vol);

    if(playMp31.isPlaying()){
    

#if 0	
	 Serial.print("Max Usage: ");
	 Serial.print(playMp31.processorUsageMax());
	 Serial.print("% Audio, ");
	 Serial.print(playMp31.processorUsageMaxDecoder());	 	 
	 Serial.print("% Decoding max, ");
	 
	 Serial.print(playMp31.processorUsageMaxSD());	 
	 Serial.print("% SD max, ");
	 	 
	 Serial.print(AudioProcessorUsageMax());	 
	 Serial.println("% All");
	 
	 AudioProcessorUsageMaxReset();
	 playMp31.processorUsageMaxReset();
	 playMp31.processorUsageMaxResetDecoder();
#endif 
	 
	 delay(250);
  }
}
}


void loop() {
  playFile("Walk with Charlie.mp3");	
  playFile("Cipher.mp3");
  playFile("Snow.mp3");
  delay(500);
}

With "going down" to the Teensy I actually meant physically, because the audio board sits on top of the Teensy. I dunno, just seems cleaner and more efficient this way.

The project is a car stereo together with Nextion display. Weirdly, making Music play was not the first To-Do item on the list, but rather file system navigation and play list creation. So now I can put everything together and finish the project.

Thanks again, Michael. Your help gave me much joy.
 
Back
Top