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.

479 lines
13 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=====================================================================================//
  6. #include "audio_pch.h"
  7. // memdbgon must be the last include file in a .cpp file!!!
  8. #include "tier0/memdbgon.h"
  9. // max size of ADPCM block in bytes
  10. #define MAX_BLOCK_SIZE 4096
  11. //-----------------------------------------------------------------------------
  12. // Purpose: Mixer for ADPCM encoded audio
  13. //-----------------------------------------------------------------------------
  14. class CAudioMixerWaveADPCM : public CAudioMixerWave
  15. {
  16. public:
  17. CAudioMixerWaveADPCM( IWaveData *data );
  18. ~CAudioMixerWaveADPCM( void );
  19. virtual void Mix( channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress );
  20. virtual int GetOutputData( void **pData, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] );
  21. // need to override this to fixup blocks
  22. virtual bool IsSetSampleStartSupported() const;
  23. virtual void SetSampleStart( int newPosition );
  24. virtual int GetMixSampleSize() { return CalcSampleSize( 16, NumChannels() ); }
  25. private:
  26. bool DecodeBlock( void );
  27. int NumChannels( void );
  28. void DecompressBlockMono( short *pOut, const char *pIn, int count );
  29. void DecompressBlockStereo( short *pOut, const char *pIn, int count );
  30. const ADPCMWAVEFORMAT *m_pFormat;
  31. const ADPCMCOEFSET *m_pCoefficients;
  32. short *m_pSamples;
  33. int m_sampleCount;
  34. int m_samplePosition;
  35. int m_blockSize;
  36. int m_offset;
  37. int m_totalBytes;
  38. };
  39. CAudioMixerWaveADPCM::CAudioMixerWaveADPCM( IWaveData *data ) : CAudioMixerWave( data )
  40. {
  41. m_pSamples = NULL;
  42. m_sampleCount = 0;
  43. m_samplePosition = 0;
  44. m_offset = 0;
  45. CAudioSourceWave &source = reinterpret_cast<CAudioSourceWave &>(m_pData->Source());
  46. #ifdef _DEBUG
  47. CAudioSource *pSource = NULL;
  48. pSource = &m_pData->Source();
  49. Assert( dynamic_cast<CAudioSourceWave *>(pSource) != NULL );
  50. #endif
  51. m_pFormat = (const ADPCMWAVEFORMAT *)source.GetHeader();
  52. if ( m_pFormat )
  53. {
  54. m_pCoefficients = (ADPCMCOEFSET *)((char *)m_pFormat + sizeof(WAVEFORMATEX) + 4);
  55. // create the decode buffer
  56. m_pSamples = new short[m_pFormat->wSamplesPerBlock * m_pFormat->wfx.nChannels];
  57. // number of bytes for samples
  58. m_blockSize = ((m_pFormat->wSamplesPerBlock - 2) * m_pFormat->wfx.nChannels ) / 2;
  59. // size of channel header
  60. m_blockSize += 7 * m_pFormat->wfx.nChannels;
  61. Assert( m_blockSize < MAX_BLOCK_SIZE );
  62. m_totalBytes = source.DataSize();
  63. }
  64. }
  65. CAudioMixerWaveADPCM::~CAudioMixerWaveADPCM( void )
  66. {
  67. delete[] m_pSamples;
  68. }
  69. int CAudioMixerWaveADPCM::NumChannels( void )
  70. {
  71. if ( m_pFormat )
  72. {
  73. return m_pFormat->wfx.nChannels;
  74. }
  75. return 0;
  76. }
  77. void CAudioMixerWaveADPCM::Mix( channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress )
  78. {
  79. if ( NumChannels() == 1 )
  80. {
  81. Device_Mix16Mono( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress );
  82. }
  83. else
  84. {
  85. Device_Mix16Stereo( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress );
  86. }
  87. }
  88. static int error_sign_lut[] = { 0, 1, 2, 3, 4, 5, 6, 7, -8, -7, -6, -5, -4, -3, -2, -1 };
  89. static int error_coefficients_lut[] = { 230, 230, 230, 230, 307, 409, 512, 614,
  90. 768, 614, 512, 409, 307, 230, 230, 230 };
  91. //-----------------------------------------------------------------------------
  92. // Purpose: ADPCM decompress a single block of 1-channel audio
  93. // Input : *pOut - output buffer 16-bit
  94. // *pIn - input block
  95. // count - number of samples to decode (to support partial blocks)
  96. //-----------------------------------------------------------------------------
  97. void CAudioMixerWaveADPCM::DecompressBlockMono( short *pOut, const char *pIn, int count )
  98. {
  99. int pred = *pIn++;
  100. int co1 = m_pCoefficients[pred].iCoef1;
  101. int co2 = m_pCoefficients[pred].iCoef2;
  102. // read initial delta
  103. int delta = *((short *)pIn);
  104. pIn += 2;
  105. // read initial samples for prediction
  106. int samp1 = *((short *)pIn);
  107. pIn += 2;
  108. int samp2 = *((short *)pIn);
  109. pIn += 2;
  110. // write out the initial samples (stored in reverse order)
  111. *pOut++ = (short)samp2;
  112. *pOut++ = (short)samp1;
  113. // subtract the 2 samples in the header
  114. count -= 2;
  115. // this is a toggle to read nibbles, first nibble is high
  116. int high = 1;
  117. int error, sample=0;
  118. // now process the block
  119. while ( count )
  120. {
  121. // read the error nibble from the input stream
  122. if ( high )
  123. {
  124. sample = (unsigned char) (*pIn++);
  125. // high nibble
  126. error = sample >> 4;
  127. // cache low nibble for next read
  128. sample = sample & 0xf;
  129. // Next read is from cache, not stream
  130. high = 0;
  131. }
  132. else
  133. {
  134. // stored in previous read (low nibble)
  135. error = sample;
  136. // next read is from stream
  137. high = 1;
  138. }
  139. // convert to signed with LUT
  140. int errorSign = error_sign_lut[error];
  141. // interpolate the new sample
  142. int predSample = (samp1 * co1) + (samp2 * co2);
  143. // coefficients are fixed point 8-bit, so shift back to 16-bit integer
  144. predSample >>= 8;
  145. // Add in current error estimate
  146. predSample += (errorSign * delta);
  147. // Correct error estimate
  148. delta = (delta * error_coefficients_lut[error]) >> 8;
  149. // Clamp error estimate
  150. if ( delta < 16 )
  151. delta = 16;
  152. // clamp
  153. if ( predSample > 32767L )
  154. predSample = 32767L;
  155. else if ( predSample < -32768L )
  156. predSample = -32768L;
  157. // output
  158. *pOut++ = (short)predSample;
  159. // move samples over
  160. samp2 = samp1;
  161. samp1 = predSample;
  162. count--;
  163. }
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose: Decode a single block of stereo ADPCM audio
  167. // Input : *pOut - 16-bit output buffer
  168. // *pIn - ADPCM encoded block data
  169. // count - number of sample pairs to decode
  170. //-----------------------------------------------------------------------------
  171. void CAudioMixerWaveADPCM::DecompressBlockStereo( short *pOut, const char *pIn, int count )
  172. {
  173. int pred[2], co1[2], co2[2];
  174. int i;
  175. for ( i = 0; i < 2; i++ )
  176. {
  177. pred[i] = *pIn++;
  178. co1[i] = m_pCoefficients[pred[i]].iCoef1;
  179. co2[i] = m_pCoefficients[pred[i]].iCoef2;
  180. }
  181. int delta[2], samp1[2], samp2[2];
  182. for ( i = 0; i < 2; i++, pIn += 2 )
  183. {
  184. // read initial delta
  185. delta[i] = *((short *)pIn);
  186. }
  187. // read initial samples for prediction
  188. for ( i = 0; i < 2; i++, pIn += 2 )
  189. {
  190. samp1[i] = *((short *)pIn);
  191. }
  192. for ( i = 0; i < 2; i++, pIn += 2 )
  193. {
  194. samp2[i] = *((short *)pIn);
  195. }
  196. // write out the initial samples (stored in reverse order)
  197. *pOut++ = (short)samp2[0]; // left
  198. *pOut++ = (short)samp2[1]; // right
  199. *pOut++ = (short)samp1[0]; // left
  200. *pOut++ = (short)samp1[1]; // right
  201. // subtract the 2 samples in the header
  202. count -= 2;
  203. // this is a toggle to read nibbles, first nibble is high
  204. int high = 1;
  205. int error, sample=0;
  206. // now process the block
  207. while ( count )
  208. {
  209. for ( i = 0; i < 2; i++ )
  210. {
  211. // read the error nibble from the input stream
  212. if ( high )
  213. {
  214. sample = (unsigned char) (*pIn++);
  215. // high nibble
  216. error = sample >> 4;
  217. // cache low nibble for next read
  218. sample = sample & 0xf;
  219. // Next read is from cache, not stream
  220. high = 0;
  221. }
  222. else
  223. {
  224. // stored in previous read (low nibble)
  225. error = sample;
  226. // next read is from stream
  227. high = 1;
  228. }
  229. // convert to signed with LUT
  230. int errorSign = error_sign_lut[error];
  231. // interpolate the new sample
  232. int predSample = (samp1[i] * co1[i]) + (samp2[i] * co2[i]);
  233. // coefficients are fixed point 8-bit, so shift back to 16-bit integer
  234. predSample >>= 8;
  235. // Add in current error estimate
  236. predSample += (errorSign * delta[i]);
  237. // Correct error estimate
  238. delta[i] = (delta[i] * error_coefficients_lut[error]) >> 8;
  239. // Clamp error estimate
  240. if ( delta[i] < 16 )
  241. delta[i] = 16;
  242. // clamp
  243. if ( predSample > 32767L )
  244. predSample = 32767L;
  245. else if ( predSample < -32768L )
  246. predSample = -32768L;
  247. // output
  248. *pOut++ = (short)predSample;
  249. // move samples over
  250. samp2[i] = samp1[i];
  251. samp1[i] = predSample;
  252. }
  253. count--;
  254. }
  255. }
  256. //-----------------------------------------------------------------------------
  257. // Purpose: Read data from the source and pass it to the appropriate decompress
  258. // routine.
  259. // Output : Returns true if data was decoded, false if none.
  260. //-----------------------------------------------------------------------------
  261. bool CAudioMixerWaveADPCM::DecodeBlock( void )
  262. {
  263. char tmpBlock[MAX_BLOCK_SIZE];
  264. char *pData;
  265. int blockSize;
  266. int firstSample;
  267. // fixup position with possible loop
  268. CAudioSourceWave &source = reinterpret_cast<CAudioSourceWave &>(m_pData->Source());
  269. m_offset = source.ConvertLoopedPosition( m_offset );
  270. if ( m_offset >= m_totalBytes )
  271. {
  272. // no more data
  273. return false;
  274. }
  275. // can only decode in block sized chunks
  276. firstSample = m_offset % m_blockSize;
  277. m_offset = m_offset - firstSample;
  278. // adpcm must calculate and request correct block size for proper decoding
  279. // last block size may be truncated
  280. blockSize = m_totalBytes - m_offset;
  281. if ( blockSize > m_blockSize )
  282. {
  283. blockSize = m_blockSize;
  284. }
  285. // get requested data
  286. int available = m_pData->ReadSourceData( (void **)(&pData), m_offset, blockSize, NULL );
  287. if ( available < blockSize )
  288. {
  289. // pump to get all of requested data
  290. int total = 0;
  291. while ( available && total < blockSize )
  292. {
  293. memcpy( tmpBlock + total, pData, available );
  294. total += available;
  295. available = m_pData->ReadSourceData( (void **)(&pData), m_offset + total, blockSize - total, NULL );
  296. }
  297. pData = tmpBlock;
  298. available = total;
  299. }
  300. if ( !available )
  301. {
  302. // no more data
  303. return false;
  304. }
  305. // advance the file pointer
  306. m_offset += available;
  307. int channelCount = NumChannels();
  308. // this is sample pairs for stereo, samples for mono
  309. m_sampleCount = m_pFormat->wSamplesPerBlock;
  310. // short block?, fixup sample count (2 samples per byte, divided by number of channels per sample set)
  311. m_sampleCount -= ((m_blockSize - available) * 2) / channelCount;
  312. // new block, start at the first sample
  313. m_samplePosition = firstSample;
  314. // no need to subclass for different channel counts...
  315. if ( channelCount == 1 )
  316. {
  317. DecompressBlockMono( m_pSamples, pData, m_sampleCount );
  318. }
  319. else
  320. {
  321. DecompressBlockStereo( m_pSamples, pData, m_sampleCount );
  322. }
  323. return true;
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Purpose: Read existing buffer or decompress a new block when necessary
  327. // Input : **pData - output data pointer
  328. // sampleCount - number of samples (or pairs)
  329. // Output : int - available samples (zero to stop decoding)
  330. //-----------------------------------------------------------------------------
  331. int CAudioMixerWaveADPCM::GetOutputData( void **pData, int sampleCount, char copyBuf[AUDIOSOURCE_COPYBUF_SIZE] )
  332. {
  333. if ( m_samplePosition >= m_sampleCount )
  334. {
  335. if ( !DecodeBlock() )
  336. return 0;
  337. }
  338. if ( m_samplePosition < m_sampleCount )
  339. {
  340. *pData = (void *)(m_pSamples + m_samplePosition * NumChannels());
  341. int available = m_sampleCount - m_samplePosition;
  342. if ( available > sampleCount )
  343. available = sampleCount;
  344. m_samplePosition += available;
  345. // update count of max samples loaded in CAudioMixerWave
  346. CAudioMixerWave::m_sample_max_loaded += available;
  347. // update index of last sample loaded
  348. CAudioMixerWave::m_sample_loaded_index += available;
  349. return available;
  350. }
  351. return 0;
  352. }
  353. bool CAudioMixerWaveADPCM::IsSetSampleStartSupported() const
  354. {
  355. return true;
  356. }
  357. //-----------------------------------------------------------------------------
  358. // Purpose: Seek to a new position in the file
  359. // NOTE: In most cases, only call this once, and call it before playing
  360. // any data.
  361. // Input : newPosition - new position in the sample clocks of this sample
  362. //-----------------------------------------------------------------------------
  363. void CAudioMixerWaveADPCM::SetSampleStart( int newPosition )
  364. {
  365. // cascade to base wave to update sample counter
  366. CAudioMixerWave::SetSampleStart( newPosition );
  367. // which block is the desired starting sample in?
  368. int blockStart = newPosition / m_pFormat->wSamplesPerBlock;
  369. // how far into the block is the sample
  370. int blockOffset = newPosition % m_pFormat->wSamplesPerBlock;
  371. // set the file position
  372. m_offset = blockStart * m_blockSize;
  373. // NOTE: Must decode a block here to properly position the sample Index
  374. // THIS MEANS YOU DON'T WANT TO CALL THIS ROUTINE OFTEN FOR ADPCM SOUNDS
  375. DecodeBlock();
  376. // limit to the samples decoded
  377. if ( blockOffset < m_sampleCount )
  378. blockOffset = m_sampleCount;
  379. // set the new current position
  380. m_samplePosition = blockOffset;
  381. }
  382. //-----------------------------------------------------------------------------
  383. // Purpose: Abstract factory function for ADPCM mixers
  384. // Input : *data - wave data access object
  385. // channels -
  386. // Output : CAudioMixer
  387. //-----------------------------------------------------------------------------
  388. CAudioMixer *CreateADPCMMixer( IWaveData *data )
  389. {
  390. return new CAudioMixerWaveADPCM( data );
  391. }