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;
|
||||
}
|
||||
|
||||
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){
|
||||
if(counter < bufferSize){
|
||||
rp2040.memcpyDMA(&buffer[write], source, 4);
|
||||
@ -48,6 +62,16 @@ class RingBuffer{
|
||||
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){
|
||||
if(counter > 0) {
|
||||
counter -= 2;
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
#define FASTLED_FORCE_SOFTWARE_SPI
|
||||
#include <FastLED.h>
|
||||
|
||||
//#include <PWMAudio.h>
|
||||
#include <PWMAudio.h>
|
||||
#include <I2S.h>
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
@ -22,7 +22,7 @@ bool core1_disable_systick = true;
|
||||
#define AURAL 1
|
||||
#define UI_SAMPLERATE 22050
|
||||
|
||||
#define BUFFERSIZE 32
|
||||
#define BUFFERSIZE 64
|
||||
#define NSTREAMS 16
|
||||
|
||||
I2S i2s(INPUT_PULLUP);
|
||||
@ -38,7 +38,7 @@ AS5600 ENC(&Wire1);
|
||||
|
||||
DAC8552 dac(9, &SPI1);
|
||||
|
||||
//PWMAudio ui_snd(8);
|
||||
PWMAudio ui_snd(8);
|
||||
|
||||
CRGB ui_leds[74];
|
||||
CRGB edge_leds[11];
|
||||
@ -71,6 +71,8 @@ volatile bool setup1_finished = false;
|
||||
volatile bool buttonChanged = false;
|
||||
volatile bool sdInitialized = false;
|
||||
|
||||
volatile bool wire_ready = false;
|
||||
|
||||
volatile bool ui_click = false;
|
||||
volatile bool ui_beep = false;
|
||||
bool amp = false;
|
||||
@ -170,14 +172,23 @@ void codec_transmit() {
|
||||
for(int i = 0; i < count; i+=2){
|
||||
if(streams_loaded){
|
||||
for(int k = 0; k < NSTREAMS; k++){
|
||||
int32_t twosamples;
|
||||
stream[k].wavefile.buffer.popDMA(&twosamples);
|
||||
//int32_t twosamples;
|
||||
int16_t twosamples[2];
|
||||
stream[k].getDMA((int32_t*)&twosamples);
|
||||
|
||||
int16_t sample_l = sample_l = twosamples >> 16;
|
||||
int16_t sample_r = sample_r = twosamples & 0xFFFF;
|
||||
int16_t sample_l = twosamples[0];// >> 16;
|
||||
int16_t sample_r = twosamples[1];// & 0xFFFF;
|
||||
|
||||
buffer[i] += sample_l >> 3;
|
||||
buffer[i+1] += sample_r >> 3;
|
||||
// int16_t *sample_l = stream[k].wavefile.buffer.getReadPointer(); //twosamples >> 16;
|
||||
// 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() {
|
||||
// while (ui_snd.availableForWrite()) {
|
||||
// if(ui_click || ui_beep) {
|
||||
// if(ui_beep) {
|
||||
// ui_snd.write(ui_beep_snd[counter]);
|
||||
// counter++;
|
||||
// if(counter == beep_length) {
|
||||
// counter = 0;
|
||||
// ui_beep = false;
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
// if(ui_click) {
|
||||
// ui_snd.write(ui_click_snd[counter]);
|
||||
// counter++;
|
||||
// if(counter == click_length) {
|
||||
// counter = 0;
|
||||
// ui_click = false;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// digitalWrite(7, LOW);
|
||||
// ui_snd.write(0);
|
||||
// counter = 0;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
void pwm_audio_callback() {
|
||||
while (ui_snd.availableForWrite()) {
|
||||
if(ui_click || ui_beep) {
|
||||
if(ui_beep) {
|
||||
ui_snd.write(ui_beep_snd[counter]);
|
||||
counter++;
|
||||
if(counter == beep_length) {
|
||||
counter = 0;
|
||||
ui_beep = false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(ui_click) {
|
||||
ui_snd.write(ui_click_snd[counter]);
|
||||
counter++;
|
||||
if(counter == click_length) {
|
||||
counter = 0;
|
||||
ui_click = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
digitalWrite(7, LOW);
|
||||
ui_snd.write(0);
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool load_ui_sounds(const char* file, int16_t *buffer, uint16_t &length){
|
||||
if(SD.exists(file)) {
|
||||
@ -338,83 +349,20 @@ Vibration vibration;
|
||||
void setup() {
|
||||
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);
|
||||
|
||||
while(!sdInitialized){
|
||||
sdInitialized = SD.begin(22, 23, 24);
|
||||
delay(250);
|
||||
Serial.println("0: Initializing SD Card");
|
||||
}
|
||||
Serial.print("1: INIT WIRE: ");
|
||||
Wire1.setSDA(2);
|
||||
Wire1.setSCL(3);
|
||||
Wire1.begin();
|
||||
Serial.println("SUCCESS");
|
||||
|
||||
if(sdInitialized) loadConfiguration(config);
|
||||
wire_ready = true;
|
||||
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
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.print("1: INIT SPI: ");
|
||||
SPI1.setSCK(10);
|
||||
SPI1.setTX(11);
|
||||
SPI1.begin();
|
||||
Serial.println("SUCCESS");
|
||||
delay(100);
|
||||
|
||||
@ -422,40 +370,14 @@ void setup1(){
|
||||
pinMode(20, OUTPUT); // CODEC reset (enable)
|
||||
digitalWrite(20, HIGH);
|
||||
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: 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: ");
|
||||
TCA.begin();
|
||||
TCA.pinMode16(0xFFFF);
|
||||
@ -473,6 +395,9 @@ void setup1(){
|
||||
ENC.resetCumulativePosition();
|
||||
Serial.println("SUCCESS");
|
||||
|
||||
Serial.print("1: INIT DAC: ");
|
||||
dac.begin();
|
||||
Serial.println("SUCCESS");
|
||||
|
||||
pinMode(6, OUTPUT); // Vibration Motor
|
||||
pinMode(7, OUTPUT); // UI Amp Enable
|
||||
@ -492,6 +417,83 @@ void setup1(){
|
||||
digitalWrite(6, HIGH);
|
||||
delay(25);
|
||||
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;
|
||||
@ -731,7 +733,7 @@ void loop1() {
|
||||
}
|
||||
}
|
||||
//int sc = 0;
|
||||
|
||||
int cnt = 0;
|
||||
void loop(){
|
||||
if(setup1_finished && setup0_finished){
|
||||
|
||||
@ -753,26 +755,29 @@ void loop(){
|
||||
last = millis();
|
||||
}
|
||||
|
||||
// stream[cnt].stream();
|
||||
// cnt++;
|
||||
// if(cnt == 16) cnt = 0;
|
||||
if(streams_loaded) {
|
||||
for(int i = 0; i < NSTREAMS; i++){
|
||||
stream[i].stream();
|
||||
stream[i].streamChunk();
|
||||
}
|
||||
}
|
||||
int16_t sample_l = 0;
|
||||
int16_t sample_r = 0;
|
||||
|
||||
if(streams_loaded){
|
||||
for(int k = 0; k < NSTREAMS; k++){
|
||||
sample_l += stream[k].get() >> 2;
|
||||
sample_r += stream[k].get() >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t l = 0, r = 0;
|
||||
//i2s.read16(&l, &r);
|
||||
l += sample_l;
|
||||
r += sample_r;
|
||||
i2s.write16(l, r);
|
||||
// int16_t sample_l = 0;
|
||||
// int16_t sample_r = 0;
|
||||
//
|
||||
// if(streams_loaded){
|
||||
// for(int k = 0; k < NSTREAMS; k++){
|
||||
// sample_l += stream[k].get() >> 2;
|
||||
// sample_r += stream[k].get() >> 2;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// int16_t l = 0, r = 0;
|
||||
// i2s.read16(&l, &r);
|
||||
// l += sample_l;
|
||||
// r += sample_r;
|
||||
// i2s.write16(l, r);
|
||||
|
||||
if(i2s.getOverflow()) Serial.println("overflow");
|
||||
if(i2s.getUnderflow()) Serial.println("underflow");
|
||||
|
||||
@ -96,6 +96,21 @@ struct WaveFile{
|
||||
void *bufferStart = buffer.getWritePointer();
|
||||
|
||||
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) {
|
||||
@ -157,13 +172,18 @@ class WaveStream{
|
||||
void pause(){playing = false;}
|
||||
|
||||
void stream(){
|
||||
if(!wavefile.buffer.isFull() && playing){
|
||||
int cnt = 0;
|
||||
while (!wavefile.buffer.isFull() && cnt < 1024) {
|
||||
bool ok = wavefile.readblockDMA();
|
||||
if(!ok) playing = false;
|
||||
cnt += 2;
|
||||
}
|
||||
int cnt = 0;
|
||||
while (!wavefile.buffer.isFull() && cnt < 128 && playing) {
|
||||
bool ok = wavefile.readblockDMA();
|
||||
if(!ok) playing = false;
|
||||
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;
|
||||
}
|
||||
|
||||
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(){
|
||||
return playing;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user