//========================================================================= #define PROGRAMMER "SOLUTIONS, Nofrills" #define PROG_CODE "soln" #define COURSE "ECE-1021" #define YEAR (2004) #define TERM "Spring" #define SECTION (0) #define ASSIGNMENT "HW #7B" #define REVISION (0) #define TITLE "Research of WAV and DTMF" #define SUBTITLE "Last Modified on 14 APR 04" #define EMAIL "ece1021@eas.uccs.edu" #define FILENAME "07b0soln.txt" //========================================================================= //========================================================================= // PROBLEM //========================================================================= // // 1) Describe the basic format of a WAV file. // 2) Describe the basics of Touch-Tone dailing. // 3) Describe how a dialing signal would be stored in a WAV file. //========================================================================= // WAV Basics //========================================================================= // // Source of information: // // http://www.borg.com/~jglatt/tech/wave.htm // http://www.ringthis.com/dev/wave_format.htm // // A WAV file consists of "chunks". Each chunk starts with a four-byte // series of ASCII characters that identifies the type of the chunk // followed by a four-byte integer that give the remaining number of // bytes in the chunk. In otherwords, the size is the total size of the // chunk minus eight. // // All multi-byte values are stored in Intel Little Endian format. // // Three types of chunks in a basic WAV File: // // RIFF chunk (aka, RIFF Header) // fmt chunk // data chunk // // ============================ // RIFF chunk // ============================ // // 12 bytes: // 4 bytes: ASCII codes for 'RIFF' // 4 bytes: Size of file remaining (total file size - 8) // 4 bytes: ASCII codes for 'WAVE' (Type of RIFF file) // // ============================ // fmt chunk // ============================ // // 24 bytes (minimum): // 4 bytes: ASCII codes for 'fmt ' (note the ending space) // 4 bytes: Size of chunk remaining (total chunk size - 8) (usually 16) // 2 bytes: Wave type (uncompressed PCM = 0x01) // 2 bytes: Number of channels // 4 bytes: Sample Rate (sample frames per second) // 4 bytes: Byte Rate (bytes per second that must be read from file) // 2 bytes: Block alignment - bytes per sample frame // 2 bytes: Bits per sample (usually 8,12,16) // // ============================ // data chunk // ============================ // // 4 bytes: ASCII codes for 'data' // 4 bytes: Size of chunk remaining (total chunk size - 8) // X bytes: The actual data // // The data is organized by Sample Frame. All of the data for the first // Sample Frame is first, then the next Sample Frame's data, and so on. // // Within a Sample Frame, the data is presented in Channel Order. // // The data for a sample occupies the smallest number of whole bytes // required to hold the number of bits and the bits are left justified // with any unused bits set to zero. // // If there are eight or fewer bits per sample, then the value is stored // as an unsigned value. But if there are more than eight bits per sample, // the bits are stored as signed values. // // ============================ // Calculations // ============================ // // The three pieces of information that will be in the TXT file header // for HW#8B are: // // Number of channels (Channels) // Significant bits per sample (Bits) // Sample rate (samples per second) (SampleRate) // // Given this information: // // BytesPerSample = (Bits/8) + (0 < Bits%8) (integer division intended) // BlockAlign = Channels * BytesPerSample // ByteRate = BlockAlign * SampleRate // // If the number of bits per sample is not evenly divisble by eight, then // we must take care of the required left justification. This can be done // by simply shifting the value to the left by the appropriate number of // bits and can be accomplished by: // // BitsToShift = (8 - BITS%8)%8 // datavalue >>= BitsToShift //========================================================================= // DTMF Basics //========================================================================= // // Source of information: // http://www.hut.fi/~then/mytexts/dtmf_generation.html // // 1209 Hz 1336 Hz 1477 Hz 1633 Hz // // ABC DEF // 697 Hz 1 2 3 A // // GHI JKL MNO // 770 Hz 4 5 6 B // // PRS TUV WXY // 852 Hz 7 8 9 C // // oper // 941 Hz * 0 # D // // If I want to generate the tones for the number five key, I need to // generate a sinewave at 852 Hz and one at 1336 Hz and add them together. // //========================================================================= // DTMF WAV File //========================================================================= // // The basic approach to generating the file will be to get a string of // digits (the phone number) from the user and to generate a set of data // representing the DTMF tones for that string of digits. For each digit, // there will be a short segment of silence, followed by data obtained // from the addition of the appropriate pair of tones, follwed by another // short period of silence. // // 1) TASK: Get phone number from User // 2) TASK: Initialize the WAV File // 2.1) TASK: Compute Values that must be exported // 2.2) TASK: Output all values to file except actual data // 3) TASK: Generate the sound data // 3.1) LOOP: For each digit in the phone number // 3.1.1) TASK: Generate the "front porch" // 3.1.1.1) LOOP: For duration of "front porch" // 3.1.1.1.1) OUT: Zero Signal to file // 3.1.2) TASK: Generate the DTMF signal // 3.1.2.1) TASK: Look up the HI frequency. // 3.1.2.2) TASK: Look up the LO frequency. // 3.1.2.3) LOOP: For duration of tone // 3.1.2.3.1) SET: Value = Amplitude * (sine(HI*t) + sine(LO*t)) // 3.1.2.3.1) OUT: Value to file // 3.1.3) TASK: Generate the "back porch" // 3.1.3.1) LOOP: For duration of "back porch" // 3.1.3.1.1) OUT: Zero Signal to file // 4) TASK: Close WAV file and perform any other housekeeping tasks