forked from W4D/soundcube-firmware
dma and pointer optimization, but still no luck
This commit is contained in:
@ -35,6 +35,20 @@ class RingBuffer{
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t* getReadPointer(){
|
||||||
|
return &buffer[read];
|
||||||
|
}
|
||||||
|
|
||||||
|
void pointerPop(int nbytes){
|
||||||
|
for(int i=0; i<nbytes / 2; ++i){
|
||||||
|
if(counter > 0) {
|
||||||
|
counter--;
|
||||||
|
read++;// % bufferSize;
|
||||||
|
if(read == bufferSize) read = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void pushDMA(int32_t *source){
|
void pushDMA(int32_t *source){
|
||||||
if(counter < bufferSize){
|
if(counter < bufferSize){
|
||||||
rp2040.memcpyDMA(&buffer[write], source, 4);
|
rp2040.memcpyDMA(&buffer[write], source, 4);
|
||||||
@ -48,6 +62,16 @@ class RingBuffer{
|
|||||||
return &buffer[write];
|
return &buffer[write];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void advance(int nbytes){
|
||||||
|
for(int i = 0; i < nbytes/2; ++i){
|
||||||
|
if(counter < bufferSize){
|
||||||
|
write++; // % bufferSize;
|
||||||
|
if(write == bufferSize) write = 0;
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void popDMA(int32_t *target){
|
void popDMA(int32_t *target){
|
||||||
if(counter > 0) {
|
if(counter > 0) {
|
||||||
counter -= 2;
|
counter -= 2;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
#define FASTLED_FORCE_SOFTWARE_SPI
|
#define FASTLED_FORCE_SOFTWARE_SPI
|
||||||
#include <FastLED.h>
|
#include <FastLED.h>
|
||||||
|
|
||||||
//#include <PWMAudio.h>
|
#include <PWMAudio.h>
|
||||||
#include <I2S.h>
|
#include <I2S.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <SD.h>
|
#include <SD.h>
|
||||||
@ -22,7 +22,7 @@ bool core1_disable_systick = true;
|
|||||||
#define AURAL 1
|
#define AURAL 1
|
||||||
#define UI_SAMPLERATE 22050
|
#define UI_SAMPLERATE 22050
|
||||||
|
|
||||||
#define BUFFERSIZE 32
|
#define BUFFERSIZE 64
|
||||||
#define NSTREAMS 16
|
#define NSTREAMS 16
|
||||||
|
|
||||||
I2S i2s(INPUT_PULLUP);
|
I2S i2s(INPUT_PULLUP);
|
||||||
@ -38,7 +38,7 @@ AS5600 ENC(&Wire1);
|
|||||||
|
|
||||||
DAC8552 dac(9, &SPI1);
|
DAC8552 dac(9, &SPI1);
|
||||||
|
|
||||||
//PWMAudio ui_snd(8);
|
PWMAudio ui_snd(8);
|
||||||
|
|
||||||
CRGB ui_leds[74];
|
CRGB ui_leds[74];
|
||||||
CRGB edge_leds[11];
|
CRGB edge_leds[11];
|
||||||
@ -71,6 +71,8 @@ volatile bool setup1_finished = false;
|
|||||||
volatile bool buttonChanged = false;
|
volatile bool buttonChanged = false;
|
||||||
volatile bool sdInitialized = false;
|
volatile bool sdInitialized = false;
|
||||||
|
|
||||||
|
volatile bool wire_ready = false;
|
||||||
|
|
||||||
volatile bool ui_click = false;
|
volatile bool ui_click = false;
|
||||||
volatile bool ui_beep = false;
|
volatile bool ui_beep = false;
|
||||||
bool amp = false;
|
bool amp = false;
|
||||||
@ -170,14 +172,23 @@ void codec_transmit() {
|
|||||||
for(int i = 0; i < count; i+=2){
|
for(int i = 0; i < count; i+=2){
|
||||||
if(streams_loaded){
|
if(streams_loaded){
|
||||||
for(int k = 0; k < NSTREAMS; k++){
|
for(int k = 0; k < NSTREAMS; k++){
|
||||||
int32_t twosamples;
|
//int32_t twosamples;
|
||||||
stream[k].wavefile.buffer.popDMA(&twosamples);
|
int16_t twosamples[2];
|
||||||
|
stream[k].getDMA((int32_t*)&twosamples);
|
||||||
|
|
||||||
int16_t sample_l = sample_l = twosamples >> 16;
|
int16_t sample_l = twosamples[0];// >> 16;
|
||||||
int16_t sample_r = sample_r = twosamples & 0xFFFF;
|
int16_t sample_r = twosamples[1];// & 0xFFFF;
|
||||||
|
|
||||||
buffer[i] += sample_l >> 3;
|
// int16_t *sample_l = stream[k].wavefile.buffer.getReadPointer(); //twosamples >> 16;
|
||||||
buffer[i+1] += sample_r >> 3;
|
// stream[k].wavefile.buffer.pointerPop(2);
|
||||||
|
// int16_t *sample_r = stream[k].wavefile.buffer.getReadPointer(); //twosamples & 0xFFFF;
|
||||||
|
// stream[k].wavefile.buffer.pointerPop(2);
|
||||||
|
|
||||||
|
// buffer[i] += (*sample_l / 16);
|
||||||
|
// buffer[i+1] += (*sample_r / 16);
|
||||||
|
|
||||||
|
buffer[i] += (sample_l / 16);
|
||||||
|
buffer[i+1] += (sample_r / 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,33 +202,33 @@ void codec_receive(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// void pwm_audio_callback() {
|
void pwm_audio_callback() {
|
||||||
// while (ui_snd.availableForWrite()) {
|
while (ui_snd.availableForWrite()) {
|
||||||
// if(ui_click || ui_beep) {
|
if(ui_click || ui_beep) {
|
||||||
// if(ui_beep) {
|
if(ui_beep) {
|
||||||
// ui_snd.write(ui_beep_snd[counter]);
|
ui_snd.write(ui_beep_snd[counter]);
|
||||||
// counter++;
|
counter++;
|
||||||
// if(counter == beep_length) {
|
if(counter == beep_length) {
|
||||||
// counter = 0;
|
counter = 0;
|
||||||
// ui_beep = false;
|
ui_beep = false;
|
||||||
// }
|
}
|
||||||
// continue;
|
continue;
|
||||||
// }
|
}
|
||||||
// if(ui_click) {
|
if(ui_click) {
|
||||||
// ui_snd.write(ui_click_snd[counter]);
|
ui_snd.write(ui_click_snd[counter]);
|
||||||
// counter++;
|
counter++;
|
||||||
// if(counter == click_length) {
|
if(counter == click_length) {
|
||||||
// counter = 0;
|
counter = 0;
|
||||||
// ui_click = false;
|
ui_click = false;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// } else {
|
} else {
|
||||||
// digitalWrite(7, LOW);
|
digitalWrite(7, LOW);
|
||||||
// ui_snd.write(0);
|
ui_snd.write(0);
|
||||||
// counter = 0;
|
counter = 0;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
bool load_ui_sounds(const char* file, int16_t *buffer, uint16_t &length){
|
bool load_ui_sounds(const char* file, int16_t *buffer, uint16_t &length){
|
||||||
if(SD.exists(file)) {
|
if(SD.exists(file)) {
|
||||||
@ -338,83 +349,20 @@ Vibration vibration;
|
|||||||
void setup() {
|
void setup() {
|
||||||
i2s.setSysClk(48000);
|
i2s.setSysClk(48000);
|
||||||
|
|
||||||
Serial.begin();
|
|
||||||
|
|
||||||
while(!codec_ready){
|
|
||||||
Serial.println("0: Waiting for codec");
|
|
||||||
delay(250);
|
|
||||||
}
|
|
||||||
|
|
||||||
// i2s.onTransmit(codec_transmit);
|
|
||||||
// i2s.onReceive(codec_receive);
|
|
||||||
|
|
||||||
i2s.setDOUT(15);
|
|
||||||
i2s.setDIN(14);
|
|
||||||
i2s.setBCLK(16); // Note: LRCLK = BCLK + 1
|
|
||||||
i2s.setMCLK(18);
|
|
||||||
i2s.setMCLKmult(512); // 256 = 12.288.000Hz 512 = 25MHz
|
|
||||||
i2s.swapClocks();
|
|
||||||
|
|
||||||
i2s.setFrequency(48000);
|
|
||||||
i2s.setBitsPerSample(16);
|
|
||||||
|
|
||||||
i2s.setBuffers(6, BUFFERSIZE * sizeof(int16_t) / sizeof(uint32_t));
|
|
||||||
|
|
||||||
if(!i2s.begin(48000)){
|
|
||||||
Serial.println("0: I2S error!");
|
|
||||||
while(100);
|
|
||||||
}
|
|
||||||
Serial.println("0: I2S OK");
|
|
||||||
|
|
||||||
delay(100);
|
|
||||||
|
|
||||||
i2s_ready = true;
|
|
||||||
|
|
||||||
pinMode(12, OUTPUT); // speaker enable l
|
|
||||||
pinMode(13, OUTPUT); // speaker enable r
|
|
||||||
speaker(false);
|
|
||||||
|
|
||||||
pinMode(21, INPUT_PULLUP);
|
|
||||||
sd_card_detected = !digitalRead(21);
|
|
||||||
delay(500);
|
delay(500);
|
||||||
|
|
||||||
while(!sdInitialized){
|
Serial.print("1: INIT WIRE: ");
|
||||||
sdInitialized = SD.begin(22, 23, 24);
|
Wire1.setSDA(2);
|
||||||
delay(250);
|
Wire1.setSCL(3);
|
||||||
Serial.println("0: Initializing SD Card");
|
Wire1.begin();
|
||||||
}
|
Serial.println("SUCCESS");
|
||||||
|
|
||||||
if(sdInitialized) loadConfiguration(config);
|
wire_ready = true;
|
||||||
|
|
||||||
// if(sdInitialized){
|
Serial.print("1: INIT SPI: ");
|
||||||
// load_ui_sounds("/ui/click.wav", ui_click_snd, click_length);
|
SPI1.setSCK(10);
|
||||||
// load_ui_sounds("/ui/beep.wav", ui_beep_snd, beep_length);
|
SPI1.setTX(11);
|
||||||
// }
|
SPI1.begin();
|
||||||
|
|
||||||
config_loaded = true;
|
|
||||||
|
|
||||||
if(sdInitialized) {
|
|
||||||
streams_loaded = load_samples();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(streams_loaded) {
|
|
||||||
for(int i = 0; i < NSTREAMS; i++){
|
|
||||||
samples[i].file = &stream[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.print("0: STARTUP COMPLETE");
|
|
||||||
|
|
||||||
digitalWrite(6, HIGH);
|
|
||||||
delay(25);
|
|
||||||
digitalWrite(6, LOW);
|
|
||||||
setup0_finished = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup1(){
|
|
||||||
Serial.print("1: ENABLE I2S MCLK: ");
|
|
||||||
pinMode(19, OUTPUT); // MCLK enable
|
|
||||||
digitalWrite(19, HIGH); // enable MCLK
|
|
||||||
Serial.println("SUCCESS");
|
Serial.println("SUCCESS");
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
@ -422,40 +370,14 @@ void setup1(){
|
|||||||
pinMode(20, OUTPUT); // CODEC reset (enable)
|
pinMode(20, OUTPUT); // CODEC reset (enable)
|
||||||
digitalWrite(20, HIGH);
|
digitalWrite(20, HIGH);
|
||||||
Serial.println("SUCCESS");
|
Serial.println("SUCCESS");
|
||||||
delay(100);
|
|
||||||
|
Serial.print("1: ENABLE I2S MCLK: ");
|
||||||
|
pinMode(19, OUTPUT); // MCLK enable
|
||||||
|
digitalWrite(19, HIGH); // enable MCLK
|
||||||
|
Serial.println("SUCCESS");
|
||||||
|
|
||||||
Serial.print("1: STARTUP");
|
Serial.print("1: STARTUP");
|
||||||
|
|
||||||
Serial.print("1: INIT WIRE: ");
|
|
||||||
Wire1.setSDA(2);
|
|
||||||
Wire1.setSCL(3);
|
|
||||||
Wire1.begin();
|
|
||||||
Serial.println("SUCCESS");
|
|
||||||
delay(100);
|
|
||||||
|
|
||||||
Serial.print("1: INIT CODEC: ");
|
|
||||||
codec.begin(&Wire1);
|
|
||||||
Serial.println("SUCCESS");
|
|
||||||
delay(500);
|
|
||||||
|
|
||||||
codec_ready = true;
|
|
||||||
|
|
||||||
Serial.print("1: INIT SPI: ");
|
|
||||||
SPI1.setSCK(10);
|
|
||||||
SPI1.setTX(11);
|
|
||||||
SPI1.begin();
|
|
||||||
Serial.println("SUCCESS");
|
|
||||||
|
|
||||||
Serial.print("1: INIT DAC: ");
|
|
||||||
dac.begin();
|
|
||||||
Serial.println("SUCCESS");
|
|
||||||
|
|
||||||
|
|
||||||
while(!config_loaded){
|
|
||||||
delay(250);
|
|
||||||
Serial.println("1: Waiting for config");
|
|
||||||
}
|
|
||||||
|
|
||||||
Serial.print("1: INIT TCA: ");
|
Serial.print("1: INIT TCA: ");
|
||||||
TCA.begin();
|
TCA.begin();
|
||||||
TCA.pinMode16(0xFFFF);
|
TCA.pinMode16(0xFFFF);
|
||||||
@ -473,6 +395,9 @@ void setup1(){
|
|||||||
ENC.resetCumulativePosition();
|
ENC.resetCumulativePosition();
|
||||||
Serial.println("SUCCESS");
|
Serial.println("SUCCESS");
|
||||||
|
|
||||||
|
Serial.print("1: INIT DAC: ");
|
||||||
|
dac.begin();
|
||||||
|
Serial.println("SUCCESS");
|
||||||
|
|
||||||
pinMode(6, OUTPUT); // Vibration Motor
|
pinMode(6, OUTPUT); // Vibration Motor
|
||||||
pinMode(7, OUTPUT); // UI Amp Enable
|
pinMode(7, OUTPUT); // UI Amp Enable
|
||||||
@ -492,6 +417,83 @@ void setup1(){
|
|||||||
digitalWrite(6, HIGH);
|
digitalWrite(6, HIGH);
|
||||||
delay(25);
|
delay(25);
|
||||||
digitalWrite(6, LOW);
|
digitalWrite(6, LOW);
|
||||||
|
Serial.begin();
|
||||||
|
|
||||||
|
Serial.print("0: INIT CODEC: ");
|
||||||
|
codec.begin(&Wire1);
|
||||||
|
Serial.println("SUCCESS");
|
||||||
|
|
||||||
|
codec_ready = true;
|
||||||
|
|
||||||
|
pinMode(12, OUTPUT); // speaker enable l
|
||||||
|
pinMode(13, OUTPUT); // speaker enable r
|
||||||
|
speaker(false);
|
||||||
|
|
||||||
|
pinMode(21, INPUT_PULLUP);
|
||||||
|
sd_card_detected = !digitalRead(21);
|
||||||
|
delay(500);
|
||||||
|
|
||||||
|
while(!sdInitialized){
|
||||||
|
sdInitialized = SD.begin(22, 23, 24);
|
||||||
|
delay(250);
|
||||||
|
Serial.println("0: Initializing SD Card");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sdInitialized) loadConfiguration(config);
|
||||||
|
|
||||||
|
if(sdInitialized){
|
||||||
|
load_ui_sounds("/ui/click.wav", ui_click_snd, click_length);
|
||||||
|
load_ui_sounds("/ui/beep.wav", ui_beep_snd, beep_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
config_loaded = true;
|
||||||
|
|
||||||
|
if(sdInitialized) {
|
||||||
|
streams_loaded = load_samples();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(streams_loaded) {
|
||||||
|
for(int i = 0; i < NSTREAMS; i++){
|
||||||
|
samples[i].file = &stream[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
i2s.onTransmit(codec_transmit);
|
||||||
|
i2s.onReceive(codec_receive);
|
||||||
|
|
||||||
|
i2s.setDOUT(15);
|
||||||
|
i2s.setDIN(14);
|
||||||
|
i2s.setBCLK(16); // Note: LRCLK = BCLK + 1
|
||||||
|
i2s.setMCLK(18);
|
||||||
|
i2s.setMCLKmult(512); // 256 = 12.288.000Hz 512 = 25MHz
|
||||||
|
i2s.swapClocks();
|
||||||
|
|
||||||
|
// i2s.setFrequency(48000);
|
||||||
|
i2s.setBitsPerSample(16);
|
||||||
|
|
||||||
|
i2s.setBuffers(4, BUFFERSIZE * sizeof(int16_t) / sizeof(uint32_t));
|
||||||
|
|
||||||
|
if(!i2s.begin(48000)){
|
||||||
|
Serial.println("0: I2S error!");
|
||||||
|
while(100);
|
||||||
|
}
|
||||||
|
Serial.println("0: I2S OK");
|
||||||
|
|
||||||
|
delay(100);
|
||||||
|
|
||||||
|
i2s_ready = true;
|
||||||
|
|
||||||
|
Serial.print("0: STARTUP COMPLETE");
|
||||||
|
|
||||||
|
digitalWrite(6, HIGH);
|
||||||
|
delay(25);
|
||||||
|
digitalWrite(6, LOW);
|
||||||
|
setup0_finished = true;
|
||||||
|
setup1_finished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup1(){
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t last = 0;
|
uint32_t last = 0;
|
||||||
@ -731,7 +733,7 @@ void loop1() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//int sc = 0;
|
//int sc = 0;
|
||||||
|
int cnt = 0;
|
||||||
void loop(){
|
void loop(){
|
||||||
if(setup1_finished && setup0_finished){
|
if(setup1_finished && setup0_finished){
|
||||||
|
|
||||||
@ -753,26 +755,29 @@ void loop(){
|
|||||||
last = millis();
|
last = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stream[cnt].stream();
|
||||||
|
// cnt++;
|
||||||
|
// if(cnt == 16) cnt = 0;
|
||||||
if(streams_loaded) {
|
if(streams_loaded) {
|
||||||
for(int i = 0; i < NSTREAMS; i++){
|
for(int i = 0; i < NSTREAMS; i++){
|
||||||
stream[i].stream();
|
stream[i].streamChunk();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int16_t sample_l = 0;
|
// int16_t sample_l = 0;
|
||||||
int16_t sample_r = 0;
|
// int16_t sample_r = 0;
|
||||||
|
//
|
||||||
if(streams_loaded){
|
// if(streams_loaded){
|
||||||
for(int k = 0; k < NSTREAMS; k++){
|
// for(int k = 0; k < NSTREAMS; k++){
|
||||||
sample_l += stream[k].get() >> 2;
|
// sample_l += stream[k].get() >> 2;
|
||||||
sample_r += stream[k].get() >> 2;
|
// sample_r += stream[k].get() >> 2;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
int16_t l = 0, r = 0;
|
// int16_t l = 0, r = 0;
|
||||||
//i2s.read16(&l, &r);
|
// i2s.read16(&l, &r);
|
||||||
l += sample_l;
|
// l += sample_l;
|
||||||
r += sample_r;
|
// r += sample_r;
|
||||||
i2s.write16(l, r);
|
// i2s.write16(l, r);
|
||||||
|
|
||||||
if(i2s.getOverflow()) Serial.println("overflow");
|
if(i2s.getOverflow()) Serial.println("overflow");
|
||||||
if(i2s.getUnderflow()) Serial.println("underflow");
|
if(i2s.getUnderflow()) Serial.println("underflow");
|
||||||
|
|||||||
@ -96,6 +96,21 @@ struct WaveFile{
|
|||||||
void *bufferStart = buffer.getWritePointer();
|
void *bufferStart = buffer.getWritePointer();
|
||||||
|
|
||||||
file.read((uint8_t*)bufferStart, 4);
|
file.read((uint8_t*)bufferStart, 4);
|
||||||
|
buffer.advance(4);
|
||||||
|
|
||||||
|
if(!file.available() && loop) file.seek(44, SeekSet);
|
||||||
|
if(!file.available() && !loop) {
|
||||||
|
file.seek(44, SeekSet);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readblockDMA128(){
|
||||||
|
void *bufferStart = buffer.getWritePointer();
|
||||||
|
|
||||||
|
file.read((uint8_t*)bufferStart, 128);
|
||||||
|
buffer.advance(128);
|
||||||
|
|
||||||
if(!file.available() && loop) file.seek(44, SeekSet);
|
if(!file.available() && loop) file.seek(44, SeekSet);
|
||||||
if(!file.available() && !loop) {
|
if(!file.available() && !loop) {
|
||||||
@ -157,13 +172,18 @@ class WaveStream{
|
|||||||
void pause(){playing = false;}
|
void pause(){playing = false;}
|
||||||
|
|
||||||
void stream(){
|
void stream(){
|
||||||
if(!wavefile.buffer.isFull() && playing){
|
int cnt = 0;
|
||||||
int cnt = 0;
|
while (!wavefile.buffer.isFull() && cnt < 128 && playing) {
|
||||||
while (!wavefile.buffer.isFull() && cnt < 1024) {
|
bool ok = wavefile.readblockDMA();
|
||||||
bool ok = wavefile.readblockDMA();
|
if(!ok) playing = false;
|
||||||
if(!ok) playing = false;
|
cnt += 2;
|
||||||
cnt += 2;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void streamChunk(){
|
||||||
|
if(!wavefile.buffer.isFull()){
|
||||||
|
bool ok = wavefile.readblockDMA128();
|
||||||
|
if(!ok) playing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,6 +191,16 @@ class WaveStream{
|
|||||||
return playing ? wavefile.get() : 0;
|
return playing ? wavefile.get() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t* getPointer(){
|
||||||
|
int16_t* p = wavefile.buffer.getReadPointer();
|
||||||
|
wavefile.buffer.pointerPop(2);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getDMA(int32_t *samples){
|
||||||
|
if(playing) wavefile.buffer.popDMA(samples);
|
||||||
|
}
|
||||||
|
|
||||||
bool isPlaying(){
|
bool isPlaying(){
|
||||||
return playing;
|
return playing;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user