Now for MP3 with FS...

@mjs513 - This is cool. Got the day off today so have time to play and test your development with MTP and MP3. Going to spend some more time with Arduino-Teensy-Codec-lib today as well. Clean my mess up. I know that there is a better way do do the buffering than the way I have it done now. Then issue a PR to FrankB.

Thanks for testing:)
 
@mjs513 - Your MTP version is working on my end:) One thing I noticed is it is only playing one channel. The right channel I think. Did you set it up that way? Otherwise it played all the songs that I had on all of the devices. Enjoying the heck out of this:)
 
@mjs513 - Your MTP version is working on my end:) One thing I noticed is it is only playing one channel. The right channel I think. Did you set it up that way? Otherwise it played all the songs that I had on all of the devices. Enjoying the heck out of this:)

Glad you are enjoying it. Should be playing 2 channels unless I didn;t set the audio up right - only use 1 speaker on the audio jack. So can't really tell :)

EDIT: UPDATED
think for wav files I forgot to add:
Code:
AudioConnection          patchCord4(playWav, 1, mixer1, 3);

Not sure what else is needed to make it work correctly
 
Last edited:
Glad you are enjoying it. Should be playing 2 channels unless I didn;t set the audio up right - only use 1 speaker on the audio jack. So can't really tell :)

EDIT: UPDATED
think for wav files I forgot to add:
Code:
AudioConnection          patchCord4(playWav, 1, mixer1, 3);

Not sure what else is needed to make it work correctly

Thanks, Will add it in and test. As a side note was looking at FLAC type and it looks it uses a lot of dynamic memory allocation which appears to be based on a variable block size. If I am right. This is going to make it very challenging to make it work with MSC:( Other more important things to confuse me right now:)
 
Yes, the blocksize is a real showstopper for FLA on microcontrollers. The memory usage is ... pervert... :)
I've added some example files here (Blocksize up to 1024) : https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib/tree/master/examples/testfiles
Up to 512 worked ok on a T3.2 - but this small blocksize is unusual.

Best is, to convert existing files to a smaller blocksize - but this affects the compression ratio.
In sum, FLA does not make much sense on micros... wave is larger, but needs way less ram and today SD is fast enough.

Apart of that, anyone who says he can hear a difference between a 256K AAC and a "lossless" file, buys golden speaker cables and plays vinyl only because the audio quality is better, of course... and is afraid of black cats...
(/Yes, AAC is indeed much better quality than MP3 (with same bitrate)) I have no Idea why everybody uses mp3...
 
Last edited:
Yes, the blocksize is a real showstopper for FLA on microcontrollers. The memory usage is ... pervert... :)
I've added some example files here (Blocksize up to 1024) : https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib/tree/master/examples/testfiles
Up to 512 worked ok on a T3.2 - but this small blocksize is unusual.

Best is, to convert existing files to a smaller blocksize - but this affects the compression ratio.
In sum, FLA does not make much sense on micros... wave is larger, but needs way less ram and today SD is fast enough

Thanks for the info Frank. Probably won't put much if any effort into it:)
 
Yes, the blocksize is a real showstopper for FLA on microcontrollers. The memory usage is ... pervert... :)
I've added some example files here (Blocksize up to 1024) : https://github.com/FrankBoesing/Arduino-Teensy-Codec-lib/tree/master/examples/testfiles
Up to 512 worked ok on a T3.2 - but this small blocksize is unusual.

Best is, to convert existing files to a smaller blocksize - but this affects the compression ratio.
In sum, FLA does not make much sense on micros... wave is larger, but needs way less ram and today SD is fast enough.

Apart of that, anyone who says he can hear a difference between a 256K AAC and a "lossless" file, buys golden speaker cables and plays vinyl only because the audio quality is better, of course... and is afraid of black cats...
(/Yes, AAC is indeed much better quality than MP3 (with same bitrate)) I have no Idea why everybody uses mp3...

Yes - thanks Frank. Learn something new every day. The FLA I was using to test has a blocksize of 1024 going to try the smaller ones just to be sure it works. And you are right just on my cheap-o speaker AAC sounds better.
 
@wwatson - @Frank B
Tried the FLAC test files with the smaller blocksizes so still no dice. So for the heck of it I tried the example FLAC sketch in the library using SIDO and the T1_128.FLA on the SD Card. Interestingly enough it has the same problem - it says its playing with audio usage of 0.06% usage:
Code:
0.06% Audio
0.06% Audio
0.06% Audio
But no sound.

Also tried the example sketch on the T3.6 and it didn't work there either.

EDIT: Wondering if its the same problem as you had with the MP3?
 
Last edited:
@Frank B = @wwatson

Made a change to OpusPlayFile sketch and that is working on the T4.1 - used Frank's instructions in the referenced thread. Going to add it to MTP_test_audio sketch - probably in the morning - it does sound good :)
Code:
// Simple Opus file player example
//
// Requires the audio shield:
//   http://www.pjrc.com/store/teensy3_audio.html
//
// This example code is in the public domain.

