; ; 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 } }