Patch title: Release 89 bulk changes
Abstract:
File: /linux/multimedia/sound.pli
Key:
    Removed line
    Added line
module "/pliant/admin/file.pli"
module "/pliant/language/unsafe.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/os.pli"
module "/pliant/admin/execute.pli"
module "/pliant/language/stream/pipe.pli"


constant os_SNDCTL_DSP_RESET 0C0045000h
constant os_SNDCTL_DSP_SYNC 0C0045001h
constant os_SNDCTL_DSP_SPEED 0C0045002h
constant os_SNDCTL_DSP_STEREO 0C0045003h
constant os_SNDCTL_DSP_SETFMT 0C0045005h
constant os_SNDCTL_DSP_CHANNELS 0C0045006h
constant os_SNDCTL_DSP_GETOSPACE 8010500Ch
constant os_SNDCTL_DSP_GETISPACE 8010500Dh
constant os_SNDCTL_DSP_GETODELAY 80045017h

type os_count_info
  field Int bytes
  field Int blocs
  field Int ptr


function sound_open dsp options
  arg_rw Stream dsp ; arg Str options
  os_ioctl dsp:stream_handle os_SNDCTL_DSP_RESET null
  var Int rate := options option "rate" Int 44100
  if (os_ioctl dsp:stream_handle os_SNDCTL_DSP_SPEED addressof:rate)<>0
    console "failed to set audio sampling rate" eol
  if (options option "reset")
    os_ioctl dsp:stream_handle os_SNDCTL_DSP_RESET null
  var Int stereo := shunt (options option "mono") 0 1
  if (os_ioctl dsp:stream_handle os_SNDCTL_DSP_STEREO addressof:stereo)<>0
    console "failed to set audio mono/stereo" eol
  var Int rate := options option "rate" Int 44100
  if (os_ioctl dsp:stream_handle os_SNDCTL_DSP_SPEED addressof:rate)<>0
    console "failed to set audio sampling rate" eol
  var Int bits := options option "bits" Int 16
  if (os_ioctl dsp:stream_handle os_SNDCTL_DSP_SETFMT addressof:bits)<>0
    console "failed to set audio sampling resolution" eol

function sound_close dsp
  arg_rw Stream dsp
  os_ioctl dsp:stream_handle os_SNDCTL_DSP_SYNC null
function sound_close dsp options
  arg_rw Stream dsp ; arg Str options
  if not (options option "nosync")
    os_ioctl dsp:stream_handle os_SNDCTL_DSP_SYNC null


type WavSignature
  field (Array Char 4) riff
  field uInt32_li length
  field (Array Char 4) wave
 
type WavFormat
  field (Array Char 4) fmt_
  field uInt32_li length
  field uInt16_li version
  field uInt16_li channel
  field uInt32_li rate
  field uInt32_li bytes_per_second
  field uInt16_li bytes_per_sample
  field uInt16_li bits_per_sample
 
type WavChunk
  field (Array Char 4) data
  field uInt32_li length


function sound_play stream dsp options
  arg_rw Stream stream ; arg_rw Stream dsp ; arg Str options
  var Str ext := options option "extension" Str
  if ext=""
    ext := stream:name (stream:name search_last "." stream:name:len) stream:name:len
  var Pointer:Stream clear
  if ext=".flac" or ext=".ogg"
    stream_pipe (var Str encoded_in) (var Str encoded_out)
    thread
      (var Stream send) open encoded_out out+safe
      while not stream:atend and send=success
        raw_copy stream send 1 2^24
    stream_pipe (var Str wav_in) (var Str wav_out)
    thread
      if ext=".flac"
        execute "flac --decode --stdout --silent -" input encoded_in output wav_out
      eif ext=".ogg"
        execute "oggdec --quiet -o - -" input encoded_in output wav_out
    (var Stream receive) open wav_in in+safe
    clear :> receive
  else
    clear :> stream
  var Str opt := options ; var Int remain := undefined
  if not (options option "raw")
    clear raw_read addressof:(var WavSignature sign) WavSignature:size
    clear raw_read addressof:(var WavFormat format) WavFormat:size
    clear raw_read addressof:(var WavChunk chunk) WavChunk:size
    opt += " "+(shunt format:channel>1 "stereo" "mono")+" rate "+string:(cast format:rate Int)+" bits "+string:(cast format:bits_per_sample Int)
    if (options option "verbose")
      console (cast chunk:length Int)\(cast format:bytes_per_second Int) " seconds" eol
    remain := chunk length
  if not (options option "noopen")
    sound_open dsp opt
  while not clear:atend and dsp=success
    var Int step := raw_copy clear dsp 1 remain
    if remain<>undefined
      remain -= step
  if not (options option "noclose")
    sound_close dsp opt

function sound_play stream options
  arg_rw Stream stream ; arg Str options
  (var Stream dsp) open "device:/dsp" out+safe
  sound_open dsp options
  while not stream:atend and dsp=success
    raw_copy stream dsp 1 2^24
  sound_close dsp
  sound_play stream dsp options
  

function sound_record stream options
  arg_rw Stream stream ; arg Str options
  (var Stream dsp) open "device:/dsp" in+safe
  sound_open dsp options
  while not dsp:atend and stream=success
    raw_copy dsp stream 1 2^24
  sound_close dsp
  sound_close dsp options


function sound_record file options
  arg Str file options
  (var Stream data) open file out+safe
  sound_record data options

function sound_play file options
  arg Str file options
  (var Stream data) open file in+safe
  sound_play data options
  var Str ext := file (file search_last "." file:len) file:len
  if file:len>0 and (file file:len-1)="/"
    (var Stream dsp) open "device:/dsp" out+safe
    var Array:FileInfo files := file_list file standard+sorted
    var Int first := (options option "track" Int 1)-1
    for (var Int i) first files:size-1
      console "track " i+1 ": "
      (var Stream data) open files:i:name in+safe
      sound_play data dsp options+" verbose"+(shunt i=first "" " noopen")+(shunt i=files:size-1 "" " noclose")
      if i<>files:size-1      
        var Float silent := options option "silent" Float 0
        for (var Int j) 1 2*(cast silent*44100 Int)
          var Int16 z := 0 ; dsp raw_write addressof:z Int16:size
  else
    (var Stream data) open file in+safe
    sound_play data options


export sound_play sound_record