#include <Audio.h>
#include <utility/imxrt_hw.h> //this has to go after audio.
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

#include <play_sd_opus.h>

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

//Here's the function to change the sample rate of the system (via changing the clocking of the I2S bus)
//https://forum.pjrc.com/threads/38753-Discussion-about-a-simple-way-to-change-the-sample-rate?p=121365&viewfull=1#post121365
void setI2SFreq(int freq) { //Teensy 4
  // PLL between 27*24 = 648MHz und 54*24=1296MHz
  int n1 = 4; //SAI prescaler 4 => (n1*n2) = multiple of 4
  int n2 = 1 + (24000000 * 27) / (freq * 256 * n1);
  double C = ((double)freq * 256 * n1 * n2) / 24000000;
  int c0 = C;
  int c2 = 10000;
  int c1 = C * c2 - (c0 * c2);
  set_audioClock(c0, c1, c2, true);
  CCM_CS1CDR = (CCM_CS1CDR & ~(CCM_CS1CDR_SAI1_CLK_PRED_MASK | CCM_CS1CDR_SAI1_CLK_PODF_MASK))
       | CCM_CS1CDR_SAI1_CLK_PRED(n1-1) // &0x07
       | CCM_CS1CDR_SAI1_CLK_PODF(n2-1); // &0x3f 
}

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

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

  sgtl5000_1.enable();
  sgtl5000_1.volume(0.6);

  if (!(SD.begin(BUILTIN_SDCARD))) {
    // 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.
  playOpus1.play(filename);
  setI2SFreq(48000);

  // Simply wait for the file to finish playing.
  while (playOpus1.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 1	 
	 Serial.print(AudioProcessorUsageMax());
	 Serial.println("% Audio");
	 AudioProcessorUsageMaxReset();
#endif	
	 delay(200); 
  }
}


void loop() {
  playFile("256K.OPU");

  delay(500);
}
 
@mjs513 - Kinda cleaning up the mess I made with this. Right now I am redoing the buffer allocation to make it less invasive on @FrankB's library. What I have done to make this work with MSC is a workaround. Been experimenting with ways to keep the original buffering and only use a static buffer if MSC is involved. At one point early on I had a define that I used to recognize MSC usage. That got lost with UsbMscFat. Soooo... I think to start off with I need to add a define to USBHost_t36-FS_integration_MSC like #define USING_MSC. That way I can make use of conditional buffering and preserve the original malloc/calloc for anything else other than MSC. Also not sure how all of this will end up with final decisions on usage of MSC:)
 
@mjs513 - Kinda cleaning up the mess I made with this. Right now I am redoing the buffer allocation to make it less invasive on @FrankB's library. What I have done to make this work with MSC is a workaround. Been experimenting with ways to keep the original buffering and only use a static buffer if MSC is involved. At one point early on I had a define that I used to recognize MSC usage. That got lost with UsbMscFat. Soooo... I think to start off with I need to add a define to USBHost_t36-FS_integration_MSC like #define USING_MSC. That way I can make use of conditional buffering and preserve the original malloc/calloc for anything else other than MSC. Also not sure how all of this will end up with final decisions on usage of MSC:)

Think the real issue is why isn't malloc/calloc working with MSC to begin with - maybe @KurtE has an idea.
 
@mjs513 - I agree. That is the root problem...

If I trace it through allocateBuffer is defined in codecs.h as:
Code:
	uint8_t *allocBuffer(size_t size) { rdbufsize = size;  bufptr = (uint8_t *) calloc(size,1); return bufptr;}
malloc seems to work as we are using it in the next lines in play_sd_mp3.cpp, so the issue is with either with calloc or this call.

EDIT: Ok think I got it working changed calloc so it reads as:
Code:
	uint8_t *allocBuffer(size_t size) { 
		rdbufsize = size;  
[COLOR="#FF0000"]		bufptr = (uint8_t *) calloc(size,sizeof(uint8_t)); 
[/COLOR]		return bufptr;
	}

Can you give it a try on your end?
 
Last edited:
Think the real issue is why isn't malloc/calloc working with MSC to begin with - maybe @KurtE has an idea.
Ideas? Maybe not ;) Darts(Questions)? Maybe :D

Things like: How often is allocBuffer called? And for what sizes? Is it ever called with 0? Does that cause problems?
Why does it use calloc versus malloc? I assume he has done that to zero the memory?

I believe you said it works with static buffer instead?
If so have you tried the static buffer using DMAMEM? does it make a difference?

is by chance something defining calloc to be extmem_calloc() or to some other smalloc buffer pool? sm_calloc ?
If so does you board have a PSRAM? If so could be allocating memory from PSRAM which can be pretty slow?

You might try instrumenting the call to see sizes and return pointers, which will tell you where memory is allocated, how often and any interesting sizes

