1
0
Fork 0

gfx to blob, gfx sd reading poc

sd2
radex 2024-05-17 20:40:58 +02:00
parent cd49ebf186
commit db2cb2bc43
Signed by: radex
SSH Key Fingerprint: SHA256:hvqRXAGG1h89yqnS+cyFTLKQbzjWD4uXIqw7Y+0ws30
8 changed files with 122 additions and 24 deletions

1
firmware/.gitignore vendored
View File

@ -6,4 +6,5 @@
src/gfx_png.h
src/audio_sample.h
gfx/
gfx_output/
audio/

View File

@ -1,21 +1,21 @@
**add graphics**
convert video
```
ffmpeg -i badapple.webm -ss 00:01:00 -t 30 -vf "fps=30,scale=20:20:force_original_aspect_ratio=increase,crop=20:20,format=gray" badapple-frames/badapple_%04d.png
ffmpeg -i ../badapple.webm -vf "fps=30,scale=40:40:force_original_aspect_ratio=increase,crop=40:40,format=gray" gfx/frame_%04d.png
```
move to `gfx` folder, then:
```
python3 scripts/gfx_convert.py
# old method
# python3 scripts/gfx_convert.py
python3 scripts/gfx_to_blob.py
```
convert audio
```
ffmpeg -i badapple.webm -t 30 -ar 11000 output.wav
ffmpeg -i ../badapple.webm -ar 44000 audio/output.wav
```
move to `audio` folder, then:
@ -23,3 +23,5 @@ move to `audio` folder, then:
```
python3 scripts/audio_convert.py
```
on the SD card, create a folder named `badapple` and inside, add `audio.bin` from `audio` and `gfx.bin` and `gfx_len.bin` from `gfx_output`.

View File

@ -16,7 +16,7 @@ if len(data_in.shape)>1:
print("resampling...")
converter = 'sinc_best' # or 'sinc_fastest', ...
desired_sample_rate = 11000.0
desired_sample_rate = 44000.0
ratio = desired_sample_rate/datasamplerate
data_out = samplerate.resample(data_in, ratio, converter)
@ -35,26 +35,26 @@ print("normalizing...")
# normalize to 0-1
normalized = [int((v-minValue)/vrange*255) for v in data_out]
print("generating header...")
# print("generating header...")
m68code = "/* File "+soundfile+ "\r\n * Sample rate "+str(int(desired_sample_rate)) +" Hz\r\n */\r\n"
m68code += "#define WAV_DATA_LENGTH "+str(len(data_out))+" \r\n\r\n"
m68code += "static const uint8_t WAV_DATA[] = {\r\n "
# m68code = "/* File "+soundfile+ "\r\n * Sample rate "+str(int(desired_sample_rate)) +" Hz\r\n */\r\n"
# m68code += "#define WAV_DATA_LENGTH "+str(len(data_out))+" \r\n\r\n"
# m68code += "static const uint8_t WAV_DATA[] = {\r\n "
m68code += ','.join(str(v) for v in normalized)
# m68code += ','.join(str(v) for v in normalized)
# keep track of first and last values to avoid
# blip when the loop restarts.. make the end value
# the average of the first and last.
end_value = int( (normalized[0] + normalized[len(normalized) - 1]) / 2)
m68code+=","+str(end_value)+'\n};\n'
# # keep track of first and last values to avoid
# # blip when the loop restarts.. make the end value
# # the average of the first and last.
# end_value = int( (normalized[0] + normalized[len(normalized) - 1]) / 2)
# m68code+=","+str(end_value)+'\n};\n'
print("writing output...")
# print("writing output...")
with open("src/audio_sample.h", "w") as f:
f.write(m68code)
# with open("src/audio_sample.h", "w") as f:
# f.write(m68code)
print("done!")
# print("done!")
print("writing blob...")

View File

@ -0,0 +1,35 @@
import os
import sys
def get_all_gfx():
gfx = []
for root, dirs, files in os.walk("gfx"):
for file in files:
if file.startswith("."):
continue
# file name without extention
name = os.path.splitext(file)[0]
gfx.append((name, os.path.join(root, file)))
gfx.sort()
return gfx
blob = bytes()
lengths = bytes()
gfx_files = get_all_gfx()
for (name, path) in gfx_files:
with open(path, "rb") as f:
data = f.read()
size = len(data)
blob += data
lengths += size.to_bytes(2, byteorder="little")
# create the output directory if it doesn't exist
os.makedirs("gfx_output", exist_ok=True)
with open("gfx_output/gfx.bin", "wb") as f:
f.write(blob)
with open("gfx_output/gfx_len.bin", "wb") as f:
f.write(lengths)

View File

@ -3,8 +3,8 @@
#ifndef _audio_h
#define _audio_h
#define AUDIO_RATE 11000.0f
#define BUFFER_LEN 8192
#define AUDIO_RATE 44000.0f
#define BUFFER_LEN 16384
#define BUFFER_LEN_MS (BUFFER_LEN / AUDIO_RATE) * 1000.0f
extern uint8_t wav_buffer_0[BUFFER_LEN];

View File

@ -75,7 +75,8 @@ void setup() {
setupSD();
sd_getAudio();
// sd_getAudio();
sd_getGfx();
return;

View File

@ -43,7 +43,7 @@ void setupSD() {
// printSDConfig();
if (!SD.begin(PIN_SPI_SS)) {
if (!SD.begin(5000000, PIN_SPI_SS)) {
Serial.println("SD Initialization failed!");
// Serial.print("Error code: ");
// Serial.println(SD.card.errorCode(), HEX);
@ -205,3 +205,61 @@ void sd_getAudio() {
}
}
}
uint16_t lenBuffer[12000] = {0};
uint8_t dataBuffer[2048] = {0};
uint16_t frameCount = 0;
void sd_getGfx() {
// read frame lengths
auto lengthsFile = SD.open("badapple/gfx_len.bin", FILE_READ);
frameCount = lengthsFile.size() / sizeof(uint16_t);
Serial.print("Frames: ");
Serial.println(frameCount);
while (lengthsFile.available()) {
lengthsFile.read(&lenBuffer, sizeof(lenBuffer));
}
lengthsFile.close();
Serial.println("Done reading frame lengths");
auto gfxBlobFile = SD.open("badapple/gfx.bin", FILE_READ);
auto b4 = millis();
for (uint16_t i = 0; i < frameCount; i++) {
Serial.print("Frame ");
Serial.print(i);
Serial.print(" - length ");
auto len = lenBuffer[i];
Serial.print(lenBuffer[i]);
Serial.print(" - read in ");
if (len > sizeof(dataBuffer)) {
Serial.println("Frame too large");
return;
}
auto bytesRead = gfxBlobFile.read(&dataBuffer, len);
if (bytesRead < len) {
Serial.println("Could not read the entire frame");
return;
}
auto now = millis();
auto time = now - b4;
Serial.print(time);
Serial.println("ms");
if (time > 20) {
Serial.println("Frame took too long to read");
return;
}
b4 = now;
}
gfxBlobFile.close();
Serial.println("Done reading frames");
}

View File

@ -6,3 +6,4 @@ void setupSD();
bool isSDCardInserted();
void sd_getAudio();
void sd_getGfx();