void do_thresher(t_thresher *x) { int i; t_fftease *fft = x->fft; t_float *channel = fft->channel; t_float damping_factor = x->damping_factor; int max_hold_frames = x->max_hold_frames; int *frames_left = x->frames_left; t_float *composite_frame = x->composite_frame; int N = fft->N; t_float move_threshold = x->move_threshold; fold(fft); rdft(fft,FFT_FORWARD); convert(fft); if( x->first_frame ){ for ( i = 0; i < N+2; i++ ){ composite_frame[i] = channel[i]; frames_left[i] = max_hold_frames; } x->first_frame = 0; } else { for( i = 0; i < N+2; i += 2 ){ if(fabs( composite_frame[i] - channel[i] ) > move_threshold || frames_left[i] <= 0 ){ composite_frame[i] = channel[i]; composite_frame[i+1] = channel[i+1]; frames_left[i] = max_hold_frames; } else { --(frames_left[i]); composite_frame[i] *= damping_factor; } } } // try memcpy here for ( i = 0; i < N+2; i++ ){ channel[i] = composite_frame[i]; } if(fft->obank_flag){ oscbank(fft); } else { unconvert(fft); rdft(fft,FFT_INVERSE); overlapadd(fft); } }
void makeWaves( struct FFTSound *fftsound, struct RSynthData *rsd, void(*waveconsumer)(struct FFTSound *fftsound,void *pointer,double **samples,int num_samples), bool (*progressupdate)(int pr,void *pointer), void *pointer, int start,int end, bool obank, bool keep_formants ) { double a0=0.0; long point=0, point2=0; int ch; int on=(-fftsound->Nw*fftsound->I)/fftsound->Dn, in=-fftsound->Nw; int j,i; double coef[fftsound->numcoef2+2]; int keepform=0; if(obank){ fprintf(stderr,"\n\nWarning! The result of the additiv resynthesis might be buggy. Please listen to the result to check that its okey or use the IFFT type.\n\n"); } // init_again(); // rsd=getRSynthData(fftsound); memset(coef,0.0,sizeof(double)*(fftsound->numcoef2+2)); if (keep_formants && fftsound->numcoef2!=0) keepform=1; for (j=start; j<end; j++) { on+=fftsound->I; in+=fftsound->Dn; for (ch=0; ch<fftsound->samps_per_frame; ch++) { point = ch*fftsound->horiz_num*fftsound->numchannels + j*fftsound->numchannels; point2=ch*lpc_horiz_num*(fftsound->numcoef2+2)+j*(fftsound->numcoef2+2); if(fftsound->usemem==false) pthread_mutex_lock(&fftsound->mutex); for (i=0; i<fftsound->numchannels; i++) { rsd->channel[i+i]=MEGAMP_GET(point+i); //ch*fftsound->horiz_num + i,j rsd->channel[i+i+1]=MEGFREQ_GET(point+i); } if(fftsound->usemem==false) pthread_mutex_unlock(&fftsound->mutex); // printf("j2: %d\n",j); if (obank==true) { if (j==start){ for (i=0; i<fftsound->N2+1; i++) { rsd->lastfreq[ch][i]=rsd->channel[i+i+1]; rsd->lastamp[ch][i]=rsd->channel[i+i]; rsd->indx[ch][i]=0.; } } if (j>=lpc_horiz_num) keepform=0; if (keepform) { for (i=0; i<fftsound->numcoef2+2; i++) { coef[i]=lpc_coef[point2]; point2++; } a0=coef[fftsound->numcoef2+1]; } oscbank( fftsound, rsd,rsd->channel, fftsound->N2, fftsound->R, fftsound->I, rsd->output[ch], ch, fftsound->Nw,coef, fftsound->numcoef2*keepform,a0 ); } else { unconvert(rsd, rsd->channel, rsd->buffer, fftsound->N2, fftsound->I, fftsound->R, ch); rfft(rsd->buffer, fftsound->N2, INVERSE); overlapadd(rsd->buffer, fftsound->N, fftsound->Wsyn, rsd->output[ch], fftsound->Nw, on); } } // end for(ch=0; ch<fftsound->samps_per_frame; ch++) if (obank==true){ shiftout( fftsound, waveconsumer, pointer, rsd->output, fftsound->Nw, fftsound->I, in+fftsound->Nw2+fftsound->Dn ); }else{ shiftout( fftsound, waveconsumer, pointer, rsd->output, fftsound->Nw, fftsound->I, on ); } if(progressupdate!=NULL){ if((*progressupdate)(j,pointer)==false)break; } } // end for(j=start; j<end; j++) // returnRSynthData(rsd); }
int PVOC::run() { #ifdef debug printf("PVOC::run\n\n"); #endif // This runs the engine forward until the first buffer of output data is ready (see PVOC::shiftout()). // This compensates for the group delay of the windowed output. int outFramesNeeded = framesToRun(); if (_cachedOutFrames) { int toCopy = min(_cachedOutFrames, outFramesNeeded); if (toCopy >= 0) { #ifdef debug printf("\twriting %d of %d leftover frames from _outbuf at offset %d to rtbaddout\n", toCopy, _cachedOutFrames, _outReadOffset); #endif rtbaddout(&_outbuf[_outReadOffset], toCopy); increment(toCopy); _outReadOffset += toCopy; assert(_outReadOffset <= _outWriteOffset); if (_outReadOffset == _outWriteOffset) _outReadOffset = _outWriteOffset = 0; #ifdef debug printf("\t_outbuf read offset %d, write offset %d\n", _outReadOffset, _outWriteOffset); #endif outFramesNeeded -= toCopy; _cachedOutFrames -= toCopy; } } while (outFramesNeeded > 0) { #ifdef debug printf("\ttop of loop: needed=%d _in=%d _on=%d Nw=%d\n", outFramesNeeded, _in, _on, Nw); #endif /* * analysis: input D samples; window, fold and rotate input * samples into FFT buffer; take FFT; and convert to * amplitude-frequency (phase vocoder) form */ shiftin( _pvInput, Nw, D); /* * increment times */ _in += D; _on += I; if ( Np ) { ::vvmult( winput, Hwin, _pvInput, Nw ); lpcoef[0] = ::lpa( winput, Nw, lpcoef, Np ); /* printf("%.3g/", lpcoef[0] ); */ } ::fold( _pvInput, Wanal, Nw, _fftBuf, N, _in ); ::rfft( _fftBuf, N2, FORWARD ); convert( _fftBuf, channel, N2, D, R ); // if ( I == 0 ) { // if ( Np ) // fwrite( lpcoef, sizeof(float), Np+1, stdout ); // fwrite( channel, sizeof(float), N+2, stdout ); // fflush( stdout ); // /* printf("\n" ); // continue; // } /* * at this point channel[2*i] contains amplitude data and * channel[2*i+1] contains frequency data (in Hz) for phase * vocoder channels i = 0, 1, ... N/2; the center frequency * associated with each channel is i*f, where f is the * fundamental frequency of analysis R/N; any desired spectral * modifications can be made at this point: pitch modifications * are generally well suited to oscillator bank resynthesis, * while time modifications are generally well (and more * efficiently) suited to overlap-add resynthesis */ if (_pvFilter) { _pvFilter->run(channel, N2); } if ( obank ) { /* * oscillator bank resynthesis */ oscbank( channel, N2, lpcoef, Np, R, Nw, I, P, _pvOutput ); #if defined(debug) && 0 printf("osc output (first 16):\n"); for (int x=0; x<16; ++x) printf("%g ",_pvOutput[x]); printf("\n"); #endif shiftout( _pvOutput, Nw, I, _on+Nw-I); } else { /* * overlap-add resynthesis */ unconvert( channel, _fftBuf, N2, I, R ); ::rfft( _fftBuf, N2, INVERSE ); ::overlapadd( _fftBuf, N, Wsyn, _pvOutput, Nw, _on ); // I samples written into _outbuf shiftout( _pvOutput, Nw, I, _on); } // Handle case where last synthesized block extended beyond outFramesNeeded int framesToOutput = ::min(outFramesNeeded, I); #ifdef debug printf("\tbottom of loop. framesToOutput: %d\n", framesToOutput); #endif int framesAvailable = _outWriteOffset - _outReadOffset; framesToOutput = ::min(framesToOutput, framesAvailable); if (framesToOutput > 0) { #ifdef debug printf("\twriting %d frames from offset %d to rtbaddout\n", framesToOutput, _outReadOffset); #endif rtbaddout(&_outbuf[_outReadOffset], framesToOutput); increment(framesToOutput); _outReadOffset += framesToOutput; if (_outReadOffset == _outWriteOffset) _outReadOffset = _outWriteOffset = 0; } _cachedOutFrames = _outWriteOffset - _outReadOffset; #ifdef debug if (_cachedOutFrames > 0) { printf("\tsaving %d samples left over\n", _cachedOutFrames); } printf("\toutbuf read offset %d, write offset %d\n\n", _outReadOffset, _outWriteOffset); #endif outFramesNeeded -= framesToOutput; } /* while (outFramesNeeded > 0) */ return framesToRun(); }