Go Down

Topic: Audio Output from SD (Read 688 times) previous topic - next topic

MSULudingtonPump

Hey guys. I'm not very experienced with audio, and most of the posts in this category make no sense to me, so I thought I'd just make my own post.

The Goal: I want to play an audio file from an SD card through two 4 Ohm 3 W speakers.

Background:
  • I already have an SD card breakout board and an SD card.
  • The SD card is wired up to my Arduino (Mega 2560), and the audio file is detected.
  • Needs to be sort of loud, so an amplifier is needed

I've been looking at the amplifier below, but am not sure how to send the data from the audio file to the board. There are three terminals for Left channel, Right channel, and ground; but what would I connect those to on the Arduino? Is this even possible? Any help is greatly appreciated!

Amplifier:
https://learn.adafruit.com/adafruit-20w-stereo-audio-amplifier-class-d-max9744?view=all

DVDdoug

Quote
and the audio file is detected.
What does that mean?

Quote
but what would I connect those to on the Arduino? Is this even possible? Any help is greatly appreciated!
Connect the ground to ground.   Connect an Arduino output pin to the left & right inputs.   You can use two separate outputs if you have stereo.*      It's OK to connect the left right inputs together and connect to one Arduino output pin if you have mono but you want to drive both channels.

You can test it with the tone() function, but start with the volume all the way down!

Since the Arduino doesn't have an analog output you'll have to use the TMRpcm library to get PWM that approximates analog audio.    

Personally, I wouldn't use the Arduino (directly) for audio, since it doesn't have a DAC.   There are audio shields that have a DAC, SDcard slot, clock, and everything else for audio.    Some even have built-in MP3 decoders.





* I don't know if the TMRpcm library supports stereo.  

The general rule is, you can connect two (or more) inputs together but you should NEVER "short" two audio outputs together.


BJHenry

That amplifier also takes line level signals on the inputs so you'll need to make sure the input voltage doesn't go over about 1V.

Lucario448

What does that mean?
It means the file could be opened.


You can test it with the tone() function, but start with the volume all the way down!
Specially when 20w amp is kind of an overkill; but as long as the speaker doesn't get too loud it's fine.



Personally, I wouldn't use the Arduino (directly) for audio, since it doesn't have a DAC.
Besides of needing external passive components, is actually not that bad. Of course it will chew up quite a lot of the CPU time (when playing); but the audio quality can be amazing, considering the lack of a true DAC.
I'm not saying it's superior than professional DACs; but with enough sampling rate (22 KHz and above), you can't even tell if the audio comes from an Arduino unless you're an audiophile.



* I don't know if the TMRpcm library supports stereo.
It does; however you have to uncomment #define STEREO_OR_16_BIT in the configuration file, in order to enable that feature.
Otherwise, the library assumes all wav files as 8-bit mono.

As you can tell in the definition's name, this feature allows the library to properly playback 8-bit stereo or 16-bit mono wav files.
Also you have to declare as an OUTPUT the second pin of the timer the library uses. By default, it's the timer1; thus the pin 10 in ATmega328P (Uno, Nano, Pro Mini), 12 in ATmega2560 (Mega).


That amplifier also takes line level signals on the inputs so you'll need to make sure the input voltage doesn't go over about 1V.
Then use a potentiometer to lower the input's amplitude, and so the volume.
It has to be placed between the low-pass filter and the amp's input.

BJHenry

Then use a potentiometer to lower the input's amplitude, and so the volume.
It has to be placed between the low-pass filter and the amp's input.
The amplifier board has a built-in volume adjustment. Surely it would be better to use a fixed voltage divider so that you can't accidentally set the signal level too high?

Lucario448

So in this case you need to know what's the peak voltage without a potenciometer. With a RC low-pass filter, I think it isn't the exact supply voltage, there should be a little drop

Also, your claim of 1V maxium is a bit confusing; is it 1V for a half amplitude (2 Vpp) or is it a total for both halves (aka 1 Vpp)? Remember that Vpp stands for "peak-to-peak voltage".

Grumpy_Mike

#6
Sep 22, 2018, 08:06 pm Last Edit: Sep 22, 2018, 08:09 pm by Grumpy_Mike
Quote
It does; however you have to uncomment #define STEREO_OR_16_BIT in the configuration file, in order to enable that feature.
Not as simple as that:-
Quote
Stereo and 16-Bit Playback

