This is how we set the csound part:
import { browser } from "$app/environment";
import csd from '$lib/csound/main.csd?raw'
import helper from '$lib/csound/helper.udo?raw'
import additivStruct from '$lib/csound/additivStruct.csd?raw'
import subBeatings from '$lib/csound/subBeatings.csd?raw'
import type { CsoundObj } from "@csound/browser";
let Csound: typeof import("@csound/browser").Csound;
class SoundAdapter {
csound: CsoundObj | undefined;
soundPaused = $state(false);
async toggleSound() {
this.soundPaused = !this.soundPaused;
if (this.csound) {
if (this.soundPaused) {
this.csound.pause();
} else {
if (await this.csound.getScoreTime() === 0) { // this is the case, if a user has turned the sound off before entering. In that case we need to start the sound here for the first time.
await this.csound.start();
} else {
this.csound.resume();
}
}
}
}
async prepareSound() {
// Csound throws an error when using it on the server side, so we only import it on the client
if (browser) {
({ Csound } = await import("@csound/browser"));
}
if (this.csound) return;
this.csound = await Csound({ useWorker: false, }); // useWorker, so it runs in a separate thread, inputChannelCount: 0, so it doesn't expect any input
// console.log(csound)
// await csound?.setOption("-m0");
const encoder = new TextEncoder();
const helperBinary = encoder.encode(helper);
await this.csound?.fs.writeFile("helper.udo", helperBinary);
const additivStructBinary = encoder.encode(additivStruct);
await this.csound?.fs.writeFile("additivStruct.csd", additivStructBinary);
const subBeatingsBinary = encoder.encode(subBeatings);
await this.csound?.fs.writeFile("subBeatings.csd", subBeatingsBinary);
const filePaths = await this.csound?.fs.readdir("/");
console.log("Csound File System:", filePaths);
await this.csound?.compileCsdText(csd);
}
async startSound() {
const csoundContext = await this.csound?.getAudioContext();
csoundContext?.resume(); // since the browser blocks the audioContext from starting automatically, we need to resume it here on a use action
if (!this.soundPaused) { // check if the user has turned the sound off before entering the page
await this.csound?.start();
}
// you can add some initial sound interaction here, too
}
async cursorPosXHandler(value: number) {
// value is a number between 0 and 1 (left-right screen position)
await this.csound?.setControlChannel('cursorPosXHandler', value);
}
async cursorPosYHandler(value: number) {
// value is a number between 0 and 1 (top-bottom screen position)
await this.csound?.setControlChannel('cursorPosYHandler', value);
}
async transitionStartedInteraction() {
// this gets called when the user clicks on one of the image cards around the origin
// TODO: implement sound here
// Example:
// await this.csound?.evalCode(`
// schedule("Flourish", next_time(.25), 0, 0)
// `)
await this.csound?.evalCode(`schedule("transitionSound", 0,
2.75, i(gkSubBeatings))`);
}
async disposeSound() {
await this.csound?.stop();
await this.csound?.cleanup();
await this.csound?.destroy();
this.csound = undefined;
}
}
export const soundAdapter = new SoundAdapter();