SD Audio playback speed

Status
Not open for further replies.

Geroge

New member
Hello

Trying to find out if it is possible to play audio files from an sd card while adjusting the speed of which the audio files are played at. I would only need to change the speed by -10% / +10%. This seems like a bit of a grey area atm so any guidance would be greatly appreciated. I am using a teensy 3.6 with a teensy audio adapter.

Cheers!
 
Hello

Trying to find out if it is possible to play audio files from an sd card while adjusting the speed of which the audio files are played at. I would only need to change the speed by -10% / +10%. This seems like a bit of a grey area atm so any guidance would be greatly appreciated. I am using a teensy 3.6 with a teensy audio adapter.

Cheers!

Reading from SD card is independent from playing audio. As audio sampling rate is fixed, you could insert a resampling filter between sd card read and audio output. However, I do not know if there are examples available.
 
Reading from SD card is independent from playing audio. As audio sampling rate is fixed, you could insert a resampling filter between sd card read and audio output. However, I do not know if there are examples available.

Hmmm massive over-sight on my behalf, should have noticed on that one. I am trying to make a small beatmatching tool, kind of based off cdj 500s. Forgive me as I am pretty new to this, but is there a way of slowing down / speeding up the sd card read rate? Doesn't exactly need to sound good. I noticed that with the flash memory chip installed on the audio board you can get about 8 sec of delay, perhaps this could be used for a re-sampling filter?
Cheers
 
is there a way of slowing down / speeding up the sd card read rate? Doesn't exactly need to sound good.

So far nobody has written the code to do this. It's on my todo list, together with *many* other features. I do not have a solid timeframe for when I'll get around to it.

To specifically answer your "is there a way" question, yes, there most certainly is a way. But that way involves pretty substantial programming effort within the library. If "a way" is restricted to mean only ways that involve using existing audio library features without difficult programming, then no, there isn't currently such a way.

I noticed that with the flash memory chip installed on the audio board you can get about 8 sec of delay, perhaps this could be used for a re-sampling filter?

This is purely a matter of software. The extra memory chip is not needed and would not significantly help. In fact, the software would likely be much more difficult to write if it unnecessarily tried to use that chip in some way.
 
Last edited:
Great this clears up a lot thank you. Looking forward to this feature being implemented, along with the many others!

Cheers!
 
I had an unsuccessful go at this a few months ago, the goal was to be able to detune samples for a sample-based keyboard.

Reading from SD card is independent from playing audio, but the code for AudioPlaySdRaw reads data from the SD card in chunks matching the audio buffer size. Reading at double or half speed is relatively easy, but something like 10% slower/faster would require keeping track of excess data that's already read but doesn't fill an entire audio buffer yet. My attempt just resulted in a lot of terrible noise with a hint of the original sound.
 
I had an unsuccessful go at this a few months ago, the goal was to be able to detune samples for a sample-based keyboard.

Reading from SD card is independent from playing audio, but the code for AudioPlaySdRaw reads data from the SD card in chunks matching the audio buffer size. Reading at double or half speed is relatively easy, but something like 10% slower/faster would require keeping track of excess data that's already read but doesn't fill an entire audio buffer yet. My attempt just resulted in a lot of terrible noise with a hint of the original sound.

Have you tried to sync the speed-change with the audioblocks (speed-change only when between blocks)
 
RAW files playback speed

I was also looking for some kind of playback speed control, and since I didn't find any solutions and quite a few people who seems to have a similar requirements, I thought I'd see if I could hack it... well at least the easy version, which is resampled RAW files...

I implemented a ResamplingSdReader class which has equivalent methods to File::read(char *buf, long len) but returns a resampled buffer instead of direct buffer from file.

I've copied play_sd_raw class to play_sd_raw_resampled class and added method setReadRate(float f): where 1 would be regular playback rate, 0.5 half speed, 2 double speed, etc). [Maybe it should be called setPlaybackRate?]

I've forked https://github.com/PaulStoffregen/Audio -> https://github.com/newdigate/Audio, added this feature, even tested briefly on a teensy, and to my surprise to seemed to work really nicely.

