diff --git a/soundcube-firmware/ringbuffer.h b/soundcube-firmware/ringbuffer.h index 98916cf..decd4b1 100644 --- a/soundcube-firmware/ringbuffer.h +++ b/soundcube-firmware/ringbuffer.h @@ -3,21 +3,53 @@ template class RingBuffer{ public: + RingBuffer() {} RingBuffer(size_t size) : bufferSize(size) {} - void begin(){ + + void setSize(size_t size) { + bufferSize = size; + } + + void begin(){ buffer = new T[bufferSize]; - }; + } bool push(T data){ - counter++; - }; + if(counter < bufferSize){ + buffer[write] = data; + write = (write+1) % bufferSize; + counter++; + return true; + } + return false; + } T pop(){ - counter--; - }; + T retval; + if(counter > 0) { + counter--; + retval = buffer[read]; + read = (read+1) % bufferSize; + } + return retval; + } + + bool isEmpty(){ + return counter == 0; + } + + bool isFull(){ + return counter == bufferSize; + } + + int size(){ + return counter; + } + private: size_t bufferSize = 0; int counter = 0; - bool - T buffer[]; -} \ No newline at end of file + int write = 0; + int read = 0; + T *buffer; +}; diff --git a/soundcube-firmware/soundcube-firmware.ino b/soundcube-firmware/soundcube-firmware.ino index 740395e..b45b7db 100644 --- a/soundcube-firmware/soundcube-firmware.ino +++ b/soundcube-firmware/soundcube-firmware.ino @@ -1,4 +1,3 @@ -#include #include #include @@ -10,24 +9,28 @@ #include #include #include "codec.h" +#include "ringbuffer.h" #define HAPTIC 1 #define AURAL 1 #define UI_SAMPLERATE 22050 -#define SIZE 256 -#define RINGBUFFER 1024 -#define ECHO 96000 +#define SIZE 1024 +#define RINGBUFFER 16384 +#define ECHO 24000 + +#define NSTREAMS 4 + int16_t buffer[SIZE]; int16_t buffer2[ECHO]; -RingBuf ringbuffer; +RingBuffer ringbuffer[NSTREAMS]; -File stream1; +File streams[NSTREAMS]; I2S i2s(INPUT_PULLUP); -TLV320AIC3204 codec; +TLV320AIC3204 codec; TCA9555 TCA(0x20, &Wire1); AS5600 ENC(&Wire1); @@ -40,6 +43,12 @@ int lut_ring_cw[48] = {39,38,37,36,35,34,33,32,31,30,29,28,27,26,25,24,23,22,21, int lut_ring_ccw[48] = {40,41,42,43,44,45,46,47,48,49,50,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39}; int lut_matrix[13] = {56,55,57,58,59,62,61,60,63,64,65,67,66}; +int active = 0; +int active_led_ring = 0; + +uint32_t lastTime = 0; +int32_t position = 0; + CRGB ui_leds[74]; CRGB edge_leds[11]; @@ -95,7 +104,11 @@ void codec_transmit() { // } for(int i = 0; i < count; i++){ - buffer[i] += ringbuffer.pop(); + int16_t sample = 0; + for(int j = 0; j < NSTREAMS; j++){ + if(!ringbuffer[j].isEmpty()) sample = ringbuffer[j].pop(); + buffer[i] += (sample / 4); + } } i2s.write((const uint8_t *)&buffer, count * sizeof(int16_t)); @@ -131,7 +144,13 @@ void tca_irq() { void setup() { //Serial.begin(); - //delay(2000); + //delay(1000); + + i2s.setFrequency(48000); + + for(int i = 0; i < NSTREAMS; i++){ + ringbuffer[i].setSize(RINGBUFFER); + } FastLED.addLeds(edge_leds, 11); FastLED.addLeds(ui_leds, 74); @@ -229,26 +248,49 @@ void setup() { i2s.setBuffers(6, SIZE * sizeof(int16_t) / sizeof(uint32_t)); + for(int i = 0; i < NSTREAMS; i++){ + ringbuffer[i].begin(); + } + if(!i2s.begin(48000)){ Serial.println("I2S error!"); while(100); } - if(sdInitialized && SD.exists("/piano.wav")) { - stream1 = SD.open("/piano.wav"); + if(sdInitialized) { + for(int i = 0; i < NSTREAMS; i++){ + char filename[40]; + sprintf(filename, "/sound/%d.wav", i+1); + if(SD.exists(filename)){ + streams[i] = SD.open(filename); + streams[i].seek(44, SeekSet); + } else { + for(int k = 0; k < 3; k++){ + digitalWrite(6, HIGH); + delay(20); + digitalWrite(6, LOW); + delay(50); + } + } + } } + // if(!ringbuffer.isFull()){ + // int cnt = 0; + // while (!ringbuffer.isFull() && cnt < RINGBUFFER) { + // int16_t sample = stream1.read(); + // ringbuffer.push(sample); + // if(!stream1.available()) stream1.seek(48000*6, SeekSet); + // cnt++; + // } + // } + + digitalWrite(6, HIGH); delay(50); digitalWrite(6, LOW); } -int active = 0; -int active_led_ring = 0; - -uint32_t lastTime = 0; -int32_t position = 0; - void loop() { position = ENC.getCumulativePosition(); @@ -256,11 +298,18 @@ void loop() { if(sd_card_detected) edge_leds[8] = CRGB(0,10,0); if(!sd_card_detected) edge_leds[8] = CRGB(10,0,0); - if(!ringbuffer.isFull()){ - while (!ringbuffer.isFull()) { - int16_t sample = stream1.read(); - ringbuffer.push(sample); - if(!stream1.available()) stream1.seek(0, SeekSet); + for (int i = 0; i < NSTREAMS; i++) { + if(!ringbuffer[i].isFull()){ + int cnt = 0; + while (!ringbuffer[i].isFull() && cnt < 10000) { + uint8_t samplebyte[2]; + streams[i].read(samplebyte, 2); + if(!streams[i].available()) streams[i].seek(44, SeekSet); + + int16_t sample = (samplebyte[1] << 8) + samplebyte[0]; + ringbuffer[i].push(sample); + cnt++; + } } } @@ -338,7 +387,7 @@ void loop() { ui_leds[lut_ring_ccw[i]] = CRGB(50, 0, 25); } - FastLED.show(); + //FastLED.show(); //delay(1); // wait 1ms } diff --git a/tools/ringbuffer-test.cpp b/tools/ringbuffer-test.cpp new file mode 100644 index 0000000..3ae80e0 --- /dev/null +++ b/tools/ringbuffer-test.cpp @@ -0,0 +1,18 @@ +#include +#include "ringbuffer.h" + +RingBuffer ringbuffer(25); + +int main(){ + ringbuffer.begin(); + + for(int j = 0; j < 3; j++){ + for(int i = 0; i < 15; i++){ + if(!ringbuffer.isFull()) ringbuffer.push(i); + } + std::cout << "---" << std::endl; + for(int i = 0; i < 25; i++){ + if(!ringbuffer.isEmpty()) ringbuffer.pop(); + } + } +} diff --git a/tools/ringbuffer.h b/tools/ringbuffer.h new file mode 100644 index 0000000..2d75338 --- /dev/null +++ b/tools/ringbuffer.h @@ -0,0 +1,49 @@ +#pragma once +#include + +template +class RingBuffer{ + public: + RingBuffer(size_t size) : bufferSize(size) {} + + void begin(){ + buffer = new T[bufferSize]; + } + + bool push(T data){ + std::cout << "write: " << data << std::endl; + if(counter < bufferSize){ + buffer[write] = data; + write = (write+1) % bufferSize; + counter++; + return true; + } + return false; + } + + T pop(){ + T retval; + if(counter > 0) { + counter--; + retval = buffer[read]; + read = (read+1) % bufferSize; + } + std::cout << "read: " << retval << std::endl; + return retval; + } + + bool isEmpty(){ + return counter == 0; + } + + bool isFull(){ + return counter == bufferSize; + } + + private: + size_t bufferSize = 0; + int counter = 0; + int write = 0; + int read = 0; + T *buffer; +};