Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "audio_pch.h"
  8. #include "minmax.h"
  9. #include "voice_gain.h"
  10. // memdbgon must be the last include file in a .cpp file!!!
  11. #include "tier0/memdbgon.h"
  12. CAutoGain::CAutoGain()
  13. {
  14. Reset(128, 5.0f, 0.5f, 1);
  15. }
  16. void CAutoGain::Reset(int blockSize, float maxGain, float avgToMaxVal, float scale)
  17. {
  18. m_BlockSize = blockSize;
  19. m_MaxGain = maxGain;
  20. m_AvgToMaxVal = avgToMaxVal;
  21. m_CurBlockOffset = 0;
  22. m_CurTotal = 0;
  23. m_CurMax = 0;
  24. m_CurrentGain = 1;
  25. m_NextGain = 1;
  26. m_Scale = scale;
  27. m_GainMultiplier = 0;
  28. m_FixedCurrentGain = 1 << AG_FIX_SHIFT;
  29. }
  30. void CAutoGain::ProcessSamples(
  31. short *pSamples,
  32. int nSamples)
  33. {
  34. short *pCurPos = pSamples;
  35. int nSamplesLeft = nSamples;
  36. // Continue until we hit the end of this block.
  37. while(nSamplesLeft)
  38. {
  39. int nToProcess = min(nSamplesLeft, (m_BlockSize - m_CurBlockOffset));
  40. for(int iSample=0; iSample < nToProcess; iSample++)
  41. {
  42. // Update running totals..
  43. m_CurTotal += abs( pCurPos[iSample] );
  44. m_CurMax = max( m_CurMax, (int)abs( pCurPos[iSample] ) );
  45. // Apply gain on this sample.
  46. AGFixed gain = m_FixedCurrentGain + m_CurBlockOffset * m_GainMultiplier;
  47. m_CurBlockOffset++;
  48. int newval = ((int)pCurPos[iSample] * gain) >> AG_FIX_SHIFT;
  49. newval = min(32767, max(newval, -32768));
  50. pCurPos[iSample] = (short)newval;
  51. }
  52. pCurPos += nToProcess;
  53. nSamplesLeft -= nToProcess;
  54. // Did we just end a block? Update our next gain.
  55. if((m_CurBlockOffset % m_BlockSize) == 0)
  56. {
  57. // Now we've interpolated to our next gain, make it our current gain.
  58. m_CurrentGain = m_NextGain * m_Scale;
  59. m_FixedCurrentGain = (int)((double)m_CurrentGain * (1 << AG_FIX_SHIFT));
  60. // Figure out the next gain (the gain we'll interpolate to).
  61. int avg = m_CurTotal / m_BlockSize;
  62. float modifiedMax = avg + (m_CurMax - avg) * m_AvgToMaxVal;
  63. m_NextGain = min(32767.0f / modifiedMax, m_MaxGain) * m_Scale;
  64. // Setup the interpolation multiplier.
  65. float fGainMultiplier = (m_NextGain - m_CurrentGain) / (m_BlockSize - 1);
  66. m_GainMultiplier = (AGFixed)((double)fGainMultiplier * (1 << AG_FIX_SHIFT));
  67. // Reset counters.
  68. m_CurTotal = 0;
  69. m_CurMax = 0;
  70. m_CurBlockOffset = 0;
  71. }
  72. }
  73. }