00001
00002
00003
00004 #include "gapefunctionunit.h"
00005 #include "gapewaveformpalette.h"
00006 #include "WvIn.h"
00007 #include "qstring.h"
00008 #include "AifWvIn.h"
00009 #include "SndWvIn.h"
00010 #include "RawWvIn.h"
00011 #include "WavWvIn.h"
00012
00013
00014 GapeFunctionUnit::GapeFunctionUnit(GapeController* c, int nChannels)
00015 : GapeUnit(c, nChannels),
00016 sampleData(NULL),
00017 initialized(false),
00018 currentTime(0.0) {
00019
00020 setFreq(GAPE_FUNCTION_UNIT_DEFAULT_FREQ);
00021 setGain(GAPE_FUNCTION_UNIT_DEFAULT_GAIN);
00022 setMute(false);
00023
00024
00025 }
00026
00027
00028 GapeFunctionUnit::~GapeFunctionUnit() {
00029 delete[] sampleData;
00030 sampleData = NULL;
00031 }
00032
00033
00034
00035
00036
00037 void GapeFunctionUnit::receiveTick(const GapeFloat* values, int numValues) {
00038 if (!initialized) {
00039 fillBuffer();
00040 period = (double) GapeConsts::sampleRate / frequency;
00041 timeScalar = ((double) dataLength) / period;
00042 oldFrequency = frequency;
00043 initialized = true;
00044 }
00045
00046 if (muted) {
00047 emit emitTick(values,numValues);
00048 return;
00049 }
00050
00051
00052
00053 if (frequency != oldFrequency) {
00054 updateMutex.lock();
00055 double newFrequency = frequency;
00056 updateMutex.unlock();
00057 period = (double) GapeConsts::sampleRate / newFrequency;
00058 timeScalar = ((double) dataLength) / period;
00059 currentTime = currentTime * (oldFrequency / newFrequency);
00060 oldFrequency = newFrequency;
00061 }
00062
00063
00064
00065
00066
00067 double scaledTime = currentTime * timeScalar;
00068 int index = (int) scaledTime;
00069 double indexRemainder = scaledTime - (double)index;
00070 double difference;
00071 if (index + 1 < dataLength) {
00072 difference = difference = sampleData[index+1] - sampleData[index];
00073 } else {
00074 difference = sampleData[0] - sampleData[index];
00075 }
00076 GapeFloat currentValue = sampleData[index] + indexRemainder*difference;
00077
00078
00079
00080
00081 currentTime = currentTime + 1.0;
00082 if (currentTime >= period) {
00083 currentTime = currentTime - period;
00084 }
00085
00086 GapeFloat sample[GAPE_MAX_NUM_CHANNELS] = {0.0};
00087 if (numValues > GAPE_MAX_NUM_CHANNELS) {
00088 numValues = GAPE_MAX_NUM_CHANNELS;
00089 }
00090
00091
00092 if (numValues == 0 || values == NULL) {
00093 numValues = numChannels;
00094 for (int i = 0; i < numChannels; i++) {
00095 sample[i] = (currentValue * gain);
00096 }
00097
00098 } else {
00099 int i;
00100 for (i = 0;i < numValues;i++) {
00101 sample[i] = values[i];
00102 }
00103 for (i = 0; i < numValues; i++) {
00104 sample[i] += (currentValue * gain);
00105 }
00106 if (numValues < numChannels) {
00107 numValues = numChannels;
00108 }
00109 }
00110 emit emitTick(sample,numValues);
00111
00112 }
00113
00114
00115 void GapeFunctionUnit::normalize() {
00116 GapeFloat max = 0.0;
00117 double scalar;
00118 int i;
00119
00120 for (i = 0;i < dataLength; i++) {
00121 if (sampleData[i] > max) {
00122 max = sampleData[i];
00123 }
00124 }
00125
00126 for (i = 0;i < dataLength; i++) {
00127 sampleData[i] *= 1.0 / max;
00128 }
00129 }
00130
00131
00132 void GapeSineUnit::fillBuffer() {
00133 int i;
00134
00135 sampleData = new GapeFloat[GAPE_FN_BUFFER_LENGTH];
00136 for(i = 0; i < GAPE_FN_BUFFER_LENGTH; ++i) {
00137 sampleData[i] = sin(i * 2 * PI / (double) GAPE_FN_BUFFER_LENGTH);
00138 }
00139 dataLength = GAPE_FN_BUFFER_LENGTH;
00140 normalize();
00141 }
00142
00143
00144 void GapeTriangleUnit::fillBuffer() {
00145 int i, j, maxHarmonic;
00146 maxHarmonic = GAPE_FUNCTION_UNIT_MAX_HARMONICS;
00147 bool positive = true;
00148 sampleData = new GapeFloat[GAPE_FN_BUFFER_LENGTH];
00149
00150 for(i = 0; i < GAPE_FN_BUFFER_LENGTH; ++i) {
00151 sampleData[i] = 0;
00152 for(j = 1; j < maxHarmonic; j += 2) {
00153 sampleData[i] += ((positive) ? 1 : -1) * sin(j * i * 2 * PI /
00154 (double) GAPE_FN_BUFFER_LENGTH) /
00155 ((double) j * j);
00156 positive = !positive;
00157 }
00158 }
00159 dataLength = GAPE_FN_BUFFER_LENGTH;
00160 normalize();
00161 }
00162
00163
00164 void GapeSawtoothUnit::fillBuffer() {
00165 int i, j, maxHarmonic;
00166 maxHarmonic = GAPE_FUNCTION_UNIT_MAX_HARMONICS;
00167 sampleData = new GapeFloat[GAPE_FN_BUFFER_LENGTH];
00168
00169 for(i = 0; i < GAPE_FN_BUFFER_LENGTH; ++i) {
00170 sampleData[i] = 0;
00171 for(j = 1; j < maxHarmonic; ++j) {
00172 sampleData[i] += sin(j * i * 2 * PI / (double) GAPE_FN_BUFFER_LENGTH) / (double) j;
00173 }
00174 }
00175 dataLength = GAPE_FN_BUFFER_LENGTH;
00176 normalize();
00177 }
00178
00179
00180 void GapeSquareUnit::fillBuffer() {
00181 int i, j, maxHarmonic;
00182 maxHarmonic = GAPE_FUNCTION_UNIT_MAX_HARMONICS;
00183 sampleData = new GapeFloat[GAPE_FN_BUFFER_LENGTH];
00184
00185 for(i = 0; i < GAPE_FN_BUFFER_LENGTH; ++i) {
00186 sampleData[i] = 0;
00187 for(j = 1; j < maxHarmonic; j+=2) {
00188 sampleData[i] += sin(j * i * 2 * PI / (double) GAPE_FN_BUFFER_LENGTH) / (double) j;
00189 }
00190 }
00191 dataLength = GAPE_FN_BUFFER_LENGTH;
00192 normalize();
00193 }
00194
00195
00196 void GapeHalfwaveUnit::fillBuffer() {
00197 int i;
00198 sampleData = new GapeFloat[GAPE_FN_BUFFER_LENGTH];
00199
00200 for(i = 0; i < GAPE_FN_BUFFER_LENGTH / 2; ++i) {
00201 sampleData[i] = sin(i * 2 * PI / (double) GAPE_FN_BUFFER_LENGTH);
00202 }
00203 for(i = GAPE_FN_BUFFER_LENGTH / 2; i < GAPE_FN_BUFFER_LENGTH; ++i) {
00204 sampleData[i] = 0;
00205 }
00206 dataLength = GAPE_FN_BUFFER_LENGTH;
00207 normalize();
00208 }
00209
00210
00211 GapeDrawnWaveformUnit::GapeDrawnWaveformUnit(QWidget* parent)
00212 : GapeFunctionUnit(new GapeWaveformPalette(parent,"Drawn Waveform")),
00213 xData(NULL) {
00214 fillBuffer();
00215 period = (double) GapeConsts::sampleRate / frequency;
00216 timeScalar = ((double) dataLength) / period;
00217 oldFrequency = frequency;
00218 initialized = true;
00219 xData = new double[dataLength];
00220 for (int i = 0; i < dataLength; i++) {
00221 xData[i] = (double) i / (double) dataLength;
00222 }
00223 GapeWaveformPalette* c = (GapeWaveformPalette*) controllers[0];
00224 connect(c, SIGNAL(emitPoint(double, double)), this, SLOT(setPoint(double, double)));
00225 c->setRawData(xData, sampleData, dataLength);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235 void GapeDrawnWaveformUnit::setPoint(double x, double y) {
00236 int index = (int) (x * ((double) dataLength));
00237 sampleData[index] = y;
00238 }
00239
00240
00241 void GapeDrawnWaveformUnit::fillBuffer() {
00242 int i;
00243 sampleData = new GapeFloat[GAPE_DRAWN_WAVEFORM_BUFFER_LENGTH];
00244
00245 for(i = 0; i < GAPE_DRAWN_WAVEFORM_BUFFER_LENGTH; i++) {
00246 sampleData[i] = 0;
00247 }
00248 dataLength = GAPE_DRAWN_WAVEFORM_BUFFER_LENGTH;
00249 }
00250
00251
00252
00253
00254 GapeFileSampleUnit::GapeFileSampleUnit (QWidget* parent, const QString& file)
00255 : GapeFunctionUnit(new GapeSimpleController(parent,"SampleLoadedFromFile")),
00256 dataReader(NULL),
00257 validFile(false) {
00258 filename = new QString(file.latin1());
00259 fillBuffer();
00260 period = (double) GapeConsts::sampleRate / frequency;
00261 timeScalar = ((double) dataLength) / period;
00262 oldFrequency = frequency;
00263 initialized = true;
00264 ((GapeSimpleController*) controllers[0])->setFreqRange(1.0, GAPE_SIMPLE_CONTROLLER_FREQ_MAX, GAPE_SIMPLE_CONTROLLER_FREQ_STEP);
00265 controllers[0]->setFreq(1.0);
00266 }
00267
00268
00269 GapeFileSampleUnit::~GapeFileSampleUnit () {delete filename;}
00270
00271 void GapeFileSampleUnit::fillBuffer() {
00272 char buffer[512];
00273 validFile = true;
00274
00275
00276 strncpy(buffer, filename->latin1(), 512);
00277
00278 try {
00279 if (filename->find(".aif",-5,false) >= 0) {
00280 dataReader = new AifWvIn(buffer,"oneshot");
00281 } else if (filename->find(".raw",-4,false) >= 0) {
00282 dataReader = new RawWvIn(buffer,"oneshot");
00283 } else if (filename->find(".wav",-4,false) >= 0) {
00284 dataReader = new WavWvIn(buffer,"oneshot");
00285 } else if (filename->find(".snd",-4,false) >= 0) {
00286 dataReader = new SndWvIn(buffer,"oneshot");
00287 } else {
00288
00289 QString errorMessage("Vague filename for GapeFileSampleUnit (should end in .raw/wav/snd/aif/aiff) - ");
00290 errorMessage.append(*filename);
00291 errorMessage.append("\n Opening as raw file \n");
00292 GapeConsts::reportError(errorMessage.latin1());
00293 dataReader = new WavWvIn(buffer,"oneshot");
00294 }
00295 } catch(StkError& e) {
00296 validFile = false;
00297 QString errorMessage("Error opening file - ");
00298 errorMessage.append(*filename);
00299 GapeConsts::reportError(errorMessage.latin1());
00300 }
00301 setNumChannels(1);
00302
00303 if (dataReader->getSize() > GAPE_FILE_SAMPLE_UNIT_MAX_SIZE) {
00304 validFile = false;
00305 QString errorMessage("File: ");
00306 errorMessage.append(*filename);
00307 errorMessage.append("too large for GapeFileSampleUnit \n");
00308 GapeConsts::reportError(errorMessage.latin1());
00309 }
00310
00311 if (!validFile) return;
00312
00313
00314 dataReader->setRate(1.5);
00315
00316
00317
00318 dataLength = dataReader->getSize();
00319 sampleData = new GapeFloat[dataLength];
00320
00321 for (int i = 0; i < dataLength; i++) {
00322 if (dataReader->isFinished()) break;
00323 for (int j = 0; j < numChannels; j++) {
00324 sampleData[i] = dataReader->tick();
00325 }
00326 }
00327
00328 delete dataReader;
00329 }
00330
00331
00332 void GapeFileSampleUnit::receiveTick(const GapeFloat* values, int numValues) {
00333 if (validFile) {
00334 GapeFunctionUnit::receiveTick(values, numValues);
00335 } else {
00336 emit emitTick(values, numValues);
00337 }
00338 }