From 0f204f5fbf7f81e7cd97bf5762fe318a59cff224 Mon Sep 17 00:00:00 2001 From: Andrew Lalis Date: Mon, 2 Jan 2023 21:52:21 +0100 Subject: [PATCH] Added pcm-reader and more sounds. --- elevator/elevator-controller.lua | 8 ++++-- elevator/going-down.pcm | Bin 0 -> 41670 bytes pcm-reader.lua | 43 +++++++++++++++++++++++++++++++ pcmToLua.d | 2 ++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 elevator/going-down.pcm create mode 100644 pcm-reader.lua diff --git a/elevator/elevator-controller.lua b/elevator/elevator-controller.lua index 337b6ef..a895568 100644 --- a/elevator/elevator-controller.lua +++ b/elevator/elevator-controller.lua @@ -3,8 +3,12 @@ A script for an all-in-one elevator with floor selection, sounds, doors, and more. + +Requires `pcm-reader.lua` installed as to be required with `require("pcm")` ]] +local pcm = require("pcm") + -- Load floors from elevator settings. local FLOORS = {} local floorsFile = io.open("floors.tbl", "r") or error("Missing floors.tbl") @@ -200,6 +204,8 @@ local function goToFloor(floorLabel) local motionKeyframes = computeLinearMotion(distance) playChime(currentFloor) closeDoor(currentFloor) + local audioFile = "audio/going-up.pcm" + if rpmDir == -1 then audioFile = "audio/going-down.pcm" end for _, frame in pairs(motionKeyframes) do local sleepTime = math.floor((frame.duration - 0.05) * 20) / 20 -- Make sure we round down to safely arrive before the detector. if frame.rpm == CONTROL_MAX_RPM then @@ -366,8 +372,6 @@ end Main Script Area. ]] - - initControls() initUserInterface() while true do diff --git a/elevator/going-down.pcm b/elevator/going-down.pcm new file mode 100644 index 0000000000000000000000000000000000000000..4c265891d287156dda049d1d9253628c525d600f GIT binary patch literal 41670 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 E0pp|~Q~&?~ literal 0 HcmV?d00001 diff --git a/pcm-reader.lua b/pcm-reader.lua new file mode 100644 index 0000000..8ab4217 --- /dev/null +++ b/pcm-reader.lua @@ -0,0 +1,43 @@ +local pcm = {} + +-- Reads a file containing signed 8-bit PCM audio data, and converts it into a list of buffers to play. +function pcm.readFile(filename) + if not fs.exists(filename) then error("Audio file " .. filename .. " doesn't exist.") end + if fs.isDir(filename) then error("Cannot read audio from directory: " .. filename) end + local frames = {} + local currentFrame = {} + local currentFrameSampleCount = 0 + local file = fs.open(filename, "rb") + while true do + local n = file.read() + if n == nil then break end + if n > 127 then n = n - 256 end + table.insert(currentFrame, n) + currentFrameSampleCount = currentFrameSampleCount + 1 + if currentFrameSampleCount == (128 * 1024) then + table.insert(frames, currentFrame) + currentFrame = {} + currentFrameSampleCount = 0 + end + end + file.close() + if currentFrameSampleCount > 0 then + table.insert(frames, currentFrame) + end + return frames +end + +function pcm.playFrames(speaker, frames) + for i = 1, #frames do + while not speaker.playAudio(frames[i]) do + os.pullEvent("speaker_audio_empty") + end + end +end + +function pcm.playFile(speaker, filename) + local frames = pcm.readFile(filename) + pcm.playFrames(frames) +end + +return pcm \ No newline at end of file diff --git a/pcmToLua.d b/pcmToLua.d index 8f66a65..04313fc 100755 --- a/pcmToLua.d +++ b/pcmToLua.d @@ -7,6 +7,7 @@ module pcm_to_lua; import std.stdio; import std.file; +import std.array; const frameSize = 128 * 1024; @@ -23,6 +24,7 @@ int main(string[] args) { byte[] contents = cast(byte[]) std.file.read(audioFilename); ulong sampleIndex = 0; + auto app = appender!string; stdout.writeln("local audio = {"); foreach (byte sample; contents) { stdout.writefln!" %d,"(sample);