Main Page   Class Hierarchy   Compound List   File List   Compound Members   Related Pages  

gapeaudioinput.cpp

00001 //GapeAudioInput.cpp
00002 //Dave Chisholm dkc@ccrma.stanford.edu 12/1/00
00003 #include "gapeaudioinput.h"
00004 #include <limits.h>
00005 
00006 GapeAudioInput::GapeAudioInput(GapeController* c, int numChannels, int device)
00007 : GapeUnit(c, numChannels),
00008 properInitializationReportedFlag(false),
00009 tickCounter(INT_MAX),
00010 hasBeenMuted(false) {
00011     properlyInitialized = true;
00012     if (numChannels > GAPE_MAX_NUM_CHANNELS) {
00013         numChannels = GAPE_MAX_NUM_CHANNELS;
00014         GapeConsts::reportError("GapeAudioInput does not support the requested number of channels - the max number of channels is being used instead. Redefine GAPE_MAX_NUM_CHANNELS and re-compile if necesary.");
00015     }
00016     try {
00017         input = new RtAudio(numChannels, GapeConsts::sampleRate, "record", device);
00018     } catch (StkError& e) {
00019         QString message("GapeAudioInput - unable to initialize - ");
00020         message.append(e.getMessage());
00021         GapeConsts::reportError(message.latin1());
00022         properlyInitialized = false;
00023     }
00024     soundBufferSize =   GAPE_RT_IO_BUFFER_SIZE * numChannels;
00025     soundBuffer = new GapeIntSample[soundBufferSize];
00026     currentBufferPosition = soundBufferSize;
00027 }
00028 
00029 GapeAudioInput::~GapeAudioInput() {
00030     delete []soundBuffer;
00031     soundBuffer = NULL;
00032     delete input;
00033     input = NULL;
00034 }
00035 
00036 
00037 void GapeAudioInput::setMute(bool b) {
00038     if (muted == b) return;
00039     //GapeConsts::reportError("changing mute\n");
00040     updateMutex.lock();
00041     /*
00042     if (b) {
00043         //stop();//removed b/c new mutex code needs this to be in main
00044     } else {
00045         //start();
00046     }*/
00047     muted = b;
00048     updateMutex.unlock();
00049     emit emitMute(b);
00050 }
00051 
00052 
00053 void GapeAudioInput::stop() {
00054     //GapeConsts::reportError("stopinput\n");
00055     currentBufferPosition = soundBufferSize;
00056     #ifdef DIRECTX_API
00057         input->stopRecord();
00058     #endif
00059 }
00060 
00061 
00062 void GapeAudioInput::start() {
00063     //GapeConsts::reportError("startinput\n");
00064     #ifdef DIRECTX_API
00065         input->startRecord();
00066     #endif
00067 }
00068 
00069 
00070 void GapeAudioInput::receiveTick(const GapeFloat* values, int numValues) {
00071     static bool properInitializtionReportedFlag;
00072     int i;
00073 
00074     if (!properlyInitialized) {
00075             if (!properInitializtionReportedFlag) {
00076                 properInitializtionReportedFlag = true;
00077                 GapeConsts::reportError("GapeAudioInput was not properly initialized! Not inputting samples.\n");
00078             }
00079         emit emitTick(values, numValues);
00080         return;
00081     }
00082 
00083 
00084     //some terse code and a redundant boolean (changed) to ensure we're thread safe and
00085     //don't double start or stop b/c of thread stuff, but still keep critical section small
00086     if (tickCounter >= GapeConsts::updateMutexPeriod) {
00087         //GapeConsts::reportError("checking mute\n");
00088         bool changed = false;
00089 
00090         updateMutex.lock();
00091         if (hasBeenMuted != muted) {
00092             //GapeConsts::reportError("checking mute change\n");
00093             hasBeenMuted = muted;
00094             changed = true;
00095         }
00096         updateMutex.unlock();
00097         if (changed) {
00098             if (hasBeenMuted) {
00099                 stop();
00100             } else {
00101                 start();
00102             }
00103         }
00104         tickCounter = 0;
00105     }
00106     tickCounter++;
00107 
00108     if (hasBeenMuted) {
00109             emit emitTick(values, numValues);
00110             return;
00111     }
00112 
00113 
00114 //if (updateMutex.locked()) GapeConsts::reportError("locked GAI\n");
00115     //updateMutex.lock();
00116     if (currentBufferPosition == soundBufferSize) {
00117         getMoreData();
00118         currentBufferPosition = 0;
00119     }
00120 
00121     GapeFloat output[GAPE_MAX_NUM_CHANNELS];
00122 
00123     if (numValues > GAPE_MAX_NUM_CHANNELS) {
00124         numValues = GAPE_MAX_NUM_CHANNELS;
00125     }
00126 
00127     if ((values == NULL) || (numValues == 0)) {
00128         numValues = numChannels;
00129         for (i = 0;i < numChannels; i++) {
00130             output[i] = GapeConsts::IntToFloat(soundBuffer[currentBufferPosition + i]);
00131         }
00132     } else {
00133         for (i =0; i < numValues; i++) {
00134             output[i] = values[i];
00135         }
00136         for (i = 0; i < numChannels; i++) {
00137             output[i] += GapeConsts::IntToFloat(soundBuffer[currentBufferPosition + i]);
00138         }
00139         if (numValues < numChannels) {
00140             numValues = numChannels;
00141         }
00142     }
00143 
00144     currentBufferPosition += numChannels;
00145     //updateMutex.unlock();
00146 
00147     emit emitTick(output, numValues);
00148 }
00149 
00150 
00151 //i should put a try/catch clause here.
00152 void GapeAudioInput::getMoreData() {
00153     input->recordBuffer(soundBuffer, numChannels * soundBufferSize);
00154 }

Generated at Thu Jun 21 13:28:49 2001 for GAPE by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001