portal/screen.ts
2025-04-22 07:20:32 -07:00

103 lines
2.5 KiB
TypeScript

import { PrismaClient } from "@prisma/client";
import LCD from "raspberrypi-liquid-crystal";
import fs from "node:fs";
import * as WavFileDecoder from "wav-file-decoder";
const timer = (ms: number) => new Promise((res) => setTimeout(res, ms));
const prisma = new PrismaClient();
const getStanza = async (register: string) => {
const stanzaCount = await prisma.stanza.count({ where: { register } });
const skip = Math.floor(Math.random() * stanzaCount);
const randomStanza = await prisma.stanza.findMany({
skip: skip,
take: 1,
where: {
register,
},
});
return randomStanza[0].text as string;
};
// Play portal wave PCM data and set bands
const fileData = fs.readFileSync("/home/grace/portal/blackportal1000.wav");
const wavFileInfo = WavFileDecoder.getWavFileInfo(fileData);
const audioData = WavFileDecoder.decodeWavFile(fileData);
const totalSamples = wavFileInfo.chunkInfo.filter(
(ci) => ci.chunkId === "data"
)[0].dataLength;
let sample = 0;
let register = "high";
let count = 0;
setInterval(() => {
const absSample = Math.abs(audioData.channelData[0][count]);
if (count == totalSamples - 1) {
count = 0;
} else {
count++;
}
register = "high";
if (absSample < 0.01) {
register = "mid";
}
if (absSample < 0.001) {
register = "low";
}
sample = absSample;
}, 1);
const lcd = new LCD(1, 0x27, 16, 2);
lcd.beginSync();
lcd.clearSync();
const TICK = 250;
const WAIT = 10;
// Play bottom line
const tag =
" Black Portal 4856 E Davison, Detroit ";
let tagCharacterLocation = 0;
setInterval(() => {
lcd.printLineSync(1, " ");
setTimeout(() => {
lcd.printLineSync(
1,
tag.substring(tagCharacterLocation, 16 + tagCharacterLocation)
);
}, WAIT);
tagCharacterLocation++;
if (tagCharacterLocation > tag.length) {
tagCharacterLocation = 0;
}
}, TICK);
// Play top line
let stanzaCharacterLocation = 0;
let stanza = await getStanza(register);
while (true) {
if (stanzaCharacterLocation == stanza.length) {
stanzaCharacterLocation = 0;
stanza = await getStanza(register);
}
lcd.printLineSync(0, " ");
setTimeout(() => {
lcd.printLineSync(
0,
`${
16 - stanzaCharacterLocation > 0
? Array(16 - stanzaCharacterLocation).join(" ")
: ""
}${stanza}`.substring(stanzaCharacterLocation, stanza.length)
);
}, WAIT);
await timer(TICK);
stanzaCharacterLocation++;
}