Go to: Title Page Chapter 1 Appendix A Appendix J Copyright Chapter 2 Appendix B Appendix K Abstract Chapter 3 Appendix C Appendix L Acknowledgements Chapter 4 Appendix D References Table of Contents Chapter 5 Appendix E List of Figure Conclusions/ Appendix F List of Tables Future Directions Appendix G List of Audio Examples Appendix H List of Programs Appendix I
I. Motivation and Background
This appendix documents class WAiff_file, a C++ class designed to hold wavelet-domain sound data. The development of this class is similar in purpose to the continuing development of a standard file format for spectral data produced from a FFT analysis: as the wavelet representation of audio becomes more popular, a standard file format will be needed for the exchange of audio files across networks and different hardware platforms.
Wavelet analysis is more complex than a standard Fourier analysis in the following respect: there are many more parameters that have to be included with a wavelet- transformed data set in order to correctly interpret the transformed data. Typically, in addition to the sound data itself, one must not only know the window-size of the transformed data, but one must also know how many channels were used in the original analysis, the wavelet analysis and resynthesis filter coefficients, and the number of iterations of the inverse transform to perform on the data to achieve the desired reconstruction.
This class documents an attempt to use the standard AIFF file format to include some of this necessary data in an existing and widely used file format. Specifically, it tries to re-use code developed for class Aiff_file in Appendix G by using C++'s class inheritance scheme in providing support for a standard two-channel dyadic wavelet decomposition whose analysis and synthesis filters' are biorthogonal.
During the implementation of this class, however,
several serious problems were encountered in using the AIFF file
format as a basis for the WAIFF file format. The implementation
was abandoned, and many of the member functions, therefore, were
left unimplemented. The following information is provided here
in hopes that it may be of use to other programmers interested
in developing a wavelet file format.
II. Specific Design Issues
A. Protected derivation from class Aiff_file
In addition to sample data, the WAIFF file
format contains a window size, number of iterations of inverse
transform to apply to sample data, number of channels in the original
analysis, and filter coefficients for both the analysis and reconstruction
of all channels. The AIFF file format is used as a host structure
on top of which the WAIFF file format is built. In order to take
advantage of the code already developed, C++ techniques of inheritance
were used. Specifically, class WAiff_file is protectively derived
from class Aiff_file; that is, class WAiff_file has access to
all member data and member functions of class Aiff_file, only
they are hidden from the public interface. A programmer interfaces
with the class with other access functions with act on the internal,
or private member data and functions of class WAiff_file. In this
manner, several functions inherited from class Aiff_file which
are no longer suitable for direct use are hidden from the user.
B. Storage of filter coefficients, number of iterations, window size
Since the host structure for the WAIFF file
format is the AIFF file format, storage of the filter coefficients,
number of inverse iterations to perform, and window size all have
to be incorporated into the AIFF file format's existing structure.
As a result, this information was placed in an AIFF "miscellaneous"
chunk; this information is kept separate from the actual sound
data.
C. Error handling
A similar error handling scheme, directly
inherited from class Aiff_file's code, is used to report errors
in a human-readable format.
III. General Usage
class WAiff_file is designed to be as simple
as possible; the best way to learn its usage, therefore, is to
refer to the included examples. The user must #include "ac3.h"
to declare class Aiff_file and its member functions and data.
The example program in this section can be compiled with the following
command. The audio libraries libaudio.a and libaudiofile.a, available
in standard releases of the Irix operating system, are required
for compilation:
g++ -o output_binary waiff_test.cc ac.cc
ac3.cc ac.error.cc -laudio -laudiofile
ac.cc provides definitions for class Aiff_file's
member functions, ac3.cc provides definitions for class WAiff_file's
member functions, and ac.error.cc provides definitions for the
error codes referenced in Appendix H, Part II.C. The output will
be output_binary, which can be executed directly at the command
line.
A. Construction and destruction
The constructors and destructors work in a
very similar manner to class Aiff_file's constructor and destructor.
However, the constructor for a write-only WAiff_file must be given
the tap locations and filter coefficients associated with each
of the high and low pass filters of both the analysis and synthesis
wavelet transform filterbanks. Upon successful completion, the
status variable (obtained by calling member function get_status()
) is set to AC_FILE_OPEN.
The destructors are called when the object goes out of scope.
However, it is important that the destructor is called for write-only
files, as the internal output buffer is flushed by the destructor.
Please note that there is no Makefile for any of these programs;
they need to be compiled individually. There are two legal constructions
for a WAiff_file:
1) open a file for writing with a pre-determined
set of characteristics
WAiff_file(char* _filename, unsigned _sr,
unsigned _num_channels,unsigned _sample_width,
AC_WRITE_ONLY, long _iterations,
long _chunk_size_in_frames,
long _num_low_pass_coefficients,
long* _low_pass_tap_locations,
float* _low_pass_gains,
long _num_high_pass_coefficients,
long* _high_pass_tap_locations,
float* _high_pass_gains,
long _num_inv_low_pass_coefficients,
long* _inv_low_pass_tap_locations,
float* _inv_low_pass_gains,
long _num_inv_high_pass_coefficients,
long* _inv_high_pass_tap_locations,
float* _inv_high_pass_gains);
2) open a file for reading with a pre-determined
set of characteristics
WAiff_file(char* _filename, unsigned _sr,
unsigned _num_channels,unsigned _sample_width,
AC_READ_ONLY, long _iterations,
long _chunk_size_in_frames);
The user will have to query a read-only file
with the utilities in III.B to determine the filter coefficients.
B. Getting soundfile information and status
These are an exact copy of the functions listed
in Appendix G, part III.B.
C. Reading and writing sample data
These functions read/write _chunk_size_in_frames
number of frames of audio to/from the specified buffer. Additional
routines perform forward/inverse wavelet transforms on the passed
data block before writing/reading to/from disk. These functions
are not implemented in the current version of class WAiff_file.
int write_block(float* data_block);
int write_and_transform_block(float* data_block);
int read_block(float* data_block);
int read_and_transform_block(float* data_block);
D. Handling filter coefficients.
The following functions allow the user to
specify or retrieve the filter coefficients for the forward and
inverse transform's low and high pass filters. The first
member of each array passed or returned is the 0th filter coefficient,
the second member of each array is the 1st filter coefficient,
etc. Note that the array which contains the filter coefficients
is an array of floats, while the array which contains the tap
locations is an array of longs. Other interfacing routines that
return the number of iterations to perform in the inverse transform
and the chunk size are included here as well.
void
get_low_pass_filter(long& _num_low_pass_coefficients,
long* _low_pass_tap_locations,
float* _low_pass_gains);
void
set_low_pass_filter(long _num_low_pass_coefficients,
long* _low_pass_tap_locations,
float* _low_pass_gains);
void
get_high_pass_filter(long& _num_high_pass_coefficients,
long* _high_pass_tap_locations,
float* _high_pass_gains);
void
set_high_pass_filter(long _num_high_pass_coefficients,
long* _high_pass_tap_locations,
float* _high_pass_gains);
void
get_inv_low_pass_filter(
long& _num_inv_low_pass_coefficients,
long* _inv_low_pass_tap_locations,
float* _inv_low_pass_gains);
void
set_inv_low_pass_filter(
long _num_inv_low_pass_coefficients,
long* _inv_low_pass_tap_locations,
float* _inv_low_pass_gains);
void
get_inv_high_pass_filter(
long& _num_inv_high_pass_coefficients,
long* _inv_high_pass_tap_locations,
float* _inv_high_pass_gains);
void
set_inv_high_pass_filter(
long _num_inv_high_pass_coefficients,
long* _inv_high_pass_tap_locations,
float* _inv_high_pass_gains);
long
get_iterations() { return iterations; }
long
get_chunk_size_in_frames() {
return chunk_size_in_frames; }
IV. Examples
The following table lists some examples that
make exclusive use of class WAiff_file.
| file | description |
| waiff_test.cc | tests elementary reading and writing of wavelet filter coefficients |
V. Future Directions
Unfortunately, due to the integer-based constraints of the AIFF file format, the wavelet file format representation developed here is not usable. The accuracy and dynamic range of the wavelet coefficients makes integer-based representation impractical. A more flexible, floating-point representation is needed to represent the wavelet coefficients accurately.
However, the use of miscellaneous chunks to
represent filter coefficients was successful. The development
of a standard spectral file format with a chunk structure similar
to the AIFF standard will be instructive in further developing
a standard wavelet file format.
Go to: Title Page Chapter 1 Appendix A Appendix J Copyright Chapter 2 Appendix B Appendix K Abstract Chapter 3 Appendix C Appendix L Acknowledgements Chapter 4 Appendix D References Table of Contents Chapter 5 Appendix E List of Figure Conclusions/ Appendix F List of Tables Future Directions Appendix G List of Audio Examples Appendix H List of Programs Appendix I