These modes require additional resources and processing power since double the data must be read from the SD card. Mono tracks can be played in Stereo mode, not so in reverse. The operation can be a bit difficult to explain, but here goes:

Normal Mode:
#define STEREO_OR_16BIT
In this mode, stereo and 16-bit files are treated the same, with the first byte being read into one
output, and the second byte into the other output. This will produce a stereo output for two speakers,
connected from speaker pin(s) to ground, or a single 16-bit output using a resistor ladder.
#define MODE2
In Normal Mode, MODE2 will enable output STEREO or 16BIT audio using two additional timer pins. The timer and pins are
specified by the speakerPin2 variable. Complimentary timer pins need to be set as output pins manually.

In MULTI Mode:
#define STEREO_OR_16BIT
Enabling this option along with MULTI mode will allow two stereo or 16-bit tracks to be played on separate
timer pins. This provides output for four speakers, connected from speaker pin(s) to ground or a single
16-bit output for each track.
#define MODE2
Enabling this option with MULTI mode and STEREO_OR_16BIT both enabled will make no difference    

See MULTI mode above.
Quote
Connect the ground to ground.   Connect an Arduino output pin to the left & right inputs.
While you can try that, it often upsets audio amplifiers, as some members of the forum have found. You need a reconstitution filter for the signal. That can be done with a series resistor of 1K5 on the output pin with a 10nF capacitor on the other end of the resistor to ground.

Lucario448

Not as simple as that:-
Nonsense.

Uncommenting #define STEREO_OR_16BIT actually enables stereo playback. MODE2 makes use of a second 16-bit timer (thus, Arduino Mega only). MULTI or ENABLE_MULTI redefines most of the library's functions, in order to play two audio files simultaneously (at the expense of doubling the RAM usage). Uncommenting all three will let you play two stereo tracks at the same time.

I bet you only need one audio playback at once, so STEREO_OR_16BIT is more than enough.
If you plan to play stereo tracks with sampling rates higher than 16 KHz, I will suggest you to uncomment #define buffSize 128 as well.


You need a reconstitution filter for the signal. That can be done with a series resistor of 1K5 on the output pin with a 10nF capacitor on the other end of the resistor to ground.
Yeah, that's the RC low-pass filter I was talking about. The purpose of this component is to convert the squary PWM signal into analog voltage levels. It is not a SMPS, due to the high impedance caused by the series resistor. Don't even dare to place an LED in parallel, that will attenuate the signal by a lot.

Since the Arduino works only with positive voltage, the resulting analog signal becomes DC biased (aka with a DC offset); and some audio amplifiers don't like that. To solve this problem, a high-pass filter is required; don't worry, this time is just one large enough series capacitor.
Why "large enough"? If the capacitance is small, only the high frequency parts will be heard (sounding like a tiny speaker); if it's big, DC offset will be still eliminated, while maintaining the mighty audible low frequencies or bass (percussion is mostly low frequencies by the way).

Grumpy_Mike

#8
Sep 23, 2018, 11:24 am Last Edit: Sep 23, 2018, 12:00 pm by Grumpy_Mike
Quote
Nonsense
You tried it then and not just read the document?

Quote
Don't even dare to place an LED in parallel, that will attenuate the signal by a lot.
No that depends on where you put the LED does it not?

Quote
To solve this problem, a high-pass filter is required;
When is AC coupling a high pass filter?
When you have lots of theory but not much practice.

When is a restoration filter a low pass filter?
When you know about electronics but nothing about audio.

MarkT

#9
Sep 23, 2018, 01:55 pm Last Edit: Sep 23, 2018, 01:56 pm by MarkT
But AC coupling is a high-pass filter and restoration filter is a low pass.  You can call them either, noone is
being wrong.

BTW its also possible to drive a speaker using class-D direct from a digital pin using phase-correct PWM and a noise-shaping filter  - replace the audio amp on the output with half-H-bridge.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Grumpy_Mike

Quote
But AC coupling is a high-pass filter and restoration filter is a low pass.
Yes of course it is.

Quote
You can call them either, noone is being wrong.
While it is not wrong it is not the correct term to use in the context. We are trying to help beginners here and using a term that needs a lot more qualifying and is not the normal term is at the best confusing.

The term AC coupling carries with it the band pass characteristics of a very low audio break point for the filter, without having to say so. Where as the simple term high pass filter needs that qualification.

Likewise a restoration filter is a low pass filter but using the name that describes its function in the context it is being used tells you the characteristics of that filter without having to spell it out.

