6.7 Exercise: Audio
The exercises in this section assume that the operating system handles the audio device in a way similar to how the Solaris operating environment handles it.
Add the following access functions to the audio object of Program 6.16.
The play_file function plays an audio file. It has the following prototype. int play_file(char *filename);
The play_file outputs the audio file specified by filename to the audio device, assuming that the speaker has already been opened. If successful, play_file returns the total number of bytes output. If unsuccessful, play_file returns �1 and sets errno. The record_file function saves incoming audio data to a disk file. It has the following prototype. int record_file(char *filename, int seconds);
The record_file function saves audio information for a time interval of seconds in the file given by filename, assuming that the microphone has already been opened. If successful, record_file returns the total number of bytes recorded. If unsuccessful, record_file returns �1 and sets errno. The get_record_sample_rate function determines the sampling rate for recording. It has the following prototype. int get_record_sample_rate(void);
If successful, get_record_sample_rate returns the sampling rate for recording. If unsuccessful, get_record_sample_rate returns �1 and sets errno. The get_play_buffer_size returns the buffer size that the audio device driver uses to transfer information to the audio output device. It has the following prototype. int get_play_buffer_size(void);
If successful, get_play_buffer_size returns the buffer size for recording. If unsuccessful, get_play_buffer_size returns �1 and sets errno. The get_play_sample_rate function determines the sampling rate for playing. It has the following prototype. int get_play_sample_rate(void);
If successful, get_play_sample_rate returns the sampling rate used for playing audio files on the speaker. If unsuccessful, get_play_sample_rate returns �1 and sets errno. A rate of 8000 samples/second is considered voice quality. The set_play_volume function changes the volume at which sound plays on the speaker. It has the following prototype. int set_play_volume(double volume);
The set_play_volume sets the gain on the speaker. The volume must be between 0.0 and 1.0. If successful, set_play_volume returns 0. If unsuccessful, set_play_volume returns �1 and sets errno. The set_record_volume function changes the volume of incoming sound from the microphone. It has the following prototype. int set_record_volume(double volume);
The set_record_volume function sets the gain on the microphone. The volume value must be between 0.0 and 1.0. If successful, set_record_volume returns 0. If unsuccessful, it returns �1 and sets errno.
Rewrite Program 6.17 to copy from the microphone to the speaker, using the preferred buffer size of each of these devices. Call get_record_buffer_size and get_play_buffer_size to determine the respective sizes. Do not assume that they are the same in your implementation. Use the record_file function to create eight audio files, each of which is ten seconds in duration: pid1.au, pid2.au, and so on. In the file pid1.au, record the following message (in your voice): "I am process 1 sending to standard error". Record similar messages in the remaining files. Play the files back by using the play_file function. Be sure to create a header file (say, audiolib.h) with the prototypes of the functions in the audio library. Include this header file in any program that calls functions from this library. Record your speaking of the individual numerical digits (from 0 to 9) in ten different files. Write a function called speak_number that takes a string representing an integer and speaks the number corresponding to the string by calling play_file to play the files for the individual digits. (How does the program sound compared to the computer-generated messages of the phone company?) Replace the fprintf statement that outputs the various IDs in Program 3.1 on page 67 with a call to play_file. For the process with i having value 1, play the file pid1.au, and so on. Listen to the results for different numbers of processes when the speaker is opened before the fork loop. What happens when the speaker is opened after the fork? Be sure to use snprintf to construct the filenames from the i value. Do not hardcode the filenames into the program. Make a recording of the following statement in file pid.au: "My process ID is". Instead of having each process in the previous part play a pidi.au file corresponding to its i number, use speak_number to speak the process ID. Handle the parent and child IDs similarly. Redesign the audio object representation and access functions so that processes have the option of opening separately for read and for write. Replace audio_fd with the descriptors play_fd and record_fd. Change the open_audio so that it sets both play_fd and record_fd to the file descriptor value returned by open. Add the following access functions to the audio object of Program 6.16.
The open_audio_for_record function opens the audio device for read (O_RDONLY). It has the following prototype. int open_audio_for_record(void);
The function returns 0 if successful or �1 if an error occurs. The open_audio_for_play function opens the audio device for write (O_WRONLY). It has the following prototype. int open_audio_for_play(void);
The open_audio_for_play function returns 0 if successful or �1 if an error occurs.
|
No comments:
Post a Comment