Converting PCM WAV audio to a sequence of PWM data to play on a piezo speaker?

Hello,

I was hoping if someone could give me some guidance on the following.

I have a piezo speaker connected to Arduino, and I can play homophonic tones on it using code e.g. like PlayMelody sample here https://www.arduino.cc/en/Tutorial/PlayMelody . Everything works nicely.

Now, to play my own kind of tunes, I have captured audio in PCM .wav format, which is (nearly) perfectly homophonic. For an example, see the audio here: Outrun - PC - YouTube

How should one go about converting such PCM .wav file to a PWM sequence of pitch-duration pairs so that it could be reproduced on a piezo speaker? For homophonic audio such as in the above Outrun tune which was originally played back on a PC speaker, such conversion could be more or less perfect(?) (For arbitrary PCM data, it can of course sound very gross and approximate)

I've tried searching for algorithms/tools/discussion on how to write such a converter, but I'm somewhat new to audio, and have not been able to quite figure out what this kind of conversion would be called and what to search for.

Try this:-

Thanks. It looks like that link is about playing PCM audio on a real speaker. However I'm not looking to use a real speaker, but just a piezo crystal speaker (Piezoelectric speaker - Wikipedia or Search Results for 'piezo' on Adafruit Industries ), so I'm looking at a conversion tool that I could use "offline" on the PC side to convert the PCM data to PWM form for playback on the piezo speaker. I wonder if there exists tools for that?

There is no difference in what you have to do to use a speaker or a piezo. It is just that using a piezo gives you crap audio no matter what your software is.

Oh, sorry, let me clarify.

The reason why I am not trying to trying to push the PCM data to the chip is that PCM data takes up a lot of memory, e.g. if I have ten seconds of a square wave in PCM wave form in 8-bit 8kHz, it takes up 8000samples/sec * 1byte/sample * 10seconds = 80000 bytes, whereas in PWM tone-duration pair form, one can use just two bytes to encode the same information, first being the tone frequence, and second being the duration (e.g. in seconds or 1/16th of seconds or similar). That's why it would be desirable to have a sequence of pitch-duration pairs of PWM data instead of PCM to store the audio, and why I'd like to do it offline. I just don't know what would be a proper algorithm to do this kind of conversion?

"whereas in PWM tone-duration pair form, one can use just two bytes to encode the same information, first being the tone frequence, and second being the duration (e.g. in seconds or 1/16th of seconds or similar)."

Maybe you don't understand what PWM is.
It does not allow you to define the tone (frequency), it allows you to define the ratio of the high part of the wave to the total wave. 100 means the high part will be 100/255 of the wave. The frequency is set at about 500hz.

Maybe you want to look at tone()

It helps if you use the right words when asking a question. >:(

The simple answer is you can not convert what you are asking for from what you have on an Arduino. You might possibly be able to write some sort of analysis program on a computer using FFT but it is a long shot, and quite a complex program if you could.

I am very sorry to have made you angry. Thanks for all the answers and the help!

clbri,

I don't think anybody is angry... Maybe just grumpy. :smiley: I think he's trying to make sure he has your attention....

You are confusing a couple of things... If you use something like PlayMelody() it takes no more memory to generate PCM than to generate PWM. It just takes different hardware.

There's a difference between generating a sound and storing a sound. If I store a 1kHz tone on an audio CD, I can store store a little more than an hour of sound and it takes about 700MB. But, it only takes a few bytes to store a "message" that says "1Khz, 24 hours".

You could write a little program for the Arduino that plays randomized melodies for year and it would take no more memory than a program that plays a song for 1 minute... It doesn't take much memory to generate a randomized series of notes or loop your program (with randomized changes every time through the loop).

A practical example is a [u]MIDI[/u] file, which contains "notes & timing" (and some other information) and is MUCH smaller than a digital audio recording. (A MIDI file can be very high quality depending on the quality of your virtual instruments but it can't generate vocals/lyrics.)

In practice, I think PWM requires a much higher sample rate than PCM (for the same quality). I'm not an expert on PWM and philosophically, there's no more information so it shouldn't require a bigger file but it practice, it might require a bigger file. But, nobody stores audio in PWM in files... There are a couple of formats similar to PWM, and class-D amplifiers convert analog to high frequency PWM. (Class-D amplifiers don't have any software or memory.)

And of course, you have lossless and lossy audio compression. FLAC (lossless) compresses PCM data and MP3 (lossy) works in the frequency domain which is a whole 'nother story.