diff --git a/src/main.cpp b/src/main.cpp index 75e05a3..f0ef103 100644 --- a/src/main.cpp +++ b/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]); } } } diff --git a/src/sound.cpp b/src/sound.cpp index 8320f06..f97acce 100644 --- a/src/sound.cpp +++ b/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 ); } diff --git a/src/sound.h b/src/sound.h index 265bd55..9502330 100644 --- a/src/sound.h +++ b/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 */