?? hsphook.cpp
字號:
/* ********** * * This software is released under the provisions of the GPL version 2. * see file "COPYING". If that file is not available, the full statement * of the license can be found at * * http://www.fsf.org/licensing/licenses/gpl.txt * * Copyright (c) Paul Cifarelli 2005 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. * PCM time-domain equalizer: * (c) 2002 Felipe Rivera <liebremx at users sourceforge net> * (c) 2004 Mark Kretschmann <markey@web.de> * * ********** */#include <math.h>#include <stdlib.h>#include "hxcomm.h"#include "hxcore.h"#include "hxprefs.h"#include "hxstrutl.h"#include "hxvsrc.h"#include "hxresult.h"#include "hxausvc.h"#include "helix-sp.h"#ifndef HELIX_SW_VOLUME_INTERFACE#include "gain.h"#endif#include "hsphook.h"#include "iir_cf.h" // IIR filter coefficients#include "hspalsadevice.h"#define SCOPESIZE 512HSPPreMixAudioHook::HSPPreMixAudioHook(HelixSimplePlayer *player, int playerIndex, IHXAudioStream *pAudioStream, bool fadein, unsigned long fadelength) : m_Player(player), m_lRefCount(0), m_index(playerIndex), m_stream(pAudioStream), m_count(0), m_gaintool(0), m_gaindb(0), m_fadein(fadein), m_fadeout(false), m_fadelength(fadelength){ AddRef();}HSPPreMixAudioHook::~HSPPreMixAudioHook(){ if (m_gaintool) gainFree(m_gaintool);}STDMETHODIMPHSPPreMixAudioHook::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)HSPPreMixAudioHook::AddRef(){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(UINT32)HSPPreMixAudioHook::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}int HSPPreMixAudioHook::volumeize(unsigned char *data, unsigned char *outbuf, size_t len){ gainFeed(data, outbuf, len, m_gaintool); return len;}void HSPPreMixAudioHook::setFadeout(bool fadeout){ m_fadeout = fadeout; if (m_fadeout) { // the "time constant" (ms) is the time it takes to reach +/- 6db of the original gainSetTimeConstant((float) m_fadelength / 8.0, m_gaintool); gainSetSmoothdB(FADE_MIN_dB, m_gaintool); }}STDMETHODIMP HSPPreMixAudioHook::OnBuffer(HXAudioData *pAudioInData, HXAudioData *pAudioOutData){ m_count++;#ifdef DEBUG_PURPOSES_ONLY if (!(m_count % 100)) { m_Player->print2stderr("PRE: time: %d ", pAudioInData->ulAudioTime); switch (pAudioInData->uAudioStreamType) { case INSTANTANEOUS_AUDIO: m_Player->print2stderr(" INSTANTANEOUS_AUDIO "); break; case STREAMING_AUDIO: m_Player->print2stderr(" STREAMING_AUDIO "); break; case TIMED_AUDIO: m_Player->print2stderr(" TIMED_AUDIO "); break; case STREAMING_INSTANTANEOUS_AUDIO: m_Player->print2stderr(" STREAMING_INSTANTANEOUS_AUDIO "); break; } m_Player->print2stderr("pAudioOutData %lx, data %lx\n", pAudioOutData, pAudioOutData->pData); }#endif unsigned char *outbuf; IHXBuffer *ibuf; unsigned long len; unsigned char *data; pAudioInData->pData->Get(data, len); // provide a little margin to prevent a slight but noticeable jump in vol when the fadein ends if ((m_fadein && pAudioInData->ulAudioTime < 2*m_fadelength) || m_fadeout) { m_Player->pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &ibuf); if (ibuf) { ibuf->SetSize(len); outbuf = ibuf->GetBuffer(); len = volumeize(data, outbuf, len); pAudioOutData->pData = ibuf; pAudioOutData->ulAudioTime = pAudioInData->ulAudioTime; pAudioOutData->uAudioStreamType = pAudioInData->uAudioStreamType; } } return 0;}STDMETHODIMP HSPPreMixAudioHook::OnInit(HXAudioFormat *pFormat){ m_Player->print2stderr("PRE MIX HOOK OnInit AudioFormat: ch %d, bps %d, sps %ld, mbs %d\n", pFormat->uChannels, pFormat->uBitsPerSample, pFormat->ulSamplesPerSec, pFormat->uMaxBlockSize); m_format = *pFormat; int bps = pFormat->uBitsPerSample / 8; m_gaintool = gainInit(pFormat->ulSamplesPerSec, pFormat->uChannels, bps); gainSetImmediatedB(0, m_gaintool); if (m_fadein) { gainSetImmediatedB(FADE_MIN_dB, m_gaintool); // the "time constant" (ms) is the time it takes to reach -6db of the target gainSetTimeConstant((float) m_fadelength / 2.0, m_gaintool); gainSetSmoothdB(0, m_gaintool); } return 0;}///////////////////////////////////////////////////////////////////////////////////////////////////HSPPostProcessor::HSPPostProcessor(HelixSimplePlayer *player, int playerIndex) : m_Player(player), m_lRefCount(0), m_index(playerIndex), m_count(0), m_item(0), m_current(0), m_prevtime(0), m_i(0), m_j(2), m_k(1)#ifndef HELIX_SW_VOLUME_INTERFACE , m_gaintool(0), m_gaindB(0.0)#endif{ AddRef(); memset(&m_format, 0, sizeof(m_format)); // zero the data_history, to eliminate the buzz on playing the first track after enabling the equalizer memset(&data_history, 0, sizeof(data_history));}HSPPostProcessor::~HSPPostProcessor(){#ifndef HELIX_SW_VOLUME_INTERFACE if (m_gaintool) gainFree(m_gaintool);#endif}STDMETHODIMPHSPPostProcessor::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)HSPPostProcessor::AddRef(){ return InterlockedIncrement(&m_lRefCount);}STDMETHODIMP_(UINT32)HSPPostProcessor::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}STDMETHODIMP HSPPostProcessor::OnBuffer(HXAudioData *pAudioInData, HXAudioData *pAudioOutData){ unsigned long len; unsigned char *data; pAudioInData->pData->Get(data, len); m_count++;#ifdef DEBUG_PURPOSES_ONLY if (!(m_count % 100)) { m_Player->print2stderr("POST: time: %d ", pAudioInData->ulAudioTime); switch (pAudioInData->uAudioStreamType) { case INSTANTANEOUS_AUDIO: m_Player->print2stderr(" INSTANTANEOUS_AUDIO "); break; case STREAMING_AUDIO: m_Player->print2stderr(" STREAMING_AUDIO "); break; case TIMED_AUDIO: m_Player->print2stderr(" TIMED_AUDIO "); break; case STREAMING_INSTANTANEOUS_AUDIO: m_Player->print2stderr(" STREAMING_INSTANTANEOUS_AUDIO "); break; } m_Player->print2stderr("len %d\n", len); m_Player->print2stderr("pAudioOutData %lx, data %lx\n", pAudioOutData, pAudioOutData->pData); m_Player->print2stderr("Volume is %d\n",m_Player->getDirectHWVolume()); }#endif#ifndef HELIX_SW_VOLUME_INTERFACE unsigned char *outbuf; IHXBuffer *ibuf; m_Player->pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &ibuf); if (ibuf) { ibuf->SetSize(len); outbuf = ibuf->GetBuffer(); // equalize if (m_Player->ppctrl[m_index]->volume && m_Player->isEQenabled() && m_format.uBitsPerSample == 16) { equalize(data, outbuf, len); // finally adjust the volume len = volumeize(outbuf, len); } else // finally adjust the volume len = volumeize(data, outbuf, len); pAudioOutData->pData = ibuf; pAudioOutData->ulAudioTime = pAudioInData->ulAudioTime; pAudioOutData->uAudioStreamType = pAudioInData->uAudioStreamType; }#else // equalize if (m_Player->ppctrl[m_index]->volume && m_Player->isEQenabled() && m_format.uBitsPerSample == 16) { unsigned char *outbuf; IHXBuffer *ibuf; m_Player->pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &ibuf); if (ibuf) { ibuf->SetSize(len); outbuf = ibuf->GetBuffer(); equalize(data, outbuf, len); pAudioOutData->pData = ibuf; pAudioOutData->ulAudioTime = pAudioInData->ulAudioTime; pAudioOutData->uAudioStreamType = pAudioInData->uAudioStreamType; pAudioInData->pData->Release(); } }#endif return 0;}STDMETHODIMP HSPPostProcessor::OnInit(HXAudioFormat *pFormat){ m_format = *pFormat; m_count = 0; m_prevtime = 0; // set the filter coefficients, in case we need to use the equalizer switch(pFormat->ulSamplesPerSec) { case 8000: //iir_cf = iir_cf10_8000; <-- doesn't work iir_cf = iir_cf10_11k_11025; // works break; case 11025: //iir_cf = iir_cf10_11025; <-- not tested (cant get an encoder to give me this sfreq) iir_cf = iir_cf10_11k_11025; // not tested, but works for 8k break; case 16000: //iir_cf = iir_cf10_16000; <-- doesn't work iir_cf = iir_cf10_22k_22050; // works break; case 22050: //iir_cf = iir_cf10_22050; iir_cf = iir_cf10_22k_22050; // this set actually works... break; case 32000: iir_cf = iir_cf10_32000; // works break; case 48000: iir_cf = iir_cf10_48000; // not tested break; case 44100: default: iir_cf = iir_cf10_44100; // works break; } m_i = 0; m_j = 2; m_k = 1; memset(&data_history, 0, sizeof(data_history));
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -