Here’s the protocol I think I’ve settled on.
First output.
export interface StateUpdate {
...
/** Sound channels (new channels, or new operations) */
schannels?: SoundChannelUpdate[],
}
export interface SoundChannelUpdate {
/** Sound channel ID */
id: number,
/** Sound channel operations */
ops?: SoundChannelOperation[],
}
export type SoundChannelOperation = PauseOperation | PlayOperation | SetVolumeOperation | StopOperation | UnpauseOperation
export interface PauseOperation {
op: 'pause',
}
export interface PlayOperation {
op: 'play',
/** Notification value */
notify?: number,
/** Number of repeats (default: 1) */
repeats?: number,
/** Sound resource ID (from a Blorb) */
snd: number,
}
export interface SetVolumeOperation {
op: 'volume',
/** Duration in milliseconds */
dur?: number,
/** Notification value */
notify?: number,
/** The volume as a number between 0 and 1 */
vol: number,
}
export interface StopOperation {
op: 'stop',
}
export interface UnpauseOperation {
op: 'unpause',
}
This is largely the same as @Hanna proposed above, just with a few props renamed. The main difference is as I wrote above - channel and operation updates are all done together. If you have many channels but only play a sound on one, it will be a little bit verbose as you’ll need to send updates for all those channels, but each channel’s update only needs to include its ID.
Also, play operations may need to send a URL rather than a Blorb resource ID. I’m not sure about this - it wouldn’t work with the sound event below. Rather than sending a URL in the case of non-Blorb resources, it may be better to use the garglk_add_resource_from_file extension.
Events will be updated with:
export type Event = ... | SoundEvent | VolumeEvent
export interface SoundEvent extends EventBase {
/** Event code */
type: 'sound',
/** Sound resource ID which finished playing */
snd: number,
/** Notification value */
notify: number,
}
export interface VolumeEvent extends EventBase {
/** Event code */
type: 'volume',
/** Notification value */
notify: number,
}