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.

511 lines
14 KiB

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