Counter Strike : Global Offensive Source Code
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.

516 lines
14 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. #define WIN32_LEAN_AND_MEAN
  9. #include <windows.h>
  10. #pragma warning( disable: 4201 )
  11. #include <mmsystem.h>
  12. #pragma warning( default: 4201 )
  13. #include <mmreg.h>
  14. #include "snd_wave_source.h"
  15. #include "snd_wave_mixer_adpcm.h"
  16. #include "snd_wave_mixer_private.h"
  17. #include "hlfaceposer.h"
  18. // max size of ADPCM block in bytes
  19. #define MAX_BLOCK_SIZE 4096
  20. //-----------------------------------------------------------------------------
  21. // Purpose: Mixer for ADPCM encoded audio
  22. //-----------------------------------------------------------------------------
  23. class CAudioMixerWaveADPCM : public CAudioMixerWave
  24. {
  25. public:
  26. CAudioMixerWaveADPCM( CWaveData *data );
  27. ~CAudioMixerWaveADPCM( void );
  28. virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true );
  29. virtual int GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward = true );
  30. virtual bool SetSamplePosition( int position, bool scrubbing = false );
  31. private:
  32. bool DecodeBlock( void );
  33. int NumChannels( void );
  34. void DecompressBlockMono( short *pOut, const char *pIn, int count );
  35. void DecompressBlockStereo( short *pOut, const char *pIn, int count );
  36. void SetCurrentBlock( int block );
  37. int GetCurrentBlock( void ) const;
  38. int GetBlockNumberForSample( int samplePosition );
  39. bool IsSampleInCurrentBlock( int samplePosition );
  40. int GetFirstSampleForBlock( int blocknum ) const;
  41. const ADPCMWAVEFORMAT *m_pFormat;
  42. const ADPCMCOEFSET *m_pCoefficients;
  43. short *m_pSamples;
  44. int m_sampleCount;
  45. int m_samplePosition;
  46. int m_blockSize;
  47. int m_offset;
  48. int m_currentBlock;
  49. };
  50. CAudioMixerWaveADPCM::CAudioMixerWaveADPCM( CWaveData *data ) : CAudioMixerWave( data )
  51. {
  52. m_currentBlock = -1;
  53. m_pSamples = NULL;
  54. m_sampleCount = 0;
  55. m_samplePosition = 0;
  56. m_offset = 0;
  57. m_pFormat = (const ADPCMWAVEFORMAT *)m_pData->Source().GetHeader();
  58. if ( m_pFormat )
  59. {
  60. m_pCoefficients = (ADPCMCOEFSET *)((char *)m_pFormat + sizeof(WAVEFORMATEX) + 4);
  61. // create the decode buffer
  62. m_pSamples = new short[m_pFormat->wSamplesPerBlock * m_pFormat->wfx.nChannels];
  63. // number of bytes for samples
  64. m_blockSize = ((m_pFormat->wSamplesPerBlock - 2) * m_pFormat->wfx.nChannels ) / 2;
  65. // size of channel header
  66. m_blockSize += 7 * m_pFormat->wfx.nChannels;
  67. // Assert(m_blockSize < MAX_BLOCK_SIZE);
  68. }
  69. }
  70. CAudioMixerWaveADPCM::~CAudioMixerWaveADPCM( void )
  71. {
  72. delete[] m_pSamples;
  73. }
  74. int CAudioMixerWaveADPCM::NumChannels( void )
  75. {
  76. if ( m_pFormat )
  77. {
  78. return m_pFormat->wfx.nChannels;
  79. }
  80. return 0;
  81. }
  82. void CAudioMixerWaveADPCM::Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward /*= true*/ )
  83. {
  84. if ( NumChannels() == 1 )
  85. pDevice->Mix16Mono( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
  86. else
  87. pDevice->Mix16Stereo( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
  88. }
  89. static int error_sign_lut[] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 };
  90. static int error_coefficients_lut[] = { 230, 230, 230, 230, 307, 409, 512, 614,
  91. 768, 614, 512, 409, 307, 230, 230, 230 };
  92. //-----------------------------------------------------------------------------
  93. // Purpose: ADPCM decompress a single block of 1-channel audio
  94. // Input : *pOut - output buffer 16-bit
  95. // *pIn - input block
  96. // count - number of samples to decode (to support partial blocks)
  97. //-----------------------------------------------------------------------------
  98. void CAudioMixerWaveADPCM::DecompressBlockMono( short *pOut, const char *pIn, int count )
  99. {
  100. int pred = *pIn++;
  101. int co1 = m_pCoefficients[pred].iCoef1;
  102. int co2 = m_pCoefficients[pred].iCoef2;
  103. // read initial delta
  104. int delta = *((short *)pIn);
  105. pIn += 2;
  106. // read initial samples for prediction
  107. int samp1 = *((short *)pIn);
  108. pIn += 2;
  109. int samp2 = *((short *)pIn);
  110. pIn += 2;
  111. // write out the initial samples (stored in reverse order)
  112. *pOut++ = (short)samp2;
  113. *pOut++ = (short)samp1;
  114. // subtract the 2 samples in the header
  115. count -= 2;
  116. // this is a toggle to read nibbles, first nibble is high
  117. int high = 1;
  118. int error = 0, sample = 0;
  119. // now process the block
  120. while ( count )
  121. {
  122. // read the error nibble from the input stream
  123. if ( high )
  124. {
  125. sample = (unsigned char) (*pIn++);
  126. // high nibble
  127. error = sample >> 4;
  128. // cache low nibble for next read
  129. sample = sample & 0xf;
  130. // Next read is from cache, not stream
  131. high = 0;
  132. }
  133. else
  134. {
  135. // stored in previous read (low nibble)
  136. error = sample;
  137. // next read is from stream
  138. high = 1;
  139. }
  140. // convert to signed with LUT
  141. int errorSign = error_sign_lut[error];
  142. // interpolate the new sample
  143. int predSample = (samp1 * co1) + (samp2 * co2);
  144. // coefficients are fixed point 8-bit, so shift back to 16-bit integer
  145. predSample >>= 8;
  146. // Add in current error estimate
  147. predSample += (errorSign * delta);
  148. // Correct error estimate
  149. delta = (delta * error_coefficients_lut[error]) >> 8;
  150. // Clamp error estimate
  151. if ( delta < 16 )
  152. delta = 16;
  153. // clamp
  154. if ( predSample > 32767L )
  155. predSample = 32767L;
  156. else if ( predSample < -32768L )
  157. predSample = -32768L;
  158. // output
  159. *pOut++ = (short)predSample;
  160. // move samples over
  161. samp2 = samp1;
  162. samp1 = predSample;
  163. count--;
  164. }
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Purpose: Decode a single block of stereo ADPCM audio
  168. // Input : *pOut - 16-bit output buffer
  169. // *pIn - ADPCM encoded block data
  170. // count - number of sample pairs to decode
  171. //-----------------------------------------------------------------------------
  172. void CAudioMixerWaveADPCM::DecompressBlockStereo( short *pOut, const char *pIn, int count )
  173. {
  174. int pred[2], co1[2], co2[2];
  175. int i;
  176. for ( i = 0; i < 2; i++ )
  177. {
  178. pred[i] = *pIn++;
  179. co1[i] = m_pCoefficients[pred[i]].iCoef1;
  180. co2[i] = m_pCoefficients[pred[i]].iCoef2;
  181. }
  182. int delta[2], samp1[2], samp2[2];
  183. for ( i = 0; i < 2; i++, pIn += 2 )
  184. {
  185. // read initial delta
  186. delta[i] = *((short *)pIn);
  187. }
  188. // read initial samples for prediction
  189. for ( i = 0; i < 2; i++, pIn += 2 )
  190. {
  191. samp1[i] = *((short *)pIn);
  192. }
  193. for ( i = 0; i < 2; i++, pIn += 2 )
  194. {
  195. samp2[i] = *((short *)pIn);
  196. }
  197. // write out the initial samples (stored in reverse order)
  198. *pOut++ = (short)samp2[0]; // left
  199. *pOut++ = (short)samp2[1]; // right
  200. *pOut++ = (short)samp1[0]; // left
  201. *pOut++ = (short)samp1[1]; // right
  202. // subtract the 2 samples in the header
  203. count -= 2;
  204. // this is a toggle to read nibbles, first nibble is high
  205. int high = 1;
  206. int error, sample = 0;
  207. // now process the block
  208. while ( count )
  209. {
  210. for ( i = 0; i < 2; i++ )
  211. {
  212. // read the error nibble from the input stream
  213. if ( high )
  214. {
  215. sample = (unsigned char) (*pIn++);
  216. // high nibble
  217. error = sample >> 4;
  218. // cache low nibble for next read
  219. sample = sample & 0xf;
  220. // Next read is from cache, not stream
  221. high = 0;
  222. }
  223. else
  224. {
  225. // stored in previous read (low nibble)
  226. error = sample;
  227. // next read is from stream
  228. high = 1;
  229. }
  230. // convert to signed with LUT
  231. int errorSign = error_sign_lut[error];
  232. // interpolate the new sample
  233. int predSample = (samp1[i] * co1[i]) + (samp2[i] * co2[i]);
  234. // coefficients are fixed point 8-bit, so shift back to 16-bit integer
  235. predSample >>= 8;
  236. // Add in current error estimate
  237. predSample += (errorSign * delta[i]);
  238. // Correct error estimate
  239. delta[i] = (delta[i] * error_coefficients_lut[error]) >> 8;
  240. // Clamp error estimate
  241. if ( delta[i] < 16 )
  242. delta[i] = 16;
  243. // clamp
  244. if ( predSample > 32767L )
  245. predSample = 32767L;
  246. else if ( predSample < -32768L )
  247. predSample = -32768L;
  248. // output
  249. *pOut++ = (short)predSample;
  250. // move samples over
  251. samp2[i] = samp1[i];
  252. samp1[i] = predSample;
  253. }
  254. count--;
  255. }
  256. }
  257. bool CAudioMixerWaveADPCM::DecodeBlock( void )
  258. {
  259. char tmpBlock[MAX_BLOCK_SIZE];
  260. char *pData;
  261. int available = m_pData->ReadSourceData( (void **) (&pData), m_offset, m_blockSize );
  262. if ( available < m_blockSize )
  263. {
  264. int total = 0;
  265. while ( available && total < m_blockSize )
  266. {
  267. memcpy( tmpBlock + total, pData, available );
  268. total += available;
  269. available = m_pData->ReadSourceData( (void **) (&pData), m_offset + total, m_blockSize - total );
  270. }
  271. pData = tmpBlock;
  272. available = total;
  273. }
  274. Assert( m_blockSize > 0 );
  275. // Current block number is based on starting offset
  276. int blockNumber = m_offset / m_blockSize;
  277. SetCurrentBlock( blockNumber );
  278. if ( !available )
  279. {
  280. return false;
  281. }
  282. // advance the file pointer
  283. m_offset += available;
  284. int channelCount = NumChannels();
  285. // this is sample pairs for stereo, samples for mono
  286. m_sampleCount = m_pFormat->wSamplesPerBlock;
  287. // short block?, fixup sample count (2 samples per byte, divided by number of channels per sample set)
  288. m_sampleCount -= ((m_blockSize - available) * 2) / channelCount;
  289. // new block, start at the first sample
  290. m_samplePosition = 0;
  291. // no need to subclass for different channel counts...
  292. if ( channelCount == 1 )
  293. {
  294. DecompressBlockMono( m_pSamples, pData, m_sampleCount );
  295. }
  296. else
  297. {
  298. DecompressBlockStereo( m_pSamples, pData, m_sampleCount );
  299. }
  300. return true;
  301. }
  302. //-----------------------------------------------------------------------------
  303. // Purpose:
  304. // Input : block -
  305. //-----------------------------------------------------------------------------
  306. void CAudioMixerWaveADPCM::SetCurrentBlock( int block )
  307. {
  308. m_currentBlock = block;
  309. }
  310. //-----------------------------------------------------------------------------
  311. // Purpose:
  312. // Output : int
  313. //-----------------------------------------------------------------------------
  314. int CAudioMixerWaveADPCM::GetCurrentBlock( void ) const
  315. {
  316. return m_currentBlock;
  317. }
  318. //-----------------------------------------------------------------------------
  319. // Purpose:
  320. // Input : samplePosition -
  321. // Output : int
  322. //-----------------------------------------------------------------------------
  323. int CAudioMixerWaveADPCM::GetBlockNumberForSample( int samplePosition )
  324. {
  325. int blockNum = samplePosition / m_pFormat->wSamplesPerBlock;
  326. return blockNum;
  327. }
  328. //-----------------------------------------------------------------------------
  329. // Purpose:
  330. // Input : samplePosition -
  331. // Output : Returns true on success, false on failure.
  332. //-----------------------------------------------------------------------------
  333. bool CAudioMixerWaveADPCM::IsSampleInCurrentBlock( int samplePosition )
  334. {
  335. int currentBlock = GetCurrentBlock();
  336. int startSample = currentBlock * m_pFormat->wSamplesPerBlock;
  337. int endSample = startSample + m_pFormat->wSamplesPerBlock - 1;
  338. if ( samplePosition >= startSample &&
  339. samplePosition <= endSample )
  340. {
  341. return true;
  342. }
  343. return false;
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose:
  347. // Input : blocknum -
  348. // Output : int
  349. //-----------------------------------------------------------------------------
  350. int CAudioMixerWaveADPCM::GetFirstSampleForBlock( int blocknum ) const
  351. {
  352. return m_pFormat->wSamplesPerBlock * blocknum;
  353. }
  354. //-----------------------------------------------------------------------------
  355. // Purpose: Read existing buffer or decompress a new block when necessary
  356. // Input : **pData - output data pointer
  357. // sampleCount - number of samples (or pairs)
  358. // Output : int - available samples (zero to stop decoding)
  359. //-----------------------------------------------------------------------------
  360. int CAudioMixerWaveADPCM::GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward /*= true*/ )
  361. {
  362. int requestedBlock = GetBlockNumberForSample( samplePosition );
  363. if ( requestedBlock != GetCurrentBlock() )
  364. {
  365. // Ran out of data!!!
  366. if ( !SetSamplePosition( samplePosition ) )
  367. return 0;
  368. }
  369. Assert( requestedBlock == GetCurrentBlock() );
  370. if ( m_samplePosition >= m_sampleCount )
  371. {
  372. if ( !DecodeBlock() )
  373. return 0;
  374. }
  375. if ( m_samplePosition < m_sampleCount )
  376. {
  377. *pData = (void *)(m_pSamples + m_samplePosition * NumChannels());
  378. int available = m_sampleCount - m_samplePosition;
  379. if ( available > sampleCount )
  380. available = sampleCount;
  381. m_samplePosition += available;
  382. return available;
  383. }
  384. return 0;
  385. }
  386. //-----------------------------------------------------------------------------
  387. // Purpose:
  388. // Input : position -
  389. //-----------------------------------------------------------------------------
  390. bool CAudioMixerWaveADPCM::SetSamplePosition( int position, bool scrubbing )
  391. {
  392. position = max( 0, position );
  393. CAudioMixerWave::SetSamplePosition( position, scrubbing );
  394. int requestedBlock = GetBlockNumberForSample( position );
  395. int firstSample = GetFirstSampleForBlock( requestedBlock );
  396. if ( firstSample >= m_pData->Source().SampleCount() )
  397. {
  398. // Read past end of file!!!
  399. return false;
  400. }
  401. int currentSample = ( position - firstSample );
  402. if ( requestedBlock != GetCurrentBlock() )
  403. {
  404. // Rewind file to beginning of block
  405. m_offset = requestedBlock * m_blockSize;
  406. if ( !DecodeBlock() )
  407. {
  408. return false;
  409. }
  410. }
  411. m_samplePosition = currentSample;
  412. return true;
  413. }
  414. //-----------------------------------------------------------------------------
  415. // Purpose: Abstract factory function for ADPCM mixers
  416. // Input : *data - wave data access object
  417. // channels -
  418. // Output : CAudioMixer
  419. //-----------------------------------------------------------------------------
  420. CAudioMixer *CreateADPCMMixer( CWaveData *data )
  421. {
  422. return new CAudioMixerWaveADPCM( data );
  423. }