TMRh20 / TMRpcm

Arduino library for asynchronous playback of PCM/WAV files direct from SD card. Arduino Uno,Nano,Mega etc supported
http://tmrh20.blogspot.com
594 stars 178 forks source link

ENABLE_MULTI doesn't work with nano #22

Closed orange-cloud closed 4 years ago

orange-cloud commented 9 years ago

Hi, Using a nano v3 328 for slave audio playback in a project of mine with this great library.

However, have an issue. Audio can be played ok on a single channel (pin D9), but when you enable the ENABLE-MULTI option nothing is played on either channel. (pin D9 or pin D10). D10 is correctly set as an output and the SD card cs line is set to pin 4 as per instructions.

What else can i do to resolve this, or is it a bug?

TMRh20 commented 9 years ago

Not sure, as far as I know it should still work, and tests OK on a Mega board.

Have you tried using audio.play("sound.wav",0); and audio.play("sound.wav",1); to specify the separate outputs?

Also what happens if you try to start playback then call audio.isPlaying ? Does it return 1 or 0?

orange-cloud commented 9 years ago

i was using audio.play("sound.wav",0); in my code, but haven't tried the audio.isPlaying option as yet. I notice that the Led on the nano does not activate in the same way as when playing a sound in single channel mode. i.e you can normally see it flickering as the data is accessed off the sd card. In multi mode its not flickering

TMRh20 commented 9 years ago

Ok I finally got a chance to wire up a nano v3.0 and try this out, and was quickly reminded why I generally test these features using a Mega.

  1. The nano could not handle powering the speaker + SD module when playing multi-tracks. I used my mega to power the SD card separately.
  2. The default memory allocation does not use enough memory for multi-track with 328-based devices. To resolve: Edit pcmConfig.h with a text editor. Uncomment #define buffSize 154 to enable a larger memory buffer.

Multi-track is more of a novelty than anything, so may be a bit buggy on the Nano. I'm not sure if this is partly due to the crappy breadboard setup I was using as can be seen in the video below. The Mega has much more memory, and seems to operate better.

Quick and dirty video demo using Nano: http://youtu.be/V39QstC6o3k

orange-cloud commented 9 years ago

My setup is like this - http://mypinballs.com/electronics/pics/cpc-ingame1.jpg , so 1 master mega controlling 2 slave nanos. 1 nano is purely for the sound, which based on the documentation i thought would be sufficient for running purely this library. A mega cannot run my pinball framework and the sound library together as it bogs.

I already run the sd card from my mega's 3.3v power output and have an on board amp to power the speaker, so point 1 is not an issue. In regard to point 2, the buffer size i had set as per the instructions at 128, but will amend to 154 and see if it works ok and report back. Thanks for testing it out.

2 channel playback is an essential for my project, as i need background music and sound/speech effects.

TMRh20 commented 9 years ago

Very nice setup.

There may be other things that affect the performance also. The SD card itself can make a difference, as they will differ in read/write access times, so the memory required can be dependent on that.

I used 16khz sounds in my testing, but if you are creating relatively simple sound effects, you could get away with 11khz samples, which would ease the memory requirements, and improve performance a bit.

orange-cloud commented 9 years ago

Thanks, getting there now after a lot of dev!! and have all the line levels into the amp from the arduino sorted out now (i think!) Also my pinball framework is coming along nicely to.

I am using 32kHz, 8 bit, mono samples at present and i use duracell class 10 8gb sd cards (200x) at the mo. Will they be ok? I will try the change of buffer size and report back. Also, am i correct in thinking that audio files need to be max 8 character in length before the .wav extension??

TMRh20 commented 9 years ago

Off the top of my head, I thought Arduino had problems with class 10 SD cards, but if it works, all the power to you. Files do follow the 8.3 naming convention http://en.wikipedia.org/wiki/8.3_filename so yeah, 8-character limit + extension.

On Tue, May 5, 2015 at 7:42 AM, Jim notifications@github.com wrote:

Thanks, getting there now after a lot of dev!! and have all the line levels into the amp from the arduino sorted out now (i think!) Also my pinball framework is coming along nicely to.

I am using 32kHz, 8 bit, mono samples at present and i use duracell class 10 8gb sd cards (200x) at the mo. Will they be ok? I will try the change of buffer size and report back. Also, am i correct in thinking that audio files need to be max 8 character in length before the .wav extension??

— Reply to this email directly or view it on GitHub https://github.com/TMRh20/TMRpcm/issues/22#issuecomment-99081295.

orange-cloud commented 9 years ago

Hmmm, still can't get the multi-channel working. :( Single channel is working lovely - see here https://youtu.be/TldF3Rgg_14. As soon as i set the ENABLE_MULTI option the sound ceases to function. I just get loud buzzing on either channel. Seems that the arduino is crashing repeatedly on inspection of the serial output. Dynamic memory usage with multi on is 86% and off is 68%

TMRh20 commented 9 years ago

Well it was a bit of a challenge just getting single-track 32khz audio working, so multi-track with 32khz will == buzzing and crashing. As I mentioned, 11khz or so is probably your best bet for initial stability etc. and may not be too bad for sound effects. 16khz seemed maybe a bit much for the Nano.

To be honest, if you are using an Arduino as a dedicated audio device, it would generally handle multi-track better if the library was designed as such. In this case, it uses interrupts to function separate from the main loop, so other tasks can take place as usual. A lib or sketch designed to work as a dedicated audio device would likely be able to offer better performance/higher sample rates.

