aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xaudio.sh40
-rw-r--r--flake.nix1
-rw-r--r--justfile10
-rw-r--r--setup.sql19
-rw-r--r--src/supermariobros.audio.sql33
5 files changed, 103 insertions, 0 deletions
diff --git a/audio.sh b/audio.sh
new file mode 100755
index 0000000..c5d3c06
--- /dev/null
+++ b/audio.sh
@@ -0,0 +1,40 @@
+#!/usr/bin/env sh
+
+set -eu -o pipefail
+
+[ $# -lt 1 ] && echo "Fuck" && exit 1;
+AUDIO_TRACK_ID="$1"
+DB="${2:-fun.db}"
+
+db() { sqlite3 -tabs -noheader "$DB" "$@"; }
+
+samples() {
+ audio_track_id="$1"
+ db "SELECT value FROM audio_track_samples WHERE audio_track_id='$audio_track_id' ORDER BY position ASC"
+}
+
+to_pcm() {
+ awk '{printf "%02x\n", $1}' | xxd -r -p
+}
+
+play() {
+ format="$1"
+ sample_rate="$2"
+ ffplay -f "$format" -ar "$sample_rate" -b:a 128K -ch_layout mono -autoexit -
+}
+
+track_info() {
+ local audio_id="$1"
+ db "SELECT format, sample_rate FROM audio_tracks WHERE id='$audio_id'"
+}
+
+
+# ## Main stuff
+
+data="$(track_info "$AUDIO_TRACK_ID")"
+format="$(echo "$data" | cut -f1)"
+sample_rate="$(echo "$data" | cut -f2)"
+
+echo "-----------$data--------"
+
+samples "$AUDIO_TRACK_ID" | to_pcm | play "$format" "$sample_rate"
diff --git a/flake.nix b/flake.nix
index 9aeb3e2..17276e7 100644
--- a/flake.nix
+++ b/flake.nix
@@ -19,6 +19,7 @@
buildInputs = with pkgs; [
imagemagick
sqlite
+ unixtools.xxd
];
};
}
diff --git a/justfile b/justfile
index 69420b7..63f5eae 100644
--- a/justfile
+++ b/justfile
@@ -25,6 +25,16 @@ gen-video video_id:
echo "Displaying {{video_id}}" 1>&2
./video.sh "{{video_id}}"
+audio file *args:
+ #!/usr/bin/env sh
+ set -eu
+ audio_id=$(just run "{{file}}" {{args}})
+ just gen-audio "$audio_id"
+
+gen-audio audio_id:
+ echo "Displaying {{audio_id}}" 1>&2
+ ./audio.sh "{{audio_id}}"
+
repl *args:
rlwrap sqlite3 "{{DB}}" {{args}}
diff --git a/setup.sql b/setup.sql
index 0a56f55..18e34d7 100644
--- a/setup.sql
+++ b/setup.sql
@@ -29,6 +29,18 @@ CREATE TABLE pixels (
UNIQUE(image_id, x, y)
);
+CREATE TABLE audio_tracks (
+ id TEXT PRIMARY KEY,
+ sample_rate INTEGER NOT NULL,
+ format TEXT NOT NULL
+);
+CREATE TABLE audio_track_samples (
+ value INTEGER NOT NULL,
+ position INTEGER NOT NULL,
+ audio_track_id TEXT,
+ FOREIGN KEY(audio_track_id) REFERENCES audio_tracks(id) ON DELETE CASCADE
+);
+
CREATE TRIGGER delete_pixels_when_image_reinserted_because_i_said_so_and_to_make_rerunning_easier
BEFORE INSERT ON images
BEGIN
@@ -40,3 +52,10 @@ BEFORE INSERT ON videos
BEGIN
DELETE FROM images WHERE video_id = NEW.id;
END;
+
+CREATE TRIGGER delete_samples_when_track_reinserted_because_i_said_so_and_to_make_rerunning_easier
+BEFORE INSERT ON audio_tracks
+BEGIN
+ DELETE FROM audio_track_samples WHERE audio_track_id = NEW.id;
+END;
+
diff --git a/src/supermariobros.audio.sql b/src/supermariobros.audio.sql
new file mode 100644
index 0000000..b6ce0a7
--- /dev/null
+++ b/src/supermariobros.audio.sql
@@ -0,0 +1,33 @@
+INSERT OR REPLACE INTO audio_tracks (id, sample_rate, format) VALUES ('supermariobros', 8000, 'u8') RETURNING id;
+
+WITH RECURSIVE
+ audio AS (SELECT *, 250 AS n, 100 AS total_tones, 160 AS gain FROM audio_tracks WHERE id = 'supermariobros'),
+ notes AS (SELECT 659.225 AS E5, 523.2511 AS C5, 783.9909 AS G5, 391.9954 AS G4),
+ tone(position) AS (SELECT 0 UNION ALL SELECT position + 1 FROM tone, audio WHERE position < total_tones * n),
+ _samples(value, position) AS (
+ SELECT
+ (CASE
+ WHEN position < 5*n THEN position * E5
+ WHEN position < 6*n THEN 0
+ WHEN position < 11*n THEN position * E5
+ WHEN position < 17*n THEN 0
+ WHEN position < 22*n THEN position * E5
+ WHEN position < 28*n THEN 0
+ WHEN position < (28+5)*n THEN position * C5
+ WHEN position < (28+6)*n THEN 0
+ WHEN position < (28+11)*n THEN position * E5
+ WHEN position < (28+17)*n THEN 0
+ WHEN position < (28+22)*n THEN position * G5
+ WHEN position < (28+39)*n THEN 0
+ WHEN position < (28+39+5)*n THEN position * G4
+ ELSE 0
+ END) AS value,
+ position
+ FROM tone, notes, audio
+ ),
+ samples(value, position) AS (
+ SELECT MOD(FLOOR(value * 2.0 / sample_rate), 2) * gain, position
+ FROM _samples, audio
+ )
+-- SELECT value FROM samples ORDER BY position;
+INSERT INTO audio_track_samples (audio_track_id, value, position) SELECT 'supermariobros', value, position FROM samples ORDER BY position;