00001
00002
00003 #include "gapeaudiooutput.h"
00004
00005 GapeAudioOutput::GapeAudioOutput(GapeController* c, int numChannels, int device)
00006 : GapeUnit(c, numChannels) {
00007 properlyInitialized = true;
00008 if (numChannels > GAPE_MAX_NUM_CHANNELS) {
00009 numChannels = GAPE_MAX_NUM_CHANNELS;
00010 GapeConsts::reportError("GapeAudioOutput 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.");
00011 }
00012 try {
00013 output = new RtAudio(numChannels, GapeConsts::sampleRate, "play", device);
00014 } catch (StkError& e) {
00015 QString message("GapeAudioOutput - unable to initialize - ");
00016 message.append(e.getMessage());
00017 GapeConsts::reportError(message.latin1());
00018 properlyInitialized = false;
00019 }
00020 soundBufferSize = GAPE_RT_IO_BUFFER_SIZE * numChannels;
00021 soundBuffer = new GapeIntSample[soundBufferSize];
00022 currentBufferPosition = 0;
00023
00024 }
00025
00026 GapeAudioOutput::~GapeAudioOutput() {
00027 if (currentBufferPosition != 0) {
00028 output->playBuffer(soundBuffer, currentBufferPosition);
00029 }
00030 delete []soundBuffer;
00031 soundBuffer = NULL;
00032 delete output;
00033 output = NULL;
00034 }
00035
00036
00037 void GapeAudioOutput::setMute(bool b) {
00038 if (muted == b) return;
00039 if (b) {
00040 stop();
00041 } else {
00042 start();
00043 }
00044 muted = b;
00045 emit emitMute(b);
00046 }
00047
00048
00049 void GapeAudioOutput::stop() {
00050 #ifdef DIRECTX_API
00051 output->stopPlay();
00052 #endif
00053 }
00054
00055
00056 void GapeAudioOutput::start() {
00057 #ifdef DIRECTX_API
00058 output->startPlay();
00059 #endif
00060 }
00061
00062
00063
00064 void GapeAudioOutput::receiveTick(const GapeFloat* values, int numValues) {
00065 static bool wrongNumberOfChannelsFlag = false;
00066 static bool waitingForGoodInput = false;
00067 static bool properInitializtionReportedFlag = false;
00068 int numToCopy, i;
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 if ((values == NULL) || (numValues == 0)) {
00079 if (!waitingForGoodInput) {
00080 output->playBuffer(soundBuffer, soundBufferSize);
00081 currentBufferPosition = 0;
00082 stop();
00083 waitingForGoodInput = true;
00084 GapeConsts::reportError("GapeAudioOutput received a null tick and muted itself!\n");
00085 }
00086 emit emitTick(values, numValues);
00087 return;
00088
00089 } else {
00090 if (waitingForGoodInput) {
00091 GapeConsts::reportError("GapeAudioOutput unmuted itself\n");
00092 start();
00093 waitingForGoodInput = false;
00094 }
00095 }
00096
00097 if (!properlyInitialized) {
00098 if (!properInitializtionReportedFlag) {
00099 properInitializtionReportedFlag = true;
00100 GapeConsts::reportError("GapeAudioOutput was not properly initialized - *not* outputting sound to DAC!\n");
00101 }
00102 emit emitTick(values, numValues);
00103 return;
00104 }
00105
00106 if (muted) {
00107 emit emitTick(values, numValues);
00108 return;
00109 }
00110
00111 if (numValues == numChannels) {
00112 while (numValues > 0) {
00113 if (numValues < (soundBufferSize - currentBufferPosition)) {
00114 numToCopy = numValues;
00115 } else {
00116 numToCopy = soundBufferSize - currentBufferPosition;
00117 }
00118 for (i = 0; i < numToCopy; i++) {
00119 soundBuffer[currentBufferPosition + i] = GapeConsts::floatToInt(values[i]);
00120 }
00121 currentBufferPosition += numToCopy;
00122 numValues -= numToCopy;
00123 if (currentBufferPosition == (soundBufferSize)) {
00124 output->playBuffer(soundBuffer, soundBufferSize);
00125 currentBufferPosition = 0;
00126 }
00127 }
00128
00129
00130
00131
00132
00133
00134 emit emitTick(values,numValues);
00135
00136 } else {
00137 GapeFloat sample[GAPE_MAX_NUM_CHANNELS] = {0.0};
00138
00139 if (!wrongNumberOfChannelsFlag) {
00140 GapeConsts::reportError("GapeAudioOutput was sent the wrong number of channels to play!\n");
00141 wrongNumberOfChannelsFlag = true;
00142 }
00143
00144 if (numValues > numChannels) {
00145 for (i = 0; i < numChannels; i++) {
00146 sample[i] = values[i];
00147 }
00148
00149 } else {
00150 for (i = 0; i < numValues; i++) {
00151 sample[i] = values[i];
00152 }
00153 }
00154 receiveTick(sample, numChannels);
00155 }
00156 }