void Interpolator::create(int phaseSteps, double sampleRate, double cutoff) { free(); std::vector<Real> taps = createPolyphaseLowPass( phaseSteps, // number of polyphases 1.0, // gain phaseSteps * sampleRate, // sampling frequency cutoff, // hz beginning of transition band sampleRate / 5.0, // hz width of transition band 20.0); // out of band attenuation // init state m_ptr = 0; m_nTaps = taps.size() / phaseSteps; m_phaseSteps = phaseSteps; m_samples.resize(m_nTaps + 2); for(int i = 0; i < m_nTaps + 2; i++) m_samples[i] = 0; // reorder into polyphase std::vector<Real> polyphase(taps.size()); for(int phase = 0; phase < phaseSteps; phase++) { for(int i = 0; i < m_nTaps; i++) polyphase[phase * m_nTaps + i] = taps[i * phaseSteps + phase]; } // normalize phase filters for(int phase = 0; phase < phaseSteps; phase++) { Real sum = 0; for(int i = phase * m_nTaps; i < phase * m_nTaps + m_nTaps; i++) sum += polyphase[i]; for(int i = phase * m_nTaps; i < phase * m_nTaps + m_nTaps; i++) polyphase[i] /= sum; } // move taps around to match sse storage requirements m_taps = new float[2 * taps.size() + 8]; for(int i = 0; i < 2 * taps.size() + 8; ++i) m_taps[i] = 0; m_alignedTaps = (float*)((((quint64)m_taps) + 15) & ~15); for(int i = 0; i < taps.size(); ++i) { m_alignedTaps[2 * i + 0] = polyphase[i]; m_alignedTaps[2 * i + 1] = polyphase[i]; } m_taps2 = new float[2 * taps.size() + 8]; for(int i = 0; i < 2 * taps.size() + 8; ++i) m_taps2[i] = 0; m_alignedTaps2 = (float*)((((quint64)m_taps2) + 15) & ~15); for(int i = 1; i < taps.size(); ++i) { m_alignedTaps2[2 * (i - 1) + 0] = polyphase[i]; m_alignedTaps2[2 * (i - 1) + 1] = polyphase[i]; } }
bool AMPDecoder::L3_DecodeFrame() { int gr, ch, sb, ss; profile_set(0); // bring in new bits fillbits(frame_size); // rewind read point back to beginning of data for this frame //_RPT2(0,"Layer III: added %ld bytes, rewind to %ld\n", frame_size, sideinfo.main_data_begin + frame_size); rewind(sideinfo.main_data_begin + frame_size); profile_add(p_header); // process granules. // // 2 for MPEG-1, 1 for MPEG-2 for (gr=0;gr<(is_mpeg2 ? 1 : 2);gr++) { float lr[2][SBLIMIT][SSLIMIT],ro[SBLIMIT][SSLIMIT]; III_scalefac_t scalefac; int sample_end[2]; int new_end; // process each channel in the granule. for (ch=0; ch<channels; ch++) { long int is[SBLIMIT*SSLIMIT]; /* Quantized samples. */ int part2_start; part2_start = tellbits(); int limit; // decode scale factors if (is_mpeg2) L3_GetScaleFactors2(&scalefac, ch); else L3_GetScaleFactors1(&scalefac, gr, ch); profile_add(p_scalefac); // decode samples limit = L3_HuffmanDecode(is, ch, gr, part2_start); profile_add(p_huffdec); // dequantize samples sample_end[ch] = L3_DequantizeSample(is, (float *)lr[ch], &scalefac[ch], &sideinfo.ch[ch].gr[gr], ch, limit); profile_add(p_dequan); } // process joint stereo in lr new_end = L3_Stereo((float (*)[576])lr, &scalefac, &sideinfo.ch[0].gr[gr], sample_end[0], sample_end[1]); if (new_end > 0) sample_end[0] = sample_end[1] = new_end; profile_add(p_stereo); float polyPhaseIn[2][SSLIMIT][SBLIMIT]; for (ch=0; ch<channels; ch++) { // reorder samples; use 'hybridOut' as our out here, to reuse memory L3_Reorder((float *)lr[ch],(float *)ro,&sideinfo.ch[ch].gr[gr]); // antialiasing L3_Antialias(lr[ch], /* Antialias butterflies. */ &sideinfo.ch[ch].gr[gr]); profile_add(p_antialias); // Hybrid synthesis. L3_Hybrid(lr[ch], polyPhaseIn[ch], ch, &sideinfo.ch[ch].gr[gr], sample_end[ch]); profile_add(p_hybrid); } if (mode == MODE_MONO) for(ss=0; ss<18; ss++) polyphase(polyPhaseIn[0][ss], NULL, psDest + 32*ss + 576*gr, !!(ss&1)); else for(ss=0; ss<18; ss++) polyphase(polyPhaseIn[0][ss], polyPhaseIn[1][ss], psDest + 64*ss + 1152*gr, !!(ss&1)); profile_add(p_polyphase2); } #ifdef RDTSC_PROFILE if (!(++p_frames & 127)) { static char buf[256]; sprintf(buf, "%d frames: total %I64d, header %d%%, scalefac %d%%, huffdec %d%%, dequan %d%%, stereo %d%%, antialias %d%%, hybrid %d%%, poly %d%%/%d%%\n" ,p_frames ,p_total ,(long)((p_header*100)/p_total) ,(long)((p_scalefac*100)/p_total) ,(long)((p_huffdec*100)/p_total) ,(long)((p_dequan*100)/p_total) ,(long)((p_stereo*100)/p_total) ,(long)((p_antialias*100)/p_total) ,(long)((p_hybrid*100)/p_total) ,(long)((p_polyphase1*100)/p_total) ,(long)((p_polyphase2*100)/p_total) ); OutputDebugString(buf); } #endif // set sample count lSampleCount = 1152; if (is_mpeg2) lSampleCount = 576; if (channels>1) lSampleCount <<=1; // _RPT2(0,"Layer III: terminated with %ld bits left (%ld bytes)\n", tellbits(), tellbits()/8); return true; }