New library for PWM playback from SD cards: SimpleSDAudio

I hope people are still working with this library. At least I am :slight_smile:

I have got a question. I have built the schematic from the site: Datei:SSDA Better16bit.png – Hackerspace Ffm. When I connect my speaker, I hear a very high pitch tone, which is very annoying. I think this tone is there because of the square wave that is constantly present at PIN 9. So when I'm not playing any audio, I would like PIN 9 to be constant 0 V. When I want to play an audiofile, the square wave should be there again. How do I do that? When I use analogWrite(9,0); the tone is indeed gone, but then the audiofiles are almost not hearable anymore.

sincerely,

Marcel

Hi, I see no reason why there should be an audible tone because the PWM frequency is ~62kHz for 16 MHz and ~31kHz for 8 MHz controllers. I have this circuit here in use and if playback stops there is not such a tone. Of course you can try to override the output pin to input when not in use, but I don't think that it will help. BUT: If you really use a 74HC14 or something like that please ensure that all inputs of unused buffers are connected to GND. If there is still noise also try to improve the supply of the buffer by placing a small 100nF capacitor in parallel to the bigger one. Please let us know here if anything of that I've written helps.

Hi, want to add something:

Please also beware of one common made mistake:

If you want to use the 16-Bit feature of the library, you have to set the correct configuration flags: If you want 1 channel mono output but with 16-Bit you have to choose SSDA_MODE_STEREO and not SSDA_MODE_MONO to enable that "magic additional pin that makes audio better".

Hello,

Thanks for the quick reaction.

I have used the HEF40106, a 100nF and a 100uF capacitor over the supply. The input pins of the non-used buffers were indeed floating. I have connected them to the ground now but the tone is still very present. The tone isn't introduced by the schmitt triggers anyway since connecting ports 9 and 10 directly to the resistor network still causes the tone to appear on the output.
With the most simple piece of code the tone still appears:
#include <SimpleSDAudio.h>
void setup()
{

if (!SdPlay.init(SSDA_MODE_FULLRATE | SSDA_MODE_STEREO | SSDA_MODE_AUTOWORKER)) {
while(1); // Error while initialization of SD card -> stop.
}

void loop(void) {
}

I'm using this amplifier: http://www.ebay.com/itm/PAM8403-Mini-Digital-Power-Amplifier-Board-Class-D-2-3W-/221293221137?pt=LH_DefaultDomain_0&hash=item33861a9511
Could that be of any influence?

The PWM frequency is 62 kHz, but can a minor random shift in the duty cycle cause a tone that is hearable?

Marcel

Hi,
sorry that I have to say that, but I think both IC's are not the best choice.

Your CMOS inverter is pretty slow - remember that the PWM is operating with full 16 MHz resolution, so 1 bit change means a length of 62ns, whereas your inverter is way slower than that! Even if that might not be the source of your issues this could make the audio quality worse. I recommend fast ones like SN74HC14 or even SN74AC14. The last one is so powerfull that it is often enough to connect the speaker just to a bunch of paralleled inverters. But for 16-Bit you will need a little modification then (the resistors are then too big).

Second: You are using a class-D amplifier. Have you tried it before using some other active speakers or line-in from other amplifier? The issue is that my circuit is lacking a low pass filter and in combination with Class-D amp this might not be a good idea. So just try to add a capacitor between ground and the point where the 1k and 220k are connected together. Experiment with different values e.g. 1nF, 100nF up to 1uF.

Hello,

Ok I have already a few 74HC14's. I will buy some capacitors tomorrow and order 74AC14's. I will get back at you with the results as soon as possible, but maybe that will be after the weekend.

Thanks.

Marcel

Hi,

Adding a capacitor after the resistance network helped to decrease the noise. However, still ordered some analog amplifiers to see whether I can get better results. Haven't tested the SN74AC14 yet, that one has arrived today.
To get 16 bit mono output I have to set the flags like: SSDA_MODE_FULLRATE | SSDA_MODE_STEREO | SSDA_MODE_AUTOWORKER ? And I have to convert my .wav file to: .BFM? Because with this combination of settings I do not get good results. I get some kind of very noisy output where I'm trying to play a gunshot. What could be the cause of this? Are there any restrictions for the .wav file, too?

Marcel

Hi,
your flags seem to be correct as well as the file format. Of course you need good quality audio material if you want good results. Maybe you have to swap the pwm pins, try playing in 16 bit mode and test what you hear on each of both channels by connecting only one of them to the input of the circuit where the resistor with the lower value is.
On one channel you should hear the sound in good but 8 bit quality and on the other one you should hear loud noise when the 16-bit file is playing. this goes later to the input with the higher value resitor. With both outputs combined you have to adjust the poti the lowest noise. The quality should be then less noisy than 8 bit mode.

how to build class
play next, previous file
Please help :slight_smile:

THX

hmm
#include <SimpleSDAudio.h>
not working with
#include <SD.h>
:frowning:

Hm, looking into crystal ball, try starting with the examples provided by the library. Use Arduino IDE V1.0.x instead of beta versions in case of build trouble.

Great project!!! i will try it!

i am just looking not very much for quality but if possible gapless play of parts of the file or between files... don't know if possible. Want to use atmega328 or 2560

thanks!!

Gap-less playback from SD is always a challenge. Even the .play() function might be fast enough, at least the .setFile() function will always do a lot of searching through the FAT filesystem. First try to play the same file again and again using a loop like:

while(1) {
   if(SdPlay.isStopped()) SdPlay.play();
}

If this works ok for you, you might youself patch the library in a way that the information that is retrieved by setFile is stored somewhere in RAM and used for quicker change of the file to playback. But this might be not the right starting-project for beginners...

Tuttut:
Gap-less playback from SD is always a challenge. Even the .play() function might be fast enough, at least the .setFile() function will always do a lot of searching through the FAT filesystem. First try to play the same file again and again using a loop like:

while(1) {

if(SdPlay.isStopped()) SdPlay.play();
}




If this works ok for you, you might youself patch the library in a way that the information that is retrieved by setFile is stored somewhere in RAM and used for quicker change of the file to playback. But this might be not the right starting-project for beginners...

Thank you SO MUCH for the quick answer and the tip too! ... I'll check it and come back with results..

Hi again.. used the code below

while (S < 1000) {
    S=(pulseIn(13,HIGH,20000);
    if (millis()-t > 999){p=1;t=millis();
    if (p == 1) {
      SdPlay.setFile("START.AFM"); 
      SdPlay.play();p=0;t=millis();}

and my loop played perfect!!.. BUT now i noticed another problem with pulseIn as i am reading a PWM input to change sounds...

any tips if i can do that? is this an interrupt problem or because changes of the timers? is there anyway to measure PWM while playing sound?

Is there a way to adjust the volume?
I have a home automation including a clock with my arduino mega, and would decrease the sound (westminster gong) in the night and set it to normal (it's loud enough) at the day.
Currently i must disable the sound in the night :frowning:
thanks

Hi,
actually there is no such a feature. But usually SD cards have plenty of space - so just prepare one set of files with a lower volume (using a wav editor like Audacity) and switch between them.

Tuttut:
Hi,
actually there is no such a feature. But usually SD cards have plenty of space - so just prepare one set of files with a lower volume (using a wav editor like Audacity) and switch between them.

Good idea. Done. Works.
Thanks...

its possible make this with this library? Onix arts :: Arduino soundcard

SimpleSDAudio patch for Atmega128 with MegaCore bootloader (file SimpleSDAudioDef.h)

SimpleSDAudioDefs.h (15.5 KB)