So using a term where you have to jump through hoops to see it is the same as using the proper name is useful when we are trying to educate.


MarkT

Then why not say "a.k.a. restoration filter" rather than being confrontational?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Lucario448

You tried it then and not just read the document?
I've looked in my copy of the library, and I have uncommented (from default):

  • #define buffSize 128
  • #define SDFAT
  • #define STEREO_OR_16BIT

And stereo playback works like a charm. Worth mentioning that the first two options are actually optional, I uncommented them for lower RAM footprint and better performance.

I just don't understand why you say it's not as simple as that. I know it takes more resources, but what else I've missed that makes it "not simple"?


No that depends on where you put the LED does it not?
I mean after the low-pass filter. Before it's the PWM signal, with enough current to drive a typical 5mm THT LED.

When you have lots of theory but not much practice.
I do have the theory, but if I hadn't the practice I wouldn't even have meddled in this topic.


When you know about electronics but nothing about audio.
I'm not an audio expert or professional, but at least I do know the fundamentals of sound, digitized sound and audio amplifiers; maybe a bit further.

But AC coupling is a high-pass filter and restoration filter is a low pass.  You can call them either, noone is
being wrong.
So they are synonyms? Makes sense for me.
I mean, one says what it does, and the other says what it is (sounding more technical though); but in the end both "words" lead to the same thing.


BTW its also possible to drive a speaker using class-D direct from a digital pin using phase-correct PWM and a noise-shaping filter  - replace the audio amp on the output with half-H-bridge.
Once I had that "crazy" idea too; but not with a H bridge, rather with a single MOSFET (thus still requiring the series capacitor).

Does an H bridge need two inputs? If the second input is just the inverted of the first one, then nothing to complain about; otherwise it's a downside of requiring two PWM signals for just one audio channel.

Furthermore, splitting the output in two signals implies sacrificing one bit of resolution. For example: an audio file is composed of 8-bit samples (with 256 possible values or steps); by splitting the positive and negative halves of the wave, we end up with two 7-bit samples (with 128 possible values or steps), each one used to drive the inputs of the H bridge.
To figure out in which half the sample is located (and it's value relative from the center), it depends of its sign. If it's signed, is pretty straightfoward getting the value and the location. If it's unsigned, you'll to use two or three bitwise operations to figure that out.

Of course, if the sample is located in certain half, you have to apply the corresponding duty cycle to the corresponding input; the other one should stay inactive. Remember that if both inputs are active, the H bridge will short circuit.



To make life easier, I think you can use a L293D as a prebuilt class D amplifier in this case. Since there are two H bridges in one package, then it's perfect for stereo output.



Then why not say "a.k.a. restoration filter" rather than being confrontational?
Yeah good call, because I don't to argue.



PD: I admit sometimes I end up speaking a lot, deviating of the main topic; or maybe my explainations are too technical and not comprehensive by beginners. So I will apologize for any inconvinient :(

MarkT

#13
Sep 24, 2018, 07:38 pm Last Edit: Sep 24, 2018, 07:41 pm by MarkT
Darlington based H-bridges aren't really fast enough for class-D of any quality, and are woefully lossy
at low voltage.

I've used low-side MOSFET drivers as half-H-bridges before to generate class-D, paralleling several for
extra current handling.  Choose a driver with several amps output for best results and add freewheel
schottky diodes.  After all a MOSFET gate driver is little more than a high speed half-H-bridge.

The main problem with drivers is they aren't usually thermally up to high continuous load currents, being
designed to charge/discharge the gate capacitances of a bigger MOSFET.

Quote
Of course, if the sample is located in certain half, you have to apply the corresponding duty cycle to the corresponding input; the other one should stay inactive. Remember that if both inputs are active, the H bridge will short circuit.

I don't understand this, that's not how direct class D is done, there is one PWM waveform that is modulated
by all the samples, with zero sample mapping to 50% duty cycle.

With noise-shaping you can get good quality from as low as 5 or 6 bits of PWM resolution, if the
PWM frequency is nice and high (100kHz+), but you then have to do a lot of work doing
the noise shaping as that has to be calculated for every PWM cycle.

Phase-correct PWM is needed for class-D generation, note.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Lucario448

Hmm, interesting; so it's not as simple as outputting a PWM with a duty cycle proportional to the sample's value.

It will be a discussion for another thread if you want to keep talking about that, because we are getting off topic here.

Go Up