Supporting audio for parser games on the web

This thread paints a rather dire picture of sound support in Glulx, even with Bisquixe. I thought I’d share how the Å-machine implementation works, since it’s very simple, but I’ve found it very successful so far.

On the Å-machine, the compiled story file contains the URLs to various resources, along with “options” for each. When the story file wants to play audio, the only thing it sends the interpreter is an index into the list of URLs. For Bisquixe, presumably the game could supply all these options at runtime instead.

Once that message is sent…

// res: {url:"", options:[""], alt:""}
// this.audio: {}
// check the file extension on res.url, and if it's audio...
for(const opt of res.options) { // Look for option strings like "channel main" or "channel: main"
	if(match = opt.match(/channel(\s|:)\s*(.*)/)) {
		chan = m[1];
	}
	if(opt.match(/loop(\s|:)/)) { // Look for option strings like "loop" or "loop: something"
		loop = true;
	}
}
if(!chan) chan = "main";
url = this.transform_url(res.url); // For local (file://) URLs, transform them to point into the resources/ directory
if(chan in this.audio && !this.audio[chan].ended) { // Something is currently playing on this channel, we need to stop it
	if(!this.audio[chan].src.endsWith(url)) { // Don't replace a sound with the same sound
		let duration = 500;
		$(this.audio[chan]).animate({volume:0}, duration); // Fade out the existing audio
		setTimeout(function(t, url, loop){ // Start the new audio once the fade is done
			t.audio[chan].pause(); // Stop the old audio object completely
			t.audio[chan].removeAttribute("src");
			t.audio[chan].load();
			t.audio[chan] = new Audio(url); // Start the new one
			t.audio[chan].play();
			t.audio[chan].loop = loop;
		}, duration, this, url, loop);
	}
} else {
	this.audio[chan] = new Audio(url);
	this.audio[chan].play();
	this.audio[chan].loop = loop;
}

It’s very simple, but in general it does The Right Thing. You can start background music based on the current location every turn, for example, and trust that it’ll start after reloading a save, won’t keep resetting itself, won’t have awkward jumps, and so on. To stop a channel, play a null sound on it.

3 Likes

It’s not as dire as it sounds. Parchment now supports AIFF and Ogg/Vorbis directly from Blorbs (though I need to update the I7 template, and I7 needs to output the whole Blorb.) But if you play it via iplayif.com it just works.

@mathbrush has said that eventually he’ll probably update Bisquixe to be based on the updated Parchment and let it natively handle sound.

4 Likes

I think that a lot of these challenges, when viewed narrowly, seem readily solved, but the author, looking out at the vast possibility space of different interpreters and player preferences, may have a different perspective.

To use inline css styling, the only convenient option is Bisquixe, which involves some overhead when it comes to sound. It’s true that Parchment handles sounds fine, and, if we run ifsitegen.py over our project, that will be evident. Everything should work without any added effort.

Meanwhile, some interpreters scale images; some do not. And so forth. When an author begins to think about the project as a whole, all of these different qualities must be considered. As the author of a reference, my goal is to help authors understand the significance of their decisions without criticizing platforms and people who do technical development.

The situation with Bisquixe and sound is challenging at the moment, but an author can persevere. I would like to see Bisquixe move to Parchment eventually. That will be an occasion for a new, updated guide!

One thing I do like about current Bisquixe is the ability to reference files outside of the BLORB, which Daniel’s design does with what appears to be (I really only understand Inform) fewer steps.

1 Like

I have an ADR for sound in sharpee. It would have assets in the project which get bundled with a web publish. Haven’t tried it but a game I’m porting right now would be cool with music.

This is currently in a graphics client ADR but a web version could be included.

ADR? Automated Dialogue Replacement?

1 Like

Architecture Decision Record is a technical discussion document identifying a feature and working through its design and practicality.

Sharpee has 138 of these in docs/architecture/adrs.

1 Like