|
|
module "/pliant/language/compiler.pli" module "/pliant/language/stream.pli" module "/pliant/util/pml/io.pli" module "/pliant/language/type/misc/blob.pli"
constant libmad (shunt (file_query "file:/lib/libmad.so" standard)=defined or (file_query "file:/usr/lib/libmad.so" standard)=defined "libmad.so" (file_query "file:/usr/lib/libmad.so.0" standard)=defined "libmad.so.0" "libmad.so")
#------------------------------------------------------------------------
type mad_bitptr field Address byte field uInt16 cache left
type mad_stream field Address buffer bufend field Int skiplen field Int sync freerate field Address this_frame next_frame field mad_bitptr ptr anc_ptr field Int anc_bitlen field Address main_data field Int md_len field Int options field Int error # console "mad_stream size = " mad_stream:size eol
function mad_stream_init stream arg_rw mad_stream stream external libmad "mad_stream_init"
function mad_stream_buffer stream adr size arg_rw mad_stream stream ; arg Address adr ; arg Int size external libmad "mad_stream_buffer"
function mad_stream_skip stream size arg_rw mad_stream stream ; arg Int size external libmad "mad_stream_skip"
function mad_stream_sync stream arg_rw mad_stream stream external libmad "mad_stream_sync"
function mad_stream_finish stream arg_rw mad_stream stream external libmad "mad_stream_finish"
constant MAD_FLOW_CONTINUE 0 constant MAD_FLOW_STOP 10h constant MAD_FLOW_BREAK 11h constant MAD_FLOW_IGNORE 20h
function mad_stream_errorstr stream -> s arg_rw mad_stream stream ; arg CStr s external libmad "mad_stream_errorstr"
#------------------------------------------------------------------------
type mad_async field Int pid in out
type mad_decoder field Int mode # sync=0, async=1 field Int options field mad_async async field Address sync field Address cb_data field Address init_func header_func filter_func output_func error_func message_func # console "mad_decoder size = " mad_decoder:size eol
function mad_decoder_init decoder data input_func header_func filter_func output_func error_func message_func arg_rw mad_decoder decoder ; arg Address data input_func header_func filter_func output_func error_func message_func external libmad "mad_decoder_init"
function mad_decoder_run decoder mode -> err arg_rw mad_decoder decoder ; arg Int mode err external libmad "mad_decoder_run"
function mad_decoder_finish decoder arg_rw mad_decoder decoder external libmad "mad_decoder_finish"
constant MAD_DECODER_MODE_SYNC 0 constant MAD_DECODER_MODE_ASYNC 1
#------------------------------------------------------------------------
type mad_header field Int layer field Int mode field Int mode_extension field Int emphasis field Int bitrate field Int samplerate field uInt16 crc_check crc_target field Int flags private_bits field Int seconds fraction # console "mad_header size = " mad_header:size eol
type mad_pcm field Int samplerate field uInt16 channels length field (Array (Array Int32 1152) 2) samples # console "mad_pcm size = " mad_pcm:size eol
#------------------------------------------------------------------------
type MadContext field Stream input field Address buffer <- null field Int bufsize <- 0 field Stream output field (Array uInt16 1152*2) audio field Int rate <- 44100 field CBool multiplexed field Pointer:Float late field Pointer:FastSem sem function destroy c arg_w MadContext c memory_free c:buffer
function input c stream -> retcode arg_rw MadContext c ; arg_rw mad_stream stream ; arg Int retcode external_calling_convention var Int remain := (cast stream:bufend Int).-.(cast stream:next_frame Int) if remain>0 memory_move stream:next_frame c:buffer remain var Address adr ; var Int extra if c:multiplexed if (c:input iraw (var Float ts)) if ((c:output query "pending") parse (var Float pending)) void if (c:input iraw (var Blob blob)) adr := blob content extra := blob size else adr := null extra := 0 else c:input read_available adr extra if extra>0 if remain+extra>c:bufsize c buffer := memory_resize c:buffer remain+extra addressof:c memory_copy adr (c:buffer translate Byte remain) extra mad_stream_buffer stream c:buffer remain+extra retcode := shunt extra>0 MAD_FLOW_CONTINUE MAD_FLOW_STOP
function scale x -> y arg Int x y constant fractbits 28 constant one 10000000h var Int v := x+2^(28-16) if v>=one v := one-1 eif v<(-one) v := -one y := v\2^(fractbits+1-16)
function output c header pcm -> retcode arg_rw MadContext c ; arg_rw mad_header header ; arg_rw mad_pcm pcm ; arg Int retcode external_calling_convention if header:samplerate<>c:rate # console "sample rate is " header:samplerate eol c:output configure "rate "+(string header:samplerate) c rate := header samplerate for (var Int ch) 0 1 for (var Int i) 0 1151 c:audio i+i+ch := scale pcm:samples:ch:i c:output raw_write (addressof c:audio) 1152*2*uInt16:size c:output flush anytime retcode := MAD_FLOW_CONTINUE
function error c stream frame -> retcode arg_rw MadContext c ; arg_rw mad_stream stream ; arg Address frame ; arg Int retcode external_calling_convention console "mad error " (cast mad_stream_errorstr:stream Str) eol retcode := MAD_FLOW_CONTINUE
module "audio.pli"
function libmad_play filename options start late sem arg Str filename ; arg Str options ; arg DateTime start ; arg_rw Float late ; arg_rw FastSem sem var mad_decoder decoder var MadContext c c:input open filename in c:output open "audio:" "" out c multiplexed := options option "multiplexed" c late :> late c sem :> sem mad_decoder_init decoder addressof:c (the_function input MadContext mad_stream -> Int):executable null null (the_function output MadContext mad_header mad_pcm -> Int):executable (the_function error MadContext mad_stream Address -> Int):executable null var Int retcode := mad_decoder_run decoder MAD_DECODER_MODE_SYNC mad_decoder_finish decoder
function play filename arg Str filename libmad_play filename "" datetime (null map Float) (null map FastSem)
export libmad_play play
|
|