Is there a way to convert PCM data to PWM impulsion so that I can send it a basic stamp microcontroler in order to play audio on a external speaker ?

(without using an IC)


Convert your sound file to a WAV file:

mplayer -ao pcm music.mp3

Make an unsigned mono 8bit version at the desired sample rate:

sox audiodump.wav -c 1 -r 8000 -u -1 converted.wav

Convert the samples to a C header file (get wav2c):

wav2c converted.wav sounddata.h sounddata

(For your BASIC Stamp, you'll need to convert this array into some other format).

Then, in your application you need to read one sample from the array each time the sample rate duration expires and transmit it out of your PWM pin.

  • \$\begingroup\$ jpc: You could make that comment into an answer so it can receive upvotes. \$\endgroup\$ – hlovdal Mar 25 '11 at 13:48
  • \$\begingroup\$ Yes I can. It still would be best represented as an answer. \$\endgroup\$ – hlovdal Mar 25 '11 at 14:52

To generate RAW samples from an audio file you could use mplayer

mplayer -af resample=48000,channels=2:2:0:1:0:0,format=s16le 
        -ao pcm:nowaveheader:file=outfile.raw

This outputs raw 16 bit little-endian samples to outfile.raw. You can then proceed like Joby suggested (just use a bin2c tool, and not wav2c).


I've tried to do such procedure before (I read Enide! - PIC sound player (PCM to PWM converter)), but I didn't regonize the original sound.

I called the statement: PWM pin, duty, cycles, which "converts a digital value to analog output via pulse-width modulation, where Cycles is a variable/constant (0-65535) specifying an approximate number of milliseconds of PWM output."

This means I can send only one sample per millisecond. So my sample rate should be 1000 Hz. Is it true?

I'm wondering why I didn't recognize the sound. Maybe it comes from the way I converted the WAV file on my computer.

  • \$\begingroup\$ In this case you would need to change the 48000 to 1000 in the conversion. What is the resolution of the duty parameter and does it depend on cycles? Another possible problem is that you must keep calling this PWM statement on regular intervals or you will get distortion. \$\endgroup\$ – jpc Mar 26 '11 at 10:41
  • \$\begingroup\$ duty : a value between 0 and 255 which is translated in a voltage between +0 and +5 Volt mplayer -af resample=1000 is not accepted, according to mplayer rate must be >=8000 \$\endgroup\$ – user3601 Mar 26 '11 at 10:55
  • \$\begingroup\$ 1kHz is really very low bandwidth for audio. You may try to use 8kHz — I think you should be able to recognize a slowed down version of your sound. Audacity seems to support 1000 Hz sample rates (and AFAIR it can directly export to a RAW file) so you may try to generate a simple sinusoid to see if the PWM is working well. \$\endgroup\$ – jpc Mar 26 '11 at 11:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy