Open M0ahgra opened 1 week ago
It would definitely be convenient to have this as part of, say, the NPM package. But you can put something like that together yourself without too much work, today (this is meant to be executed with Node.js, for clarity):
import * as fs from "node:fs/promises";
import { Synth } from "beepbox"; // npm install beepbox
import wavefile from "wavefile"; // npm install wavefile
const { WaveFile } = wavefile; // See https://github.com/rochars/wavefile/pull/30 for why this.
// Could also pull the wav code from editor/ExportPrompt.ts, that works too.
async function main(argc, argv) {
if (argc !== 4) return console.log(`Usage:\n ${argv[0]} ${argv[1]} input.txt output.wav`);
const songPath = argv[2];
const outputPath = argv[3];
const samplesPerSecond = 48000; // or 44100
const bitDepth = "16";
const channelCount = 2;
const songString = await fs.readFile(songPath, { encoding: "utf-8" });
const synth = new Synth(songString); // songString can either be JSON data or the #... portion of song URLs.
synth.samplesPerSecond = samplesPerSecond;
synth.loopRepeatCount = 0;
// See https://github.com/johnnesky/beepbox/blob/main/editor/ExportPrompt.ts#L194
const song = synth.song;
const enableIntro = song.loopStart !== 0;
const enableOutro = song.loopStart + song.loopLength !== song.barCount;
if (!enableIntro) for (let i = 0; i < song.loopStart; i++) synth.goToNextBar();
const songDurationInSamples = Math.ceil(synth.getSamplesPerBar() * synth.getTotalBars(enableIntro, enableOutro));
const samplesLeft = new Float32Array(songDurationInSamples);
const samplesRight = new Float32Array(songDurationInSamples);
synth.synthesize(samplesLeft, samplesRight, songDurationInSamples);
const wav = new WaveFile();
wav.fromScratch(channelCount, samplesPerSecond, "32f", [samplesLeft, samplesRight]);
wav.toBitDepth(bitDepth);
await fs.writeFile(outputPath, wav.toBuffer());
}
main(process.argv.length, process.argv);
...which is maybe why this doesn't already exist?
where did u get that?
I just wrote it right now. I work with BeepBox's source code a lot so I knew what to look for.
It's definitely inconvenient to have to set this up manually if you need it, but I don't know if johnnesky wants to maintain a command-line interface for BeepBox at this point in time.
I just wrote it right now. I work with BeepBox's source code a lot so I knew what to look for.
It's definitely inconvenient to have to set this up manually if you need it, but I don't know if johnnesky wants to maintain a command-line interface for BeepBox at this point in time.
i would love a cli for beepbox just fyi. the way im trying to do it is i stripped out alot of the player code down to just whats needed, but the big problem is the code has several things in it that inherently tie it up with a web browser, which i dont want to use.
the player code includes the synth code, and the synth code makes references to web api stuff, its kinda hard to remove the 'web' from javascript/typescript.
What else do you need from the player? The only thing that it does, besides synthesizing the song on the fly, is visualize it.
Is the issue getting just the synthesizer code? You could grab just that then -- in the script I posted above, I rely on the NPM package. But the synth code can also be found here: https://www.beepbox.co/beepbox_synth.js. It's not really meant for use with Node.js (...do you need to run the JavaScript code in some other environment?), since it has all the code wrapped in an IIFE and sets a global variable, which works fine in the browser, but Node expects modules to be CommonJS ones or ES modules.
This still has "web" dependencies inside it (Web Audio stuff specifically), but those will only run if you try to use the built-in methods to play songs. If you instead use the synthesize
method like I did above then that shouldn't be an issue.
i want to just run the synth code just to generate the audio data, no playing, then just save it to a file. and have this b scriptable.
i wish there was a script-compatible offline version of beepbox that could be sent a .json or song hash, and then just render an audio file automatically. as im writing this im in the process of trying to hack together this exact idea from the source code, so i can use it in conjunction with python scripts to automatically create low quality previews of my .json beepbox songs.
im not sure where to put this idea, im not sure if anyone cares, but maybe someone other than me could benefit from it.