Pause Audio on the Teensy 3.1 Audio shield

Status
Not open for further replies.

kurogane

New member
Hi

Would just like to know if it Possible to Pause Audio on the Teensy 3.1 Audio shield?
I have looked everywhere, also in the audio library, but there don't not seem to be a dedicated function, that just pauses the audio.
Does anybody have a good solutions for that?
 
what kind of audio?

i assume you mean pause as in pause/resume a .wav file? or stop things in general?

if the former, you'd need to add some simple functions to the respective class.

for instance, or that's one way (re: PlaySdWav):*

Code:
uint32_t AudioPlaySdWav::positionBytes(void) // keep track of the current position

Code:
bool AudioPlaySdWav::seek(const char *filename, uint32_t pos) // resume from position pos


if the latter, someone else would have to chime in, it's not something I felt i needed so far. there's "AudioNoInterrupts" which "allows you to briefly suspend the audio library"; but I'm not sure what "briefly" means in this context. (ie whether it implies suspend "indefinitely").

* more detail here
 
Yes it is a wav file i need to pause and resume, need to integrate some basic audio player functions in a project. The teensy audio shield is a bit overkill for this, but the DFPlayer module i started out with, was just way to unstable. Will try out what you suggested.

Thanks, for the quick response :)
 
Have had a look at it, and its probably a bit above my skills to fix at the moment :(

An other easy way is to add a line like "if (pause) return;" after the line "if (state == STATE_STOP) return;" in void AudioPlaySdWav::update(void)
Add "int pause =0"; in the class class AudioPlaySdWav : public AudioStream and a function that sets pause to 1 or 0.
 
what kind of audio?

i assume you mean pause as in pause/resume a .wav file? or stop things in general?

if the former, you'd need to add some simple functions to the respective class.

for instance, or that's one way (re: PlaySdWav):*

Code:
uint32_t AudioPlaySdWav::positionBytes(void) // keep track of the current position

Code:
bool AudioPlaySdWav::seek(const char *filename, uint32_t pos) // resume from position pos


if the latter, someone else would have to chime in, it's not something I felt i needed so far. there's "AudioNoInterrupts" which "allows you to briefly suspend the audio library"; but I'm not sure what "briefly" means in this context. (ie whether it implies suspend "indefinitely").

* more detail here

Hi,

So I've tried using this pausing technique the the updated Play_SD_Wav library suggested here. I am feeding wavfile.seek() the correct file name and byte, but the file just restarts.

Here is the data from the .cpp file

Code:
bool AudioPlaySdWav::seek(const char *filename, uint32_t pos)
{
	byte_offset = (1+pos)<<9;
	stop();
	__disable_irq();
	AudioStartUsingSPI();
	wavfile = SD.open(filename);
	__enable_irq();
	if (!wavfile) {
		AudioStopUsingSPI();
		return false;
	}
	buffer_length = 0;
	buffer_offset = 0;
	state_play = STATE_STOP;
	data_length = 20;
	header_offset = 0;
	playseek = true;
	state = STATE_PARSE1;
	return true;
}

Should I be able to restart where I left off using this class and method?

As a bonus, can someone explain to me what AudioPlaySdWav::update(void) does?

Thanks!
 
Hi , I just played with Granular effect in audio lib on t3.5 native dacs output... then I needed to pause playSdRaw when granular freeze, and after red lot of toppic I succeed to corrupt the playsdRaw lib (I guess will work on playsdwav).
But I think it's not the right way to do it :
playSdRaw.h
Code:
#ifndef play_sd_raw_h_
#define play_sd_raw_h_

#include "AudioStream.h"
#include "SD.h"

class AudioPlaySdRaw : public AudioStream
{
public:
	AudioPlaySdRaw(void) : AudioStream(0, NULL) { begin(); }
	void begin(void);
	bool play(const char *filename);
        void pause(bool pst);/////////////////////// PAUSE TEST
        bool seek(const char *filename, uint32_t pos);
	void stop(void);
	bool isPlaying(void) { return playing; }
	uint32_t positionMillis(void);
        uint32_t positionBytes(void);
	uint32_t lengthMillis(void);
	uint32_t lengthBytes(void);
	virtual void update(void);
private:
	File rawfile;
	uint32_t file_size;
	volatile uint32_t file_offset;
	volatile bool playing;
	volatile bool attend = false; /////////////////////////PAUSE TEST
     uint32_t byte_offset;
};

#endif

and in playSdRaw.cpp
Code:
void AudioPlaySdRaw::update(void)
{
	unsigned int i, n;
	audio_block_t *block;

	// only update if we're playing
	if (!playing) return;

	// allocate the audio blocks to transmit
	block = allocate();
	if (block == NULL) return;

	if (rawfile.available()) { 
		// we can read more data from the file...
		if (attend == false){n = rawfile.read(block->data, AUDIO_BLOCK_SAMPLES*2);}////////////////PAUSE TEST
		 file_offset += n; 
		for (i=n/2; i < AUDIO_BLOCK_SAMPLES; i++) {
			block->data[i] = 0;
		}
		transmit(block);
	} else {
		rawfile.close();
		AudioStopUsingSPI();
		playing = false;
	}
	release(block);
}

void AudioPlaySdRaw::pause(bool pst){ ////////////////PAUSE TEST
attend = pst;

}

in my poorly understand when I call : playSdRaw.pause(true); it stop the read head and playSdRaw.pause(false); release it...
For granular effect I call I call ' playSdRaw.pause(true); ' after a delay of the length of the grain. trig 'playSdRaw.pause(false);' just after stop ganular effect...
It work more or less, at least it freeze one block...
in my schetch :
Code:
if (button0.fallingEdge()) {
    //freeze = 1;
    //pos = playSdRaw.positionMillis();
    float ax = sq(AcX/4+4000);
    //Serial.println(ax);
    float msec = ax/100000.0;
    msec = constrain(msec, 10, 550);
    granular.beginFreeze(msec); //msec
    Serial.print("Begin granular freeze using ");
    Serial.print(msec);
    Serial.println(" grains");
    delay(msec);
    playSdRaw.pause(true);
  }
  if (button0.risingEdge()) {
    granular.stop();
    //freeze = 0;
    playSdRaw.pause(false);
  }
 
Last edited:
Status
Not open for further replies.
Back
Top