1
0
Fork 0

audio from sd

sd2
radex 2024-05-17 19:03:59 +02:00
parent 111700b0e9
commit cd49ebf186
Signed by: radex
SSH Key Fingerprint: SHA256:hvqRXAGG1h89yqnS+cyFTLKQbzjWD4uXIqw7Y+0ws30
7 changed files with 123 additions and 16 deletions

View File

@ -13,7 +13,5 @@ platform = raspberrypi
board = pico
framework = arduino
lib_deps =
fastled/FastLED@^3.6.0
; arduino-libraries/SD@^1.2.4
khoih-prog/RP2040_SD@^1.0.1

View File

@ -55,3 +55,10 @@ with open("src/audio_sample.h", "w") as f:
f.write(m68code)
print("done!")
print("writing blob...")
with open("audio/audio.bin", "wb") as f:
f.write(bytes(normalized))
print("done!")

View File

@ -3,13 +3,21 @@
#include "hardware/pwm.h" // pwm
#include "hardware/sync.h" // wait for interrupt
#include "hardware/gpio.h"
#include "audio.h"
#include "audio_sample.h"
// #include "audio_sample.h"
// Adapted from https://github.com/rgrosset/pico-pwm-audio
#define AUDIO_PIN 23
int wav_position = 0;
#define MAX_PWM_POS (BUFFER_LEN << 3)
uint8_t wav_buffer_0[BUFFER_LEN] = {0};
uint8_t wav_buffer_1[BUFFER_LEN] = {0};
bool wav_buffer1_active = false;
volatile bool next_buffer_requested = false; // horrible, use some interrupt-based solution or at least locks or whatever
uint32_t pwm_position = 0;
/*
* PWM Interrupt Handler which outputs PWM level and advances the
@ -21,21 +29,23 @@ int wav_position = 0;
*/
void pwm_interrupt_handler() {
pwm_clear_irq(pwm_gpio_to_slice_num(AUDIO_PIN));
if (wav_position < (WAV_DATA_LENGTH<<3) - 1) {
if (pwm_position < MAX_PWM_POS - 1) {
auto wav_buffer = wav_buffer1_active ? wav_buffer_1 : wav_buffer_0;
// set pwm level
// allow the pwm value to repeat for 8 cycles this is >>3
pwm_set_gpio_level(AUDIO_PIN, WAV_DATA[wav_position>>3]);
wav_position++;
pwm_set_gpio_level(AUDIO_PIN, wav_buffer[pwm_position>>3]);
pwm_position++;
} else {
// reset to start
wav_position = 0;
// reset to start, flip to other buffer
pwm_position = 0;
next_buffer_requested = true;
wav_buffer1_active = !wav_buffer1_active;
}
}
// 11 KHz is fine for speech. Phone lines generally sample at 8 KHz
#define SYS_CLOCK 125000000.0f
#define AUDIO_WRAP 250.0f
#define AUDIO_RATE 11000.0f
#define AUDIO_CLK_DIV (SYS_CLOCK / AUDIO_WRAP / 8 / AUDIO_RATE)
void init_audio() {
@ -49,7 +59,7 @@ void init_audio() {
// set the handle function above
irq_set_exclusive_handler(PWM_IRQ_WRAP, pwm_interrupt_handler);
irq_set_enabled(PWM_IRQ_WRAP, true);
// irq_set_enabled(PWM_IRQ_WRAP, true);
// Setup PWM for audio output
pwm_config config = pwm_get_default_config();
@ -60,3 +70,17 @@ void init_audio() {
pwm_set_gpio_level(AUDIO_PIN, 0);
}
void audio_stop() {
Serial.println("audio_stop");
irq_set_enabled(PWM_IRQ_WRAP, false);
pwm_set_gpio_level(AUDIO_PIN, 0);
}
void audio_start() {
Serial.println("audio_start");
audio_stop();
pwm_position = 0;
wav_buffer1_active = false;
irq_set_enabled(PWM_IRQ_WRAP, true);
}

View File

@ -1 +1,19 @@
#pragma once
#ifndef _audio_h
#define _audio_h
#define AUDIO_RATE 11000.0f
#define BUFFER_LEN 8192
#define BUFFER_LEN_MS (BUFFER_LEN / AUDIO_RATE) * 1000.0f
extern uint8_t wav_buffer_0[BUFFER_LEN];
extern uint8_t wav_buffer_1[BUFFER_LEN];
extern bool wav_buffer1_active;
extern volatile bool next_buffer_requested;
void init_audio();
void audio_stop();
void audio_start();
#endif

View File

@ -75,6 +75,8 @@ void setup() {
setupSD();
sd_getAudio();
return;
memset(framebuffer, 0, sizeof(framebuffer));

View File

@ -1,6 +1,8 @@
#include <Arduino.h>
#include <RP2040_SD.h>
#include <SPI.h>
#include <RP2040_SD.h>
#include "sd.h"
#include "audio.h"
#define SD_DET_PIN 28
@ -39,22 +41,23 @@ void printDirectory(File dir, int numTabs);
void setupSD() {
SPI.begin();
printSDConfig();
// printSDConfig();
if (!SD.begin(PIN_SPI_SS)) {
Serial.println("SD Initialization failed!");
// Serial.print("Error code: ");
// Serial.println(SD.card.errorCode(), HEX);
while (true) {}
return;
}
Serial.println("SD Initialization done");
testSDCard();
// testSDCard();
// printSDStats(SD.volume);
File root = SD.open("/");
printDirectory(root, 0);
// File root = SD.open("/");
// printDirectory(root, 0);
}
void printSDConfig() {
@ -151,3 +154,54 @@ void printSDStats(RP2040_SdVolume volume) {
Serial.print("Volume size (GB): ");
Serial.println((float)volumesize / 1024.0);
}
File file;
void sd_getAudio() {
if (!SD.exists("/badapple/audio.bin")) {
Serial.println("Audio not found :(");
return;
}
if (file) {
file.close();
}
file = SD.open("/badapple/audio.bin", FILE_READ);
Serial.println("Audio file opened");
audio_stop();
// load two buffers' worth of audio
if (file.read(&wav_buffer_0, BUFFER_LEN) < BUFFER_LEN) {
Serial.println("Could not read first sample");
return;
}
if (file.read(&wav_buffer_1, BUFFER_LEN) < BUFFER_LEN) {
Serial.println("Could not read second sample");
return;
}
audio_start();
while (true) {
if (!next_buffer_requested) {
delay(50);
continue;
}
next_buffer_requested = false;
auto next_buffer = wav_buffer1_active ? &wav_buffer_0 : &wav_buffer_1;
auto bytesRead = file.read(next_buffer, BUFFER_LEN);
if (bytesRead < BUFFER_LEN) {
Serial.println("End of audio file");
file.seek(0);
} else {
Serial.print("Read ");
Serial.print(bytesRead);
Serial.println(" bytes from audio file");
}
}
}

View File

@ -1,4 +1,8 @@
#pragma once
void setupSDPins();
void setupSD();
bool isSDCardInserted();
void sd_getAudio();