https://github.com/newdigate/Audio/commit/fe2f8dace558614d8a48cb00fc47aecc0c7a1960

if anybody is interested, I'd be happy to send pull request to PaulStoffregen/Audio

A nice improvement would be to implement an option to enable linear interpolation on the resampled output.

It would also be nice to be able to play WAV files at arbitrary rates.
 
I moved the variable playback rate feature to its own branch here https://github.com/newdigate/Audio/tree/play-audio-sd-raw-resampled

I've briefly tested the code, seems to be okay between -1.0 and 1.0, posted quick video https://www.youtube.com/watch?v=rEEJf7q9tRY (apologies - its pretty raw)

If anybody has the time and inclination, I'd be interested to know your thoughts/experiences/questions...

Im planning on using this feature with a tempo synch'ed teensy audio recorder/looper... Also like to see if I can get it to work with .wav files
 
This looks cool, I'll try this at some point. Were there any artefacts above 1.0 or -1.0 values as you have only tested that?
 
Subsequently I’ve tested it between -4.0 and 4.0... works successfully. beyond that I’ve not tested.
 
Subsequently I’ve tested it between -4.0 and 4.0... works successfully. beyond that I’ve not tested.

Hi Moo,

Is there any reason your code only works with Teensy 3.6? Can't seem to get it to compile for 3.2 sadly. Will buy a 3.6, but wondering what the issue is with 3.2 compatibility.

Great work, can't wait to try it out. And sounds like wobbly glitch hop in the video, nice work!
 
Oh... I didn't realise it wasn't compiling for teensy 3.2 - Im sure it should be able to - I'll have a look when I get a moment, thanks for letting me know...

I got alot of satisfaction from turning that knob back and forth, it sounds just like an old vinyl being scratched....
 
Oh... I didn't realise it wasn't compiling for teensy 3.2 - Im sure it should be able to - I'll have a look when I get a moment, thanks for letting me know...

I got alot of satisfaction from turning that knob back and forth, it sounds just like an old vinyl being scratched....

I got it to compile a while ago, the mistake was all my fault not realising you code was using the built in SD card and not the SD care from the audio shield.

From my test so far I'm not getting great quality results on 3.2, very crakly/bitty, I think talking to the audio SD card over SPI may be causing some performance issues. Not sure if accessing the built in one on 3.6 performs a load quicker and therefore gets better quality results.

Will get my hands on a 3.6 soon enough and test!
 
I got it to compile a while ago, the mistake was all my fault not realising you code was using the built in SD card and not the SD care from the audio shield.

From my test so far I'm not getting great quality results on 3.2, very crakly/bitty,

I also got it to work on a 3.2 using audio shield SD card. I'm also getting some crackly sound, but weirdly enough I cannot change the 'rate' when the file is playing. It seems to poll the analogread at startup but once it plays it almost seems like the sketch gets stuck?

Any clue as to where I should be looking to solve this? I am using the entire forked audio folder and can compile without errors.
 
I also got it to work on a 3.2 using audio shield SD card. I'm also getting some crackly sound, but weirdly enough I cannot change the 'rate' when the file is playing. It seems to poll the analogread at startup but once it plays it almost seems like the sketch gets stuck?

Any clue as to where I should be looking to solve this? I am using the entire forked audio folder and can compile without errors.

Yes that sounds like my experience too, checked the serial monitor and the sensor data looked like it was being dragged through the monitor, wouldn't rest when pot was at 1. and I couldn't get it to change rate either. I think it's due to the SD card, from what I've read now the 3.6 card has 6 dedicated wires, nothing is shared with the card, the audio shield SD card uses four wire SPI communication which is slower than the dedicated one on 3.6 or 3.5.

After a whole bunch of research yesterday Moo's seems like one of the more robust solutions, maybe bite the bullet and grab a better teensy? (apologies if that's not what you want to hear)
 
Hmm, I kinda see how the speed access speed could be slower, but then I would expect a slower response- not no response at all to be honest. From what I understand it is not an official audio lib, so maybe it just doesn't work well across different teensy models? Be that as it may, I'll probably will grab a 3.6 just to try if it works for my purposes, would be keen to hear your experience on it as well!
 
