libraryextensions/audio/lib/Audio.xtl
Audio.xtl -- the facade of the audio extension: decode Ogg Vorbis, MP3 and WAV, play them on the sound device, read what is playing as arrays, and play arrays. Import: "au:" u_se< "Audio" Run with xetal-x (xetal-x --ext DIR puts this directory on XETAL_PATH). With XETAL_HEADLESS=1 (or XETAL_AUDIO=off) nothing sounds and playback advances a 60th of a second per au:w_indow (or au:p_layed) -- for tests. Each signature line is written out by the binding macro (lib/Ffi.xtlm).
ˡo̲pen : Char -> Int
au:o_pen path: an audio file (Ogg Vorbis, MP3 or WAV); its id.
"o_pen : text -> int" ᶠᶠⁱb̲ind< "audio/open"
ᶠᶠⁱb̲ind< expands to
ˡo̲pen ← { a → pa ← a ⎕N̲PUT "ext:audio/open?text" f̲loor f̲irst n̲umbers ⎕N̲GET "ext:audio/open" }
ˡi̲nfo : Num a => a -> Float
au:i_nfo id: sample rate, channels, frames, seconds (-1 when unknown).
"i_nfo : float -> floats" ᶠᶠⁱb̲ind< "audio/info"
ᶠᶠⁱb̲ind< expands to
ˡi̲nfo ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/info?float=" c̲at f̲ormat s̲hape a v ← n̲umbers ⎕N̲GET "ext:audio/info" (f̲loor n̲umbers ⎕N̲GET "ext:audio/info?shape") r̲eshape v }
ˡc̲hunk : (Num a, Num b) => a -> b -> Float
id au:c_hunk n: the next n frames read in order (apart from playback): a 2 by m matrix, left over right; fewer at the end, none after it.
"c_hunk : float float -> floats" ᶠᶠⁱb̲ind< "audio/chunk"
ᶠᶠⁱb̲ind< expands to
ˡc̲hunk ← { a b → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/chunk?float=" c̲at f̲ormat s̲hape a pb ← (f̲ormat r̲avel f̲loat b) ⎕N̲PUT "ext:audio/chunk?float=" c̲at f̲ormat s̲hape b v ← n̲umbers ⎕N̲GET "ext:audio/chunk" (f̲loor n̲umbers ⎕N̲GET "ext:audio/chunk?shape") r̲eshape v }
ˡp̲lay! : Num a => a -> Int
au:p_lay! id: start or resume playing; the id.
"p_lay! : float -> int" ᶠᶠⁱb̲ind< "audio/play"
ˡp̲ause! : Num a => a -> Int
au:p_ause! id: pause; the id.
"p_ause! : float -> int" ᶠᶠⁱb̲ind< "audio/pause"
ᶠᶠⁱb̲ind< expands to
ˡp̲ause! ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/pause?float=" c̲at f̲ormat s̲hape a f̲loor f̲irst n̲umbers ⎕N̲GET "ext:audio/pause" }
ˡs̲eek! : (Num a, Num b) => a -> b -> Float
id au:s_eek! seconds: move playback there; the second it landed on.
"s_eek! : float float -> float" ᶠᶠⁱb̲ind< "audio/seek"
ᶠᶠⁱb̲ind< expands to
ˡs̲eek! ← { a b → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/seek?float=" c̲at f̲ormat s̲hape a pb ← (f̲ormat r̲avel f̲loat b) ⎕N̲PUT "ext:audio/seek?float=" c̲at f̲ormat s̲hape b f̲irst n̲umbers ⎕N̲GET "ext:audio/seek" }
ˡp̲osition : Num a => a -> Float
au:p_osition id: the second playing now.
"p_osition : float -> float" ᶠᶠⁱb̲ind< "audio/position"
ᶠᶠⁱb̲ind< expands to
ˡp̲osition ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/position?float=" c̲at f̲ormat s̲hape a f̲irst n̲umbers ⎕N̲GET "ext:audio/position" }
ˡw̲indow : (Num a, Num b) => a -> b -> Float
id au:w_indow n: the n frames ending at what plays now, 2 by n (left over right; zeros before the start). Call it once a frame.
"w_indow : float float -> floats" ᶠᶠⁱb̲ind< "audio/window"
ᶠᶠⁱb̲ind< expands to
ˡw̲indow ← { a b → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/window?float=" c̲at f̲ormat s̲hape a pb ← (f̲ormat r̲avel f̲loat b) ⎕N̲PUT "ext:audio/window?float=" c̲at f̲ormat s̲hape b v ← n̲umbers ⎕N̲GET "ext:audio/window" (f̲loor n̲umbers ⎕N̲GET "ext:audio/window?shape") r̲eshape v }
ˡs̲tate : Num a => a -> Int
au:s_tate id: 0 stopped (not started, or at the end), 1 playing, 2 paused.
"s_tate : float -> int" ᶠᶠⁱb̲ind< "audio/state"
ˡc̲lose! : Num a => a -> Int
au:c_lose! id: stop and forget a file; a voice plays out what is queued (or writes its WAV) first; 1.
"c_lose! : float -> int" ᶠᶠⁱb̲ind< "audio/close"
Sound out of arrays
ˡo̲utput : Num a => a -> Int
au:o_utput rate: a voice playing what the program queues, at rate frames a second (22050 is plenty for a synthesizer); its id.
"o_utput : float -> int" ᶠᶠⁱb̲ind< "audio/output"
ˡq̲ueue! : (Num a, Num b) => a -> b -> Float
id au:q_ueue! samples: play these after what is queued -- a vector (mono) or 2 by n (left over right), from -1 to 1; the seconds now queued ahead. With no device (XETAL_AUDIO=off) nothing sounds, and XETAL_AUDIO_WAV=FILE collects everything queued in a WAV file.
"q_ueue! : float float -> float" ᶠᶠⁱb̲ind< "audio/queue"
ˡw̲ait! : (Num a, Num b) => a -> b -> Float
id au:w_ait! seconds: wait until at most that much is queued, so a program can stream without hurrying; the seconds played so far.
"w_ait! : float float -> float" ᶠᶠⁱb̲ind< "audio/wait"
ᶠᶠⁱb̲ind< expands to
ˡw̲ait! ← { a b → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/wait?float=" c̲at f̲ormat s̲hape a pb ← (f̲ormat r̲avel f̲loat b) ⎕N̲PUT "ext:audio/wait?float=" c̲at f̲ormat s̲hape b f̲irst n̲umbers ⎕N̲GET "ext:audio/wait" }
ˡp̲layed : Num a => a -> Float
au:p_layed id: the second a voice is playing now -- to draw what is heard (with no device, a 60th of a second more each time it is asked).
"p_layed : float -> float" ᶠᶠⁱb̲ind< "audio/played"
ᶠᶠⁱb̲ind< expands to
ˡp̲layed ← { a → pa ← (f̲ormat r̲avel f̲loat a) ⎕N̲PUT "ext:audio/played?float=" c̲at f̲ormat s̲hape a f̲irst n̲umbers ⎕N̲GET "ext:audio/played" }