Browse Source

Merge pull request #365 from standarddeviant/sdwav-pausable

AudioPlaySdWav Feature: togglePlayPause
dds
Paul Stoffregen 3 years ago
parent
commit
6650038cc1
No account linked to committer's email address
3 changed files with 170 additions and 5 deletions
  1. +133
    -0
      examples/WavFilePlayerPause/WavFilePlayerPause.ino
  2. +34
    -5
      play_sd_wav.cpp
  3. +3
    -0
      play_sd_wav.h

+ 133
- 0
examples/WavFilePlayerPause/WavFilePlayerPause.ino View File

@@ -0,0 +1,133 @@
// Simple WAV file player example
//
// Three types of output may be used, by configuring the code below.
//
// 1: Digital I2S - Normally used with the audio shield:
// http://www.pjrc.com/store/teensy3_audio.html
//
// 2: Digital S/PDIF - Connect pin 22 to a S/PDIF transmitter
// https://www.oshpark.com/shared_projects/KcDBKHta
//
// 3: Analog DAC - Connect the DAC pin to an amplified speaker
// http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
//
// To configure the output type, first uncomment one of the three
// output objects. If not using the audio shield, comment out
// the sgtl5000_1 lines in setup(), so it does not wait forever
// trying to configure the SGTL5000 codec chip.
//
// The SD card may connect to different pins, depending on the
// hardware you are using. Uncomment or configure the SD card
// pins to match your hardware.
//
// Data files to put on your SD card can be downloaded here:
// http://www.pjrc.com/teensy/td_libs_AudioDataFiles.html
//
// This example code is in the public domain.

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav playWav1;
// Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC
AudioOutputI2S audioOutput;
//AudioOutputSPDIF audioOutput;
//AudioOutputAnalog audioOutput;
AudioConnection patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection patchCord2(playWav1, 1, audioOutput, 1);
AudioControlSGTL5000 sgtl5000_1;

// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14

// Use these with the Teensy 3.5 & 3.6 SD card
//#define SDCARD_CS_PIN BUILTIN_SDCARD
//#define SDCARD_MOSI_PIN 11 // not actually used
//#define SDCARD_SCK_PIN 13 // not actually used

// Use these for the SD+Wiz820 or other adaptors
//#define SDCARD_CS_PIN 4
//#define SDCARD_MOSI_PIN 11
//#define SDCARD_SCK_PIN 13

void setup() {
Serial.begin(9600);

// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);

// Comment these out if not using the audio adaptor board.
// This may wait forever if the SDA & SCL pins lack
// pullup resistors
sgtl5000_1.enable();
sgtl5000_1.volume(0.5);

SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
// stop here, but print a message repetitively
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
}

void playFile(const char *filename)
{
Serial.print("Playing file: ");
Serial.println(filename);

// Start playing the file. This sketch continues to
// run while the file plays.
playWav1.play(filename);

// A brief delay for the library read WAV info
delay(5);

// Simply wait for the file to finish playing.
while (!playWav1.isStopped()) {
if(playWav1.isPlaying()) {
// play for 10 seconds
delay(10000);
}
else if(playWav1.isPaused()) {
// pause for 2 seconds
delay(2000);
}

// toggle play/pause state
playWav1.togglePlayPause();
Serial.println(filename);
Serial.print("positionMillis() = ");
Serial.println(playWav1.positionMillis());
Serial.print("lengthMillis() = ");
Serial.println(playWav1.lengthMillis());
Serial.print("isPlaying() = ");
Serial.println(playWav1.isPlaying());
Serial.print("isPaused() = ");
Serial.println(playWav1.isPaused());
Serial.print("isStopped() = ");
Serial.println(playWav1.isStopped());
Serial.println();
}
}


void loop() {
playFile("SDTEST1.WAV"); // filenames are always uppercase 8.3 format
delay(500);
playFile("SDTEST2.WAV");
delay(500);
playFile("SDTEST3.WAV");
delay(500);
playFile("SDTEST4.WAV");
delay(1500);
}


+ 34
- 5
play_sd_wav.cpp View File

@@ -42,7 +42,8 @@
#define STATE_PARSE3 10 // looking for 8 byte data header
#define STATE_PARSE4 11 // ignoring unknown chunk after "fmt "
#define STATE_PARSE5 12 // ignoring unknown chunk before "fmt "
#define STATE_STOP 13
#define STATE_PAUSED 13
#define STATE_STOP 14

void AudioPlaySdWav::begin(void)
{
@@ -118,13 +119,26 @@ void AudioPlaySdWav::stop(void)
if (irq) NVIC_ENABLE_IRQ(IRQ_SOFTWARE);
}

void AudioPlaySdWav::togglePlayPause(void) {
// take no action if wave header is not parsed OR
// state is explicitly STATE_STOP
if(state_play >= 8 || state == STATE_STOP) return;

// toggle back and forth between state_play and STATE_PAUSED
if(state == state_play) {
state = STATE_PAUSED;
}
else if(state == STATE_PAUSED) {
state = state_play;
}
}

void AudioPlaySdWav::update(void)
{
int32_t n;

// only update if we're playing
if (state == STATE_STOP) return;
// only update if we're playing and not paused
if (state == STATE_STOP || state == STATE_PAUSED) return;

// allocate the audio blocks to transmit
block_left = allocate();
@@ -580,10 +594,25 @@ bool AudioPlaySdWav::isPlaying(void)
return (s < 8);
}


bool AudioPlaySdWav::isPaused(void)
{
uint8_t s = *(volatile uint8_t *)&state;
return (s == STATE_PAUSED);
}


bool AudioPlaySdWav::isStopped(void)
{
uint8_t s = *(volatile uint8_t *)&state;
return (s == STATE_STOP);
}


uint32_t AudioPlaySdWav::positionMillis(void)
{
uint8_t s = *(volatile uint8_t *)&state;
if (s >= 8) return 0;
if (s >= 8 && s != STATE_PAUSED) return 0;
uint32_t tlength = *(volatile uint32_t *)&total_length;
uint32_t dlength = *(volatile uint32_t *)&data_length;
uint32_t offset = tlength - dlength;
@@ -595,7 +624,7 @@ uint32_t AudioPlaySdWav::positionMillis(void)
uint32_t AudioPlaySdWav::lengthMillis(void)
{
uint8_t s = *(volatile uint8_t *)&state;
if (s >= 8) return 0;
if (s >= 8 && s != STATE_PAUSED) return 0;
uint32_t tlength = *(volatile uint32_t *)&total_length;
uint32_t b2m = *(volatile uint32_t *)&bytes2millis;
return ((uint64_t)tlength * b2m) >> 32;

+ 3
- 0
play_sd_wav.h View File

@@ -37,8 +37,11 @@ public:
AudioPlaySdWav(void) : AudioStream(0, NULL), block_left(NULL), block_right(NULL) { begin(); }
void begin(void);
bool play(const char *filename);
void togglePlayPause(void);
void stop(void);
bool isPlaying(void);
bool isPaused(void);
bool isStopped(void);
uint32_t positionMillis(void);
uint32_t lengthMillis(void);
virtual void update(void);

Loading…
Cancel
Save