From c91b89b3f84ce72d771f854c7c10f16eef4e1849 Mon Sep 17 00:00:00 2001 From: Hendrik Langer Date: Fri, 21 Apr 2017 20:00:49 +0200 Subject: [PATCH] rewrite sound/sdcard --- src/main.cpp | 8 +++---- src/sdcard.cpp | 46 +++++++----------------------------- src/sdcard.h | 9 ++++---- src/sound.cpp | 63 ++++++++++++++++++++++++++++---------------------- src/sound.h | 7 +++--- 5 files changed, 55 insertions(+), 78 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6ba66fe..75e05a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,7 +45,7 @@ void setup() static const char *bootSound = "/boot.wav"; - //xTaskCreate(&(Sound::buffer_refill_task), "buffer_refill_task", 3072, (void*)bootSound, 5, &xTaskSound); + //xTaskCreate(&(Sound::play_task), "play_task", 3072, (void*)bootSound, 5, &xTaskSound); } void loop() @@ -56,10 +56,10 @@ void loop() touched = true; Serial.print("touch "); Serial.println(i, DEC); - if (Sound::playing == false) { - Sound::playing == true; // ToDo: fix double task init + if (playing == false) { + playing == true; Serial.println("main loop touched==true: new task"); - xTaskCreate(&(Sound::buffer_refill_task), "buffer_refill_task", 3072, (void*)soundFile[i/3][i%3], 5, &xTaskSound); + xTaskCreate(&(Sound::play_task), "play_task", 3072, (void*)soundFile[i/3][i%3], 5, &xTaskSound); } } } diff --git a/src/sdcard.cpp b/src/sdcard.cpp index 9d840b8..b33345d 100644 --- a/src/sdcard.cpp +++ b/src/sdcard.cpp @@ -9,7 +9,6 @@ #include "FS.h" #include "SD.h" #include "SPI.h" -#include "freertos/semphr.h" #include "hardware.h" #include "sdcard.h" @@ -20,13 +19,7 @@ using namespace std; static const char* TAG = "SDCard"; -unsigned char *DataSource::buffer = NULL; -SemaphoreHandle_t xSemaphore = NULL; -unsigned int DataSource::buf_pos = 0; -File SDCard::file; - SDCard::SDCard() { - xSemaphore = xSemaphoreCreateMutex(); } void SDCard::mount() { @@ -64,41 +57,18 @@ void SDCard::umount() { SD.end(); } -void SDCard::open(const char *path) { - if( xSemaphore != NULL ) { - if( xSemaphoreTake( xSemaphore, ( TickType_t ) 10 ) == pdTRUE ) { - if (DataSource::buffer != NULL) Serial.println("double malloc for buffer?"); - DataSource::buffer = (unsigned char *)malloc(BUF_LENGTH); - Serial.print("Allocated buffer at: "); Serial.println((int)(DataSource::buffer),HEX); - SDCard::file = (SDCard::fs).open(path); - if(!SDCard::file){ - Serial.println("Failed to open file for reading"); - return; - } - } else { - /* xSemaphoreTake() != pdTRUE */ - /* could not obtain the semaphore */ - Serial.println("sdcard: open(): could not obtain semaphore"); - } - } - - +File SDCard::open(const char* path) { + return SD.open(path); } -void SDCard::close() { - if (DataSource::buffer != NULL) { // ToDo: really fix this - Serial.print("free(buffer) at: "); Serial.println((int)(DataSource::buffer),HEX); - free(DataSource::buffer); - DataSource::buffer = NULL; - xSemaphoreGive( xSemaphore ); - } - SDCard::file.close(); +void SDCard::close(File file) { + file.close(); } -bool SDCard::available() { - return SDCard::file.available(); +bool SDCard::available(File file) { + return file.available(); } -size_t SDCard::read(){ - return SDCard::file.read((uint8_t *)DataSource::buffer, BUF_LENGTH); +size_t SDCard::read(File file, unsigned char* buffer, int length){ + return file.read((uint8_t *)buffer, length); } diff --git a/src/sdcard.h b/src/sdcard.h index 074eb46..2ce7756 100644 --- a/src/sdcard.h +++ b/src/sdcard.h @@ -12,11 +12,10 @@ class SDCard: public DataSource { SDCard(); void mount(); void umount(); - static void open(const char *path); - static void close(); - static size_t read(); - static bool available(); - static File file; + static File open(const char*); + static void close(File); + static size_t read(File file, unsigned char* buffer, int length); + static bool available(File); static constexpr fs::FS &fs = SD; private: uint8_t cardType; diff --git a/src/sound.cpp b/src/sound.cpp index 3aa935d..8320f06 100644 --- a/src/sound.cpp +++ b/src/sound.cpp @@ -17,6 +17,7 @@ #include "driver/i2s.h" //#include #include +#include "freertos/semphr.h" #define SAMPLE_RATE (11025) @@ -28,9 +29,10 @@ using namespace std; -volatile bool Sound::playing = false; +SemaphoreHandle_t xPlayingSemaphore = NULL; Sound::Sound() { + xPlayingSemaphore = xSemaphoreCreateMutex(); } void Sound::init() { @@ -78,60 +80,67 @@ void Sound::init() { i2s_push_sample(i2s_num, (char *)&sample_val, portMAX_DELAY); } - stop(); + i2s_stop(i2s_num); } -void Sound::play() { - Serial.println("Sound::play()"); - i2s_start(i2s_num); - Sound::playing = true; -} - -void Sound::stop() { - Serial.println("Sound::stop()"); - i2s_stop(i2s_num); - Sound::playing = false; -} void Sound::end() { i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver } -void Sound::buffer_refill_task(void *pvParameter) { +void Sound::play_task(void *pvParameter) { // Serial.print("initial free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG char *path = (char *) pvParameter; - Serial.println("sdcard: opening File"); - SDCard::open(path); + Serial.println("sound task: playing"); + if ( xPlayingSemaphore == NULL || xSemaphoreTake( xPlayingSemaphore, (TickType_t) 10) != pdTRUE ) { + Serial.println("Sound task: could not obtain semaphore"); + vTaskDelete( NULL ); + return; + } - Sound::play(); - while (SDCard::available()) { + File file = SDCard::open(path); + if (!file) { + Serial.print("Failed to open file: "); Serial.println(path); + vTaskDelete( NULL ); + return; + } + + unsigned char* buf = new unsigned char[BUF_LENGTH]; + unsigned int buf_pos; + Serial.print("Allocated buffer at: "); Serial.println((int)buf,HEX); + + i2s_start(i2s_num); + + while (SDCard::available(file)) { // Serial.print("chunk free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG // get chunk of data - SDCard::read(); // overwrite buffer - DataSource::buf_pos = 0; + SDCard::read(file, buf, BUF_LENGTH); // overwrite buffer + buf_pos = 0; - while (DataSource::buf_pos < BUF_LENGTH) { + while (buf_pos < BUF_LENGTH) { // Serial.print("i2s_push free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG - uint16_t *buf = (uint16_t *) DataSource::buffer; - int buf_pos = (DataSource::buf_pos)/4; + uint16_t *buf16 = (uint16_t *) buf; + int buf16_pos = buf_pos/4; // ToDo: why not 2? // convert data //unsigned int sample = ((unsigned short) DataSource::buffer[DataSource::buf_pos] << 16 & 0xffff0000) | ((unsigned short) DataSource::buffer[DataSource::buf_pos]); - unsigned int sample = ((unsigned short) buf[buf_pos] << 16 & 0xffff0000) | ((unsigned short) buf[buf_pos]); + unsigned int sample = ((unsigned short) buf16[buf16_pos] << 16 & 0xffff0000) | ((unsigned short) buf16[buf16_pos]); // push samples int num_pushed_bytes = i2s_push_sample(Sound::i2s_num, (char *)&sample, 0); if (num_pushed_bytes == 0) { Serial.println("i2s buf filled"); vTaskDelay(20 / portTICK_PERIOD_MS); } - DataSource::buf_pos += num_pushed_bytes; + buf_pos += num_pushed_bytes; } // Buffer now empty //TickType_t delay = 10 / portTICK_PERIOD_MS; // max delay: 10ms instead of portMAX_DELAY vTaskDelay(20 / portTICK_PERIOD_MS); } Serial.println("sdcard: EOF"); - SDCard::close(); - Sound::stop(); + SDCard::close(file); + i2s_stop(i2s_num); + delete[] buf; + xSemaphoreGive( xPlayingSemaphore ); Serial.println("task exiting"); vTaskDelete( NULL ); } diff --git a/src/sound.h b/src/sound.h index e06b5f9..265bd55 100644 --- a/src/sound.h +++ b/src/sound.h @@ -13,13 +13,12 @@ class Sound { void init(); void end(); // void close(); - static void play(); +// bool play(); // void pause(); - static void stop(); +// 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 volatile bool playing; - static void buffer_refill_task(void *pvParameter); + static void play_task(void *pvParameter); private: TaskHandle_t xTaskRefillBuffer; };