/*************************************************************************** * * * Optech Laser Range Finder (G-150) Communications Program * * * * Establishes serial communications with the Laser Range Finder (LRF). * * Continuously obtains readings from the LRF, looks up the corresponding * * piano note, generates the samples representing this note and sends them * * to the audio port. * * A reading containing more than 12.5% "drop-outs" (as indicated by * * a ')'), is treated as a valid reading. * * When an "out-of-range reading is encountered (as indicated by '))))'), * * the tone corresponding to the last valid reading is output. * * * * Distance readings are mapped linearly to the frequencies of a piano * * keyboard stored in a table. * * * * Prior to program execution, the LRF must be turned ON and in the * * "READY" mode. Should the LRF be turned OFF, the program must be * * re-executed. "CNTRL-C" to stop program execution. * * * * Written By: Bill Kapralos * * Date: Monday, June 9 1997 * * * * York University * * Department of Computer Science * * * * * ****************************************************************************/ #include "lrf_functions.h" #include "lrf_audio.h" /* 1 varies the amplitude with distance, 0 does not vary the amplitude. */ #define VARY_MAGNITUDE 0 #define NUM_OF_KEYS 88 /* Number of keys on a piano keyboard. */ /***************************************************************************/ main(){ double distance = 0.0, magnitude, frequencyInterval, numOfFreqIntervals; unsigned char *rangeReading; int index, pianoIndex; short *signalBuffer; /* Initialize table contaiing all the frequencies of the piano keyboard in ascending order (smallest index holds smallest frequency). */ double pianoNotesTable[] = { 4186.01, 3951.07, 3729.00, 3520.00, 3322.00, 3135.96, 2960.00, 2793.83, 2637.02, 2489.00, 2349.32, 2217.00, 2093.00, 1975.53, 1865.00, 1760.00, 1661.00, 1567.96, 1480.00, 1396.91, 1318.51, 1245.00, 1174.66, 1109.00, 1046.50, 987.77, 932.3, 880.00, 830.6, 783.99, 740.00, 698.46, 659.26, 622.2, 587.33, 554.4, 523.35, 493.88, 466.2, 440.00, 415.3, 392.00, 370.00, 349.23, 329.63, 311.1, 293.66, 277.2, 261.63, 246.94, 233.1, 220.00, 207.6, 196.00, 185.00, 174.61, 164.81, 155.6, 146.83, 138.6, 130.81, 123.47, 116.5, 110.00, 103.8, 98.00, 92.5, 87.31, 82.41, 77.78, 73.42, 69.30, 65.41, 61.74, 58.27, 55.00, 51.91, 49.00, 46.25, 43.65, 41.20, 38.89, 36.71, 34.65, 32.70, 30.87, 29.14, 27.5 }; if (!serialPortInit(TTY_DEVICE)) error("Serial port not opened."); if(!audioInit(AUDIO_PORT)) error("Could not initialize audio port."); rangeReading = (unsigned char *)calloc(LR_READINGLEN,sizeof(unsigned char)); if(!rangeReading){ fprintf(stderr, "ERROR: Could not allocate space for rangeReading\n"); exit(0); } signalBuffer = (short *) calloc(NUM_OF_SAMPLES, sizeof(short *)); if(!signalBuffer) error("Cannot allocate space for char signalBuffer."); lrfSetUp(); /* Obtain distance reading from the LRF, determine corresponding piano keyboard note, generate samples corresponding to this note and output. */ for(;;){ if(getReading(rangeReading)){ /* Obtained reading must be valid to proceed. */ if(distance = processReading(rangeReading)){ /* Determine the corresponding piano keyboard note for the obtained distance reading, generate the samples and output. Several distance readings may correspond to the same frequency. */ pianoIndex = (int) rint(distance / (MAX_DISTANCE/NUM_OF_KEYS)); magnitude = (VARY_MAGNITUDE) ? 20.0 * (1/pow(distance, 2)) : 1.0; signalBuffer = makeWave(pianoNotesTable[pianoIndex], magnitude); sendAudio(signalBuffer, NUM_OF_SAMPLES); } else /* When an invalid reading encountered, output previous tone. */ sendAudio(signalBuffer, NUM_OF_SAMPLES); } } free(rangeReading); close(audioFd); close(serialFd); } /**********************************************************/