I moved the variable playback rate feature to its own branch here https://github.com/newdigate/Audio/tree/play-audio-sd-raw-resampled

I've briefly tested the code, seems to be okay between -1.0 and 1.0, posted quick video https://www.youtube.com/watch?v=rEEJf7q9tRY (apologies - its pretty raw)

If anybody has the time and inclination, I'd be interested to know your thoughts/experiences/questions...

Im planning on using this feature with a tempo synch'ed teensy audio recorder/looper... Also like to see if I can get it to work with .wav files

If you ever go to Vegas, I owe you a beer. You just helped me clear a project that has been clogging up the project bin for more than a year. THANK YOU!
 
If you ever go to Vegas, I owe you a beer. You just helped me clear a project that has been clogging up the project bin for more than a year. THANK YOU!

Awesome, Im really glad to hear that!

There is still a little bit of work required - when playing in reverse and the pointer reaches zero, it currently freezes. It should be fairly easy to fix, just haven't had much time to spend on it lately. At some point in the future I will need to sort this out for myself. Also wanted to play mp3 with variable playback rate one day too...
 
I noticed that about the reversing. For my application I needed to go faster or slower but never backwards, so I changed your example code for the knob read like this:

Code:
 if (newsensorValue != sensorValue) {
            sensorValue = newsensorValue;
            PitchAmount = (sensorValue + 255) / 512.0;

I just basically futzed with the numbers until I was able to get it where I wanted it... But that does bring up 1 question that I had: I wasn't able to get that to work by doing a simple map. For instance this:
Code:
double rate = map(sensorValue, 0, 1023, -0.99, 0.99);
didn't seem to work... maybe due to the negative numbers?

Also is it possible to use this with the onboard memory? Like if I encode the RAW file into .cpp/.h files?

Thanks again!

EDIT: just tried this:
Code:
PitchAmount = map(sensorValue, 0, 1023, 0.5, 2.5);
it seemed to play high pitched, in the middle and not at all... was weird.
 
Last edited:
Not sure about map function...

If you want to use variable playback rate using memory, you would need to slightly alter the source code, play_serialflash_raw.cpp in the audio library. Or better, copy the .h and .cpp to a new class name, and do adjustments in the new class.

I found it easiest to introduce an intermediate class - ResamplingSdReader - which behaves as regular stream reader, but internally does some resampling - see ResamplingSdReader::read(void *buf, uint16_t nbyte)

https://github.com/newdigate/Audio/...eac70ef#diff-d78eb529df8ebd0395095264e84da429

Hope this helps.
 
What kind of "slightly altering"? I just have a 1 second looping .wav sound stored in memory that i need to speed up and slow down. Tried analogWrite from dac, alters speed but there is to much noise. playmem makes it sound normal but no way to adjust pitch or speed. According to other post, this topic has been going on for years. I know the developers at wav trigger have done it and used their products before. Unfortunately their board is to big and a little pricey to fit in my project and the teensy would be perfect. Any help would be appreciated.
 
The best would be to write your own code! This whole hobby lives from writing code and learning howto... :)

There is a dirty hack: You can just change the working frequency of the whole audio-library, which is 44.1kHz by default.
 
I'm of the school of do for yourself. Coding being a little above my pay grade with filling buffers and what not. Just from a marketing standpoint I think this feature would be a selling point compared to all the other "effects" the teensy and audio library has to offer. This feature accompanied with the prop shield would go far compared to other arduino props. The prop shield with 8mb flash for storing sounds and tiny form factor would be a plus in my opinion. I know there is an option for the 3.5 and 3.6's because they have an sd card but the boards are bigger and they're technically " development cards". Just think from viewing previous post going back 5+ years they would have come up with an answer by now. Or it could be just my frustration on not being able to come up with an answer. Although I'm still looking. Just my 2 cents.
 
Paul is the only developer - all others here are hobbyists, not getting any cent for their contributions and are happy with that.
Pauls just don't have enough time to fullfill all requests. There are a bunch of other things with higher priorities.
At the moment, for sure, code for T4 and hardware for 4.1

My 2 cents.
 
Status
Not open for further replies.
Back
Top