views:

1505

answers:

7

Hi, If I were to program a microcontroller (ATMega128) to play a realtone with a speaker, how would I do this? Do I need to use a digital/analog converter to send different amplitude values, or is it enough with frecuency changes? In any case, how would I encode the frecuency/amplitude values that the speaker needs to receive? Do I need some kind of frecuency multiplexion? I'm not talking about just making simple sounds with the speaker, like one note then the other, I want to play a real song, with all the instruments, vocals....

Thanks,

A: 

You could take a look at the open source mp3 player and see how they do it. My guess is that you'll need a D2A converter to produce sound of a decent quality.

David
Interesting project, but unluckyly he "outsorced" the sound decoding part to a third party chip:"The other chip on board is a VS1011 from VLSI, Finland. It is an .mp3 and .wav decoder chip, a DAC, and a headphone amplifier all in one 28 pin package"I'm after doing it myself, just for the sake of learning :)
palako
+2  A: 

Assuming you have an uncompressed 8-bit 22.1 KHz mono wave file:

1) Strip out the header
2) Every 1/22,100th second:
2.1) Read 8 bits
2.2) Use a DAC to convert it to the speaker's voltage range
2.3) Send it to the speaker

This will give you [22.1KHz/8 bits/mono] quality sound and is a simple way to play realistic samples.

All that frequency stuff is necessary for different synthesizers. The PC Speaker, for example is effectively 1-bit. In order to have different amplitudes (than 'none' and 'maximum') some tricks such as pulse-width modulation might be necessary (shift the frequencies around, like you said, so the speaker's diaphragm effectively has more positions than two).

But you don't need to bother with that. All you need to do is spew out some 22,100 or 44,200 sound samples per second at the speaker, with say 8 or 16 bits per sample to denote the amplitude.

aib
Very interesting. So from your answer I'm asumming that a WAV file is actually a very realistic representation of the sound itself. It's just a matter of converting the WAV to the analog signal that it represents. I'll give this a try.
palako
The DAC portion can be accomplished with a (relatively) simple R-2R ladder. http://en.wikipedia.org/wiki/Resistor_Ladder.
Evansbee
It depends on the WAV file. The WAV format can actually contain compressed audio - the full format specification is available here: http://msdn.microsoft.com/en-us/library/ms713497.aspx
Ori Pessach
@palako: Yes, it is. Barring the possible compression I forgot about. (thanks, Ori) In fact, you don't need a µC at all; a clock generator, a counter, a ROM and a DAC should be enough to play raw waveform data.
aib
@aib: with a clock generator, a counter and a ROM I wouldn't even need a DAC, would I? PWM would do the job, as per what I've been reading. But how would I run the program to read the ROM and send the values to the speaker without the microcontroller?
palako
@palako: You'd keep a constant "read enable" signal and generate sequential addresses, which a binary counter is capable of doing. (Of course it would probably be a bit more complicated, but the point is that it would be possible)On the other hand, if you're looking for a cheap or simple solution, there are all-in-one sound recording/playback chips that have "record" and "play" pins.
aib
@palako: Without a DAC (or the resistor ladder @Evansbee mentioned) you'd effectively have binary input, the sound quality would be 1-bit. To "play a song with all the instruments, vocals, etc." with PWM would require higher frequencies, or so I'd hazard.
aib
A: 

If you're feeling particularly creative, you can build your own digital-to-analog converter using a resistor ladder.

Mike Mueller
A: 

You dont have enough space on the ATMega128 to do anything too fancy. The easiest way to connect the speaker (small 2" or less) is via a resister. Check the current sinking capacity of the output and calculate R accordingly.

---------------------- +V
    |
    \
    / R
    \
    /              ----------
    |              |
    |   ------     |
    ----|    |-----| uC
        /    \     |
       --------    |
        Speaker    ---------

As regards producing tones basic switching of the output will produce basic stylaphone sounding crapolla. You can use pulse width modulation to produce approximations of any analog sound (too complex to go into here and the AtMega probably wont have enough puff or storage). This was the method used to make audio drivers for PC's with no sound card (only the built in speaker) in the good ol' days...

Tim Ring
+1  A: 

Today is both easy and cheap to play mp3 files from an 8-bit microcontroller. You need a memory device (an SD card for example) and an mp3 chipset. See this article for example. You can find many more at avrfreaks. There you could also find articles for playing sounds without an external chip.

You can play basic sounds with the PWM, but for a real song you would need a DAC. I have seen projects that played mp3 files using only a DAC and software, but they involved the more powerful ARM microcontrollers.

kgiannakakis
A: 

If you're using an Arduino, you can buy Lady Ada's WaveShield for $22 usd. Lady Ada offers many Arduino goodies worth purchasing. Some examples are GPS, Ethernet and stepper/servo shields.

shapr
Not using an arduino for this project, just the ATMega, as I'm interested in actually implement it, not the final result. But I keep that site bookmarked for my arduino projects, thanks!
palako
+1  A: 

I've tried something similar. First, you will NOT have enough memory on the uC to store a real song. You'll need external memory to handle that. That means using an SPI interface to external flash or EEPROM or something. SD is also good - I believe it's an SPI style interface. There is code out there for the ATMegas to interface SD.

Second big deal is to get the data in a proper format. The way I would do this is to use PWM to create the varying voltage levels. I believe you have a 16-bit PWM on that uC so you can have 16-bit fidelity on your sound. If you have problems with space you can use 8-bit PWM instead. So your sound data has to be in 8 or 16 bit PCM with 0x0000 being lowest value and 0xFFFF being the highest. If you want high-fidelity music you'll have to have a sampling rate of 44KHz to get all of the good harmonics and such. I believe this is PCM - same as it is called on the PC.

So then you'll have all of these values - for five minutes of music you'll have 5 * 60 * 44000 = 13200000 16 bit values which is 211200000 bits (211 megabits, 26.4 megabytes). Those are your storage requirements for raw data. MP3 is a possibility - there are external chips for that, but you'll still have large space requirements.

So every 1/44000th of a second you'll update a value in a PWM register. Your PWM frequency will have to be higher by 4 or 5 - ie, 5 PWM cycles per value.

That's your general algorithm - update values in a PWM register and let it go until the end. You will need at least a filter on the output - limit frequencies to the audible range of 20KHz (more if you're an audiophile). An RC filter will work but I would go for an active filter BECAUSE if you're using PWM your output range will be from 0 to 5V usually with the average voltage being about 2.5V. Speakers don't like DC levels - just signals. Pretty sine waves that have a 0 mean voltage. So your active filter will have to adjust the voltage levels and use dual supplies to provide negative voltages. You can also amplify the signal for the big pumping bass. Just don't blow out your speakers.

MP3 is probably a better alternative to PCM. There are chips out there: http://www.sparkfun.com/commerce/product_info.php?products_id=8892

That is however a whole microcontroller. And you already have one. But let's face it - the ATMega isn't going to do MP3 on its own soon no matter how you jazz it up.

It looks like the waveshield referenced above basically does this - uses SD for the storage of PCM and an external amplifier for the sound. Good Luck!

Stephen Friederichs