Cannot Mix Playing WAV snd MP3 files with latest cores library...

wwatson

Well-known member
Was testing playing both wav and mp3 files off of both SD and USB drives. For some reason only the mp3 files would play. Using Arduino 1.8.19 and TD1.57B1 and the latest cores from @KurtE's GitHub (06-03-22).

Also using mjs513's 'PLAYALL_SD_ONLY.ino' located in the 'examples/mjs' folder in the FrankB's Arduino-Teensy-Codec-lib here:
https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib

I narrowed it down to this:
Code:
// GUItool: begin automatically generated code
[COLOR="#00FF00"]AudioPlaySdMp3           playMp31;       //xy=154,78[/COLOR]
[COLOR="#FF0000"]AudioPlaySdWav           playWav; //xy=154,422[/COLOR]
AudioPlaySdRaw           playRaw; //xy=154,422
AudioPlaySdAac           playAac; //xy=154,422
AudioPlaySdFlac          playFlac;
AudioOutputI2S           i2s1;           //xy=334,89
AudioConnection          patchCord3(playWav, 0, i2s1, 0);
AudioConnection          patchCord4(playWav, 1, i2s1, 1);
AudioConnection          patchCord1(playMp31, 0, i2s1, 0);
AudioConnection          patchCord2(playMp31, 1, i2s1, 1);
AudioConnection          patchCord5(playAac, 0, i2s1, 0);
AudioConnection          patchCord6(playAac, 1, i2s1, 1);
AudioConnection          patchCord7(playRaw, 0, i2s1, 0);
AudioConnection          patchCord8(playFlac, 0, i2s1, 0);
AudioConnection          patchCord9(playFlac, 1, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=240,153

If I swapped the the order of the red and green line so that playWav was first then the the wav files would play but not the mp3 files. I remembered that I was getting a warning about AudioStream::release(block); that I posted about here:
https://forum.pjrc.com/threads/68139-Teensyduino-File-System-Integration-including-MTP-and-MSC/page50 post #1235.

To get to the point, I copied AudioStream.cpp and AudioStream.h files from the original TD1.57B1 cores library to the updated cores library that I downloaded and It solved the problem. I was able to play both wav and mp3 files consecutively. I know everybody is busier than heck right now but I thought had better bring it up before the next TD release in case it is a problem:)
 
You seem to be trying to make multiple connections to the i2s1 inputs.
Connection Rules & Guidelines

Normally a single output connects to a single input.
You may send the output from one object to as many inputs as you like. The audio library efficiently handles objects sharing the output of an object.

However, each input can receive only a single connection
 
You seem to be trying to make multiple connections to the i2s1 inputs.

I guess... I am not very familiar with the inner workings of the Audio library. The sketch above was developed by @mjs513 when a few of us were working with playing wav files with LittleFS and MSC. Fact is it did and still does work:) The wav and mp3 files are not being played at the same time. The sketch scans the SD card for music files and if the file extension matches one of the 5 types supported it will play the file. The problem occurred when I updated to the latest unreleased cores library for testing MTP. That's when I discovered that something had changed with AudioStream.cpp and/or AudioStream.h.
 
Technically you're not supposed to make more than 1 audio connection to each input. The graphical design tool won't do it, but of course you can do anything if you just edit the source code.

Whether we should preserve the old behavior is a good question. Truth is, it wasn't ever designed to be anything in particular, but looks like it ended up allowing multiple inputs in some limited cases like these file players which don't transmit data while not playing (as opposed to transmitting buffers filled with zeros).
 
Technically you're not supposed to make more than 1 audio connection to each input. The graphical design tool won't do it, but of course you can do anything if you just edit the source code.

Whether we should preserve the old behavior is a good question. Truth is, it wasn't ever designed to be anything in particular, but looks like it ended up allowing multiple inputs in some limited cases like these file players which don't transmit data while not playing (as opposed to transmitting buffers filled with zeros).

