Teensy 3.6 Multiple AudioPlaySdWav players

Status
Not open for further replies.

qniens

Member
Hi all,
I'm a bit confused about the Teensy 3.6 capabilities. I bought a Teensy 3.6 with the assumption that it would play multiple wav files polyphonic.
Because the audio designer let's you add multiple players and the manual/comments suggest using the optimized SD_t3.h library.

Doing some research I find out that the SD_t3.h is abandoned and doesn't even support the Teensy 3.6 internal SD reader.
Why is it still included in the SDK with the header /* Optimized SD Library for Teensy 3.X?
This is somewhat misleading...

The wish for proper polyphonic wav playback is also in the roadmap:
https://www.pjrc.com/teensy/td_libs_AudioRoadmap.html

I have tried 3 SD Card: Sandisk Ultra 16GB, Kingston Class 4 8GB and even a Sandisk 64GB Extreme Pro A2 (10.000 IOPS).
None of them if able just to play 2 stereo wav files without random glitches/plops. Usually glitches are mostly in the beginning of playing a file.

Is there something else I can try? Loading the files into Flash memory is no option because I need a couple of minutes stereo playback....

Thank you
 
The problem is that these cards are very slow when it comes to random accesses which occur when you play two files or more files.

The fastest card I ever had was 5 times faster with random access, it was a very very old unknown brand 512MB (yes, not GB) card.

The only way around this would be to use large read-ahead buffers and caching the FAT. Increasing the read-speed helps only a little bit, but perhaps enough to play two files.
So it's a tradeoff between memory consumption (not good on 3.2) and speed.

On 3.5/3.6 best is to use the on board sd-slot - not the one on the audio shield.
 
You can try to edit the audio-library and just search/replace the include "SD.h" with SDFat.h by Bill Greimann. This gives you long filenames, too. Maybe some additional minor edits are needed.

Some time ago I made a poll "who wants a fork with sdfat?" But there was little to no reaction - So I've spent my time for more useful things.
 
Or convert the files to 128K AAC and use my MP3/AAC library. I've not tried it, but as it read larger chunks and less often chances are good that it will work. On the other hand, decoding MP3/AAC needs more than 30KB RAM per file.
 
Hi Frank,
Thank you for your reply.

I'm aware of the slow card random access speed. I have worked with the Sparkfun WAV Trigger and it has the same issues with slow cards.
See this web page dedicated to this issue: https://robertsonics.com/microsd-cards-for-audio/
I have the Kingston 4G SDC4/4GB that I have inserted into the onboard Teensy 3.6 SD card reader. No PJRC Audio board but a external I2S DAC.


I tried to replace all the #include "SD.h" with #include "SdFat.h"

This generated a error in play_sd_wav.cpp line 71 and play_sd_raw.cpp on line 49.
Both errors was that SD was not defined. So I added these two lines into the files:

SdFatSdioEX SD;
SD.chvol();


When I compile a modified version of the WavFilePlayer it is compiling without errors and uploading to the Teensy 3.6.
Only the play() function isn't working anymore. It is doing 'nothing'. isPlaying() also returns 0.

Could you give me a direction where to look to solve this issue?

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
//#include <SD.h>
#include "SdFat.h"
#include <SerialFlash.h>

AudioPlaySdWav           playWav1;
AudioOutputI2S           audioOutput;
AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);


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


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

  AudioMemory(8);

  Serial.print("Initializing SD card...");

  SdFatSdioEX SD;

  if (!SD.begin()) {
    //sd.initErrorHalt("SdFatSdioEX begin() failed");
    Serial.println("initialization failed!");
  }
  // make sdEx the current volume.
  SD.chvol();

  Serial.println("initialization done.");


  playWav1.play("SDTEST3.WAV");

  // A brief delay for the library read WAV info
  delay(100);
  Serial.println(playWav1.isPlaying());
}

void loop() {
}
 
I'm not @ my computer - maybe tonight (Europe).
Perhaps try MP3 until then, if you need it faster. You need 44.1kHz samplerate + not too high bitrate.
 
I tried the MP3 and FLAC players. They both work perfect if you only play 1 file. If you try to start a second stream all the audio cuts out. Is this because the calculations are to complex/heavy for the CPU?

Thank you for pointing out these libraries. Hopefully you have some time this week and could look what I'm doing wrong with integrating the SdFat library
 
no the 3.6 can easily decode way more, at least with mp3. Last time I tried that it worked flawlessly.. okay that was some time ago.
 
Please see this simple code for testing two MP3 players. As soon as the second player start the first one stops.

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

// GUItool: begin automatically generated code
//AudioPlaySdWav           sdPlayer0;     //xy=360,223
//AudioPlaySdWav           sdPlayer1;     //xy=360,307

AudioPlaySdMp3           sdPlayer0;     //xy=360,223
AudioPlaySdMp3           sdPlayer1;     //xy=360,307

AudioMixer4              mixerRight;         //xy=646,308
AudioMixer4              mixerLeft;         //xy=648,211
AudioOutputI2S           i2sOutput;           //xy=903,257
AudioConnection          patchCord1(sdPlayer0, 0, mixerLeft, 0);
AudioConnection          patchCord2(sdPlayer0, 1, mixerRight, 0);
AudioConnection          patchCord3(sdPlayer1, 0, mixerLeft, 1);
AudioConnection          patchCord4(sdPlayer1, 1, mixerRight, 1);
AudioConnection          patchCord5(mixerRight, 0, i2sOutput, 1);
AudioConnection          patchCord6(mixerLeft, 0, i2sOutput, 0);
// GUItool: end automatically generated code

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


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

  AudioMemory(8);

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


  sdPlayer0.play("SDTEST1.mp3");
  delay(2000);
  sdPlayer1.play("SDTEST3.mp3");
  
  Serial.print("Memory: ");
  Serial.println(AudioMemoryUsageMax());

  Serial.print("CPU: ");
  Serial.println(AudioProcessorUsageMax());
}

void loop() {
}
 
Hi, i've attached a patched version of the audio-library.

Sketch:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
//#include <SD.h>
#include "SdFat.h"
#include <SerialFlash.h>

AudioPlaySdWav           playWav1;
AudioPlaySdWav           playWav2;
AudioOutputI2S           audioOutput;
AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav2, 0, audioOutput, 1);

AudioControlSGTL5000     sgtl5000_1;

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

  SdFatSdioEX SD;

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

  AudioMemory(10);
  sgtl5000_1.enable();
  sgtl5000_1.volume(0.5);
  
  Serial.print("Initializing SD card...");



  if (!SD.begin()) {
    //sd.initErrorHalt("SdFatSdioEX begin() failed");
    Serial.println("initialization failed!");
  }
  // make sdEx the current volume.
  SD.chvol();

  Serial.println("initialization done.");


  playWav1.play("SDTEST1.WAV");
  delay(300);
  playWav2.play("SDTEST3.WAV");

  // A brief delay for the library read WAV info
  delay(100);
  Serial.println(playWav1.isPlaying());
  Serial.println(playWav2.isPlaying());
}

void loop() {
}

For MP3: I'll look.. maybe next weekend if I have time.. maybe, when I tried that, it was a different version ... it's too long ago to remember.
 

Attachments

  • Audio_sdfat.zip
    386.9 KB · Views: 81
Dear Frank,
Thank you for the patched library. I will give it a try. On a other thread Chris sent my also modified version of the Audio library.
I have SdFat working now with the Audio library.

Unfortunately the SdFat is also not fast enough to reliable play two stereo wav files together. It does a much better job then SD library, but sometimes you get a nasty glitch sound when starting the second playSdWav player.

Is there a way to increase the buffer length when reading from the SD card? This will increase latency of course but gives better stability.
 
Status
Not open for further replies.
Back
Top