Edit: A simple start to this would be to possibly take the code from the buffering interrupt and just put it directly into a function called from the main loop, but it might require a few tweaks.

orange-cloud commented 9 years ago

Thanks for the reply. The problem with lower sample rates is the sound/music alters too much if you drop to 11025 . I could probably drop them all to 16000. The music track was actually at 22050 and the effects 32000 before.

It would be really great to be able to configure this library so that it was 'set for dedicated device' playback. Maybe another option that you can build into the config section, though at the mo i'm happy to try and modify it to be more dedicated.

I feel that i'm really close with this and i want to keep using this. Its a great piece of code :) and i really appreciate the support.

TMRh20 commented 9 years ago

Np, also setting audio.quality(0); will disable oversampling, which will also improve performance with multi-track.

Normally, audio samples of 8-16khz are really bad, but the oversampling option (default on) runs timers at 2 * sample rate which removes the standard audible interference usually present in such low frequency samples. You might be surprised at how the audio sounds, even at lower sample rates. Then again, maybe not hehe...

orange-cloud commented 9 years ago

Unfortunately still no joy with any sample rate, or setting the quality to 0 when ENABLE_MULTI is enabled. Seems that the nano isn't even getting past the initialising of the sd card, but constantly rebooting. For the test i wasn't even playing 2 samples together, just calling sound.play("bootup.wav",channel1); or sound.play("bootup.wav",channel2);

orange-cloud commented 9 years ago

Changed the SD card library to use the SD FAT one and got some results. I can now play a single sound on either channel and have had 2 running together (1 music track looped, 1 sound effect single play) but when running 2 together the output seems quieter than normal and the music track is running slow. Also it still seems unstable.

Going to experiment with more sample rates and settings, but the lower rates don't sound too good at the mo. I'd like to try the change to a dedicated setup if possible, though i'm wondering how much this will help and if i'll have to use a mega instead or 1 nano and sd per channel instead. Not a great outcome as it means board re-designs. Seems a shame there isn't a nano type board with more ram.

TMRh20 commented 9 years ago

Teensy has similar form as nano, but uses ARM chip like the Due. Not sure about available libraries, but it is definitely capable of this and more.

orange-cloud commented 9 years ago

Thanks, i'm just thinking about options seeing as the nano seems single channel only really. I could redesign the board to use a board/chipset such as this - https://www.sparkfun.com/products/12897?_ga=1.171834793.86394277.1352196205 if moving away from an atmel chip and your library.

One of my project goals though it to keep the hardware costs down for people, as this board set is a low cost solution for pinheads, so i like the idea of sticking with arduino boards. They are readily available with lots of clones that keep cost down. If using the mega board, what kind of output response and quality could i expect? 32khz, stereo, multichannel? It seems a little strange to use a chip with so many i/o pins but its the ram side of things thats important here. I could also maybe include the display controller code in here to if resources were not stretched by multichannel.

TMRh20 commented 9 years ago

The Mega isn't going to offer much more than the nano. The processor is the same, but RAM allows a bigger buffer, which smooths things out and is less buggy. It will still be nothing like using the wav trigger board mentioned above.

With the quality of work and effort put into your build, using a Mega or Nano for sound is probably only a solution for the lowest of budgets.

orange-cloud commented 9 years ago

Forgot to ask would this library be able to be used on an ARM based device like the one mentioned above?

TMRh20 commented 9 years ago

Oops, sorry for the late reply, but nope, AVR only. There are some ARM/Due libs available.

orange-cloud commented 9 years ago

I tried out using a mega board and using 22kHz sounds for all background music and effects and the results are pretty good so far. I think the previous slow playing background track was due to differing sample rates on channels. I will try this code and files setup using the nano again just to see what happens. The biggest change so far was switching to using the sd fat library, that allowed it to run much cleaner.

TMRh20 commented 9 years ago

Hmm, I forgot about the sdfat library, it should definitely make a difference.

So to recap, I think we've got the following for multi-track playback:

  1. Separate power supply for SD card
  2. Edit pcmConfig.h with a text editor. Uncomment #define buffSize 154 to enable a larger memory buffer (if not using a MEGA).
  3. Use SDFAT library for SD card.
  4. Use audio 22khz or lower
  5. Set audio.quality(0); to disable oversampling

Please let me know of anything else you've found. This info should go into the wiki.

orange-cloud commented 9 years ago

On the mega the list is correct, except i didn't change point 5, as it seemed ok set at audio.quality(1). I will report back on this config on a nano to see. One other thing i did notice so far is that i couldn't get the audio.setVolume(4,0) option to work channel independently, it seemed to change both only. I was experimenting with 'audio ducking', where you lower the background channel slightly when playing a sound/speech call on the other channel to make it slightly clearer.

orange-cloud commented 9 years ago

Hi, I tried my setting again with a nano (set to buffer 154) and no go, so i think the settings above are good for a mega only. Tested many hours with the mega and all good. Still some clicking after play stops on occasional sounds but not all so need to see if there is a pattern there. Also would still like some guidance on the audio.setVolume methods for multichannel use as above. Thanks :)

TMRh20 commented 9 years ago

Apologies for the lack of reply, I must have missed this issue. If still interested, the setVolume functions should work independently, but if not you could try the audio.Volume() function as well if it is a bug in the library.