Browse Source

freertos task test sdcard->i2s buffer

main
Hendrik Langer 8 years ago
parent
commit
5fd6510adf
  1. 63
      src/main.cpp
  2. 49
      src/ringbuf.cpp
  3. 23
      src/ringbuf.h
  4. 2
      src/sdcard.cpp
  5. 3
      src/sound.h

63
src/main.cpp

@ -10,15 +10,56 @@
#include "keyboard.h" #include "keyboard.h"
#include "sdcard.h" #include "sdcard.h"
#include "sound.h" #include "sound.h"
#include "ringbuf.h"
#define VERSION "0.0" #define VERSION "0.0"
#define LED_PIN 21 #define LED_PIN 21
#define BUF_LENGTH 1024
Keyboard keyboard; Keyboard keyboard;
SDCard sdcard; SDCard sdcard;
Sound sound; Sound sound;
Ringbuf ringbuf = Ringbuf((size_t) BUF_LENGTH);
uint16_t buffer[2048]; void sd_read_task(void *pvParameter) {
sdcard.open("/T1.wav");
for ( ;; ) {
uint16_t *start_ptr = ringbuf.getWrite();
size_t size_avail = ringbuf.getWriteAvail();
int num_samples = 0;
if (size_avail > 0) {
num_samples = sdcard.read(start_ptr, size_avail);
ringbuf.setWrite(num_samples);
}
Serial.print(num_samples,DEC);
Serial.println(" read samples from sdcard");
if (!sdcard.available()) break; // EOF
vTaskDelay(20 / portTICK_PERIOD_MS); // 20ms
}
Serial.println("sdcard: EOF");
sdcard.close();
vTaskDelete( NULL );
}
void i2s_write_task(void *pvParameter) {
for ( ;; ) {
TickType_t delay = 10 / portTICK_PERIOD_MS; // max delay: 10ms instead of portMAX_DELAY
uint16_t *start_ptr = ringbuf.getRead();
size_t size_avail = ringbuf.getReadAvail();
int num_samples = 0;
for (int i=0; i<size_avail; i++) {
unsigned int sample = ((unsigned short) start_ptr[i] << 16 & 0xffff0000) | ((unsigned short) start_ptr[i]);
int num_pushed_bytes = i2s_push_sample(sound.i2s_num, (char *)&sample, delay);
num_samples += num_pushed_bytes/4;
}
ringbuf.setRead(num_samples);
Serial.print(num_samples,DEC);
Serial.println(" pushed samples to i2s");
vTaskDelay(20 / portTICK_PERIOD_MS);
}
vTaskDelete( NULL );
}
void setup() void setup()
{ {
@ -34,20 +75,10 @@ void setup()
keyboard.init(); keyboard.init();
sdcard.mount(); sdcard.mount();
sound.init(); sound.init();
sdcard.open("/sabaton.wav");
int num_bytes_i = 0; xTaskCreate(&sd_read_task, "read_task", 2048, NULL, 5, NULL);
int num_bytes_o = 0; xTaskCreate(&i2s_write_task, "write_task", 1024,NULL,5,NULL );
while (sdcard.available()) {
num_bytes_i += sdcard.read(buffer, 2048);
num_bytes_o += sound.render_sample_block(buffer, buffer, 2048);
Serial.print(".");
}
sdcard.close();
Serial.println("");
Serial.print(num_bytes_i,DEC);
Serial.println(" bytes read from file");
Serial.print(num_bytes_o,DEC);
Serial.println(" bytes written to i2s");
delay(1000); delay(1000);
} }
@ -67,7 +98,7 @@ void loop()
} else { } else {
// turn the LED off by making the voltage LOW // turn the LED off by making the voltage LOW
digitalWrite(LED_PIN, LOW); digitalWrite(LED_PIN, LOW);
sound.stop(); // sound.stop();
} }

49
src/ringbuf.cpp

@ -0,0 +1,49 @@
#include "Arduino.h"
#include "ringbuf.h"
using namespace std;
Ringbuf::Ringbuf(size_t buf_length) {
this->buf = (uint16_t *)malloc(buf_length);
Serial.print("Allocated buffer at: ");
Serial.println((int)this->buf,HEX);
this->buf_length = buf_length;
this->read_pos = 0;
this->write_pos = 0;
this->full = false;
}
Ringbuf::~Ringbuf() {
free(this->buf);
}
uint16_t *Ringbuf::getWrite() {
return this->buf + write_pos;
}
size_t Ringbuf::getWriteAvail() {
if (full) return 0; // full
else if (read_pos<=write_pos) return buf_length - write_pos; // to the end
else return read_pos - write_pos; // between
}
uint16_t *Ringbuf::getRead() {
return this->buf + read_pos;
}
size_t Ringbuf::getReadAvail() {
if (read_pos==write_pos && !full) return 0; // empty
else if (read_pos>=write_pos) return buf_length - read_pos; // read til end
else return write_pos - read_pos;
}
void Ringbuf::setWrite(size_t bytes){
write_pos = (write_pos+bytes)%buf_length;
if(read_pos==write_pos) full = true;
}
void Ringbuf::setRead(size_t bytes){
read_pos = (read_pos+bytes)%buf_length;
if(read_pos==write_pos) full = false;
}

23
src/ringbuf.h

@ -0,0 +1,23 @@
#ifndef _RINGBUF_H
#define _RINGBUF_H
class Ringbuf {
public:
Ringbuf(size_t buf_length);
~Ringbuf();
uint16_t *buf;
unsigned int buf_length;
unsigned int read_pos;
unsigned int write_pos;
uint16_t *getWrite();
size_t getWriteAvail();
uint16_t *getRead();
size_t getReadAvail();
void setWrite(size_t bytes);
void setRead(size_t bytes);
bool full;
private:
};
#endif /* _RINGBUF_H */

2
src/sdcard.cpp

@ -73,5 +73,5 @@ bool SDCard::available() {
} }
size_t SDCard::read(uint16_t *buffer, size_t len){ size_t SDCard::read(uint16_t *buffer, size_t len){
return file.read((uint8_t *)buffer, len); return file.read((uint8_t *)buffer, len*sizeof(uint16_t))/sizeof(uint16_t);
} }

3
src/sound.h

@ -26,9 +26,10 @@ class Sound {
// void pause(); // void pause();
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);
const i2s_port_t i2s_num = (i2s_port_t)I2S_NUM;
private: private:
i2sbuffer_t buffer; i2sbuffer_t buffer;
const i2s_port_t i2s_num = (i2s_port_t)I2S_NUM;
}; };
#endif /* _SOUND_H */ #endif /* _SOUND_H */

Loading…
Cancel
Save