Music 256 - Assignment 1

Roy Fejgin

Getting the project

This tarball contains all the files needed to build and run this assignment.

Build instructions

To build just type 'make'.

To clean all temporary files and executable type 'make clean'.

Running

To run use the following syntax:

sig-zag [type] [frequency] [width] [input]

[type]: --sine | --saw | --pulse | --noise | --impulse

[frequency]: a floating-point number > 0. Not applicable to 'noise' signal.

[width]: pulse width (only applicable types saw and pulse)

[input]: --input (optional)

Notes:



README

Structure

I created one callback per waveform type. It would have been possible to create a single callback for multiple waveforms, since some could be reused. I decided against it since it would be both less readable and involve executing more logic each time a callback is called (e.g. 'if' statements to determine signal type).

Difficulties

Initially it was hard to troubleshoot problems with the waveforms. Finding a problem in a waveform is quite different from debugging a non-audio related program, it's not enough to look at values of specific variables, you need some sense of the overall waveform, over many samples. Also, using my ears wasn't always helpful since I wasn't sure how the sounds were supposed to sound, and whether the strange noises I'd occasionally hear were caused by my program or by problems in the real-time performance problems of the audio system.

As suggested on the mailing list, it turned out to be very helpful to write out the waveform to a file and use Audacity to look at the signal. I'm pretty sure I'll be using that debugging technique in the future too.

Opportunity for improvement

Some of the callbacks could be more made more efficient.

General Comments

- The command line parsing is flexible. For example, the user may (but is not required to) omit the 'frequency' or 'width' arguments for signal types where they are not required, but still supply arguments that come after that (e.g. '--input').

- Command line parsing is rather lax. E.g if the user typed in more arguments than necessary for a certain wave type, we will accept the command line. However if the input arguments are invalid (i.e. out of the acceptable range), the command line will be rejected.



Special Features

- To scale all outputs by a constant factor, modify the AMPLITUDE macro (near the start of sig-gen.cpp)

- To scale inputs only (useful for low-gain microphones), modify the INPUT_SCALE_FACTOR macro. This was useful when the signal from the microphone was very weak.

- Output to multiple channels is supported, see the OUT_CHANNELS macro. The implementation should also support multiple input channels (see IN_CHANNELS macro), but that has not been tested.

- To dump all output samples to a binary file, define the WITH_DEBUG macro.

- A signal handler was implemented for SIGINT, SIGABRT and SIGTERM. The signal handler takes care of exiting cleanly. The audio stream is closed, the RtAudio object released, and any open files (used for dumping samples) closed. This fixed a problem I encountered on Windows (and to an extent on Linux), where exiting the program using Ctrl-C used to freeze the system(!).