16 Commits

4 changed files with 838 additions and 288 deletions

View File

@ -13,9 +13,8 @@
## SD Card contents
´´´
```
config.txt
click.wav
sound/
├─ 1.wav
├─ 2.wav
@ -25,8 +24,11 @@ sound/
├─ 6.wav
├─ 7.wav
├─ 8.wav
ui/
├─ click.wav
├─ beep.wav
´´´
```
### config.txt
@ -34,45 +36,89 @@ Json formatted config file. For now only edge led color working.
```
{
"boxid":"",
"edge": {
"color":{
"r":50,
"g":0,
"b":0
"idle":{
"r":50,
"g":0,
"b":50
},
"active":{
"r":0,
"g":50,
"b":50
}
}
},
"ring": {
"color":{
"idle":{
"r":0,
"g":50,
"b":50
},
"active":{
"r":0,
"g":80,
"b":50
}
}
}
}
```
### click.wav
## Sound
Put a file called `click.wav` (not longer than a few seconds) in the root of the SD card and it will play when you press a button.
### UI
There are two UI sounds - `click.wav` and `beep.wav`.
- `click.wav` is played when a button is pressed other than the select button
- `beep.wav` is played when the rotary encoder select button is pressed
Put these files in the subfolder `ui` on the SD card.
#### Wave File Format for UI Sounds
`click.wav` needs to be **22050Hz (22kHz) 16bit Mono**
### Sounds
### Audio Out or Speakers
Put all sounds into the ´/sound´ subfolder. Name them ´1.wav, 2.wav, 3.wav...´
Put all sounds into the `/sound` subfolder. Name them `1.wav, 2.wav, 3.wav...`
## Wave File Format
#### Wave File Format for Audio Out and Speakers
Export all sounds as **48000Hz (48kHz) 16bit Stereo**.
Export all sounds except ´click.wav´ as **48000Hz (48kHz) 16bit Stereo**.
### Audacity
You can use Audacity to export all soundfiles to WAV format.
Download it here [Github](https://github.com/audacity/audacity/releases)
1. Load file into Audacity
2. Select Track
3. File -> Export Audio
#### Format options in Audacity
**Audio Out**
- WAV(Microsoft)
- Chanels: Stereo
- Samplerate: 48000Hz
- Encoding: Signed 16-bit PCM
**UI**
- WAV(Microsoft)
- Channels: Mono
- Samplerate: 22050Hz
- Encoding: Signed 16-bit PCM
----

View File

@ -1,6 +1,5 @@
#pragma once
template<typename T>
class RingBuffer{
public:
RingBuffer() {}
@ -11,10 +10,10 @@ class RingBuffer{
}
void begin(){
buffer = new T[bufferSize];
buffer = new int16_t[bufferSize];
}
bool push(T data){
bool push(int16_t data){
if(counter < bufferSize){
buffer[write] = data;
write++; // % bufferSize;
@ -25,8 +24,8 @@ class RingBuffer{
return false;
}
T pop(){
T retval = 0;
int16_t pop(){
int16_t retval = 0;
if(counter > 0) {
counter--;
retval = buffer[read];
@ -36,22 +35,72 @@ 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);
write += 2; // % bufferSize;
if(write == bufferSize) write = 0;
counter += 2;
}
}
void* getWritePointer(){
return &buffer[write];
}
void advance(int nbytes){
for(int i = 0; i < nbytes/2; ++i){
if(counter < (bufferSize-1)){
write++; // % bufferSize;
if(write == bufferSize) write = 0;
counter++;
}
}
}
void popDMA(int32_t *target){
if(counter > 1) {
counter -= 2;
rp2040.memcpyDMA(target, &buffer[read], 4);
read += 2;
if(read >= bufferSize) read = 0;
}
}
bool isEmpty(){
return counter == 0;
}
bool isFull(){
return counter == bufferSize;
return counter == (bufferSize-2);
}
int size(){
return counter;
}
int remains(){
return (bufferSize-2) - counter;
}
private:
size_t bufferSize = 0;
int counter = 0;
int write = 0;
int read = 0;
T *buffer;
int16_t *buffer;
};

File diff suppressed because it is too large Load Diff

View File

@ -74,16 +74,53 @@ struct WaveFile{
return true;
}
void readblock(){
bool readblock(){
uint8_t samplebyte[blockalign];
file.read(samplebyte, blockalign);
if(!file.available() && loop) file.seek(44, SeekSet);
if(!file.available() && !loop) {
file.seek(44, SeekSet);
return false;
}
for(int i = 0; i < blockalign; i+=2){
int16_t sample = (samplebyte[i+1] << 8) + samplebyte[i];
buffer.push(sample);
}
return true;
}
bool readblockDMA(){
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 readblockSD(){
void *bufferStart = buffer.getWritePointer();
remains = buffer.remains();
if(remains > 512){
adv = file.readBytes((char*)bufferStart, 512);
buffer.advance(adv);
if(!file.available() && loop) file.seek(44, SeekSet);
if(!file.available() && !loop) {
file.seek(44, SeekSet);
return false;
}
}
return true;
}
int16_t get(){
@ -94,6 +131,10 @@ struct WaveFile{
file.seek(44, SeekSet);
}
void reset(){
file.seek(44, SeekSet);
}
bool loop = false;
uint16_t format = 0;
uint32_t length = 0;
@ -102,7 +143,10 @@ struct WaveFile{
uint16_t blockalign = 0;
uint16_t bitspersample = 0;
RingBuffer<int16_t> buffer;
int adv = 0;
int remains = 0;
RingBuffer buffer;
};
class WaveStream{
@ -110,7 +154,7 @@ class WaveStream{
WaveStream(){}
void begin(){
wavefile.buffer.setSize(24000);
wavefile.buffer.setSize(2048);
wavefile.buffer.begin();
}
@ -121,7 +165,10 @@ class WaveStream{
void toggle(){playing = !playing;}
void play(){playing = true;}
void play(bool reset = false){
if(reset) wavefile.reset();
playing = true;
}
void stop(){
playing = false;
@ -131,12 +178,18 @@ class WaveStream{
void pause(){playing = false;}
void stream(){
if(!wavefile.buffer.isFull() && playing){
int cnt = 0;
while (!wavefile.buffer.isFull() && cnt < 6000) {
wavefile.readblock();
cnt++;
}
int cnt = 0;
while (!wavefile.buffer.isFull() && cnt < 1024) {
bool ok = wavefile.readblockDMA();
if(!ok) playing = false;
cnt += 2;
}
}
void streamChunk(){
if(!wavefile.buffer.isFull()){
bool ok = wavefile.readblockSD();
if(!ok) playing = false;
}
}
@ -144,6 +197,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;
}
@ -151,6 +214,7 @@ class WaveStream{
//private:
WaveFile wavefile;
uint32_t cuelist[16];
bool playing = false;