![]() |
Mixxx
|
00001 /*************************************************************************** 00002 enginevinylsoundemu.cpp - description 00003 ------------------- 00004 copyright : (C) 2007 by Albert Santoni 00005 email : gamegod \a\t users.sf.net 00006 ***************************************************************************/ 00007 00008 /*************************************************************************** 00009 * * 00010 * This program is free software; you can redistribute it and/or modify * 00011 * it under the terms of the GNU General Public License as published by * 00012 * the Free Software Foundation; either version 2 of the License, or * 00013 * (at your option) any later version. * 00014 * * 00015 ***************************************************************************/ 00016 00017 #include <QtDebug> 00018 #include <QtGlobal> 00019 #include "configobject.h" 00020 #include "controlobject.h" 00021 #include "enginevinylsoundemu.h" 00022 #include "sampleutil.h" 00023 00030 EngineVinylSoundEmu::EngineVinylSoundEmu(ConfigObject<ConfigValue> * pConfig, const char * group) 00031 { 00032 m_pConfig = pConfig; 00033 m_pRateEngine = ControlObject::getControl(ConfigKey(group, "rateEngine")); 00034 m_fSpeed = m_fOldSpeed = 0.0f; 00035 m_fGainFactor = 1.0f; 00036 m_iNoisePos = 0; 00037 00038 for (int i=0; i<NOISE_BUFFER_SIZE; i++) 00039 { 00040 m_fNoise[i] = (float)(rand() % 32768) / 32768 - 0.5; 00041 } 00042 } 00043 00044 EngineVinylSoundEmu::~EngineVinylSoundEmu() 00045 { 00046 00047 } 00048 00049 void EngineVinylSoundEmu::process(const CSAMPLE * pIn, const CSAMPLE * pOut, const int iBufferSize) 00050 { 00051 CSAMPLE * pOutput = (CSAMPLE *)pOut; 00052 m_fSpeed = (float)m_pRateEngine->get(); 00053 float rateFrac = 2 * (m_fSpeed - m_fOldSpeed) / (float)iBufferSize; 00054 float curRate = m_fOldSpeed; 00055 00056 const float thresholdSpeed = 0.070f; //Scale volume if playback speed is below 7%. 00057 const float ditherSpeed = 0.85f; //Dither if playback speed is below 85%. 00058 00059 //iterate over old rate to new rate to prevent audible pops 00060 for (int i=0; i<iBufferSize; i+=2) 00061 { 00062 float absCurRate = fabs(curRate); 00063 float dither = 0; 00064 if (absCurRate < ditherSpeed) { 00065 dither = m_fNoise[m_iNoisePos]; 00066 m_iNoisePos = (m_iNoisePos + 1) % NOISE_BUFFER_SIZE; 00067 } 00068 00069 if (absCurRate < thresholdSpeed) { 00070 float gainfrac = absCurRate / thresholdSpeed; 00071 pOutput[i] = gainfrac * (float)pIn[i] + dither; 00072 pOutput[i+1] = gainfrac * (float)pIn[i+1] + dither; 00073 } 00074 else 00075 { 00076 pOutput[i] = pIn[i] + dither; 00077 pOutput[i+1] = pIn[i+1] + dither; 00078 } 00079 00080 curRate += rateFrac; 00081 } 00082 m_fOldSpeed = m_fSpeed; 00083 } 00084