hsphook.cpp
来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 759 行 · 第 1/2 页
CPP
759 行
#ifndef HELIX_SW_VOLUME_INTERFACE // setup the gain tool for volume if (m_gaintool) gainFree(m_gaintool); int bps = pFormat->uBitsPerSample / 8; m_gaintool = gainInit(pFormat->ulSamplesPerSec, pFormat->uChannels, bps); setGain(m_Player->ppctrl[m_index]->volume);#endif return 0;}#ifndef HELIX_SW_VOLUME_INTERFACEvoid HSPPostProcessor::setGain(int volume){ if (m_gaintool) { if (volume == 0) gainSetMute(m_gaintool); else { //m_gaindB = GAIN_MIN_dB + (GAIN_MAX_dB - GAIN_MIN_dB) * (float) volume / 100.0; //m_Player->print2stderr("GAIN set to %f\n", m_gaindB); //gainSetImmediatedB(m_gaindB, m_gaintool); gainSetImmediate( (float) volume / 100.0, m_gaintool ); } }}#endifvoid HSPPostProcessor::scopeify(unsigned long time, unsigned char *data, size_t len){ int bytes_per_sample = m_format.uBitsPerSample / 8; // TODO: 32 bit samples if ( (bytes_per_sample != 1 && bytes_per_sample != 2) ) return; // no scope unsigned long scopebuf_timeinc = (unsigned long)(1000.0 * (double)len / ((double)m_format.ulSamplesPerSec * (double)bytes_per_sample)); DelayQueue *item = new DelayQueue(len); memcpy(item->buf, data, len); item->len = len; item->time = time; item->etime = time + scopebuf_timeinc; m_prevtime = item->etime; item->nchan = m_format.uChannels; item->bps = bytes_per_sample; item->spb = len / item->nchan; item->spb /= bytes_per_sample; item->tps = (double) scopebuf_timeinc / (double) item->spb; m_Player->addScopeBuf(item, m_index);}void HSPPostProcessor::updateEQgains(int pamp, vector<int> &equalizerGains){ for (int i=0; i<EQ_CHANNELS; i++) { preamp[i] = (float) pamp * 0.01; for (int j=0; j<EQ_MAX_BANDS; j++) gain[j][i] = (float)(equalizerGains[j]) * 0.012 - 0.2; }}void HSPPostProcessor::equalize(unsigned char *inbuf, unsigned char *outbuf, size_t length){ int index, band, channel; int tempint, halflength; float out[EQ_CHANNELS], pcm[EQ_CHANNELS]; short int *data = (short int *) inbuf; short int *dataout = (short int *) outbuf; /** * IIR filter equation is * y[n] = 2 * (alpha*(x[n]-x[n-2]) + gamma*y[n-1] - beta*y[n-2]) * * NOTE: The 2 factor was introduced in the coefficients to save * a multiplication * * This algorithm cascades two filters to get nice filtering * at the expense of extra CPU cycles */ /* 16bit, 2 bytes per sample, so divide by two the length of * the buffer (length is in bytes) */ halflength = (length >> 1); for (index = 0; index < halflength; index+=m_format.uChannels) { /* For each channel */ for (channel = 0; channel < m_format.uChannels; channel++) { pcm[channel] = (float) data[index+channel]; /* Preamp gain */ pcm[channel] *= preamp[channel]; out[channel] = 0.; /* For each band */ for (band = 0; band < BAND_NUM; band++) { /* Store Xi(n) */ data_history[band][channel].x[m_i] = pcm[channel]; /* Calculate and store Yi(n) */ data_history[band][channel].y[m_i] = ( /* = alpha * [x(n)-x(n-2)] */ iir_cf[band].alpha * ( data_history[band][channel].x[m_i] - data_history[band][channel].x[m_k]) /* + gamma * y(n-1) */ + iir_cf[band].gamma * data_history[band][channel].y[m_j] /* - beta * y(n-2) */ - iir_cf[band].beta * data_history[band][channel].y[m_k] ); /* * The multiplication by 2.0 was 'moved' into the coefficients to save * CPU cycles here */ /* Apply the gain */ out[channel] += data_history[band][channel].y[m_i]*gain[band][channel]; // * 2.0; } /* For each band */ /* Volume stuff Scale down original PCM sample and add it to the filters output. This substitutes the multiplication by 0.25 Go back to use the floating point multiplication before the conversion to give more dynamic range */ out[channel] += pcm[channel]*0.25; /* Round and convert to integer */ tempint = lrintf(out[channel]); /* Limit the output */ if (tempint < -32768) dataout[index+channel] = -32768; else if (tempint > 32767) dataout[index+channel] = 32767; else dataout[index+channel] = tempint; } /* For each channel */ m_i++; m_j++; m_k++; /* Wrap around the indexes */ if (m_i == 3) m_i = 0; else if (m_j == 3) m_j = 0; else m_k = 0; }/* For each pair of samples */}#ifndef HELIX_SW_VOLUME_INTERFACEint HSPPostProcessor::volumeize(unsigned char *data, size_t len){ gainFeed(data, data, len, m_gaintool); return len;}int HSPPostProcessor::volumeize(unsigned char *data, unsigned char *outbuf, size_t len){ gainFeed(data, outbuf, len, m_gaintool); return len;}#endifHSPPostMixAudioHook::HSPPostMixAudioHook(HelixSimplePlayer *player, int playerIndex) : m_Player(player), m_index(playerIndex), m_lRefCount(0), m_processor(0){ AddRef(); m_Player->print2stderr("POST MIX HOOK CTOR\n"); m_processor = new HSPPostProcessor(player, playerIndex);}HSPPostMixAudioHook::~HSPPostMixAudioHook(){ m_processor->Release();}/* * IUnknown methods */STDMETHODIMPHSPPostMixAudioHook::QueryInterface(REFIID riid, void** ppvObj){ if(IsEqualIID(riid, IID_IUnknown)) { AddRef(); *ppvObj = (IUnknown*)(IHXAudioHook *)this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXAudioHook)) { AddRef(); *ppvObj = (IHXAudioHook *)this; return HXR_OK; } *ppvObj = NULL; return HXR_NOINTERFACE;}STDMETHODIMP_(UINT32)HSPPostMixAudioHook::AddRef(){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(UINT32)HSPPostMixAudioHook::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } m_Player->print2stderr("DELETING POST MIX HOOK index %d\n", m_index); delete this; return 0;}STDMETHODIMP HSPPostMixAudioHook::OnBuffer(HXAudioData *pAudioInData, HXAudioData */*pAudioOutData*/){ unsigned long len; unsigned char *data; pAudioInData->pData->Get(data, len); // feed the visualizations, if this is a local file (otherwise do it in the FinalHook) if (m_Player->isLocal(m_index)) m_processor->scopeify(pAudioInData->ulAudioTime, data, len); return 0;}STDMETHODIMP HSPPostMixAudioHook::OnInit(HXAudioFormat *pFormat){ m_Player->print2stderr("POST MIX HOOK OnInit AudioFormat: idx %d ch %d, bps %d, sps %ld, mbs %d\n", m_index, pFormat->uChannels, pFormat->uBitsPerSample, pFormat->ulSamplesPerSec, pFormat->uMaxBlockSize); return (m_processor->OnInit(pFormat));}void HSPPostMixAudioHook::updateEQgains(int preamp, vector<int> &equalizerGains){ m_processor->updateEQgains(preamp, equalizerGains);}#ifndef HELIX_SW_VOLUME_INTERFACEvoid HSPPostMixAudioHook::setGain(int volume){ m_processor->setGain(volume);}#endifHSPFinalAudioHook::HSPFinalAudioHook(HelixSimplePlayer *player) : m_Player(player), m_lRefCount(0), m_processor(0){ AddRef(); m_processor = new HSPPostProcessor(player, 0);}HSPFinalAudioHook::~HSPFinalAudioHook(){ m_processor->Release();}/* * IUnknown methods */STDMETHODIMPHSPFinalAudioHook::QueryInterface(REFIID riid, void** ppvObj){ if(IsEqualIID(riid, IID_IUnknown)) { AddRef(); *ppvObj = (IUnknown*)(IHXAudioHook *)this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXAudioHook)) { AddRef(); *ppvObj = (IHXAudioHook *)this; return HXR_OK; } *ppvObj = NULL; return HXR_NOINTERFACE;}STDMETHODIMP_(UINT32)HSPFinalAudioHook::AddRef(){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(UINT32)HSPFinalAudioHook::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}STDMETHODIMP HSPFinalAudioHook::OnBuffer(HXAudioData *pAudioInData, HXAudioData *pAudioOutData){ unsigned long len; unsigned char *data; pAudioInData->pData->Get(data, len); // feed the visualizations, if this is a live stream bool anyLocal = false; int i = 0; while (i< m_Player->numPlayers()) { if (m_Player->isPlaying(i)) m_processor->setIndex(i); // put the buffers on the queue of the player that's playing if (anyLocal = m_Player->isLocal(i)) break; i++; } if (!anyLocal) m_processor->scopeify(pAudioInData->ulAudioTime, data, len); return (m_processor->OnBuffer(pAudioInData, pAudioOutData));}STDMETHODIMP HSPFinalAudioHook::OnInit(HXAudioFormat *pFormat){ m_Player->print2stderr("FINAL HOOK OnInit AudioFormat: ch %d, bps %d, sps %ld, mbs %d\n", pFormat->uChannels, pFormat->uBitsPerSample, pFormat->ulSamplesPerSec, pFormat->uMaxBlockSize); return (m_processor->OnInit(pFormat));}void HSPFinalAudioHook::updateEQgains(int preamp, vector<int> &equalizerGains){ m_processor->updateEQgains(preamp, equalizerGains);}#ifndef HELIX_SW_VOLUME_INTERFACEvoid HSPFinalAudioHook::setGain(int volume){ m_processor->setGain(volume);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?