Browse Source

rewrite sound/sdcard

main
Hendrik Langer 7 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";
//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);
}
}
}

46
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);
}

9
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;

63
src/sound.cpp

@ -17,6 +17,7 @@
#include "driver/i2s.h"
//#include <soc/i2s_reg.h>
#include <math.h>
#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 );
}

7
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;
};

Loading…
Cancel
Save