void samples_t::reorderFromStd(Speakers _spk, const int _order[NCHANNELS]) { int mask(_spk.getMask()); sample_t *tmp[NCHANNELS]; int ch = 0; for ( int i = 0; i < NCHANNELS; ++i ) { if ( mask & CH_MASK(i) ) tmp[i] = samples[ch++]; } ch = 0; for ( int i = 0; i < NCHANNELS; ++i ) { if ( mask & CH_MASK(_order[i]) ) samples[ch++] = tmp[_order[i]]; } }
void BassRedir::update_filters() { int ch, nch = spk.nch(); int sample_rate = spk.sample_rate; order_t order; spk.get_order(order); if (sample_rate) { boost::scoped_ptr<IIRInstance> lpf_iir(IIRCrossover(4, freq, IIRCrossover::lowpass).make(sample_rate)); boost::scoped_ptr<IIRInstance> hpf_iir(IIRCrossover(4, freq, IIRCrossover::highpass).make(sample_rate)); boost::scoped_ptr<IIRInstance> apf_iir(IIRCrossover(4, freq, IIRCrossover::allpass).make(sample_rate)); // When we mix basses to several channels we have to // adjust the gain to keep the resulting loudness int bass_nch = mask_nch(ch_mask); double ch_gain = bass_nch? 1.0 / sqrt((double)bass_nch) : 1.0; lpf_iir->apply_gain(gain * ch_gain); lpf.init(lpf_iir.get()); for (ch = 0; ch < nch; ch++) if ((CH_MASK(order[ch]) & ch_mask) == 0) f[ch].init(hpf_iir.get()); else f[ch].init(apf_iir.get()); for (ch = nch; ch < NCHANNELS; ch++) f[ch].drop(); } else { lpf.drop(); for (int i = 0; i < nch; i++) f[i].drop(); } }
static u32 bpmp_ch_sta(int ch) { return __raw_readl(RES_SEMA_SHRD_SMP_STA) & CH_MASK(ch); }
void bpmp_signal_slave(int ch) { __raw_writel(CH_MASK(ch), RES_SEMA_SHRD_SMP_CLR); }
bool BassRedir::process(Chunk &in, Chunk &out) { // Passthrough (process inplace later) out = in; in.clear(); if (out.is_dummy()) return false; if (!enabled || (spk.mask & ch_mask) == 0 || // Do not filter if we have no channels to mix the bass to. (spk.mask & ~ch_mask) == 0) // Do not filter if we have no channels to filter { level = 0; return true; } int ch, nch = spk.nch(); order_t order; spk.get_order(order); samples_t samples = out.samples; size_t size = out.size; size_t pos = 0; while (pos < size) { size_t block_size = buf.size(); if (block_size > size - pos) block_size = size - pos; // Mix channels to be filtered // Skip channels where we want to mix the bass to buf.zero(); for (ch = 0; ch < nch; ch++) if ((CH_MASK(order[ch]) & ch_mask) == 0) sum_samples(buf, samples[ch] + pos, block_size); // Filter bass channel lpf.process(buf, block_size); // Find bass level level_accum = max_samples(level_accum, buf, block_size); level_samples += block_size; if (level_samples > level_period * spk.sample_rate) { level = level_accum / spk.level; level_accum = 0; level_samples = 0; } // Do filtering and mix bass for (ch = 0; ch < nch; ch++) if ((CH_MASK(order[ch]) & ch_mask) == 0) { // High-pass filter f[ch].process(samples[ch] + pos, block_size); } else { // Allpass and mix bass f[ch].process(samples[ch] + pos, block_size); sum_samples(samples[ch] + pos, buf, block_size); } // Next block pos += block_size; } return true; }