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
As stated in Appendix G, most sound processing done in this thesis used AIFF files for both input and output. Nonetheless, some experiments were done as to how much real-time processing of sound signals could be done, at standard CD-quality audio specifications (stereo, 16-bit, 44.1kHz sampling rate). To accomplish this task, an easy-to-use, object-oriented class similar to class Aiff_file (Appendix G) was built to handle real-time input and output of analog and digital samples. The constructors and general programmer interface were designed to closely resemble the constructors and general programmer interface of class Aiff_file, so that audio files and real-time input could be easily substituted in small, experiment-based programs.
Specifically, class Audio_port is a templated
C++ class that models the output and input audio ports on the
SGI Indy computer. In preparation for the usage of class Audio_port,
the user opens the system's audio panel application to select
an analog or digital input, select the appropriate analog input
and output sampling and playback rates, and select the desired
record, meter, monitoring levels. After this has been accomplished,
the user can open the input or output audio ports in a C++ program
for sample reading and writing using class Audio_port. (Both the
input and output audio ports on the Indy can be switched either
to analog or digital sources/destinations via the system's audio
control panel application.)
II. Specific design issues
A. I/O speed.
The performance of class Audio_port was increased
significantly with the use of an internal buffer similar to the
one used in classes Aiff_file and WAiff_file. An internal buffer
is used to hold a user's requests for input and output samples
until a specified number of requests are queued. An operating
system call is then made to transfer the entire block of samples
to/from the output/input port, thus saving considerable time in
system overhead.
B. Templating of class Audio_port.
class Audio_port is a templated class whose
only template declaration argument is the type of sample to use
in read/write operations for that port. Although templating can
be confusing, the decision to make class Audio_port a templated
class was based on the need for the flexibility in real-time I/O
situations. Although an Audio_port's other, numerical arguments
such as sample-rate, number of channels, bit_width are easily
specified via constructor arguments, the type of audio
samples to send and return is not so easily specified in a single
argument; hence, the need for a templated class.
III. General Usage
class Audio_port 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 "ac.h"
and "ac2.h" to declare class Audio_port and, its member
functions and data, and other supporting MACRO definitions. All
example programs 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 <filename.cc>
ac.cc ac.error.cc -laudio -laudiofile
ac.cc provides definitions for class Aiff_file's
member functions, and ac.error.cc provides definitions for the
error codes referenced in Appendix H, Part II.C, above. The class
definition for class Audio_port has been completely written in
the ac2.h file. The output will be output_binary, which can be
executed directly at the command line.
A. Template instantiation, constructor and destructor.
A template declaration defines the types of
samples to be used in that input or output Audio_port; however,
one must also specify that type in the constructor using a pre-defined
MACRO as well. The legal constructors for class Audio_port are:
1) for integer sample types
Audio_port(char* _port_name, unsigned _sr,
unsigned _num_channels, unsigned _sample_width,
int _mode,
AC_INT_SAMPLE_VALUES,
AC_THIS_FIELD_NOT_APPLICABLE_FOR_NON_FLOAT_SAMPLES)
where _port_name is an arbitrary, human-readable name used to identify the port, and
_mode is either AC_READ_ONLY or AC_WRITE_ONLY.
2) for floating point sample types
Audio_port(char* _port_name, unsigned _sr,
unsigned _num_channels,
AC_THIS_FIELD_NOT_APPLICABLE_FOR_NON_INT_SAMPLES,
int _mode,
AC_FLOAT_SAMPLE_VALUES, float _floating_point_range)
where _port_name is an arbitrary, human-readable name used to identify the port,
_mode is either AC_READ_ONLY or AC_WRITE_ONLY, and _floating_point_range is the normalized range into which samples values are cast (+_floating_point_range being the highest possible magnitude - both positive and negative - for the port).
For example, the following code opens a stereo,
44.1kHz input port that returns floating_point samples:
#include "ac.h" // provides type information and
// declarations for class Aiff_file
#include "ac2.h" // provides declaration and
// definition
// for class Audio_port
...
template class Audio_port<float_sample>
...
Audio_port real_time_input("real_time_input_port",
44100, STEREO,
AC_THIS_FIELD_NOT_APPLICABLE_FOR_NON_INT_SAMPLES,
AC_READ_ONLY, AC_FLOAT_SAMPLES, 1.0);
Similarly, the following code opens a STEREO,
44.1 kHz output port that returns 16-bit two's complement integer
samples:
#include "ac.h" // provides type information and
// declarations for class Aiff_file
#include "ac2.h" // provides declaration and
// definition
// for class Audio_port
...
template class Audio_port<width_16_bit_sample>
...
Audio_port real_time_output("real_time_output_port",
44100,STEREO,
AC_WIDTH_16_BIT_SAMPLE,AC_WRITE_ONLY,
AC_INT_SAMPLE_VALUES,
AC_THIS_FIELD_NOT_APPLICABLE_FOR_NON_FLOAT_SAMPLES);
B. Reading and writing audio samples from/to an Audio_port
Note that one frame of audio is equivalent
to x samples of audio, where x is the number of channels of audio
in the file. Therefore, in allocating memory that is passed into
these functions, allocate (num_channels * desired_size) elements
to the buffer you intend to pass to the function. Frames of audio
are passed and returned sequentially, with each channel of audio
being presented sequentially in each frame of audio (e.g. for
a stereo buffer using floating point sample values, the buffer
will contain these samples, in order: 0L, 0R, 1L, 1R, 2L, 2R,
etc., where 0,1,2 represent the frame number, and L, R represent
the channel number).
Receive one frame of audio from an input Audio_port.
void
receive_frame(ElementType* user_buffer)
Receive multiple frames of audio from an input Audio_port.
void
receive_frames(ElementType* user_buffer,
unsigned long num_frames_to_receive)
Send one frame of audio to an output Audio_port.
void
send_frame(ElementType* user_buffer)
Send multiple frames of audio to an output Audio_port.
void
send_frames(ElementType* user_buffer,
unsigned long num_frames_to_send)
IV. Examples
The following table lists some examples that
make exclusive use of class Audio_port.
V. Future directions
The current templated implementation of class Audio_port is not elegant in that the type of the samples sent or retrieved from the port must be specified twice during an Audio_port's instantiation: once in the template declaration, and once in the constructor. A better implementation of this class would eliminate one of these declarations, so that a single line of code could specify a single type of sample handled by a single Audio_port.
Furthermore, although the error-checking is
designed in a similar manner to classes Aiff_file and WAiff_file,
there are several member functions in class Audio_port which do
not robustly handle errors. A significant improvement could be
made to improve error handling in these cases.
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