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.

539 lines
15 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. //
  8. //-----------------------------------------------------------------------------
  9. // $Log: $
  10. //
  11. // $NoKeywords: $
  12. //===========================================================================//
  13. #include <stdio.h>
  14. #include <windows.h>
  15. #include "snd_audio_source.h"
  16. #include "snd_wave_source.h"
  17. #include "snd_wave_mixer_private.h"
  18. #include "snd_wave_mixer_adpcm.h"
  19. #include "ifaceposersound.h"
  20. #include "AudioWaveOutput.h"
  21. #include "tier2/riff.h"
  22. typedef struct channel_s
  23. {
  24. int leftvol;
  25. int rightvol;
  26. int rleftvol;
  27. int rrightvol;
  28. float pitch;
  29. } channel_t;
  30. //-----------------------------------------------------------------------------
  31. // These mixers provide an abstraction layer between the audio device and
  32. // mixing/decoding code. They allow data to be decoded and mixed using
  33. // optimized, format sensitive code by calling back into the device that
  34. // controls them.
  35. //-----------------------------------------------------------------------------
  36. //-----------------------------------------------------------------------------
  37. // Purpose: maps mixing to 8-bit mono mixer
  38. //-----------------------------------------------------------------------------
  39. class CAudioMixerWave8Mono : public CAudioMixerWave
  40. {
  41. public:
  42. CAudioMixerWave8Mono( CWaveData *data ) : CAudioMixerWave( data ) {}
  43. virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
  44. {
  45. pDevice->Mix8Mono( pChannel, (char *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
  46. }
  47. };
  48. //-----------------------------------------------------------------------------
  49. // Purpose: maps mixing to 8-bit stereo mixer
  50. //-----------------------------------------------------------------------------
  51. class CAudioMixerWave8Stereo : public CAudioMixerWave
  52. {
  53. public:
  54. CAudioMixerWave8Stereo( CWaveData *data ) : CAudioMixerWave( data ) {}
  55. virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
  56. {
  57. pDevice->Mix8Stereo( pChannel, (char *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
  58. }
  59. };
  60. //-----------------------------------------------------------------------------
  61. // Purpose: maps mixing to 16-bit mono mixer
  62. //-----------------------------------------------------------------------------
  63. class CAudioMixerWave16Mono : public CAudioMixerWave
  64. {
  65. public:
  66. CAudioMixerWave16Mono( CWaveData *data ) : CAudioMixerWave( data ) {}
  67. virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
  68. {
  69. pDevice->Mix16Mono( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
  70. }
  71. };
  72. //-----------------------------------------------------------------------------
  73. // Purpose: maps mixing to 16-bit stereo mixer
  74. //-----------------------------------------------------------------------------
  75. class CAudioMixerWave16Stereo : public CAudioMixerWave
  76. {
  77. public:
  78. CAudioMixerWave16Stereo( CWaveData *data ) : CAudioMixerWave( data ) {}
  79. virtual void Mix( IAudioDevice *pDevice, channel_t *pChannel, void *pData, int outputOffset, int inputOffset, fixedint fracRate, int outCount, int timecompress, bool forward = true )
  80. {
  81. pDevice->Mix16Stereo( pChannel, (short *)pData, outputOffset, inputOffset, fracRate, outCount, timecompress, forward );
  82. }
  83. };
  84. //-----------------------------------------------------------------------------
  85. // Purpose: Create an approprite mixer type given the data format
  86. // Input : *data - data access abstraction
  87. // format - pcm or adpcm (1 or 2 -- RIFF format)
  88. // channels - number of audio channels (1 = mono, 2 = stereo)
  89. // bits - bits per sample
  90. // Output : CAudioMixer * abstract mixer type that maps mixing to appropriate code
  91. //-----------------------------------------------------------------------------
  92. CAudioMixer *CreateWaveMixer( CWaveData *data, int format, int channels, int bits )
  93. {
  94. if ( format == WAVE_FORMAT_PCM )
  95. {
  96. if ( channels > 1 )
  97. {
  98. if ( bits == 8 )
  99. return new CAudioMixerWave8Stereo( data );
  100. else
  101. return new CAudioMixerWave16Stereo( data );
  102. }
  103. else
  104. {
  105. if ( bits == 8 )
  106. return new CAudioMixerWave8Mono( data );
  107. else
  108. return new CAudioMixerWave16Mono( data );
  109. }
  110. }
  111. else if ( format == WAVE_FORMAT_ADPCM )
  112. {
  113. return CreateADPCMMixer( data );
  114. }
  115. return NULL;
  116. }
  117. #include "hlfaceposer.h"
  118. //-----------------------------------------------------------------------------
  119. // Purpose: Init the base WAVE mixer.
  120. // Input : *data - data access object
  121. //-----------------------------------------------------------------------------
  122. CAudioMixerWave::CAudioMixerWave( CWaveData *data ) : m_pData(data), m_pChannel(NULL)
  123. {
  124. m_loop = 0;
  125. m_sample = 0;
  126. m_absoluteSample = 0;
  127. m_scrubSample = -1;
  128. m_fracOffset = 0;
  129. m_bActive = false;
  130. m_nModelIndex = -1;
  131. m_bForward = true;
  132. m_bAutoDelete = true;
  133. m_pChannel = new channel_t;
  134. m_pChannel->leftvol = 127;
  135. m_pChannel->rightvol = 127;
  136. m_pChannel->pitch = 1.0;
  137. }
  138. //-----------------------------------------------------------------------------
  139. // Purpose: Frees the data access object (we own it after construction)
  140. //-----------------------------------------------------------------------------
  141. CAudioMixerWave::~CAudioMixerWave( void )
  142. {
  143. delete m_pData;
  144. delete m_pChannel;
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Purpose: Decode and read the data
  148. // by default we just pass the request on to the data access object
  149. // other mixers may need to buffer or decode the data for some reason
  150. //
  151. // Input : **pData - dest pointer
  152. // sampleCount - number of samples needed
  153. // Output : number of samples available in this batch
  154. //-----------------------------------------------------------------------------
  155. int CAudioMixerWave::GetOutputData( void **pData, int samplePosition, int sampleCount, bool forward /*= true*/ )
  156. {
  157. if ( samplePosition != m_sample )
  158. {
  159. // Seek
  160. m_sample = samplePosition;
  161. m_absoluteSample = samplePosition;
  162. }
  163. return m_pData->ReadSourceData( pData, m_sample, sampleCount, forward );
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose: calls through the wavedata to get the audio source
  167. // Output : CAudioSource
  168. //-----------------------------------------------------------------------------
  169. CAudioSource *CAudioMixerWave::GetSource( void )
  170. {
  171. if ( m_pData )
  172. return &m_pData->Source();
  173. return NULL;
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Purpose: Gets the current sample location in playback
  177. // Output : int (samples from start of wave)
  178. //-----------------------------------------------------------------------------
  179. int CAudioMixerWave::GetSamplePosition( void )
  180. {
  181. return m_sample;
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose: Gets the current sample location in playback
  185. // Output : int (samples from start of wave)
  186. //-----------------------------------------------------------------------------
  187. int CAudioMixerWave::GetScrubPosition( void )
  188. {
  189. if (m_scrubSample != -1)
  190. {
  191. return m_scrubSample;
  192. }
  193. return m_sample;
  194. }
  195. //-----------------------------------------------------------------------------
  196. // Purpose:
  197. // Input : position -
  198. //-----------------------------------------------------------------------------
  199. bool CAudioMixerWave::SetSamplePosition( int position, bool scrubbing )
  200. {
  201. position = max( 0, position );
  202. m_sample = position;
  203. m_absoluteSample = position;
  204. m_startpos = m_sample;
  205. if (scrubbing)
  206. {
  207. m_scrubSample = position;
  208. }
  209. else
  210. {
  211. m_scrubSample = -1;
  212. }
  213. return true;
  214. }
  215. //-----------------------------------------------------------------------------
  216. // Purpose:
  217. // Input : position -
  218. //-----------------------------------------------------------------------------
  219. void CAudioMixerWave::SetLoopPosition( int position )
  220. {
  221. m_loop = position;
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose:
  225. // Output : int
  226. //-----------------------------------------------------------------------------
  227. int CAudioMixerWave::GetStartPosition( void )
  228. {
  229. return m_startpos;
  230. }
  231. bool CAudioMixerWave::GetActive( void )
  232. {
  233. return m_bActive;
  234. }
  235. void CAudioMixerWave::SetActive( bool active )
  236. {
  237. m_bActive = active;
  238. }
  239. void CAudioMixerWave::SetModelIndex( int index )
  240. {
  241. m_nModelIndex = index;
  242. }
  243. int CAudioMixerWave::GetModelIndex( void ) const
  244. {
  245. return m_nModelIndex;
  246. }
  247. void CAudioMixerWave::SetDirection( bool forward )
  248. {
  249. m_bForward = forward;
  250. }
  251. bool CAudioMixerWave::GetDirection( void ) const
  252. {
  253. return m_bForward;
  254. }
  255. void CAudioMixerWave::SetAutoDelete( bool autodelete )
  256. {
  257. m_bAutoDelete = autodelete;
  258. }
  259. bool CAudioMixerWave::GetAutoDelete( void ) const
  260. {
  261. return m_bAutoDelete;
  262. }
  263. void CAudioMixerWave::SetVolume( float volume )
  264. {
  265. int ivolume = (int)( clamp( volume, 0.0f, 1.0f ) * 127.0f );
  266. m_pChannel->leftvol = ivolume;
  267. m_pChannel->rightvol = ivolume;
  268. }
  269. channel_t *CAudioMixerWave::GetChannel()
  270. {
  271. Assert( m_pChannel );
  272. return m_pChannel;
  273. }
  274. //-----------------------------------------------------------------------------
  275. // Purpose:
  276. // Input : *pChannel -
  277. // sampleCount -
  278. // outputRate -
  279. //-----------------------------------------------------------------------------
  280. void CAudioMixerWave::IncrementSamples( channel_t *pChannel, int startSample, int sampleCount,int outputRate, bool forward /*= true*/ )
  281. {
  282. int inputSampleRate = (int)(pChannel->pitch * m_pData->Source().SampleRate());
  283. float rate = (float)inputSampleRate / outputRate;
  284. int startpos = startSample;
  285. if ( !forward )
  286. {
  287. int requestedstart = startSample - (int)( sampleCount * rate );
  288. if ( requestedstart < 0 )
  289. return;
  290. startpos = max( 0, requestedstart );
  291. SetSamplePosition( startpos );
  292. }
  293. while ( sampleCount > 0 )
  294. {
  295. int inputSampleCount;
  296. int outputSampleCount = sampleCount;
  297. if ( outputRate != inputSampleRate )
  298. {
  299. inputSampleCount = (int)(sampleCount * rate);
  300. }
  301. else
  302. {
  303. inputSampleCount = sampleCount;
  304. }
  305. sampleCount -= outputSampleCount;
  306. if ( forward )
  307. {
  308. m_sample += inputSampleCount;
  309. m_absoluteSample += inputSampleCount;
  310. }
  311. }
  312. }
  313. //-----------------------------------------------------------------------------
  314. // Purpose: The device calls this to request data. The mixer must provide the
  315. // full amount of samples or have silence in its output stream.
  316. // Input : *pDevice - requesting device
  317. // sampleCount - number of samples at the output rate
  318. // outputRate - sampling rate of the request
  319. // Output : Returns true to keep mixing, false to delete this mixer
  320. //-----------------------------------------------------------------------------
  321. bool CAudioMixerWave::SkipSamples( channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward /*= true*/ )
  322. {
  323. int offset = 0;
  324. int inputSampleRate = (int)(pChannel->pitch * m_pData->Source().SampleRate());
  325. float rate = (float)inputSampleRate / outputRate;
  326. sampleCount = min( sampleCount, PAINTBUFFER_SIZE );
  327. int startpos = startSample;
  328. if ( !forward )
  329. {
  330. int requestedstart = startSample - (int)( sampleCount * rate );
  331. if ( requestedstart < 0 )
  332. return false;
  333. startpos = max( 0, requestedstart );
  334. SetSamplePosition( startpos );
  335. }
  336. while ( sampleCount > 0 )
  337. {
  338. int availableSamples;
  339. int inputSampleCount;
  340. char *pData = NULL;
  341. int outputSampleCount = sampleCount;
  342. if ( outputRate != inputSampleRate )
  343. {
  344. inputSampleCount = (int)(sampleCount * rate);
  345. if ( !forward )
  346. {
  347. startSample = max( 0, startSample - inputSampleCount );
  348. }
  349. int availableSamples = GetOutputData( (void **)&pData, startSample, inputSampleCount, forward );
  350. if ( !availableSamples )
  351. break;
  352. if ( availableSamples < inputSampleCount )
  353. {
  354. outputSampleCount = (int)(availableSamples / rate);
  355. inputSampleCount = availableSamples;
  356. }
  357. // compute new fraction part of sample index
  358. float offset = (m_fracOffset / FIX_SCALE) + (rate * outputSampleCount);
  359. offset = offset - (float)((int)offset);
  360. m_fracOffset = FIX_FLOAT(offset);
  361. }
  362. else
  363. {
  364. if ( !forward )
  365. {
  366. startSample = max( 0, startSample - sampleCount );
  367. }
  368. availableSamples = GetOutputData( (void **)&pData, startSample, sampleCount, forward );
  369. if ( !availableSamples )
  370. break;
  371. outputSampleCount = availableSamples;
  372. inputSampleCount = availableSamples;
  373. }
  374. offset += outputSampleCount;
  375. sampleCount -= outputSampleCount;
  376. if ( forward )
  377. {
  378. m_sample += inputSampleCount;
  379. m_absoluteSample += inputSampleCount;
  380. }
  381. if ( m_loop != 0 && m_sample >= m_loop )
  382. {
  383. SetSamplePosition( m_startpos );
  384. }
  385. }
  386. if ( sampleCount > 0 )
  387. return false;
  388. return true;
  389. }
  390. //-----------------------------------------------------------------------------
  391. // Purpose: The device calls this to request data. The mixer must provide the
  392. // full amount of samples or have silence in its output stream.
  393. // Input : *pDevice - requesting device
  394. // sampleCount - number of samples at the output rate
  395. // outputRate - sampling rate of the request
  396. // Output : Returns true to keep mixing, false to delete this mixer
  397. //-----------------------------------------------------------------------------
  398. bool CAudioMixerWave::MixDataToDevice( IAudioDevice *pDevice, channel_t *pChannel, int startSample, int sampleCount, int outputRate, bool forward /*= true*/ )
  399. {
  400. int offset = 0;
  401. int inputSampleRate = (int)(pChannel->pitch * m_pData->Source().SampleRate());
  402. float rate = (float)inputSampleRate / outputRate;
  403. fixedint fracstep = FIX_FLOAT( rate );
  404. sampleCount = min( sampleCount, PAINTBUFFER_SIZE );
  405. int startpos = startSample;
  406. if ( !forward )
  407. {
  408. int requestedstart = startSample - (int)( sampleCount * rate );
  409. if ( requestedstart < 0 )
  410. return false;
  411. startpos = max( 0, requestedstart );
  412. SetSamplePosition( startpos );
  413. }
  414. while ( sampleCount > 0 )
  415. {
  416. int availableSamples;
  417. int inputSampleCount;
  418. char *pData = NULL;
  419. int outputSampleCount = sampleCount;
  420. if ( outputRate != inputSampleRate )
  421. {
  422. inputSampleCount = (int)(sampleCount * rate);
  423. int availableSamples = GetOutputData( (void **)&pData, startpos, inputSampleCount, forward );
  424. if ( !availableSamples )
  425. break;
  426. if ( availableSamples < inputSampleCount )
  427. {
  428. outputSampleCount = (int)(availableSamples / rate);
  429. inputSampleCount = availableSamples;
  430. }
  431. Mix( pDevice, pChannel, pData, offset, m_fracOffset, fracstep, outputSampleCount, 0, forward );
  432. // compute new fraction part of sample index
  433. float offset = (m_fracOffset / FIX_SCALE) + (rate * outputSampleCount);
  434. offset = offset - (float)((int)offset);
  435. m_fracOffset = FIX_FLOAT(offset);
  436. }
  437. else
  438. {
  439. availableSamples = GetOutputData( (void **)&pData, startpos, sampleCount, forward );
  440. if ( !availableSamples )
  441. break;
  442. outputSampleCount = availableSamples;
  443. inputSampleCount = availableSamples;
  444. Mix( pDevice, pChannel, pData, offset, m_fracOffset, FIX(1), outputSampleCount, 0, forward );
  445. }
  446. offset += outputSampleCount;
  447. sampleCount -= outputSampleCount;
  448. if ( forward )
  449. {
  450. m_sample += inputSampleCount;
  451. m_absoluteSample += inputSampleCount;
  452. }
  453. if ( m_loop != 0 && m_sample >= m_loop )
  454. {
  455. SetSamplePosition( m_startpos );
  456. }
  457. }
  458. if ( sampleCount > 0 )
  459. return false;
  460. return true;
  461. }