Browse Source

make play_task interruptable

main
Hendrik Langer 7 years ago
parent
commit
8df4617953
  1. 6
      src/main.cpp
  2. 34
      src/sound.cpp
  3. 4
      src/sound.h

6
src/main.cpp

@ -20,9 +20,6 @@ SDCard sdcard;
Sound sound;
Wifi wifi;
TaskHandle_t xTaskSound = NULL;
bool playing = false;
static const char *soundFile[3][3] = {{"/T0.wav", "/T1.wav", "/T2.wav"},
{"/T3.wav", "/T4.wav", "/T5.wav"},
{"/T6.wav", "/T7.wav", "/T8.wav"}};
@ -51,6 +48,7 @@ void setup()
void loop()
{
bool touched = false;
bool playing = false;
for(int i=0; i<=9; i++) {
if (keyboard.getTouchDetected(i) == true) {
touched = true;
@ -59,7 +57,7 @@ void loop()
if (playing == false) {
playing == true;
Serial.println("main loop touched==true: new task");
xTaskCreate(&(Sound::play_task), "play_task", 3072, (void*)soundFile[i/3][i%3], 5, &xTaskSound);
sound.play(soundFile[i/3][i%3]);
}
}
}

34
src/sound.cpp

@ -26,10 +26,12 @@
#define SAMPLE_PER_CYCLE (SAMPLE_RATE/WAVE_FREQ_HZ)
#define EXIT_BIT 0x01
using namespace std;
SemaphoreHandle_t xPlayingSemaphore = NULL;
static TaskHandle_t xTaskToNotify = NULL;
Sound::Sound() {
xPlayingSemaphore = xSemaphoreCreateMutex();
@ -88,18 +90,32 @@ void Sound::end() {
i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver
}
void Sound::play(const char* path) {
if (xTaskToNotify != NULL) {
xTaskNotify( xTaskToNotify,
EXIT_BIT,
eSetBits);
taskYIELD();
}
xTaskCreate(&(Sound::play_task), "play_task", 3072, (void*)path, 5, &xTaskSound);
}
void Sound::play_task(void *pvParameter) {
// Serial.print("initial free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG
char *path = (char *) pvParameter;
Serial.println("sound task: playing");
if ( xPlayingSemaphore == NULL || xSemaphoreTake( xPlayingSemaphore, (TickType_t) 10) != pdTRUE ) {
if ( xPlayingSemaphore == NULL || xSemaphoreTake( xPlayingSemaphore, 42 / portTICK_PERIOD_MS) != pdTRUE ) {
Serial.println("Sound task: could not obtain semaphore");
vTaskDelete( NULL );
return;
}
xTaskToNotify = xTaskGetCurrentTaskHandle();
File file = SDCard::open(path);
if (!file) {
xTaskToNotify = NULL;
Serial.print("Failed to open file: "); Serial.println(path);
vTaskDelete( NULL );
return;
@ -133,6 +149,19 @@ void Sound::play_task(void *pvParameter) {
buf_pos += num_pushed_bytes;
}
// Buffer now empty
uint32_t ulNotifiedValue;
BaseType_t xResult = xTaskNotifyWait( pdFALSE, /* Don't clear bits on entry. */
ULONG_MAX, /* Clear all bits on exit. */
&ulNotifiedValue, /* Stores the notified value. */
0 ); /* xMaxBlockTime */
if( xResult == pdPASS ) { /* A notification was received */
if( ( ulNotifiedValue & EXIT_BIT ) != 0 ) { /* the EXIT BIT was set */
Serial.println("play_task: got notify. exiting.");
break;
}
}
//TickType_t delay = 10 / portTICK_PERIOD_MS; // max delay: 10ms instead of portMAX_DELAY
vTaskDelay(20 / portTICK_PERIOD_MS);
}
@ -140,8 +169,9 @@ void Sound::play_task(void *pvParameter) {
SDCard::close(file);
i2s_stop(i2s_num);
delete[] buf;
xSemaphoreGive( xPlayingSemaphore );
Serial.println("task exiting");
xTaskToNotify = NULL;
xSemaphoreGive( xPlayingSemaphore );
vTaskDelete( NULL );
}

4
src/sound.h

@ -13,14 +13,14 @@ class Sound {
void init();
void end();
// void close();
// bool play();
void play(const char*);
// void pause();
// void stop();
int render_sample_block(uint16_t *sample_buf_left, uint16_t *sample_buf_right, int num_samples);
static const i2s_port_t i2s_num = (i2s_port_t)I2S_NUM;
static void play_task(void *pvParameter);
private:
TaskHandle_t xTaskRefillBuffer;
TaskHandle_t xTaskSound = NULL;
};
#endif /* _SOUND_H */

Loading…
Cancel
Save