Change wav file playback speed.

I want to play a rhythmic sound out of a speaker and as I turn a potentiometer it speeds up. I am using a micro SD card breakout board connected to an arduino uno.

Can someone point me in the right direction?

You need to read the Pot regularly without interrupting the sample output rate.
This suggests that you have the sample output in the ISR of a timer and then use the main program to change the counter limit values so that you speed up and slow down the sample rate.

Grumpy_Mike:
You need to read the Pot regularly without interrupting the sample output rate.
This suggests that you have the sample output in the ISR of a timer and then use the main program to change the counter limit values so that you speed up and slow down the sample rate.

i am not sure what code to use to change the speed of playback.

To play a file you take a sample from the SD card and pass it to the D/A. The rate at which you do this alters the speed and pitch of what is played back. So to change this you just do this operation faster or slower than the rate it was done during the record process.

Alternatively if you want to just control the time between outputting samples of say a drum beat then simply play the sample, read the pot, delay by the value you read and play the sample again.

If you change the sampling frequency it has no influence on audiable playback speed. You can play around with this using SoX Sound eXchange, the Swiss Army knife of audio manipulation

There is pySonic library for python look at UserSpeed method of the Song object. pySonic Python wrapper of FMOD Sound library

If you change the sampling frequency it has no influence on audiable playback speed.

Sorry but you are wrong.

There is pySonic library for python look at UserSpeed method of the Song object.

Remember this is not a Linux machine this is an embedded processor.

I am making a prop that plays a sound effect and I need to be able to speed up that sound effect based on the reading from the POT.

When you say speed up. To you mean pitch, time or both.
Both is easy, separating the two is difficult.

Grumpy_Mike:
When you say speed up. To you mean pitch, time or both.
Both is easy, separating the two is difficult.

I want both.

OK. So what do you have in the way of hardware?
What code are you currently using to play the sample?
Are you lookuping to change it during the playing, which is tricky or for the pot to set it before you play the sample?
How long are your samples?

Grumpy_Mike:
OK. So what do you have in the way of hardware?
What code are you currently using to play the sample?
Are you lookuping to change it during the playing, which is tricky or for the pot to set it before you play the sample?
How long are your samples?

I am using an Arduino uno with a 3.3 volt micro SD card reader. I want the sound to change whenever I turn the pot. I have not settled on a sample yet so I am flexible on that. I am currently using the TMRpcm library and the tmrpcm.play("sound.wav"); command to play the sound.

OK I have never used that Library before so what follows is what I would do to hack it
Take the TMRpcm.cpp file from the library and replace:-

    SAMPLE_RATE = sFile.read();
    SAMPLE_RATE = sFile.read() << 8 | SAMPLE_RATE;

with

    SAMPLE_RATE = sFile.read();  // you need these two reads just to make sure that
    SAMPLE_RATE = sFile.read();  //  the file pointer is in the right place for later code
    int pot = analogRead(A0); // or what ever the pot is on
    map(SAMPLE_RATE, 0, 1023, 9000, 45055);

What this should do is change the sample rate that is read from the file into one defined by the pot.
However, as I said I have not tried this and you might need a bit of messing about with the map range, if it works at all.

Can you elaborate on the MAP part?

jardane:
Can you elaborate on the MAP part?

Grumpy_Mike:

jardane:
Can you elaborate on the MAP part?

map() - Arduino Reference

That is a lovely little piece of code!

Grumpy_Mike:
OK I have never used that Library before so what follows is what I would do to hack it
Take the TMRpcm.cpp file from the library and replace:-

    SAMPLE_RATE = sFile.read();

SAMPLE_RATE = sFile.read() << 8 | SAMPLE_RATE;



with


SAMPLE_RATE = sFile.read();  // you need these two reads just to make sure that
    SAMPLE_RATE = sFile.read();  //  the file pointer is in the right place for later code
    int pot = analogRead(A0); // or what ever the pot is on
    map(SAMPLE_RATE, 0, 1023, 9000, 45055);



What this should do is change the sample rate that is read from the file into one defined by the pot.
However, as I said I have not tried this and you might need a bit of messing about with the map range, if it works at all.

Many thanx it works perfectly, maybe..

SAMPLE_RATE = map(pot, 0, 1023, 9000, 45055);

This works, although it reads the pot only once at the beginning. Trying to find a way to read the pot / sample rate continuously and realtime from the program loop. Any insights perhaps?

Trying to find a way to read the pot / sample rate continuously and realtime from the program loop.

You can't read the pot without interrupting the sample rate, or slowing it down a lot.

You could implement an interrupt service routine that read the pot and set a new rate. So you would need a button for a "new rate" and a pot, but again you will here it glitch as it reads the pot.

Yup, I am thinking about onChangeState (pot) == refresh (Sample_Rate (potval)), and thinking about smoothing pot readings or putting average value so transition would hopefully smooth out, then putting caps to prevent cracking etc etc... need to play with it more.