📄 taudiofilterconvolver.cpp.svn-base
字号:
if (cfg->mixingStrength==100) for (unsigned int index2 = 0; index2 < chunk_length; ++index2) { float out=fft_real[index2] / normalization_factor + overlap_buffers[index][index2]; out_data[out_channel[index]+out_channels*(index2+samplesPtr)] = out; overlap_buffers[index][index2] = fft_real[index2 + chunk_length] / normalization_factor; } else for (unsigned int index2 = 0; index2 < chunk_length; ++index2) { float out=fft_real[index2] / normalization_factor + overlap_buffers[index][index2]; out_data[out_channel[index]+out_channels*(index2+samplesPtr)] = mix(in_data[in_channel[index]+in_channels*(index2+samplesPtr)],out,mixingStrength,mixingStrengthInv); overlap_buffers[index][index2] = fft_real[index2 + chunk_length] / normalization_factor; } } // advance input_chunk_ringbuffer_indexes for (unsigned int index = 0; index < number_of_responses; ++index) { input_chunk_ringbuffer_indexes[index] += chunk_length + 1; input_chunk_ringbuffer_indexes[index] %= fft_responses[index].number_of_chunks * (chunk_length + 1); } } return samplesPtr; }//==================================== TaudioFilterConvolver ====================================void TaudioFilterConvolver::Tconvolver::Tfftforward::execute(const Tin *in,Tout *out){ for (int i=0;i<length/2;i++) out[i]=complex(in[2*i+0],in[2*i+1]); rdft(length,1,(float*)out,&ip[0],&w[0]); out[length/2]=complex(out[0].imag(),0); out[0].imag()=0.0f; }void TaudioFilterConvolver::Tconvolver::Tfftbackward::execute(const Tin *in,Tout *out){ for (int i=0;i<length/2;i++) { out[2*i+0]=in[i].real(); out[2*i+1]=in[i].imag(); } out[1]=in[length/2].real(); rdft(length,-1,(float*)out,&ip[0],&w[0]); for (int i=0;i<length;i++) out[i]*=2;}void TaudioFilterConvolver::done(void){ buffer.clear(); convolvers.clear(); }bool TaudioFilterConvolver::is(const TsampleFormat &fmt,const TfilterSettingsAudio *cfg0){ const TconvolverSettings *cfg=(const TconvolverSettings*)cfg0; return super::is(fmt,cfg)/* && (cfg->mappingMode!=0 || !TwavReader<float>(cfg->file,true).empty())*/;}bool TaudioFilterConvolver::getOutputFmt(TsampleFormat &fmt,const TfilterSettingsAudio *cfg0){ if (super::getOutputFmt(fmt,cfg0)) { const TconvolverSettings *cfg=(const TconvolverSettings*)cfg0; if (cfg->mappingMode==0) { TwavReader<float> impulse(cfg->file,true); if (fmt.nchannels==1 && !(fmt.nchannels==impulse.nchannels || impulse.nchannels==1)) fmt.setChannels(impulse.nchannels); } return true; } else return false; }void TaudioFilterConvolver::resampleImpulse(TwavReader<float> &impulse,int dstfreq){ size_t lenout=impulse[0].size()*dstfreq/impulse.freq; std::vector<float> buffOut(lenout*2); for (unsigned int i=0;i<impulse.nchannels;i++) { TreSampleContext<float> resampler(1,dstfreq,impulse.freq,int(16*2.2),10,1,1.0,0); std::vector<float> bufIn(impulse[i]);bufIn.resize(bufIn.size()*2,impulse[i].back()); int ret=resampler.audio_resample(&buffOut[0],&bufIn[0],(int)bufIn.size()); impulse[i]=buffOut;impulse[i].resize(lenout); } impulse.freq=dstfreq; }HRESULT TaudioFilterConvolver::process(TfilterQueue::iterator it,TsampleFormat &fmt,void *samples0,size_t numsamples,const TfilterSettingsAudio *cfg0){ const TconvolverSettings *cfg=(const TconvolverSettings*)cfg0; if (is(fmt,cfg) && cfg->mixingStrength) { if (!cfg->equal(oldcfg)) { oldcfg=*cfg; done(); if (cfg->mappingMode==0) { TwavReader<float> impulse(cfg->file); if (!impulse.empty()) { if (impulse.freq!=fmt.freq) resampleImpulse(impulse,fmt.freq); if (fmt.nchannels==1) { convolvers.push_back(Tconvolver(fmt,impulse,cfg)); outchannels=convolvers[0].number_of_response_channels; } else if (fmt.nchannels==impulse.nchannels || impulse.nchannels==1) { for (unsigned int i=0;i<fmt.nchannels;i++) convolvers.push_back(Tconvolver(fmt,impulse,cfg,i)); outchannels=fmt.nchannels; } } } else { size_t oldsize=0; TwavReader<float> *impulses[6];memset(impulses,0,sizeof(impulses)); for (unsigned int i=0;i<fmt.nchannels;i++) { const char_t *file=NULL; if (fmt.speakers[i]&SPEAKER_FRONT_LEFT) file=cfg->fileL; else if (fmt.speakers[i]&SPEAKER_FRONT_RIGHT) file=cfg->fileR; else if (fmt.speakers[i]&SPEAKER_FRONT_CENTER) file=cfg->fileC; else if (fmt.speakers[i]&SPEAKER_LOW_FREQUENCY) file=cfg->fileLFE; else if (fmt.speakers[i]&(SPEAKER_BACK_LEFT|SPEAKER_BACK_CENTER)) file=cfg->fileSL; else if (fmt.speakers[i]&SPEAKER_BACK_RIGHT) file=cfg->fileSR; if (file) { impulses[i]=new TwavReader<float>(file); if (!impulses[i]->empty() && (impulses[i]->nchannels!=1 || (oldsize && impulses[i]->at(0).size()!=oldsize))) goto endManual; if (!impulses[i]->empty()) { if (impulses[i]->freq!=fmt.freq) resampleImpulse(*impulses[i],fmt.freq); oldsize=impulses[i]->at(0).size(); } } } if (oldsize) { for (unsigned int i=0;i<fmt.nchannels;i++) convolvers.push_back(Tconvolver(fmt,(!impulses[i] || impulses[i]->empty())?TwavReader<float>(fmt.freq,1,oldsize,0.0f):*impulses[i],cfg,i)); outchannels=fmt.nchannels; } endManual: for (unsigned int i=0;i<fmt.nchannels;i++) if (impulses[i]) delete impulses[i]; } } if (!convolvers.empty()) { float *samples=(float*)init(cfg,fmt,samples0,numsamples); unsigned int inBlockAlign=fmt.blockAlign(); buffer.append(samples,numsamples*inBlockAlign); const float * const in_data=(const float* const)&*buffer.begin(); numsamples=buffer.size()/inBlockAlign; fmt.setChannels(outchannels); float *out_data=(float*)alloc_buffer(fmt,numsamples,buf); int samplesProcessed=0; for (Tconvolvers::iterator convolver=convolvers.begin();convolver!=convolvers.end();convolver++) samplesProcessed=convolver->process(in_data,out_data,numsamples,cfg); buffer.erase(buffer.begin(),buffer.begin()+samplesProcessed*inBlockAlign); numsamples=samplesProcessed; samples0=out_data; } } return parent->deliverSamples(++it,fmt,samples0,numsamples);}void TaudioFilterConvolver::onSeek(void){ buffer.clear();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -