mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
61 lines
2.2 KiB
Plaintext
61 lines
2.2 KiB
Plaintext
|
;
|
||
|
; module to parse the header data of a .wav file
|
||
|
;
|
||
|
; note: the sample rate in hz can be converted to a vera rate via:
|
||
|
; const float vera_freq_factor = 25e6 / 65536.0
|
||
|
; vera_rate = (wavfile.sample_rate as float / vera_freq_factor) + 1.0 as ubyte
|
||
|
; vera_rate_hz = (vera_rate as float) * vera_freq_factor as uword
|
||
|
;
|
||
|
|
||
|
wavfile {
|
||
|
|
||
|
const ubyte WAVE_FORMAT_PCM = $1
|
||
|
const ubyte WAVE_FORMAT_ADPCM = $2
|
||
|
const ubyte WAVE_FORMAT_IEEE_FLOAT = $3
|
||
|
const ubyte WAVE_FORMAT_ALAW = $6
|
||
|
const ubyte WAVE_FORMAT_MULAW = $7
|
||
|
const ubyte WAVE_FORMAT_DVI_ADPCM = $11
|
||
|
|
||
|
uword sample_rate
|
||
|
ubyte bits_per_sample
|
||
|
uword data_offset
|
||
|
ubyte wavefmt
|
||
|
ubyte nchannels
|
||
|
uword block_align
|
||
|
uword data_size_hi
|
||
|
uword data_size_lo
|
||
|
|
||
|
sub parse_header(uword wav_data) -> bool {
|
||
|
; "RIFF" , filesize (int32) , "WAVE", "fmt ", fmtsize (int32)
|
||
|
uword @zp header = wav_data
|
||
|
if header[0]!=iso:'R' or header[1]!=iso:'I' or header[2]!=iso:'F' or header[3]!=iso:'F'
|
||
|
or header[8]!=iso:'W' or header[9]!=iso:'A' or header[10]!=iso:'V' or header[11]!=iso:'E'
|
||
|
or header[12]!=iso:'f' or header[13]!=iso:'m' or header[14]!=iso:'t' or header[15]!=iso:' ' {
|
||
|
return false
|
||
|
}
|
||
|
; uword filesize = peekw(header+4)
|
||
|
uword chunksize = peekw(header+16)
|
||
|
wavefmt = peek(header+20)
|
||
|
nchannels = peek(header+22)
|
||
|
sample_rate = peekw(header+24) ; we assume sample rate <= 65535 so we can ignore the upper word
|
||
|
block_align = peekw(header+32)
|
||
|
bits_per_sample = peek(header+34)
|
||
|
if wavefmt==WAVE_FORMAT_DVI_ADPCM or wavefmt==WAVE_FORMAT_ADPCM
|
||
|
bits_per_sample *= 4
|
||
|
|
||
|
; skip chunks until we reach the 'data' chunk
|
||
|
header += chunksize + 20
|
||
|
repeat {
|
||
|
chunksize = peekw(header+4) ; assume chunk size never exceeds 64kb so ignore upper word
|
||
|
if header[0]==iso:'d' and header[1]==iso:'a' and header[2]==iso:'t' and header[3]==iso:'a'
|
||
|
break
|
||
|
header += 8 + chunksize
|
||
|
}
|
||
|
|
||
|
data_size_lo = chunksize
|
||
|
data_size_hi = peekw(header+6)
|
||
|
data_offset = header + 8 - wav_data
|
||
|
return true
|
||
|
}
|
||
|
}
|