rurkabl/func.sh
2024-05-02 04:49:17 +02:00

216 lines
3.8 KiB
Bash

#!/bin/bash
_PA_SEQ_NUM=0
source bin.sh
source lib.sh
# as defined in /usr/include/pulse/def.h
pkt() {
# honestly not sure what's happening here
# i'm re-reading the docs just now and it seems that I annotated this incorrectly?
# the field descriptions are for a buffer, while i should have a descriptor here?
# this will probably make more sense when i'm less tired...
local b
b="$(ulong $(($(wc -c <<< "$1")/2)))" # maxlength
b+="ffffffff" # tlength
b+="00000000" # prebuf
b+="00000000" # minreq
b+="00000000" # fragsize
b+="$1"
br <<< "$b"
}
pkt_read() {
declare -g res
len="$((0x$(r 4)))" # len
r 16 >/dev/null # idc about the header
res="$(r $len)"
}
write_string() {
# t, then string, then nullbyte
echo -n "74$(hex "$1")00" #| sed -s 's/0a/0a/g'
}
write_nullstring() {
# just N
echo -n "4e"
}
write_arbitrary() {
# x, then ulong length, then data
echo -n "78$(ulong $(($(wc -c <<< "$1")/2)))$1" # TODO
}
write_long() {
echo -n "4c$(ulong "$1")"
}
write_samplespec() {
# a, then u8 format, then u8 channels, then u32 sample rate
local b
b="61" # 'a'
b+="$(byte 1)" # sampleformat; 1 == u8
b+="01" # channels
b+="$(ulong 8000)" # samplerate
echo -n "$b"
}
write_channelmap() {
# m, then u8 channels, then *channel_pos...
local b
b="6d" # 'm'
b+="01" # channels
b+="00" # channelposition - mono
echo -n "$b"
}
write_channelvolume() {
# v, then u8 channels, then *volume...
local b
b="76" # 'v'
b+="01" # channels
b+="$(ulong "$1")" # volume itself TODO
echo -n "$b"
}
# write_props(tag, payload, [tag, payload, ...])
write_props() {
local a
while true; do
[[ "$1" == '' ]] && break
a+="$(write_string "$1")"
a+="$(write_long "$((${#2}/2))")"
a+="$(write_arbitrary "$2")"
shift 2
done
echo -n "50${a}4e"
}
write_memblock() {
# ???
#local b
#pkt "$(dd if=/dev/urandom bs=1024 count=1 status=none | xxd -p -c1024)"
# b="$(ulong 1024)" # length
# b+="$(ulong 0)" # channel (?)
# b+="00000000$(ulong 0)" # offset
# b+="$(ulong 0)" # flags.bits (?)
#echo -n "$b"
echo -n "00000400 00000000 00000000 00000000 00000000" | xxd -p -r
dd if=/dev/urandom bs=1024 count=1 status=none
#pkt "$(dd if=/dev/urandom bs=2048 count=1 status=none | xxd -p -c99999)"
}
parse() {
# do not redeclare if we're recursing
if [[ "$1" != _ ]]; then
local data="$1"
local i=0
declare -g d=()
declare -g t=()
fi
while rr 1; do
# this is not a for.. for recursion purposes
[[ $i -ge ${#data} ]] && break
local type="$res"
t+=("$res")
case $type in
30) # 0 (BooleanFalse)
d+=(false);;
31) # 1 (BooleanTrue)
d+=(true);;
42) # B (Byte)
rr 1
d+=($res);;
4c) # L (Long)
rr 4
d+=($res);;
4e) # N (NullString) TODO
[[ $1 == _ ]] && break;; # are we recursing? return
50) # P (PropList)
parse _;; # recursion!
52|72) # R (u64) | r (s64)
rr 8
d+=($res);;
55) # U (Usec)
rr 8
d+=($res);;
56) # V (Volume)
rr 4
d+=($res);;
61) # a (SampleSpec) TODO
rr 1 # format
d+=($res)
rr 1 # channels
d+=($res)
rr 4 # sample_rate
d+=($res)
;;
66) # f (FormatInfo) TODO
rr 1 # encoding
d+=($res)
rr 1 # ????
d+=($res)
parse _;;
6d) # m (ChannelMap) TODO
rr 1 # num_channels
d+=($res)
rr $((0x$res)) # channel_pos TODO
d+=($res)
;;
74) # t (string)
local str
while rr 1; do
[[ "$res" == 00 ]] && break
str+="$res"
done
d+=($str);;
76) # v (CVolume) TODO
rr 1 # channels
rr $((4*0x$res)) # volume
d+=($str);;
78) # x (arbitrary)
rr 4
rr $((0x$res))
d+=("$res");;
*)
[[ "$type" != '' ]] && echo "wut? got type $type; ${t[-1]}:${d[-1]} ${t[-2]}:${d[-2]};" > /dev/stderr
return;;
esac
done
if [[ "${d[0]}" == 00000000 ]]; then # *sigh*
echo "Error: ${d[2]}" > /dev/stderr
fi
}