Changing speed of audio output stream

Hi,

Firstly apologies if this topic is covered, I had assumed that it would be a very simple thing to do, but it seems that all the audio playback threads implement limited wav functions.

My question is:

I would like to change the speed of a continuous stream of audio that is being output from the board. I would like to change the speed with more resolution than the wav functions 0.5x - 2x. Basically I want to control the speed of a sample of an engine noise based on an analogue pot input.

I'm happy with changing an array to do this and the theory - changing sample rate etc. but I don't know how to interface this with the analogue output in arduino.

Any ideas? Any help greatly appreciated, even if you just point me to another article or know what terms may be useful to search for!

Thanks
Pete

The ADC is too slow for proper sound sampling (the limit is just under 10 kHz, so that's less than 5 kHz for the maximum frequency).

Arduinos have very little memory (just 2 kB total RAM) which makes for very little sound to store for it to slow down.

The Arduino doesn't have an analogue output - all outputs are on/off so no better than simple tones.

Long story short: it's totally unsuitable for your project.

Hi,

Thanks for you reply.

If the ADC is slow, that is fine as the only input is coming from a pot or something and a sample rate of about 10 Hz will be more than adequate!

It's useful to know that there are no analogue outputs.

I guess a possible approach then is to pre-convert wav data into PWM, store it on an SD card, and output a PWM stream from one of the digital outputs, then apply a low pass analogue filter and amplify that signal for the speaker?

Then I'm playing with PWM in the arduino, I assume I can change the clock rate of that if I control the timers in the AT MEGA directly as detailed in this tutorial? is there a simpler way to control the rate?

Would that work?

Thanks
Pete

I guess a possible approach then is to pre-convert wav data into PWM, store it on an SD card, and output a PWM stream from one of the digital outputs, then apply a low pass analogue filter and amplify that signal for the speaker?

No, a few misconceptions here.

pre-convert wav data into PWM,

What does that actually mean? The sound is in the form of samples which is the value you need to feed to a PWM generator, so the statement is meaningless.

Where is this sound coming from? Is it in a digital or analogue form?
Do you want speed change without pitch change?

I had assumed that it would be a very simple thing to do

It is quite a complex thing to do, why would you think it was easy?

A PWM signal is a very simple block wave, a high/low signal. Only two levels available. No analog filtering of such a signal can get you anywhere near a real life sound wave representation.

It sounds like what you need is a WAV player. Those can read a WAV file from sd card, output decent quality sound, and can be controlled by an Arduino or similar microcontroller.

Thanks for the replies.

pre-convert: convert into a PWM stream externally to the arduino, i.e. convert some PCM / wav data into a simple PWM array without meta data etc. Is there a PCM to PWM generator?

Sound will be coming from a recording (i.e. wav file). I'm aiming to change the pitch of an engine sound to emulate an engine running at a higher speed. The simplest way (in theory/matlab land) to do this is just to output the audio samples faster (i.e. at a higher sample rate).

I assumed it's easy as I assumed I could change/slow the clock speed of a data stream being output from the arduino.

I think low pass filtering will give a good analogue representation, assuming it's running fast enough for decent audio bandwidth etc.

Yes, I saw the wav functions, but it can only replay at a few discrete speeds. It would be nicer if there was a way to run it a say 16 speeds.. or do you know of a way to run it at different speeds?

I guess I could alter the wav recordings in advance to give 4 speeds and use the wav players 4 speeds to get to 16 speeds, just seems a little memory heavy!

Thanks again for the replies, all helpful!

Is there a PCM to PWM generator?

No. Your concepts are all wrong here. PWM is a duty cycle, the number you feed into a PWM generator IS the sample number.

The simplest way (in theory/matlab land) to do this is just to output the audio samples faster (i.e. at a higher sample rate).

That is the way to do it in Arduino land as well. Note you will also get a pitch change and speed change with this method.

I assumed it's easy as I assumed I could change/slow the clock speed of a data stream being output from the arduino.

You still haven't said where the data is coming from. "Sound will be coming from a recording (i.e. wav file)." But from what device? One on the Arduino itself or from another device?

I saw the wav functions,

What wav functions where?

I guess I could alter the wav recordings in advance to give 4 speeds and use the wav players 4 speeds to get to 16 speeds, just seems a little memory heavy!

Yes use Audacity the free app to do this and you can change the speed to any value you want. Are you short of memory on an SD card? Surely not.

Conceptually it's easy to change the playback speed... If you play a 44.1kHz file at 22.05kHz, it will play at half-speed.

If you are "the programmer" it's simple. If you're using a library written by someone else you might have to "hack" the library. If you are using a WAV shield it's probably impossible to hack the firmware.

The sample rate for a WAV file is stored in the [u]WAV File Header[/u]. Normally, your audio player software reads the file header and plays-back at the correct sample rate.

If you want to experiment (on your computer) you can edit the WAV header with a [u]Hex Editor[/u]. If you change the sample rate in the header and play the file on your computer, it will play back at a different speed.

The sample rate is stored in byte 24 & 25 (18 & 19 hex). (The 1st byte is address zero, not address 1.)

A couple of notes on using a hex editor -

1. The values (and addresses) are in hexadecimal. You can use the Windows Calculator In Programmer View to convert between hex and decimal. For example, 44,100 decimal is AC44 hex and 22,050 decimal is 5622 hex

2. The data is stored in little-endian (low-byte first). If you look at the header for a 44,100Hz file, you'll see the bytes reversed as 44AC.

If you open a 44.1kz WAV file, you'll see 44AC at addresses 18 & 19 (hex). If you change that to 2256 and save the file, it will play at half speed.