00001
00002
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
00040 updateMutex.lock();
00041
00042
00043
00044
00045
00046
00047 muted = b;
00048 updateMutex.unlock();
00049 emit emitMute(b);
00050 }
00051
00052
00053 void GapeAudioInput::stop() {
00054
00055 currentBufferPosition = soundBufferSize;
00056 #ifdef DIRECTX_API
00057 input->stopRecord();
00058 #endif
00059 }
00060
00061
00062 void GapeAudioInput::start() {
00063
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
00085
00086 if (tickCounter >= GapeConsts::updateMutexPeriod) {
00087
00088 bool changed = false;
00089
00090 updateMutex.lock();
00091 if (hasBeenMuted != muted) {
00092
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
00115
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
00146
00147 emit emitTick(output, numValues);
00148 }
00149
00150
00151
00152 void GapeAudioInput::getMoreData() {
00153 input->recordBuffer(soundBuffer, numChannels * soundBufferSize);
00154 }