Pausing/Seeking audio

Status
Not open for further replies.

shadlx

Member
Hi All

Apologies if this has been answered before - I've found a few old posts on this subject but nothing that seems to resolve the question. I am playing back wavs from a SD card through the audio shield on a 3.2 and really need to be able to pause and/or seek to a point in an audio file - One post I found said it's easier to do using the raw format, however the link it included as an example was dead.

Ideally I don't want to modify the Audio library as this then becomes unreliable to maintain, but if that's the only way then needs must..

If anyone has any ideas they would be much appreciated!

Thanks

Richard
 
Modifying the audio lib for yourself makes things unmaintainable, that's true. But extend it thoughtfully and make a pull request afterwards, so that Paul could integrate the improved functionality for all users, could be a great idea.
A wav file is basically a raw file with an added file header containing information about the sample rate, the word size, the number of channels and so on. I think that the actual wav player object does already identify the header and thus know the offset when the raw data starts. From all that header information and the overall file size, it should not be too difficult to calculate the new read address within the file for skipping n seconds forward or backward. Pausing would simply consist of sending (repeatedly, as long as you are in pause mode) one audio block full of zeros without advancing the file read address and continue at that address when you quit the pause mode. I think that it's neither rocket science nor music theory.
 
Probably you can simply copy the rawplayer from the audio library to your sketch directory and change the name. Then add a #include "mynewplayer" to your program and change the name within "automatically generated code".
That should be all there is to do. Then you can customize the code to your needs.

Not tested.
 
UPDATED: to ensure 'paused' is 0 before calling AudioPlaySdWav::stop()

Hello,

I'm a long time user and first time poster. This is a wonderful community! This seems like the most recent thread related to what I want to do, which is playing and pausing audio. My application does not require 'seek' and I have not attempted to do that. I do seem to have a 'togglePlayPause' function working with very limited testing.

Per Frank B's suggestion in an older, similar thread, I made a small class named AudioPlaySdWavPausable

The header, AudioPlaySdWavPausable.h looks like
Code:
#ifndef _AUDIO_PLAY_SD_WAV_PAUSABLE_H_
#define _AUDIO_PLAY_SD_WAV_PAUSABLE_H_

#include <Audio.h>

class AudioPlaySdWavPausable : public AudioPlaySdWav {
public:
    AudioPlaySdWavPausable() {
        paused = 0;
    }
    void update(void); // override base class method
    void stop(void);   // override base class method

    void togglePlayPause(void);   // new method
    unsigned char isPaused(void); // new method
private:
    unsigned char paused;
};

#endif // _AUDIO_PLAY_SD_WAV_PAUSABLE_H_


The .cpp file, AudioPlaySdWavPausable.cpp looks like
Code:
#include <AudioPlaySdWavPausable.h>

void AudioPlaySdWavPausable::update(void) {
    if(paused) {
        // TODO should this put zero'ed data in to transmitted blocks???
        return;
    }
    AudioPlaySdWav::update();
}

void AudioPlaySdWavPausable::togglePlayPause(void) {
    if(paused) {
        paused = 0;
    }
    else {
        paused = 1;
    }
}

void AudioPlaySdWavPausable::stop(void) {
    // ensure paused is zero before stopping
    // NOTE: this is necessary to since the base class update function parses
    //       the header for the potential next wave filename
    paused = 0;
    AudioPlaySdWav::stop();
}

unsigned char AudioPlaySdWavPausable::isPaused(void) {
    return paused;
}

I think this solution needs more testing, but it seems to be working. I'm unsure if I'm breaking anything by not transmitting 'zero blocks' to the output during pause - but it does seem to be working for me.

I welcome thoughts or suggestions on this approach. I'm also happy to submit a pull request with this functionality added to the TeensyAudio github repo if this approach seems valid.

Many thanks,
Dave
 
Last edited:
I added this feature to my fork of the TeensyAudio repo and submitted a pull request here: https://github.com/PaulStoffregen/Audio/pull/365

All the details of how it's implemented are in the pull request. I added an example of how to use the play/pause feature that plays for 10 seconds, and pauses for 2 seconds.

I think with some effort and care, a seek function like below could be added.
Code:
void AudioPlaySdWav::seek(uint32_t millis);

As Paul alluded in another thread, that's certainly more complex, but I'm happy to give it a try.

Cheers,
Dave
 
Hi @dave_see
I was wondering if you were able to implement a "seek" function for AudioPlaySdWav. I was searching for the current state of this and it seems this is the newest post on the topic.

I am currently building a project with teensy 4.0 and audio shield, using 1 min stereo WAV samples. It would be awesome to be able to jump to specific positions within the files – even if the position is just a rough estimate (doesn't need to be precise to the ms).

Thanks!
 
Status
Not open for further replies.
Back
Top