/* ------------------------------------------------------------------ run --- */ int MBASE::run() { const int totalSamps = insamps + tapcount; int thisFrame = currentFrame(); const int outChans = outputChannels(); DBG1(printf("%s::run(): totalSamps = %d\n", name(), totalSamps)); // this will return chunksamps' worth of input, even if we have // passed the end of the input (will produce zeros) getInput(thisFrame, framesToRun()); DBG1(printf("getInput(%d, %d) called\n", thisFrame, framesToRun())); int bufsamps = getBufferSize(); const int outputOffset = this->output_offset; // loop for required number of output samples const int frameCount = framesToRun(); memset(this->outbuf, 0, frameCount * outChans * sizeof(BUFTYPE)); int frame = 0; while (frame < frameCount) { // limit buffer size to end of current pull (chunksamps) if (frameCount - frame < bufsamps) bufsamps = max(0, frameCount - frame); thisFrame = currentFrame(); // store this locally for efficiency DBG1(printf("top of main loop: frame = %d thisFrame = %d bufsamps = %d\n", frame, thisFrame, bufsamps)); DBG(printf("input signal:\n")); DBG(PrintInput(&in[frame], bufsamps)); // add signal to delay put_tap(thisFrame, &in[frame], bufsamps); // if processing input signal or flushing delay lines ... if (thisFrame < totalSamps) { // limit buffer size of end of input data if (totalSamps - thisFrame < bufsamps) bufsamps = max(0, totalSamps - thisFrame); if ((tapcount = updatePosition(thisFrame)) < 0) RTExit(-1); DBG1(printf(" vector loop: bufsamps = %d\n", bufsamps)); for (int ch = 0; ch < 2; ch++) { for (int path = 0; path < m_paths; path++) { Vector *vec = &m_vectors[ch][path]; /* get delayed samps */ get_tap(thisFrame, ch, path, bufsamps); #if 0 DBG(printf("signal [%d][%d] before filters:\n", ch, path)); DBG(PrintSig(vec->Sig, bufsamps)); #endif /* air absorpt. filters */ air(vec->Sig, bufsamps, vec->Airdata); /* wall absorpt. filters */ if (path > 0) // no filtering of direct signal wall(vec->Sig, bufsamps, vec->Walldata); /* do binaural angle filters if necessary*/ if (m_binaural) { fir(vec->Sig, thisFrame, g_Nterms[path], vec->Fircoeffs, vec->Firtaps, bufsamps); } DBG(printf("signal [%d][%d] before rvb:\n", ch, path)); DBG(PrintSig(vec->Sig, bufsamps)); // DBG(PrintSig(vec->Sig, bufsamps, SIG_THRESH)); } } DBG(printf("summing vectors\n")); Vector *vec; register float *outptr = &this->outbuf[frame*outChans]; // sum unscaled reflected paths as global input for RVB. for (int path = 0; path < m_paths; path++) { vec = &m_vectors[0][path]; addScaleBufToOut(&outptr[2], vec->Sig, bufsamps, outChans, 1.0); vec = &m_vectors[1][path]; addScaleBufToOut(&outptr[3], vec->Sig, bufsamps, outChans, 1.0); } if (!m_binaural) { // now do cardioid mike effect // add scaled reflected paths to output as early response for (int path = 1; path < m_paths; path++) { vec = &m_vectors[0][path]; addScaleBufToOut(&outptr[0], vec->Sig, bufsamps, outChans, vec->MikeAmp); vec = &m_vectors[1][path]; addScaleBufToOut(&outptr[1], vec->Sig, bufsamps, outChans, vec->MikeAmp); #if 0 DBG(printf("early response L and R:\n")); DBG(PrintOutput(&outptr[0], bufsamps, outChans, SIG_THRESH)); DBG(PrintOutput(&outptr[1], bufsamps, outChans, SIG_THRESH)); #endif } } else { // copy scaled, filtered reflected paths (reverb input) as the early reponse // to the output for (int ch = 0; ch < 2; ++ch) { float *dest = &outptr[ch]; float *src = &outptr[ch+2]; for (int n=0; n<bufsamps; ++n) { *dest = *src; dest += outChans; src += outChans; } } } /* add the direct signal into the output bus */ for (int n = 0; n < bufsamps; n++) { outptr[0] += m_vectors[0][0].Sig[n]; outptr[1] += m_vectors[1][0].Sig[n]; outptr += outChans; } DBG(printf("FINAL MIX LEFT CHAN:\n")); DBG(PrintOutput(&this->outbuf[frame*outChans], bufsamps, outChans)); } increment(bufsamps); frame += bufsamps; bufsamps = getBufferSize(); // update DBG1(printf("\tmain loop done. thisFrame now %d\n", currentFrame())); } DBG1(printf("%s::run done\n\n", name())); return frame; }
/* ------------------------------------------------------------------ run --- */ int BASE::run() { int i = 0; double roomsig[2][BUFLEN], rvbsig[2][BUFLEN]; const int totalSamps = insamps + tapcount; const int frameCount = framesToRun(); DBG1(printf("%s::run(): totalSamps = %d\n", name(), totalSamps)); // this will return frameCount' worth of input, even if we have // passed the end of the input (will produce zeros) getInput(cursamp, frameCount); DBG1(printf("getInput(%d, %d) called\n", cursamp, frameCount)); int bufsamps = getBufferSize(); // loop for required number of output samples while (i < frameCount) { // limit buffer size to end of current pull (chunksamps) if (frameCount - i < bufsamps) bufsamps = max(0, frameCount - i); DBG1(printf("top of main loop: i = %d cursamp = %d bufsamps = %d\n", i, cursamp, bufsamps)); DBG(printf("input signal:\n")); DBG(PrintInput(&in[i], bufsamps)); // add signal to delay put_tap(cursamp, &in[i], bufsamps); // if processing input signal or flushing delay lines ... if (cursamp < totalSamps) { // limit buffer size of end of input data if (totalSamps - cursamp < bufsamps) bufsamps = max(0, totalSamps - cursamp); if ((tapcount = updatePosition(cursamp)) < 0) return PARAM_ERROR; DBG1(printf(" inner loop: bufsamps = %d\n", bufsamps)); for (int ch = 0; ch < 2; ch++) { for (int path = 0; path < 13; path++) { Vector *vec = &m_vectors[ch][path]; DBG(printf("vector[%d][%d]:\n", ch, path)); /* get delayed samps */ get_tap(cursamp, ch, path, bufsamps); DBG(PrintSig(vec->Sig, bufsamps)); /* air absorpt. filters */ air(vec->Sig, bufsamps, vec->Airdata); /* wall absorpt. filters */ if (path > 0) // no filtering of direct signal wall(vec->Sig, bufsamps, vec->Walldata); /* do binaural angle filters if necessary*/ if (m_binaural) fir(vec->Sig, cursamp, g_Nterms[path], vec->Fircoeffs, vec->Firtaps, bufsamps); // sum unscaled reflected paths as input for RVB. // first path is set; the rest are summed if (path == 1) copyBuf(&roomsig[ch][0], vec->Sig, bufsamps); else if (path > 1) addBuf(&roomsig[ch][0], vec->Sig, bufsamps); /* now do cardioid mike effect if not binaural mode */ if (!m_binaural) scale(vec->Sig, bufsamps, vec->MikeAmp); DBG(printf("after final scale before rvb:\n")); DBG(PrintSig(vec->Sig, bufsamps, 0.1)); } /* scale reverb input by amp factor */ scale(&roomsig[ch][0], bufsamps, m_rvbamp); } /* run 1st and 2nd generation paths through reverberator */ for (int n = 0; n < bufsamps; n++) { if (m_rvbamp != 0.0) { double rmPair[2]; double rvbPair[2]; rmPair[0] = roomsig[0][n]; rmPair[1] = roomsig[1][n]; RVB(rmPair, rvbPair, cursamp + n); rvbsig[0][n] = rvbPair[0]; rvbsig[1][n] = rvbPair[1]; } else rvbsig[0][n] = rvbsig[1][n] = 0.0; } DBG(printf("summing vectors\n")); if (!m_binaural) { // re-sum scaled direct and reflected paths as early response // first path is set; the rest are summed for (int path = 0; path < 13; path++) { if (path == 0) { copyBuf(&roomsig[0][0], m_vectors[0][path].Sig, bufsamps); copyBuf(&roomsig[1][0], m_vectors[1][path].Sig, bufsamps); } else { addBuf(&roomsig[0][0], m_vectors[0][path].Sig, bufsamps); addBuf(&roomsig[1][0], m_vectors[1][path].Sig, bufsamps); } } } DBG(printf("left signal:\n")); DBG(PrintSig(roomsig[0], bufsamps, 0.1)); DBG(printf("right signal:\n")); DBG(PrintSig(roomsig[1], bufsamps, 0.1)); /* sum the early response & reverbed sigs */ register float *outptr = &this->outbuf[i*2]; for (int n = 0; n < bufsamps; n++) { *outptr++ = roomsig[0][n] + rvbsig[0][n]; *outptr++ = roomsig[1][n] + rvbsig[1][n]; } DBG(printf("FINAL MIX:\n")); DBG(PrintInput(&this->outbuf[i], bufsamps)); } else { /* flushing reverb */ // this is the current location in the main output buffer // to write to now register float *outptr = &this->outbuf[i*2]; DBG1(printf(" flushing reverb: i = %d, bufsamps = %d\n", i, bufsamps)); for (int n = 0; n < bufsamps; n++) { if (m_rvbamp > 0.0) { double rmPair[2]; double rvbPair[2]; rmPair[0] = 0.0; rmPair[1] = 0.0; RVB(rmPair, rvbPair, cursamp + n); *outptr++ = rvbPair[0]; *outptr++ = rvbPair[1]; } else { *outptr++ = 0.0; *outptr++ = 0.0; } } } cursamp += bufsamps; i += bufsamps; bufsamps = getBufferSize(); // update } DBG1(printf("%s::run done\n\n", name())); return i; }