📄 taudiofilter.cpp.svn-base
字号:
if (c_loop) fc_3dnow(inbuf,samples,(unsigned int)c_loop); } #endif else if (fc_sse && Tconfig::cpu_flags&FF_CPU_SSE) //TODO fix? { c_miss=count&3; c_loop=count-c_miss; if (c_loop) fc_sse(inbuf,samples,(unsigned int)c_loop); } else { c_miss=count; c_loop=0; } for (size_t i=0;i<c_miss;i++) samples[i+c_loop]=TsampleFormatInfo<Tout>::limit(inbuf[i+c_loop]*TsampleFormatInfo<Tout>::max()); return samples; }};//---------------------------- int16 -> float ----------------------------#ifndef WIN64 extern "C" void convert_16_float_3dnow(const int16_t*inbuf,float *samples,unsigned int c_loop);#else #define convert_16_float_3dnow NULL#endifstatic void convert_16_float_sse(const int16_t*inbuf,float *samples,unsigned int c_loop){ int eax=0; int edx=c_loop; const unsigned char *esi=(const unsigned char*)inbuf; edx<<=1;// Number of input bytes. const __m128 divisor_float_16=_mm_set_ps1(0.000030517578125f); __m128 xmm7=divisor_float_16; for (unsigned char *edi=(unsigned char*)samples;eax!=edx;eax+=8) { __m64 mm0,mm1; movq (mm1, esi+eax); //; d c | b a punpcklwd (mm0, mm1 ); //; b x | a x punpckhwd (mm1, mm1 ); //; d d | c c psrad (mm0, 16 ); //; sign extend psrad (mm1, 16 ); //; sign extend __m128 xmm0,xmm1; cvtpi2ps (xmm0, mm0 ); //; - b | - a -> float cvtpi2ps (xmm1, mm1 ); //; - d | - c -> float movlhps (xmm0, xmm1); //; xd xc || xb xa mulps (xmm0, xmm7); //; *=1/MAX_SHORT movups (edi+(eax+8)*2-16, xmm0); //; store xd | xc | xb | xa } _mm_empty();}#ifdef __SSE2__static void convert_16_float_sse2(const int16_t*inbuf,float *samples,unsigned int c_loop){ int eax=0; int edx=c_loop; const unsigned char *esi=(const unsigned char*)inbuf; edx<<= 1; // Number of input bytes. __m128 xmm7=_mm_set_ps1(0.000030517578125f); for (unsigned char *edi=(unsigned char*)samples;eax!=edx;eax+=16) { __m128i xmm0,xmm1; movdqu (xmm1, esi+eax); // h g | f e | d c | b a punpcklwd (xmm0, xmm1); // d x | c x | b x | a x punpckhwd (xmm1, xmm1); // h h | g g | f f | e e psrad (xmm0, 16 ); // sign extend psrad (xmm1, 16 ); // sign extend __m128 xmm2,xmm3; cvtdq2ps (xmm2, xmm0); // - d | - c | - b | - a -> float cvtdq2ps (xmm3, xmm1); // - h | - g | - f | - e -> float mulps (xmm2, xmm7); // *=1/MAX_SHORT mulps (xmm3, xmm7); // *=1/MAX_SHORT movaps (edi+(eax+16)*2-32, xmm2); // store xd | xc | xb | xa movaps (edi+(eax+16)*2-16, xmm3); // store xh | xg | xf | xe } }#else #define convert_16_float_sse2 NULL#endif//---------------------------- int32 -> float ----------------------------#ifndef WIN64 extern "C" void convert_32_float_3dnow(const int32_t*inbuf,float *samples,unsigned int c_loop);#else #define convert_32_float_3dnow NULL#endifstatic void convert_32_float_sse(const int32_t*inbuf,float *samples,unsigned int c_loop){ int eax=0; int edx= c_loop; const unsigned char *esi=(const unsigned char*)inbuf; edx<<=2;// in input bytes (*4) const __m128 divisor_float_32=_mm_set_ps1(4.656612875245796924105750827168e-10f); __m128 xmm7=divisor_float_32; for (unsigned char *edi=(unsigned char*)samples;eax!=edx;eax+= 16) { __m64 mm0,mm1; movq (mm0, esi+eax); // b b | a a movq (mm1, esi+eax+8); // d d | c c __m128 xmm0,xmm1; cvtpi2ps (xmm0, mm0); // b b | a a -> float cvtpi2ps (xmm1, mm1); // d d | c c -> float movlhps (xmm0, xmm1); // xd xc || xb xa mulps (xmm0, xmm7); // *=1/MAX_INT movups (edi+eax-16+16, xmm0); // store xd | xc | xb | xa } _mm_empty();}#ifdef __SSE2__static void convert_32_float_sse2(const int32_t*inbuf,float *samples,unsigned int c_loop){ int eax=0; // count int edx= c_loop; const unsigned char *esi=(const unsigned char*)inbuf; edx<<= 2; // in input bytes (*4) __m128 xmm7=_mm_set_ps1(4.656612875245796924105750827168e-10f); for (unsigned char *edi=(unsigned char*)samples;eax!= edx;eax+=32) { __m128i xmm0,xmm1; movdqu (xmm0, esi+eax); // dd | cc | bb | aa movdqu (xmm1, esi+eax+16); // hh | gg | ff | ee __m128 xmm2,xmm3; cvtdq2ps (xmm2, xmm0); // xd | xc | xb | xa cvtdq2ps (xmm3, xmm1); // xh | xg | xf | xe mulps (xmm2, xmm7); // *=1/MAX_INT mulps (xmm3, xmm7); // *=1/MAX_INT movaps (edi+eax+32-32, xmm2); // store xd | xc | xb | xa movaps (edi+eax+32-16, xmm3); // store xh | xg | xf | xe } }#else #define convert_32_float_sse2 NULL#endiftemplate<class Tin> struct TconvertToFloat{ typedef void (*TconvertToFloatFc)(const Tin*inbuf,float *samples,unsigned int c_loop); static float* convert(const Tin *samples,float *outbuf,size_t count,TconvertToFloatFc fc_3dnow,TconvertToFloatFc fc_sse,TconvertToFloatFc fc_sse2) { static const float divisor=1.0f/-TsampleFormatInfo<Tin>::min(); size_t c_miss,c_loop; if (fc_sse2 && Tconfig::cpu_flags&FF_CPU_SSE2) { while (((intptr_t)outbuf&15) && count) { *outbuf++=divisor*(float)*samples++; count-=1; } c_miss=count&7; c_loop=count-c_miss; if (c_loop) fc_sse2(samples,outbuf,(unsigned int)c_loop); } #ifndef WIN64 else if (fc_3dnow && Tconfig::cpu_flags&FF_CPU_3DNOW) { c_miss=count&3; c_loop=count-c_miss; if (c_loop) fc_3dnow(samples,outbuf,(unsigned int)c_loop); } #endif else if (fc_sse && Tconfig::cpu_flags&FF_CPU_SSE) { c_miss=count&3; c_loop=count-c_miss; if (c_loop) fc_sse(samples,outbuf,(unsigned int)c_loop); } else { c_miss=count; c_loop=0; } for (size_t i=0;i<c_miss;i++) outbuf[i+c_loop]=(float)samples[i+c_loop]*divisor; return outbuf; }};void* TaudioFilter::convertTo(const TsampleFormat &sfIn,const void *bufIn,size_t numsamples,const TsampleFormat &sfOut,size_t samplestoalloc){ if (sfIn.sf==sfOut.sf || numsamples==0) return (void*)bufIn; void *bufOut=alloc_buffer(sfOut,samplestoalloc?samplestoalloc:numsamples); const size_t count=sfIn.nchannels*numsamples; switch (sfIn.sf) { case TsampleFormat::SF_FLOAT32: { int dithering=deci->getParam2(IDFF_dithering),noiseshaping=deci->getParam2(IDFF_noiseShaping); //TODO don't read this always if (dithering || noiseshaping) { if (!dither || oldnoiseshaping!=noiseshaping || oldsfout!=sfOut.sf) { oldnoiseshaping=noiseshaping;oldsfout=sfOut.sf; if (dither) delete dither; dither=new Tdither(sfOut.bitsPerSample(),noiseshaping); } switch (sfOut.sf) { case TsampleFormat::SF_PCM16:return dither->process((const float*)bufIn,(int16_t*)bufOut,sfOut.nchannels,numsamples,dithering); case TsampleFormat::SF_PCM24:return dither->process((const float*)bufIn,(int24_t*)bufOut,sfOut.nchannels,numsamples,dithering); case TsampleFormat::SF_PCM32:return dither->process((const float*)bufIn,(int32_t*)bufOut,sfOut.nchannels,numsamples,dithering); } } else switch (sfOut.sf) { case TsampleFormat::SF_PCM16:return TconvertFromFloat<int16_t>::convert((const float*)bufIn,(int16_t*)bufOut,count,convert_float_16_3dnow,convert_float_16_sse,convert_float_16_sse2); case TsampleFormat::SF_PCM24:return TconvertFromFloat<int24_t>::convert((const float*)bufIn,(int24_t*)bufOut,count,NULL,NULL,NULL); case TsampleFormat::SF_PCM32:return TconvertFromFloat<int32_t>::convert((const float*)bufIn,(int32_t*)bufOut,count,convert_float_32_3dnow,convert_float_32_sse,convert_float_32_sse2); } break; } case TsampleFormat::SF_PCM16: switch (sfOut.sf) { case TsampleFormat::SF_PCM24:return convert((const int16_t*)bufIn,(int24_t*)bufOut,count); case TsampleFormat::SF_PCM32:return convert((const int16_t*)bufIn,(int32_t*)bufOut,count); case TsampleFormat::SF_FLOAT32:return TconvertToFloat<int16_t>::convert((const int16_t*)bufIn,(float*)bufOut,count,convert_16_float_3dnow,convert_16_float_sse,convert_16_float_sse2); } break; case TsampleFormat::SF_PCM24: switch (sfOut.sf) { case TsampleFormat::SF_PCM16:return convert((const int24_t*)bufIn,(int16_t*)bufOut,count); case TsampleFormat::SF_PCM32:return convert((const int24_t*)bufIn,(int32_t*)bufOut,count); case TsampleFormat::SF_FLOAT32:return TconvertToFloat<int24_t>::convert((const int24_t*)bufIn,(float*)bufOut,count,NULL,NULL,NULL); } break; case TsampleFormat::SF_PCM32: switch (sfOut.sf) { case TsampleFormat::SF_PCM16:return convert((const int32_t*)bufIn,(int16_t*)bufOut,count); case TsampleFormat::SF_PCM24:return convert((const int32_t*)bufIn,(int24_t*)bufOut,count); case TsampleFormat::SF_FLOAT32:return TconvertToFloat<int32_t>::convert((const int32_t*)bufIn,(float*)bufOut,count,convert_32_float_3dnow,convert_32_float_sse,convert_32_float_sse2); } break; } return bufOut;}void* TaudioFilter::init(const TfilterSettingsAudio *cfg,TsampleFormat &sf,const void *bufIn,size_t numsamples,size_t samplestoalloc){ bool honourPreferred=true; int supSF=getSupportedFormats(cfg,&honourPreferred); int honouredSF=honourPreferred?(parent->preferredsfs|TsampleFormat::SF_PCM24):TsampleFormat::SF_ALL; if (supSF&honouredSF) supSF&=honouredSF; if (sf.sf&supSF) return (void*)bufIn; TsampleFormat sfIn=sf; sf.sf=TsampleFormat::sf_bestMatch(sf.sf,supSF); return convertTo(sfIn,bufIn,numsamples,sf,samplestoalloc);}bool TaudioFilter::is(const TsampleFormat &fmt,const TfilterSettingsAudio *cfg){ return cfg->is && cfg->show;}bool TaudioFilter::getOutputFmt(TsampleFormat &sf,const TfilterSettingsAudio *cfg){ if (!is(sf,cfg)) return false; bool honourPreferred=true; int supSF=getSupportedFormats(cfg,&honourPreferred); int honouredSF=honourPreferred?(parent->preferredsfs|TsampleFormat::SF_PCM24):TsampleFormat::SF_ALL; if (supSF&honouredSF) supSF&=honouredSF; if ((sf.sf&supSF)==0) sf.sf=TsampleFormat::sf_bestMatch(sf.sf,supSF); return true; }HRESULT TaudioFilter::flush(TfilterQueue::iterator it,TsampleFormat &fmt,const TfilterSettingsAudio *cfg0){ return parent->deliverSamples(++it,fmt,NULL,0); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -