data TrackStatus {
int track
}
interface AudioOutputLib {
event trackFinished(TrackStatus t)
int output_new(int channels, int sampleRate)
bool output_play(int handle, int trackHandle) //extra param to tell us when to emit a progress event after N frames through samples? extra param to loop?
void output_stop(int handle, int trackHandle) //stop-and-discard
void output_stop_all(int handle)
void output_destroy(int handle)
int track_new(int4 samples[], bool loop)
bool track_append(int handle, int4 samples[], bool loop)
void track_set_volume(int handle, int1 volume)
void track_finish(int handle)
int track_get_cursor(int handle)
void track_destroy(int handle)
}
data TrackItem {
AudioTrack track
TrackItem next
}
component provides AudioOut(Destructor), AudioTrack(Destructor) requires native AudioOutputLib lib, io.Output out, data.IntUtil iu {
implementation AudioOut {
int handle
TrackItem tracks
TrackItem last
eventsink trackEvents(EventData ed)
{
TrackStatus t = ed.details
if (ed.type == AudioOutputLib.[trackFinished])
{
TrackItem tp = null
TrackItem tw = tracks
while (tw != null)
{
if (tw.track.handle == t.track)
{
if (tp == null)
{
tracks = tw.next
if (tracks == null)
last = null
}
else
{
tp.next = tw.next
if (tp.next == null)
last = tp
}
emitevent trackFinished(new TrackEvent(tw.track))
break
}
tp = tw
tw = tw.next
}
}
}
AudioOut:AudioOut(store AudioFormat format)
{
handle = lib.output_new(format.channels, format.sampleRate)
sinkevent trackEvents(lib)
}
bool AudioOut:play(store AudioTrack track)
{
TrackItem newItem = new TrackItem(track)
if (last == null)
{
tracks = newItem
}
else
{
last.next = newItem
}
last = newItem
return lib.output_play(handle, track.handle)
}
void AudioOut:stop(AudioTrack track) //stop-and-discard
{
lib.output_stop(handle, track.handle)
}
void AudioOut:stopAll()
{
lib.output_stop_all(handle)
}
void Destructor:destroy()
{
lib.output_destroy(handle)
}
}
implementation AudioTrack {
int handle
AudioTrack:AudioTrack(int4 samples[], opt bool loop)
{
handle = lib.track_new(samples, loop)
}
void AudioTrack:setVolume(int1 volume) //0-100
{
if (volume > 100) volume = 100
lib.track_set_volume(handle, volume)
}
bool AudioTrack:append(int4 samples[], opt bool loop)
{
return lib.track_append(handle, samples, loop)
}
void AudioTrack:finish()
{
lib.track_finish(handle)
}
int AudioTrack:getFrameIndex()
{
return lib.track_get_cursor(handle)
}
void Destructor:destroy()
{
lib.track_destroy(handle)
}
}
}To propose a new revision to this entity, use dana source put -uc your/new/version.dn -n io.audio.AudioOut -m "reason for update" -u yourUsername
Version 1 (this version) by barry
Notes for this version: Adds core audio output API