#------------------------------------------------------------------------
#
# Copyright (c) 1997-1998 by Cornell University.
#
# See the file "license.txt" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------
package require DvmBasic
package require DvmWave
# Read a WAV file
# input : name - file name to be read from
# output : [list $hdr $audio $inbs]
# hdr - Wave header parsed from the file
# audio - audio buffer read from the file
# inbs - bitstream of the file, should free when
# audio is freed
proc read_wave {name} {
## open Tcl Channel
set inf [open $name r]
fconfigure $inf -translation binary -buffersize 65536
## Read the WaveHeader chunk
# initialize bitstream and bitparser
set inbs [bitstream_new 100]
set inbp [bitparser_new]
bitparser_wrap $inbp $inbs
# read wave file into bitstream
bitstream_channel_read $inbs $inf 0
# parse the header
set hdr [wave_hdr_new]
wave_hdr_parse $inbp $hdr
set res [wave_hdr_get_bits_per_sample $hdr]
set bytes [wave_hdr_get_data_len $hdr]
set samples [expr $bytes * 8 / $res]
set offset [bitparser_tell $inbp]
## Read the actual Audio Data
# Shift the bitstream so that no more header chunk in it
bitstream_shift $inbs $offset
# Resize the bitstream to the length of audio data
bitstream_resize $inbs $bytes
bitparser_wrap $inbp $inbs
bitparser_seek $inbp 0
# Read the rest of the file into bitstream
set left [bitstream_bytes_left $inbs 0]
bitstream_channel_read $inbs $inf $left
## cast bitstream to audio
if {$res == 8} {
set audio [bitstream_cast_to_audio_8 $inbs 0 $samples]
} elseif {$res == 16} {
set audio [bitstream_cast_to_audio_16 $inbs 0 $samples]
}
close $inf
bitparser_free $inbp
return [list $hdr $audio $inbs]
}
# Write a WAV file
# input : hdr - Wave header to be encoded
# audio - audio buffer to be written
# name - file name to be written
# output : none
proc write_wave {hdr audio name} {
## Write WAV header
# Open Tcl Channel
set outf [open $name w]
fconfigure $outf -translation binary -buffersize 65536
# initialize bitstream and bitparser for WAV header output
set outhdrbs [bitstream_new 100]
set outhdrbp [bitparser_new]
bitparser_wrap $outhdrbp $outhdrbs
# Encode WAV header thru bitparser
wave_hdr_encode $hdr $outhdrbp
# Write the WAV header to bitstream
set hdrlen [bitparser_tell $outhdrbp]
bitstream_channel_write_segment $outhdrbs $outf 0 $hdrlen
## Write the actual Audio Buffer
set res [wave_hdr_get_bits_per_sample $hdr]
# Cast the Audio Buffer to bitstream
if {$res == 8} {
set outbs [audio_8_cast_to_bitstream $audio]
} elseif {$res == 16} {
set outbs [audio_16_cast_to_bitstream $audio]
}
# Write the bitstream to Channel
bitstream_channel_write $outbs $outf 0
### Wrap up
close $outf
bitparser_free $outhdrbp
bitstream_free $outhdrbs
}