Since I had no idea of the rule or why since I don't normally play with the Audio library I am curious about the construct in post #1. Guess its a question.

If I am only playing 1 output type (Wav, MP3, FLAC, etc) at a time (since it depends on file type is it really breaking the rule when I set up the connections. If the rule is enforced in the code may limit a music players ability to play multiple types? Please forgive me - no idea if this makes sense. Or is that what mixers are for... guess I need a lesson in audio.

Example
Capture.PNG
 
@wwatson and anyone who wants to check this. I rewickered the constructors and setup for the PLAYALL_SD_ONLY.ino example. Not sure what to do with Raw since the mixers only take 4 inputs.

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

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

// GUItool: begin automatically generated code
AudioPlaySdMp3           playMp31;       //xy=154,78
AudioPlaySdWav           playWav; //xy=154,422
AudioPlaySdRaw           playRaw; //xy=154,422
AudioPlaySdAac           playAac; //xy=154,422
AudioPlaySdFlac          playFlac;

AudioOutputI2S           i2s1;           //xy=334,89

AudioMixer4              mixer1;         //xy=623.0000038146973,393.00000381469727
AudioMixer4              mixer2; //xy=626.0000038146973,490.00000381469727
AudioOutputI2S           i2s1;           //xy=831.0000057220459,452.00000381469727
AudioConnection          patchCord1(playMp31, 0, mixer1, 3);
AudioConnection          patchCord2(playMp31, 1, mixer2, 3);
AudioConnection          patchCord3(playWav, 0, mixer1, 1);
AudioConnection          patchCord4(playWav, 1, mixer2, 1);
AudioConnection          patchCord5(playAac, 0, mixer1, 0);
AudioConnection          patchCord6(playAac, 1, mixer2, 0);
AudioConnection          patchCord7(playFlac, 0, mixer1, 2);
AudioConnection          patchCord8(playFlac, 1, mixer2, 2);
AudioConnection          patchCord9(mixer1, 0, i2s1, 0);
AudioConnection          patchCord10(mixer2, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=379.00000381469727,607.0000038146973
// GUItool: end automatically generated code


void setup() {
  // Open serial communications and wait for port to open
  while (!Serial && !Serial.available() && millis() < 5000){} 

  Serial.print(CrashReport);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  
  AudioMemory(40);
  sgtl5000_1.enable();
  sgtl5000_1.volume(volume);
  
	mixer1.gain(0, volume);
	mixer1.gain(1, volume);
	mixer1.gain(2, volume);
	mixer1.gain(3, volume);
	
	mixer2.gain(0, volume);
	mixer2.gain(1, volume);
	mixer2.gain(2, volume);
	mixer2.gain(3, volume);
	
  if (!(SD.begin(BUILTIN_SDCARD))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  Serial.println("initialization done.");
  root = SD.open("/");

}
 
Not sure what to do with Raw since the mixers only take 4 inputs.
At the moment, you add another layer of mixers: a bit messy, but they consume very little CPU if the channel gains are set to 1.0 or 0.0, or if the source is not transmitting audio blocks. That's why the OP sketch works, as the old AudioConnection object would transmit a block if the input hadn't already got one. Had the various players been transmitting silent blocks (which I wouldn't recommend, not transmitting is definitely cleaner) the issue would have been visible earlier.

As part of the Dynamic Audio effort @manicksan and I have created arbitrary-width mixers (well, up to 255 inputs, in theory) with both mono and stereo output types. These could easily be made to work with the current static scheme if needs be, and would tidy this project up a treat - just use a 10-input stereo-output mixer.

Technically you're not supposed to make more than 1 audio connection to each input. The graphical design tool won't do it, but of course you can do anything if you just edit the source code.

Whether we should preserve the old behavior is a good question. Truth is, it wasn't ever designed to be anything in particular, but looks like it ended up allowing multiple inputs in some limited cases like these file players which don't transmit data while not playing (as opposed to transmitting buffers filled with zeros).
My (admittedly biassed!) vote is to stick with the documented and now-enforced behaviour. It'll be a pain to put the old behaviour back in, and it's non-deterministic because it depends on the execution order of the preceding audio blocks (which has always been semi-opaque), and on how they behave when they are producing no output (silent blocks or not calling transmit()).
 
@wwatson and anyone who wants to check this. I rewickered the constructors and setup for the PLAYALL_SD_ONLY.ino example. Not sure what to do with Raw since the mixers only take 4 inputs.

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

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

// GUItool: begin automatically generated code
AudioPlaySdMp3           playMp31;       //xy=154,78
AudioPlaySdWav           playWav; //xy=154,422
AudioPlaySdRaw           playRaw; //xy=154,422
AudioPlaySdAac           playAac; //xy=154,422
AudioPlaySdFlac          playFlac;

AudioOutputI2S           i2s1;           //xy=334,89

AudioMixer4              mixer1;         //xy=623.0000038146973,393.00000381469727
AudioMixer4              mixer2; //xy=626.0000038146973,490.00000381469727
AudioOutputI2S           i2s1;           //xy=831.0000057220459,452.00000381469727
AudioConnection          patchCord1(playMp31, 0, mixer1, 3);
AudioConnection          patchCord2(playMp31, 1, mixer2, 3);
AudioConnection          patchCord3(playWav, 0, mixer1, 1);
AudioConnection          patchCord4(playWav, 1, mixer2, 1);
AudioConnection          patchCord5(playAac, 0, mixer1, 0);
AudioConnection          patchCord6(playAac, 1, mixer2, 0);
AudioConnection          patchCord7(playFlac, 0, mixer1, 2);
AudioConnection          patchCord8(playFlac, 1, mixer2, 2);
AudioConnection          patchCord9(mixer1, 0, i2s1, 0);
AudioConnection          patchCord10(mixer2, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=379.00000381469727,607.0000038146973
// GUItool: end automatically generated code


void setup() {
  // Open serial communications and wait for port to open
  while (!Serial && !Serial.available() && millis() < 5000){} 

  Serial.print(CrashReport);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  
  AudioMemory(40);
  sgtl5000_1.enable();
  sgtl5000_1.volume(volume);
  
	mixer1.gain(0, volume);
	mixer1.gain(1, volume);
	mixer1.gain(2, volume);
	mixer1.gain(3, volume);
	
	mixer2.gain(0, volume);
	mixer2.gain(1, volume);
	mixer2.gain(2, volume);
	mixer2.gain(3, volume);
	
  if (!(SD.begin(BUILTIN_SDCARD))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  Serial.println("initialization done.");
  root = SD.open("/");

}

I to am not that familiar with the Audio library:) I am setup to test so will modify the sketch and try out the changes...
 
@mjs513 - Your changes took care of the issue. installed the latest pre-release of the cores library and was able to consecutively play wav and mp3 files. Don't have any ogg, flac or raw files to test with at this point. So what appeared to happen was with the original AudioStream.cpp an .h files the "rule" was not being enforced for some reason and with the latest AudioStream.* it did. I'll update my Arduino-Teeny-Codec-Lib with any possible changes from @FrankB's REPO and then add the changes to PLAYALL_SD_ONLY.ino.

Issue resolved:)

EDIT: Working version of Audio-Teensy-Codecs-Lib:
https://github.com/wwatson4506/Arduino-Teensy-Codec-lib
 
Last edited:
@mjs513 - Your changes took care of the issue. installed the latest pre-release of the cores library and was able to consecutively play wav and mp3 files. Don't have any ogg, flac or raw files to test with at this point. So what appeared to happen was with the original AudioStream.cpp an .h files the "rule" was not being enforced for some reason and with the latest AudioStream.* it did. I'll update my Arduino-Teeny-Codec-Lib with any possible changes from @FrankB's REPO and then add the changes to PLAYALL_SD_ONLY.ino.

Issue resolved:)

EDIT: Working version of Audio-Teensy-Codecs-Lib:
https://github.com/wwatson4506/Arduino-Teensy-Codec-lib

Sorry for the delay in my response - been distracted with MTP again (my sketch now working again ). Glad its working again.
 
@wwatson
Playing some more with the sketch and rewickered setup and the mixer connections per @h4yn0nnym0u5e suggestion so now can now play .raw files as well. Did reset everything up and it is working.
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <play_sd_mp3.h>
#include <play_sd_aac.h>
#include <play_sd_flac.h>

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

AudioPlaySdMp3           playMp31;       //xy=154,78
AudioPlaySdWav           playWav; //xy=154,422
AudioPlaySdRaw           playRaw; //xy=154,422
AudioPlaySdAac           playAac; //xy=154,422
AudioPlaySdFlac          playFlac;

// GUItool: begin automatically generated code
AudioOutputI2S           i2s1;           //xy=1023.0000076293945,500.00000286102295
AudioMixer4              mixer1;         //xy=625.0000038146973,393.00000381469727
AudioMixer4              mixer2; //xy=626.0000038146973,490.00000381469727
AudioMixer4              mixer3; //xy=811.0000076293945,571.0000038146973
AudioMixer4              mixer4; //xy=816.0000057220459,655.0000038146973
AudioConnection          patchCord1(playWav, 0, mixer1, 3);
AudioConnection          patchCord2(playWav, 1, mixer2, 3);
AudioConnection          patchCord3(playMp31, 0, mixer1, 1);
AudioConnection          patchCord4(playMp31, 1, mixer2, 1);
AudioConnection          patchCord5(playAac, 0, mixer1, 0);
AudioConnection          patchCord6(playAac, 1, mixer2, 0);
AudioConnection          patchCord7(playFlac, 0, mixer1, 2);
AudioConnection          patchCord8(playFlac, 1, mixer2, 2);
AudioConnection          patchCord9(mixer1, 0, mixer3, 0);
AudioConnection          patchCord10(mixer2, 0, mixer4, 0);
AudioConnection          patchCord11(playRaw, 0, mixer3, 1);
AudioConnection          patchCord12(playRaw, 0, mixer4, 1);
AudioConnection          patchCord13(mixer3, 0, i2s1, 0);
AudioConnection          patchCord14(mixer4, 0, i2s1, 1);
AudioControlSGTL5000     sgtl5000_1;     //xy=385,688.0000038146973// GUItool: end automatically generated code
// GUItool: end automatically generated code

float volume = 0.6f;

File root, entry;

void setup() {
  // Open serial communications and wait for port to open
  while (!Serial && !Serial.available() && millis() < 5000){} 

  Serial.print(CrashReport);
  Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
  
  AudioMemory(40);
  sgtl5000_1.enable();
  sgtl5000_1.volume(volume);
  
	mixer1.gain(0, 1.0f);
	mixer1.gain(1, 1.0f);
	mixer1.gain(2, 1.0f);
	mixer1.gain(3, 1.0f);
	
	mixer2.gain(0, 1.0f);
	mixer2.gain(1, 1.0f);
	mixer2.gain(2, 1.0f);
	mixer2.gain(3, 1.0f);
	
	mixer3.gain(0, volume);
	mixer3.gain(1, volume);
	mixer3.gain(2, volume);
	mixer3.gain(3, volume);
	
	mixer4.gain(0, volume);
	mixer4.gain(1, volume);
	mixer4.gain(2, volume);
	mixer4.gain(3, volume);
	
  if (!(SD.begin(BUILTIN_SDCARD))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
  Serial.println("initialization done.");
  root = SD.open("/");

}
 
Running into another problem - cant seem to play anything from littlefs

Just tried myself with QPINAND and the MEM board. Both MP3 and WAV files play... I have not Updated the PLAY-All sketch yet with your changes above. Probably won't have time tonight as I am dealing with replacing a stolen phone:(

Will play tomorrow night.
 
Is this the problem we set up a littlefs in our array of them that used pin 7 which is used by audio board?
 
Back
Top