Sorry again dart board.
 
- How often is allocBuffer called?
one time, on init or when playing a new file
- And for what sizes?
Forgot that... wasn't a problem for the 3.2 - in sum around ~30kB if I remember correctly
- Is it ever called with 0?
no.
- I assume he has done that to zero the memory
Yes. It's important that is zeroed.
You could use a memset, but that will not help, as it does the same.

Could it be that the heap pointers a destroyed..? wrong cache handling? ;) There was a thread... However, that can't happen by definition because an added comment in the core sourcecode makes sure that this can't happen. And of course everything is 32 Byte aligned... and covid does not exist. ;)
Btw, in contrast to some prominent cache handling functions, malloc works with a zero-size call... no need to check that (but still, it does not happen here)

Simple test: If it (or something else with problems) works with cache disabled (startup.c) there is a cache problem.
Takes 2 minutes.
 
Last edited:
- How often is allocBuffer called?
one time, on init or when playing a new file
- And for what sizes?
Forgot that... wasn't a problem for the 3.2 - in sum around ~30kB if I remember correctly
- Is it ever called with 0?
no.
- I assume he has done that to zero the memory
Yes. It's important that is zeroed.
You could use a memset, but that will not help, as it does the same.

Could it be that the heap pointers a destroyed..? wrong cache handling? ;) There was a thread... However, that can't happen by definition because an added comment in the core sourcecode makes sure that this can't happen. And of course everything is 32 Byte aligned... and covid does not exist. ;)
Btw, in contrast to some prominent cache handling functions, malloc works with a zero-size call... no need to check that (but still, it does not happen here)

Simple test: If it (or something else with problems) works with cache disabled (startup.c) there is a cache problem.
Takes 2 minutes.

Code:
How often is allocBuffer called?
In post #39 I showed a solution to the issue with calloc. The compiler doesn't like calloc(size, 1) but it likes calloc(size, sizeof(uint8_t)) and it also works with calloc(size, (uint8_t) 1). If you remember this issue cropped up once before.

So now the issue is with why aren't FLAC files playing. Tried all sample files but non are playing - none of them are returning any errors just for reference.
 
Sorry, Just got back from work. We are getting flooded out again. Looks like you guy's have been busy. I am expecting to get called back in to work tonight but will try to get caught up and do some testing if I can.
 
Sorry, Just got back from work. We are getting flooded out again. Looks like you guy's have been busy. I am expecting to get called back in to work tonight but will try to get caught up and do some testing if I can.

Don't worry about this stuff - take care of business and yourself then worry about this.
 
@FrankB - Wow, commented out 'configure_cache(); ' line #117 in startup.c and retested with calloc(size,1). MP3 files play and repeat playing, Not even going to try to figure out why:) Will just continue with the workaround of a static buffer for now. Thanks for the pointer.
 
Don't worry about this stuff - take care of business and yourself then worry about this.

Thanks Mike. Just got called back in:( Had enough time to test a suggestion from @FrankB about the cache. That took care of the problem we were seeing with MSC and MP3 files playing once then choking or not playing at all. Post #47. Not sure why and my skill level with this device is not enough to try and figure out. But, just wondering if it is a ref man problem like in this post I saw today:
https://forum.pjrc.com/threads/68835-PXP-documentation-error?
 
Thanks Mike. Just got called back in:( Had enough time to test a suggestion from @FrankB about the cache. That took care of the problem we were seeing with MSC and MP3 files playing once then choking or not playing at all. Post #47. Not sure why and my skill level with this device is not enough to try and figure out. But, just wondering if it is a ref man problem like in this post I saw today:
https://forum.pjrc.com/threads/68835-PXP-documentation-error?

Did that happen even with the fix to calloc that I showed -calloc(size, (uint8_t) 1);
 
@wwatson - @Frank B
Tried turning off cache to see if it would help playing FLA files and to resolve another issue I was having, i.e., after playing a bunch of wav files (which worked) and then playing a AAC file failed to play even though no errors. Turning cache off worked for the latter case but not for playing FLAC files. I then remembered that we had this discussion someplace else a long time ago and found this: https://forum.pjrc.com/threads/54711-Teensy-4-0-First-Beta-Test?p=194673&viewfull=1#post194673 - look up and down for the whole discussion so changed:
Code:
	SCB_MPU_RBAR = 0x20200000 | REGION(i++); // RAM (AXI bus)
	SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_1M;
to
Code:
	SCB_MPU_RBAR = 0x20200000 | REGION(i++); // RAM (AXI bus)
	SCB_MPU_RASR = MEM_NOCACHE| READWRITE | NOEXEC | SIZE_1M;
and it still worked without commenting out configure_cache. @wwatson you may want to give this a try to see if it works.

@PaulStoffregen is this pointing to some sort of cache problem that we can change in the core or ????
 
Back
Top