Browse Source

rewrite sound/sdcard

main
Hendrik Langer 8 years ago
parent
commit
c91b89b3f8
  1. 8
      src/main.cpp
  2. 46
      src/sdcard.cpp
  3. 9
      src/sdcard.h
  4. 63
      src/sound.cpp
  5. 7
      src/sound.h

8
src/main.cpp

@ -45,7 +45,7 @@ void setup()
static const char *bootSound = "/boot.wav"; 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() void loop()
@ -56,10 +56,10 @@ void loop()
touched = true; touched = true;
Serial.print("touch "); Serial.print("touch ");
Serial.println(i, DEC); Serial.println(i, DEC);
if (Sound::playing == false) { if (playing == false) {
Sound::playing == true; // ToDo: fix double task init playing == true;
Serial.println("main loop touched==true: new task"); 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);
} }
} }
} }

46
src/sdcard.cpp

@ -9,7 +9,6 @@
#include "FS.h" #include "FS.h"
#include "SD.h" #include "SD.h"
#include "SPI.h" #include "SPI.h"
#include "freertos/semphr.h"
#include "hardware.h" #include "hardware.h"
#include "sdcard.h" #include "sdcard.h"
@ -20,13 +19,7 @@ using namespace std;
static const char* TAG = "SDCard"; 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() { SDCard::SDCard() {
xSemaphore = xSemaphoreCreateMutex();
} }
void SDCard::mount() { void SDCard::mount() {
@ -64,41 +57,18 @@ void SDCard::umount() {
SD.end(); SD.end();
} }
void SDCard::open(const char *path) { File SDCard::open(const char* path) {
if( xSemaphore != NULL ) { return SD.open(path);
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");
}
} }
void SDCard::close(File file) {
} file.close();
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();
} }
bool SDCard::available() { bool SDCard::available(File file) {
return SDCard::file.available(); return file.available();
} }
size_t SDCard::read(){ size_t SDCard::read(File file, unsigned char* buffer, int length){
return SDCard::file.read((uint8_t *)DataSource::buffer, BUF_LENGTH); return file.read((uint8_t *)buffer, length);
} }

9
src/sdcard.h

@ -12,11 +12,10 @@ class SDCard: public DataSource {
SDCard(); SDCard();
void mount(); void mount();
void umount(); void umount();
static void open(const char *path); static File open(const char*);
static void close(); static void close(File);
static size_t read(); static size_t read(File file, unsigned char* buffer, int length);
static bool available(); static bool available(File);
static File file;
static constexpr fs::FS &fs = SD; static constexpr fs::FS &fs = SD;
private: private:
uint8_t cardType; uint8_t cardType;

63
src/sound.cpp

@ -17,6 +17,7 @@
#include "driver/i2s.h" #include "driver/i2s.h"
//#include <soc/i2s_reg.h> //#include <soc/i2s_reg.h>
#include <math.h> #include <math.h>
#include "freertos/semphr.h"
#define SAMPLE_RATE (11025) #define SAMPLE_RATE (11025)
@ -28,9 +29,10 @@
using namespace std; using namespace std;
volatile bool Sound::playing = false; SemaphoreHandle_t xPlayingSemaphore = NULL;
Sound::Sound() { Sound::Sound() {
xPlayingSemaphore = xSemaphoreCreateMutex();
} }
void Sound::init() { void Sound::init() {
@ -78,60 +80,67 @@ void Sound::init() {
i2s_push_sample(i2s_num, (char *)&sample_val, portMAX_DELAY); i2s_push_sample(i2s_num, (char *)&sample_val, portMAX_DELAY);
} }
stop();
}
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); i2s_stop(i2s_num);
Sound::playing = false;
} }
void Sound::end() { void Sound::end() {
i2s_driver_uninstall(i2s_num); //stop & destroy i2s driver 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 // Serial.print("initial free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG
char *path = (char *) pvParameter; char *path = (char *) pvParameter;
Serial.println("sdcard: opening File"); Serial.println("sound task: playing");
SDCard::open(path); if ( xPlayingSemaphore == NULL || xSemaphoreTake( xPlayingSemaphore, (TickType_t) 10) != pdTRUE ) {
Serial.println("Sound task: could not obtain semaphore");
vTaskDelete( NULL );
return;
}
Sound::play(); File file = SDCard::open(path);
while (SDCard::available()) { 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 // Serial.print("chunk free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG
// get chunk of data // get chunk of data
SDCard::read(); // overwrite buffer SDCard::read(file, buf, BUF_LENGTH); // overwrite buffer
DataSource::buf_pos = 0; 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 // Serial.print("i2s_push free stack: "); Serial.println(uxTaskGetStackHighWaterMark( NULL ), DEC); // DEBUG
uint16_t *buf = (uint16_t *) DataSource::buffer; uint16_t *buf16 = (uint16_t *) buf;
int buf_pos = (DataSource::buf_pos)/4; int buf16_pos = buf_pos/4; // ToDo: why not 2?
// convert data // 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) 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 // push samples
int num_pushed_bytes = i2s_push_sample(Sound::i2s_num, (char *)&sample, 0); int num_pushed_bytes = i2s_push_sample(Sound::i2s_num, (char *)&sample, 0);
if (num_pushed_bytes == 0) { if (num_pushed_bytes == 0) {
Serial.println("i2s buf filled"); Serial.println("i2s buf filled");
vTaskDelay(20 / portTICK_PERIOD_MS); vTaskDelay(20 / portTICK_PERIOD_MS);
} }
DataSource::buf_pos += num_pushed_bytes; buf_pos += num_pushed_bytes;
} }
// Buffer now empty // Buffer now empty
//TickType_t delay = 10 / portTICK_PERIOD_MS; // max delay: 10ms instead of portMAX_DELAY //TickType_t delay = 10 / portTICK_PERIOD_MS; // max delay: 10ms instead of portMAX_DELAY
vTaskDelay(20 / portTICK_PERIOD_MS); vTaskDelay(20 / portTICK_PERIOD_MS);
} }
Serial.println("sdcard: EOF"); Serial.println("sdcard: EOF");
SDCard::close(); SDCard::close(file);
Sound::stop(); i2s_stop(i2s_num);
delete[] buf;
xSemaphoreGive( xPlayingSemaphore );
Serial.println("task exiting"); Serial.println("task exiting");
vTaskDelete( NULL ); vTaskDelete( NULL );
} }

7
src/sound.h

@ -13,13 +13,12 @@ class Sound {
void init(); void init();
void end(); void end();
// void close(); // void close();
static void play(); // bool play();
// void pause(); // void pause();
static void stop(); // void stop();
int render_sample_block(uint16_t *sample_buf_left, uint16_t *sample_buf_right, int num_samples); 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 const i2s_port_t i2s_num = (i2s_port_t)I2S_NUM;
static volatile bool playing; static void play_task(void *pvParameter);
static void buffer_refill_task(void *pvParameter);
private: private:
TaskHandle_t xTaskRefillBuffer; TaskHandle_t xTaskRefillBuffer;
}; };

Loading…
Cancel
Save