예제 #1
0
파일: MBASE.cpp 프로젝트: eriser/RTcmix-1
/* ------------------------------------------------------------------ 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;
}
예제 #2
0
파일: BASE.cpp 프로젝트: RTcmix/RTcmix
/* ------------------------------------------------------------------ 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;
}