hsphook.cpp

来自「Amarok是一款在LINUX或其他类UNIX操作系统中运行的音频播放器软件。 」· C++ 代码 · 共 759 行 · 第 1/2 页

CPP
759
字号
/* ********** * * 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 + =
减小字号Ctrl + -
显示快捷键?