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.

694 lines
15 KiB

  1. //========= Copyright 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 <stdio.h>
  14. #include <math.h>
  15. #include "snd_audio_source.h"
  16. #include "AudioWaveOutput.h"
  17. #include "ifaceposersound.h"
  18. #include "utlvector.h"
  19. #include "filesystem.h"
  20. #include "sentence.h"
  21. typedef struct channel_s
  22. {
  23. int leftvol;
  24. int rightvol;
  25. int rleftvol;
  26. int rrightvol;
  27. float pitch;
  28. } channel_t;
  29. #define WAVE_FORMAT_STEREO (WAVE_FORMAT_1S08|WAVE_FORMAT_1S16|WAVE_FORMAT_2S08|WAVE_FORMAT_2S16|WAVE_FORMAT_4S08|WAVE_FORMAT_4S16)
  30. #define WAVE_FORMATS_UNDERSTOOD (0xFFF)
  31. #define WAVE_FORMAT_11K (WAVE_FORMAT_1M08|WAVE_FORMAT_1M16)
  32. #define WAVE_FORMAT_22K (WAVE_FORMAT_2M08|WAVE_FORMAT_2M16)
  33. #define WAVE_FORMAT_44K (WAVE_FORMAT_4M08|WAVE_FORMAT_4M16)
  34. void CAudioDeviceSWMix::Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  35. {
  36. int sampleIndex = 0;
  37. fixedint sampleFrac = inputOffset;
  38. int fixup = 0;
  39. int fixupstep = 1;
  40. if ( !forward )
  41. {
  42. fixup = outCount - 1;
  43. fixupstep = -1;
  44. }
  45. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  46. {
  47. int dest = max( outputOffset + fixup, 0 );
  48. m_paintbuffer[ dest ].left += pChannel->leftvol * pData[sampleIndex];
  49. m_paintbuffer[ dest ].right += pChannel->rightvol * pData[sampleIndex];
  50. sampleFrac += rateScaleFix;
  51. sampleIndex += FIX_INTPART(sampleFrac);
  52. sampleFrac = FIX_FRACPART(sampleFrac);
  53. }
  54. }
  55. void CAudioDeviceSWMix::Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  56. {
  57. int sampleIndex = 0;
  58. fixedint sampleFrac = inputOffset;
  59. int fixup = 0;
  60. int fixupstep = 1;
  61. if ( !forward )
  62. {
  63. fixup = outCount - 1;
  64. fixupstep = -1;
  65. }
  66. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  67. {
  68. int dest = max( outputOffset + fixup, 0 );
  69. m_paintbuffer[ dest ].left += pChannel->leftvol * pData[sampleIndex];
  70. m_paintbuffer[ dest ].right += pChannel->rightvol * pData[sampleIndex+1];
  71. sampleFrac += rateScaleFix;
  72. sampleIndex += FIX_INTPART(sampleFrac)<<1;
  73. sampleFrac = FIX_FRACPART(sampleFrac);
  74. }
  75. }
  76. void CAudioDeviceSWMix::Mix16Mono( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  77. {
  78. int sampleIndex = 0;
  79. fixedint sampleFrac = inputOffset;
  80. int fixup = 0;
  81. int fixupstep = 1;
  82. if ( !forward )
  83. {
  84. fixup = outCount - 1;
  85. fixupstep = -1;
  86. }
  87. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  88. {
  89. int dest = max( outputOffset + fixup, 0 );
  90. m_paintbuffer[ dest ].left += (pChannel->leftvol * pData[sampleIndex])>>8;
  91. m_paintbuffer[ dest ].right += (pChannel->rightvol * pData[sampleIndex])>>8;
  92. sampleFrac += rateScaleFix;
  93. sampleIndex += FIX_INTPART(sampleFrac);
  94. sampleFrac = FIX_FRACPART(sampleFrac);
  95. }
  96. }
  97. void CAudioDeviceSWMix::Mix16Stereo( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  98. {
  99. int sampleIndex = 0;
  100. fixedint sampleFrac = inputOffset;
  101. int fixup = 0;
  102. int fixupstep = 1;
  103. if ( !forward )
  104. {
  105. fixup = outCount - 1;
  106. fixupstep = -1;
  107. }
  108. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  109. {
  110. int dest = max( outputOffset + fixup, 0 );
  111. m_paintbuffer[ dest ].left += (pChannel->leftvol * pData[sampleIndex])>>8;
  112. m_paintbuffer[ dest ].right += (pChannel->rightvol * pData[sampleIndex+1])>>8;
  113. sampleFrac += rateScaleFix;
  114. sampleIndex += FIX_INTPART(sampleFrac)<<1;
  115. sampleFrac = FIX_FRACPART(sampleFrac);
  116. }
  117. }
  118. int CAudioDeviceSWMix::MaxSampleCount( void )
  119. {
  120. return PAINTBUFFER_SIZE;
  121. }
  122. void CAudioDeviceSWMix::MixBegin( void )
  123. {
  124. memset( m_paintbuffer, 0, sizeof(m_paintbuffer) );
  125. }
  126. void CAudioDeviceSWMix::TransferBufferStereo16( short *pOutput, int sampleCount )
  127. {
  128. for ( int i = 0; i < sampleCount; i++ )
  129. {
  130. if ( m_paintbuffer[i].left > 32767 )
  131. m_paintbuffer[i].left = 32767;
  132. else if ( m_paintbuffer[i].left < -32768 )
  133. m_paintbuffer[i].left = -32768;
  134. if ( m_paintbuffer[i].right > 32767 )
  135. m_paintbuffer[i].right = 32767;
  136. else if ( m_paintbuffer[i].right < -32768 )
  137. m_paintbuffer[i].right = -32768;
  138. *pOutput++ = (short)m_paintbuffer[i].left;
  139. *pOutput++ = (short)m_paintbuffer[i].right;
  140. }
  141. }
  142. CAudioWaveOutput::CAudioWaveOutput( void )
  143. {
  144. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  145. {
  146. CAudioBuffer *buffer = &m_buffers[ i ];
  147. Assert( buffer );
  148. buffer->hdr = NULL;
  149. buffer->submitted = false;
  150. buffer->submit_sample_count = false;
  151. }
  152. ClearDevice();
  153. OpenDevice();
  154. m_mixTime = -1;
  155. m_sampleIndex = 0;
  156. memset( m_sourceList, 0, sizeof(m_sourceList) );
  157. m_nEstimatedSamplesAhead = (int)( ( float ) OUTPUT_SAMPLE_RATE / 10.0f );
  158. }
  159. void CAudioWaveOutput::RemoveMixerChannelReferences( CAudioMixer *mixer )
  160. {
  161. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  162. {
  163. RemoveFromReferencedList( mixer, &m_buffers[ i ] );
  164. }
  165. }
  166. void CAudioWaveOutput::AddToReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer )
  167. {
  168. // Already in list
  169. for ( int i = 0; i < buffer->m_Referenced.Size(); i++ )
  170. {
  171. if ( buffer->m_Referenced[ i ].mixer == mixer )
  172. {
  173. return;
  174. }
  175. }
  176. // Just remove it
  177. int idx = buffer->m_Referenced.AddToTail();
  178. CAudioMixerState *state = &buffer->m_Referenced[ idx ];
  179. state->mixer = mixer;
  180. state->submit_mixer_sample = mixer->GetSamplePosition();
  181. }
  182. void CAudioWaveOutput::RemoveFromReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer )
  183. {
  184. for ( int i = 0; i < buffer->m_Referenced.Size(); i++ )
  185. {
  186. if ( buffer->m_Referenced[ i ].mixer == mixer )
  187. {
  188. buffer->m_Referenced.Remove( i );
  189. break;
  190. }
  191. }
  192. }
  193. bool CAudioWaveOutput::IsSoundInReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer )
  194. {
  195. for ( int i = 0; i < buffer->m_Referenced.Size(); i++ )
  196. {
  197. if ( buffer->m_Referenced[ i ].mixer == mixer )
  198. {
  199. return true;
  200. }
  201. }
  202. return false;
  203. }
  204. bool CAudioWaveOutput::IsSourceReferencedByActiveBuffer( CAudioMixer *mixer )
  205. {
  206. if ( !ValidDevice() )
  207. return false;
  208. CAudioBuffer *buffer;
  209. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  210. {
  211. buffer = &m_buffers[ i ];
  212. if ( !buffer->submitted )
  213. continue;
  214. if ( buffer->hdr->dwFlags & WHDR_DONE )
  215. continue;
  216. // See if it's referenced
  217. if ( IsSoundInReferencedList( mixer, buffer ) )
  218. return true;
  219. }
  220. return false;
  221. }
  222. CAudioWaveOutput::~CAudioWaveOutput( void )
  223. {
  224. if ( ValidDevice() )
  225. {
  226. waveOutReset( m_deviceHandle );
  227. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  228. {
  229. if ( m_buffers[i].hdr )
  230. {
  231. waveOutUnprepareHeader( m_deviceHandle, m_buffers[i].hdr, sizeof(*m_buffers[i].hdr) );
  232. delete[] m_buffers[i].hdr->lpData;
  233. delete m_buffers[i].hdr;
  234. }
  235. m_buffers[i].hdr = NULL;
  236. m_buffers[i].submitted = false;
  237. m_buffers[i].submit_sample_count = 0;
  238. m_buffers[i].m_Referenced.Purge();
  239. }
  240. waveOutClose( m_deviceHandle );
  241. ClearDevice();
  242. }
  243. }
  244. CAudioBuffer *CAudioWaveOutput::GetEmptyBuffer( void )
  245. {
  246. CAudioBuffer *pOutput = NULL;
  247. if ( ValidDevice() )
  248. {
  249. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  250. {
  251. if ( !(m_buffers[ i ].submitted ) ||
  252. m_buffers[i].hdr->dwFlags & WHDR_DONE )
  253. {
  254. pOutput = &m_buffers[i];
  255. pOutput->submitted = true;
  256. pOutput->m_Referenced.Purge();
  257. break;
  258. }
  259. }
  260. }
  261. return pOutput;
  262. }
  263. void CAudioWaveOutput::SilenceBuffer( short *pSamples, int sampleCount )
  264. {
  265. int i;
  266. for ( i = 0; i < sampleCount; i++ )
  267. {
  268. // left
  269. *pSamples++ = 0;
  270. // right
  271. *pSamples++ = 0;
  272. }
  273. }
  274. void CAudioWaveOutput::Flush( void )
  275. {
  276. waveOutReset( m_deviceHandle );
  277. }
  278. // mix a buffer up to time (time is absolute)
  279. void CAudioWaveOutput::Update( float time )
  280. {
  281. }
  282. int CAudioWaveOutput::GetNumberofSamplesAhead( void )
  283. {
  284. ComputeSampleAheadAmount();
  285. return m_nEstimatedSamplesAhead;
  286. }
  287. float CAudioWaveOutput::GetAmountofTimeAhead( void )
  288. {
  289. ComputeSampleAheadAmount();
  290. return ( (float)m_nEstimatedSamplesAhead / (float)OUTPUT_SAMPLE_RATE );
  291. }
  292. // Find the most recent submitted sample that isn't flagged as whdr_done
  293. void CAudioWaveOutput::ComputeSampleAheadAmount( void )
  294. {
  295. m_nEstimatedSamplesAhead = 0;
  296. int newest_sample_index = -1;
  297. int newest_sample_count = 0;
  298. CAudioBuffer *buffer;
  299. if ( ValidDevice() )
  300. {
  301. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  302. {
  303. buffer = &m_buffers[ i ];
  304. if ( !buffer->submitted )
  305. continue;
  306. if ( buffer->hdr->dwFlags & WHDR_DONE )
  307. continue;
  308. if ( buffer->submit_sample_count > newest_sample_count )
  309. {
  310. newest_sample_index = i;
  311. newest_sample_count = buffer->submit_sample_count;
  312. }
  313. }
  314. }
  315. if ( newest_sample_index == -1 )
  316. return;
  317. buffer = &m_buffers[ newest_sample_index ];
  318. int currentPos = GetOutputPosition() ;
  319. m_nEstimatedSamplesAhead = currentPos - buffer->submit_sample_count;
  320. }
  321. int CAudioWaveOutput::FindSourceIndex( CAudioMixer *pSource )
  322. {
  323. for ( int i = 0; i < MAX_CHANNELS; i++ )
  324. {
  325. if ( pSource == m_sourceList[i] )
  326. {
  327. return i;
  328. }
  329. }
  330. return -1;
  331. }
  332. CAudioMixer *CAudioWaveOutput::GetMixerForSource( CAudioSource *source )
  333. {
  334. for ( int i = 0; i < MAX_CHANNELS; i++ )
  335. {
  336. if ( !m_sourceList[i] )
  337. continue;
  338. if ( source == m_sourceList[i]->GetSource() )
  339. {
  340. return m_sourceList[i];
  341. }
  342. }
  343. return NULL;
  344. }
  345. void CAudioWaveOutput::AddSource( CAudioMixer *pSource )
  346. {
  347. int slot = 0;
  348. for ( int i = 0; i < MAX_CHANNELS; i++ )
  349. {
  350. if ( !m_sourceList[i] )
  351. {
  352. slot = i;
  353. break;
  354. }
  355. }
  356. if ( m_sourceList[slot] )
  357. {
  358. FreeChannel( slot );
  359. }
  360. SetChannel( slot, pSource );
  361. pSource->SetActive( true );
  362. }
  363. void CAudioWaveOutput::StopSounds( void )
  364. {
  365. for ( int i = 0; i < MAX_CHANNELS; i++ )
  366. {
  367. if ( m_sourceList[i] )
  368. {
  369. FreeChannel( i );
  370. }
  371. }
  372. }
  373. void CAudioWaveOutput::SetChannel( int channelIndex, CAudioMixer *pSource )
  374. {
  375. if ( channelIndex < 0 || channelIndex >= MAX_CHANNELS )
  376. return;
  377. m_sourceList[channelIndex] = pSource;
  378. }
  379. void CAudioWaveOutput::FreeChannel( int channelIndex )
  380. {
  381. if ( channelIndex < 0 || channelIndex >= MAX_CHANNELS )
  382. return;
  383. if ( m_sourceList[channelIndex] )
  384. {
  385. RemoveMixerChannelReferences( m_sourceList[channelIndex] );
  386. delete m_sourceList[channelIndex];
  387. m_sourceList[channelIndex] = NULL;
  388. }
  389. }
  390. int CAudioWaveOutput::GetOutputPosition( void )
  391. {
  392. if ( !m_deviceHandle )
  393. return 0;
  394. MMTIME mmtime;
  395. mmtime.wType = TIME_SAMPLES;
  396. waveOutGetPosition( m_deviceHandle, &mmtime, sizeof( MMTIME ) );
  397. // Convert time to sample count
  398. return ( mmtime.u.sample );
  399. }
  400. void CAudioWaveOutput::OpenDevice( void )
  401. {
  402. WAVEFORMATEX waveFormat;
  403. memset( &waveFormat, 0, sizeof(waveFormat) );
  404. // Select a PCM, 16-bit stereo playback device
  405. waveFormat.cbSize = sizeof(waveFormat);
  406. waveFormat.nAvgBytesPerSec = OUTPUT_SAMPLE_RATE * 2 * 2;
  407. waveFormat.nBlockAlign = 2 * 2; // channels * sample size
  408. waveFormat.nChannels = 2; // stereo
  409. waveFormat.nSamplesPerSec = OUTPUT_SAMPLE_RATE;
  410. waveFormat.wBitsPerSample = 16;
  411. waveFormat.wFormatTag = WAVE_FORMAT_PCM;
  412. MMRESULT errorCode = waveOutOpen( &m_deviceHandle, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL );
  413. if ( errorCode == MMSYSERR_NOERROR )
  414. {
  415. int bufferSize = 4 * ( OUTPUT_SAMPLE_RATE / OUTPUT_BUFFER_COUNT ); // total of 1 second of data
  416. // Got one!
  417. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  418. {
  419. m_buffers[i].hdr = new WAVEHDR;
  420. m_buffers[i].hdr->lpData = new char[ bufferSize ];
  421. long align = (long)m_buffers[i].hdr->lpData;
  422. if ( align & 3 )
  423. {
  424. m_buffers[i].hdr->lpData = (char *) ( (align+3) &~3 );
  425. }
  426. m_buffers[i].hdr->dwBufferLength = bufferSize - (align&3);
  427. m_buffers[i].hdr->dwFlags = 0;
  428. if ( waveOutPrepareHeader( m_deviceHandle, m_buffers[i].hdr, sizeof(*m_buffers[i].hdr) ) != MMSYSERR_NOERROR )
  429. {
  430. ClearDevice();
  431. return;
  432. }
  433. }
  434. }
  435. else
  436. {
  437. ClearDevice();
  438. }
  439. }
  440. // factory to create a suitable audio output for this system
  441. CAudioOutput *CAudioOutput::Create( void )
  442. {
  443. // sound device is a singleton for now
  444. static CAudioOutput *pWaveOut = NULL;
  445. if ( !pWaveOut )
  446. {
  447. pWaveOut = new CAudioWaveOutput;
  448. }
  449. return pWaveOut;
  450. }
  451. struct CSoundFile
  452. {
  453. char filename[ 512 ];
  454. CAudioSource *source;
  455. long filetime;
  456. };
  457. //-----------------------------------------------------------------------------
  458. // Purpose:
  459. //-----------------------------------------------------------------------------
  460. class CFacePoserSound : public IFacePoserSound
  461. {
  462. public:
  463. CFacePoserSound();
  464. ~CFacePoserSound( void );
  465. void Init( void );
  466. void Shutdown( void );
  467. void Update( float dt );
  468. void Flush( void );
  469. CAudioSource *LoadSound( const char *wavfile );
  470. void PlaySound( StudioModel *source, float volume, const char *wavfile, CAudioMixer **ppMixer );
  471. void PlaySound( CAudioSource *source, float volume, CAudioMixer **ppMixer );
  472. void PlayPartialSound( StudioModel *model, float volume, const char *wavfile, CAudioMixer **ppMixer, int startSample, int endSample );
  473. bool IsSoundPlaying( CAudioMixer *pMixer );
  474. CAudioMixer *FindMixer( CAudioSource *source );
  475. void StopAll( void );
  476. void StopSound( CAudioMixer *mixer );
  477. void RenderWavToDC( HDC dc, RECT& outrect, COLORREF clr, float starttime, float endtime,
  478. CAudioSource *pWave, bool selected = false, int selectionstart = 0, int selectionend = 0 );
  479. // void InstallPhonemecallback( IPhonemeTag *pTagInterface );
  480. float GetAmountofTimeAhead( void );
  481. int GetNumberofSamplesAhead( void );
  482. CAudioOuput *GetAudioOutput( void );
  483. virtual void EnsureNoModelReferences( CAudioSource *source );
  484. private:
  485. CAudioOutput *m_pAudio;
  486. };
  487. static CFacePoserSound g_FacePoserSound;
  488. IFacePoserSound *sound = ( IFacePoserSound * )&g_FacePoserSound;
  489. CFacePoserSound::CFacePoserSound() :
  490. m_pAudio( 0 )
  491. {
  492. }
  493. CFacePoserSound::~CFacePoserSound( void )
  494. {
  495. }
  496. //-----------------------------------------------------------------------------
  497. // Purpose:
  498. //-----------------------------------------------------------------------------
  499. CAudioOuput *CFacePoserSound::GetAudioOutput( void )
  500. {
  501. return (CAudioOuput *)m_pAudio;
  502. }
  503. void CFacePoserSound::Init( void )
  504. {
  505. m_pAudio = CAudioOutput::Create();
  506. }
  507. void CFacePoserSound::Shutdown( void )
  508. {
  509. delete m_pAudio;
  510. }
  511. float CFacePoserSound::GetAmountofTimeAhead( void )
  512. {
  513. return 0.0f;
  514. }
  515. int CFacePoserSound::GetNumberofSamplesAhead( void )
  516. {
  517. return 0;
  518. }
  519. CAudioSource *CFacePoserSound::LoadSound( const char *wavfile )
  520. {
  521. if ( !m_pAudio )
  522. return NULL;
  523. CAudioSource *wave = AudioSource_Create( wavfile );
  524. return wave;
  525. }
  526. void CFacePoserSound::PlaySound( StudioModel *model, float volume, const char *wavfile, CAudioMixer **ppMixer )
  527. {
  528. }
  529. void CFacePoserSound::PlayPartialSound( StudioModel *model, float volume, const char *wavfile, CAudioMixer **ppMixer, int startSample, int endSample )
  530. {
  531. }
  532. void CFacePoserSound::PlaySound( CAudioSource *source, float volume, CAudioMixer **ppMixer )
  533. {
  534. }
  535. void CFacePoserSound::Update( float dt )
  536. {
  537. }
  538. void CFacePoserSound::Flush( void )
  539. {
  540. }
  541. void CFacePoserSound::StopAll( void )
  542. {
  543. }
  544. void CFacePoserSound::StopSound( CAudioMixer *mixer )
  545. {
  546. }
  547. void CFacePoserSound::RenderWavToDC( HDC dc, RECT& outrect, COLORREF clr,
  548. float starttime, float endtime, CAudioSource *pWave,
  549. bool selected /*= false*/, int selectionstart /*= 0*/, int selectionend /*= 0*/ )
  550. {
  551. }
  552. bool CFacePoserSound::IsSoundPlaying( CAudioMixer *pMixer )
  553. {
  554. return false;
  555. }
  556. CAudioMixer *CFacePoserSound::FindMixer( CAudioSource *source )
  557. {
  558. return NULL;
  559. }
  560. void CFacePoserSound::EnsureNoModelReferences( CAudioSource *source )
  561. {
  562. }