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.

1781 lines
40 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. #include <stdio.h>
  13. #include <math.h>
  14. #include "color.h"
  15. #include "snd_audio_source.h"
  16. #include "AudioWaveOutput.h"
  17. #include "ifaceposersound.h"
  18. #include "StudioModel.h"
  19. #include "hlfaceposer.h"
  20. #include "expressions.h"
  21. #include "expclass.h"
  22. #include "PhonemeConverter.h"
  23. #include "utlvector.h"
  24. #include "FileSystem.h"
  25. #include "sentence.h"
  26. #include "faceposer_models.h"
  27. #include "iclosecaptionmanager.h"
  28. #include "phonemeeditor.h"
  29. #include "wavebrowser.h"
  30. #include "choreoscene.h"
  31. #include "choreoview.h"
  32. typedef struct channel_s
  33. {
  34. int leftvol;
  35. int rightvol;
  36. int rleftvol;
  37. int rrightvol;
  38. float pitch;
  39. } channel_t;
  40. #define INPUT_BUFFER_COUNT 32
  41. class CAudioWaveInput : public CAudioInput
  42. {
  43. public:
  44. CAudioWaveInput( void );
  45. ~CAudioWaveInput( void );
  46. // Returns the current count of available samples
  47. int SampleCount( void );
  48. // returns the size of each sample in bytes
  49. int SampleSize( void ) { return m_sampleSize; }
  50. // returns the sampling rate of the data
  51. int SampleRate( void ) { return m_sampleRate; }
  52. // returns a pointer to the actual data
  53. void *SampleData( void );
  54. // release the available data (mark as done)
  55. void SampleRelease( void );
  56. // returns the mono/stereo status of this device (true if stereo)
  57. bool IsStereo( void ) { return m_isStereo; }
  58. // begin sampling
  59. void Start( void );
  60. // stop sampling
  61. void Stop( void );
  62. void WaveMessage( HWAVEIN hdevice, UINT uMsg, DWORD dwParam1, DWORD dwParam2 );
  63. private:
  64. void OpenDevice( void );
  65. bool ValidDevice( void ) { return m_deviceId != 0xFFFFFFFF; }
  66. void ClearDevice( void ) { m_deviceId = 0xFFFFFFFF; }
  67. // returns true if the new format is better
  68. bool BetterFormat( DWORD dwNewFormat, DWORD dwOldFormat );
  69. void InitReadyList( void );
  70. void AddToReadyList( WAVEHDR *pBuffer );
  71. void PopReadyList( void );
  72. WAVEHDR *m_pReadyList;
  73. int m_sampleSize;
  74. int m_sampleRate;
  75. bool m_isStereo;
  76. UINT m_deviceId;
  77. HWAVEIN m_deviceHandle;
  78. WAVEHDR *m_buffers[ INPUT_BUFFER_COUNT ];
  79. };
  80. extern "C" void CALLBACK WaveData( HWAVEIN hwi, UINT uMsg, CAudioWaveInput *pAudio, DWORD dwParam1, DWORD dwParam2 );
  81. CAudioWaveInput::CAudioWaveInput( void )
  82. {
  83. memset( m_buffers, 0, sizeof( m_buffers ) );
  84. int deviceCount = (int)waveInGetNumDevs();
  85. UINT deviceId = 0;
  86. DWORD deviceFormat = 0;
  87. int i;
  88. for ( i = 0; i < deviceCount; i++ )
  89. {
  90. WAVEINCAPS waveCaps;
  91. MMRESULT errorCode = waveInGetDevCaps( (UINT)i, &waveCaps, sizeof(waveCaps) );
  92. if ( errorCode == MMSYSERR_NOERROR )
  93. {
  94. // valid device
  95. if ( BetterFormat( waveCaps.dwFormats, deviceFormat ) )
  96. {
  97. deviceId = i;
  98. deviceFormat = waveCaps.dwFormats;
  99. }
  100. }
  101. }
  102. if ( !deviceFormat )
  103. {
  104. m_deviceId = 0xFFFFFFFF;
  105. m_sampleSize = 0;
  106. m_sampleRate = 0;
  107. m_isStereo = false;
  108. }
  109. else
  110. {
  111. m_deviceId = deviceId;
  112. m_sampleRate = 44100;
  113. m_isStereo = false;
  114. if ( deviceFormat & WAVE_FORMAT_4M16 )
  115. {
  116. m_sampleSize = 2;
  117. }
  118. else if ( deviceFormat & WAVE_FORMAT_4M08 )
  119. {
  120. m_sampleSize = 1;
  121. }
  122. else
  123. {
  124. // ERROR!
  125. }
  126. OpenDevice();
  127. }
  128. InitReadyList();
  129. }
  130. CAudioWaveInput::~CAudioWaveInput( void )
  131. {
  132. if ( ValidDevice() )
  133. {
  134. Stop();
  135. waveInReset( m_deviceHandle );
  136. waveInClose( m_deviceHandle );
  137. for ( int i = 0; i < INPUT_BUFFER_COUNT; i++ )
  138. {
  139. if ( m_buffers[i] )
  140. {
  141. waveInUnprepareHeader( m_deviceHandle, m_buffers[i], sizeof( *m_buffers[i] ) );
  142. delete[] m_buffers[i]->lpData;
  143. delete m_buffers[i];
  144. }
  145. m_buffers[i] = NULL;
  146. }
  147. ClearDevice();
  148. }
  149. }
  150. void CALLBACK WaveData( HWAVEIN hwi, UINT uMsg, CAudioWaveInput *pAudio, DWORD dwParam1, DWORD dwParam2 )
  151. {
  152. if ( pAudio )
  153. {
  154. pAudio->WaveMessage( hwi, uMsg, dwParam1, dwParam2 );
  155. }
  156. }
  157. void CAudioWaveInput::WaveMessage( HWAVEIN hdevice, UINT uMsg, DWORD dwParam1, DWORD dwParam2 )
  158. {
  159. if ( hdevice != m_deviceHandle )
  160. return;
  161. switch( uMsg )
  162. {
  163. case WIM_DATA:
  164. WAVEHDR *pHeader = (WAVEHDR *)dwParam1;
  165. AddToReadyList( pHeader );
  166. break;
  167. }
  168. }
  169. void CAudioWaveInput::OpenDevice( void )
  170. {
  171. if ( !ValidDevice() )
  172. return;
  173. WAVEFORMATEX format;
  174. memset( &format, 0, sizeof(format) );
  175. format.nAvgBytesPerSec = m_sampleRate * m_sampleSize;
  176. format.nChannels = 1;
  177. format.wBitsPerSample = m_sampleSize * 8;
  178. format.nSamplesPerSec = m_sampleRate;
  179. format.wFormatTag = WAVE_FORMAT_PCM;
  180. format.nBlockAlign = m_sampleSize;
  181. MMRESULT errorCode = waveInOpen( &m_deviceHandle, m_deviceId, &format, (DWORD)WaveData, (DWORD)this, CALLBACK_FUNCTION );
  182. if ( errorCode == MMSYSERR_NOERROR )
  183. {
  184. // valid device opened
  185. int bufferSize = m_sampleSize * m_sampleRate / INPUT_BUFFER_COUNT; // total of one second of data
  186. // allocate buffers
  187. for ( int i = 0; i < INPUT_BUFFER_COUNT; i++ )
  188. {
  189. m_buffers[i] = new WAVEHDR;
  190. m_buffers[i]->lpData = new char[ bufferSize ];
  191. m_buffers[i]->dwBufferLength = bufferSize;
  192. m_buffers[i]->dwUser = 0;
  193. m_buffers[i]->dwFlags = 0;
  194. waveInPrepareHeader( m_deviceHandle, m_buffers[i], sizeof( *m_buffers[i] ) );
  195. waveInAddBuffer( m_deviceHandle, m_buffers[i], sizeof( *m_buffers[i] ) );
  196. }
  197. }
  198. else
  199. {
  200. ClearDevice();
  201. }
  202. }
  203. void CAudioWaveInput::Start( void )
  204. {
  205. if ( !ValidDevice() )
  206. return;
  207. waveInStart( m_deviceHandle );
  208. }
  209. void CAudioWaveInput::Stop( void )
  210. {
  211. if ( !ValidDevice() )
  212. return;
  213. waveInStop( m_deviceHandle );
  214. }
  215. void CAudioWaveInput::InitReadyList( void )
  216. {
  217. m_pReadyList = NULL;
  218. }
  219. void CAudioWaveInput::AddToReadyList( WAVEHDR *pBuffer )
  220. {
  221. WAVEHDR **pList = &m_pReadyList;
  222. waveInUnprepareHeader( m_deviceHandle, pBuffer, sizeof(*pBuffer) );
  223. // insert at the tail of the list
  224. while ( *pList )
  225. {
  226. pList = reinterpret_cast<WAVEHDR **>(&((*pList)->dwUser));
  227. }
  228. pBuffer->dwUser = NULL;
  229. *pList = pBuffer;
  230. }
  231. void CAudioWaveInput::PopReadyList( void )
  232. {
  233. if ( m_pReadyList )
  234. {
  235. WAVEHDR *pBuffer = m_pReadyList;
  236. m_pReadyList = reinterpret_cast<WAVEHDR *>(m_pReadyList->dwUser);
  237. waveInPrepareHeader( m_deviceHandle, pBuffer, sizeof(*pBuffer) );
  238. waveInAddBuffer( m_deviceHandle, pBuffer, sizeof(*pBuffer) );
  239. }
  240. }
  241. #define WAVE_FORMAT_STEREO (WAVE_FORMAT_1S08|WAVE_FORMAT_1S16|WAVE_FORMAT_2S08|WAVE_FORMAT_2S16|WAVE_FORMAT_4S08|WAVE_FORMAT_4S16)
  242. #define WAVE_FORMATS_UNDERSTOOD (0xFFF)
  243. #define WAVE_FORMAT_11K (WAVE_FORMAT_1M08|WAVE_FORMAT_1M16)
  244. #define WAVE_FORMAT_22K (WAVE_FORMAT_2M08|WAVE_FORMAT_2M16)
  245. #define WAVE_FORMAT_44K (WAVE_FORMAT_4M08|WAVE_FORMAT_4M16)
  246. static int HighestBit( DWORD dwFlags )
  247. {
  248. int i = 31;
  249. while ( i )
  250. {
  251. if ( dwFlags & (1<<i) )
  252. return i;
  253. i--;
  254. }
  255. return 0;
  256. }
  257. bool CAudioWaveInput::BetterFormat( DWORD dwNewFormat, DWORD dwOldFormat )
  258. {
  259. dwNewFormat &= WAVE_FORMATS_UNDERSTOOD & (~WAVE_FORMAT_STEREO);
  260. dwOldFormat &= WAVE_FORMATS_UNDERSTOOD & (~WAVE_FORMAT_STEREO);
  261. // our target format is 44.1KHz, mono, 16-bit
  262. if ( HighestBit(dwOldFormat) >= HighestBit(dwNewFormat) )
  263. return false;
  264. return true;
  265. }
  266. int CAudioWaveInput::SampleCount( void )
  267. {
  268. if ( !ValidDevice() )
  269. return 0;
  270. if ( m_pReadyList )
  271. {
  272. switch( SampleSize() )
  273. {
  274. case 2:
  275. return m_pReadyList->dwBytesRecorded >> 1;
  276. case 1:
  277. return m_pReadyList->dwBytesRecorded;
  278. default:
  279. break;
  280. }
  281. }
  282. return 0;
  283. }
  284. void *CAudioWaveInput::SampleData( void )
  285. {
  286. if ( !ValidDevice() )
  287. return NULL;
  288. if ( m_pReadyList )
  289. {
  290. return m_pReadyList->lpData;
  291. }
  292. return NULL;
  293. }
  294. // release the available data (mark as done)
  295. void CAudioWaveInput::SampleRelease( void )
  296. {
  297. PopReadyList();
  298. }
  299. // factory to create a suitable audio input for this system
  300. CAudioInput *CAudioInput::Create( void )
  301. {
  302. // sound source is a singleton for now
  303. static CAudioInput *pSource = NULL;
  304. if ( !pSource )
  305. {
  306. pSource = new CAudioWaveInput;
  307. }
  308. return pSource;
  309. }
  310. void CAudioDeviceSWMix::Mix8Mono( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  311. {
  312. int sampleIndex = 0;
  313. fixedint sampleFrac = inputOffset;
  314. int fixup = 0;
  315. int fixupstep = 1;
  316. if ( !forward )
  317. {
  318. fixup = outCount - 1;
  319. fixupstep = -1;
  320. }
  321. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  322. {
  323. int dest = max( outputOffset + fixup, 0 );
  324. m_paintbuffer[ dest ].left += pChannel->leftvol * pData[sampleIndex];
  325. m_paintbuffer[ dest ].right += pChannel->rightvol * pData[sampleIndex];
  326. sampleFrac += rateScaleFix;
  327. sampleIndex += FIX_INTPART(sampleFrac);
  328. sampleFrac = FIX_FRACPART(sampleFrac);
  329. }
  330. }
  331. void CAudioDeviceSWMix::Mix8Stereo( channel_t *pChannel, char *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  332. {
  333. int sampleIndex = 0;
  334. fixedint sampleFrac = inputOffset;
  335. int fixup = 0;
  336. int fixupstep = 1;
  337. if ( !forward )
  338. {
  339. fixup = outCount - 1;
  340. fixupstep = -1;
  341. }
  342. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  343. {
  344. int dest = max( outputOffset + fixup, 0 );
  345. m_paintbuffer[ dest ].left += pChannel->leftvol * pData[sampleIndex];
  346. m_paintbuffer[ dest ].right += pChannel->rightvol * pData[sampleIndex+1];
  347. sampleFrac += rateScaleFix;
  348. sampleIndex += FIX_INTPART(sampleFrac)<<1;
  349. sampleFrac = FIX_FRACPART(sampleFrac);
  350. }
  351. }
  352. void CAudioDeviceSWMix::Mix16Mono( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  353. {
  354. int sampleIndex = 0;
  355. fixedint sampleFrac = inputOffset;
  356. int fixup = 0;
  357. int fixupstep = 1;
  358. if ( !forward )
  359. {
  360. fixup = outCount - 1;
  361. fixupstep = -1;
  362. }
  363. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  364. {
  365. int dest = max( outputOffset + fixup, 0 );
  366. m_paintbuffer[ dest ].left += (pChannel->leftvol * pData[sampleIndex])>>8;
  367. m_paintbuffer[ dest ].right += (pChannel->rightvol * pData[sampleIndex])>>8;
  368. sampleFrac += rateScaleFix;
  369. sampleIndex += FIX_INTPART(sampleFrac);
  370. sampleFrac = FIX_FRACPART(sampleFrac);
  371. }
  372. }
  373. void CAudioDeviceSWMix::Mix16Stereo( channel_t *pChannel, short *pData, int outputOffset, int inputOffset, int rateScaleFix, int outCount, int timecompress, bool forward )
  374. {
  375. int sampleIndex = 0;
  376. fixedint sampleFrac = inputOffset;
  377. int fixup = 0;
  378. int fixupstep = 1;
  379. if ( !forward )
  380. {
  381. fixup = outCount - 1;
  382. fixupstep = -1;
  383. }
  384. for ( int i = 0; i < outCount; i++, fixup += fixupstep )
  385. {
  386. int dest = max( outputOffset + fixup, 0 );
  387. m_paintbuffer[ dest ].left += (pChannel->leftvol * pData[sampleIndex])>>8;
  388. m_paintbuffer[ dest ].right += (pChannel->rightvol * pData[sampleIndex+1])>>8;
  389. sampleFrac += rateScaleFix;
  390. sampleIndex += FIX_INTPART(sampleFrac)<<1;
  391. sampleFrac = FIX_FRACPART(sampleFrac);
  392. }
  393. }
  394. int CAudioDeviceSWMix::MaxSampleCount( void )
  395. {
  396. return PAINTBUFFER_SIZE;
  397. }
  398. void CAudioDeviceSWMix::MixBegin( void )
  399. {
  400. memset( m_paintbuffer, 0, sizeof(m_paintbuffer) );
  401. }
  402. void CAudioDeviceSWMix::TransferBufferStereo16( short *pOutput, int sampleCount )
  403. {
  404. for ( int i = 0; i < sampleCount; i++ )
  405. {
  406. if ( m_paintbuffer[i].left > 32767 )
  407. m_paintbuffer[i].left = 32767;
  408. else if ( m_paintbuffer[i].left < -32768 )
  409. m_paintbuffer[i].left = -32768;
  410. if ( m_paintbuffer[i].right > 32767 )
  411. m_paintbuffer[i].right = 32767;
  412. else if ( m_paintbuffer[i].right < -32768 )
  413. m_paintbuffer[i].right = -32768;
  414. *pOutput++ = (short)m_paintbuffer[i].left;
  415. *pOutput++ = (short)m_paintbuffer[i].right;
  416. }
  417. }
  418. CAudioWaveOutput::CAudioWaveOutput( void )
  419. {
  420. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  421. {
  422. CAudioBuffer *buffer = &m_buffers[ i ];
  423. Assert( buffer );
  424. buffer->hdr = NULL;
  425. buffer->submitted = false;
  426. buffer->submit_sample_count = false;
  427. }
  428. ClearDevice();
  429. OpenDevice();
  430. m_mixTime = -1;
  431. m_sampleIndex = 0;
  432. memset( m_sourceList, 0, sizeof(m_sourceList) );
  433. m_nEstimatedSamplesAhead = (int)( ( float ) OUTPUT_SAMPLE_RATE / 10.0f );
  434. }
  435. void CAudioWaveOutput::RemoveMixerChannelReferences( CAudioMixer *mixer )
  436. {
  437. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  438. {
  439. RemoveFromReferencedList( mixer, &m_buffers[ i ] );
  440. }
  441. }
  442. void CAudioWaveOutput::AddToReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer )
  443. {
  444. // Already in list
  445. for ( int i = 0; i < buffer->m_Referenced.Count(); i++ )
  446. {
  447. if ( buffer->m_Referenced[ i ].mixer == mixer )
  448. {
  449. return;
  450. }
  451. }
  452. // Just remove it
  453. int idx = buffer->m_Referenced.AddToTail();
  454. CAudioMixerState *state = &buffer->m_Referenced[ idx ];
  455. state->mixer = mixer;
  456. state->submit_mixer_sample = mixer->GetSamplePosition();
  457. }
  458. void CAudioWaveOutput::RemoveFromReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer )
  459. {
  460. for ( int i = 0; i < buffer->m_Referenced.Count(); i++ )
  461. {
  462. if ( buffer->m_Referenced[ i ].mixer == mixer )
  463. {
  464. buffer->m_Referenced.Remove( i );
  465. break;
  466. }
  467. }
  468. }
  469. bool CAudioWaveOutput::IsSoundInReferencedList( CAudioMixer *mixer, CAudioBuffer *buffer )
  470. {
  471. for ( int i = 0; i < buffer->m_Referenced.Count(); i++ )
  472. {
  473. if ( buffer->m_Referenced[ i ].mixer == mixer )
  474. {
  475. return true;
  476. }
  477. }
  478. return false;
  479. }
  480. bool CAudioWaveOutput::IsSourceReferencedByActiveBuffer( CAudioMixer *mixer )
  481. {
  482. if ( !ValidDevice() )
  483. return false;
  484. CAudioBuffer *buffer;
  485. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  486. {
  487. buffer = &m_buffers[ i ];
  488. if ( !buffer->submitted )
  489. continue;
  490. if ( buffer->hdr->dwFlags & WHDR_DONE )
  491. continue;
  492. // See if it's referenced
  493. if ( IsSoundInReferencedList( mixer, buffer ) )
  494. return true;
  495. }
  496. return false;
  497. }
  498. CAudioWaveOutput::~CAudioWaveOutput( void )
  499. {
  500. if ( ValidDevice() )
  501. {
  502. waveOutReset( m_deviceHandle );
  503. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  504. {
  505. if ( m_buffers[i].hdr )
  506. {
  507. waveOutUnprepareHeader( m_deviceHandle, m_buffers[i].hdr, sizeof(*m_buffers[i].hdr) );
  508. delete[] m_buffers[i].hdr->lpData;
  509. delete m_buffers[i].hdr;
  510. }
  511. m_buffers[i].hdr = NULL;
  512. m_buffers[i].submitted = false;
  513. m_buffers[i].submit_sample_count = 0;
  514. m_buffers[i].m_Referenced.Purge();
  515. }
  516. waveOutClose( m_deviceHandle );
  517. ClearDevice();
  518. }
  519. }
  520. CAudioBuffer *CAudioWaveOutput::GetEmptyBuffer( void )
  521. {
  522. CAudioBuffer *pOutput = NULL;
  523. if ( ValidDevice() )
  524. {
  525. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  526. {
  527. if ( !(m_buffers[ i ].submitted ) ||
  528. m_buffers[i].hdr->dwFlags & WHDR_DONE )
  529. {
  530. pOutput = &m_buffers[i];
  531. pOutput->submitted = true;
  532. pOutput->m_Referenced.Purge();
  533. break;
  534. }
  535. }
  536. }
  537. return pOutput;
  538. }
  539. void CAudioWaveOutput::SilenceBuffer( short *pSamples, int sampleCount )
  540. {
  541. int i;
  542. for ( i = 0; i < sampleCount; i++ )
  543. {
  544. // left
  545. *pSamples++ = 0;
  546. // right
  547. *pSamples++ = 0;
  548. }
  549. }
  550. void CAudioWaveOutput::Flush( void )
  551. {
  552. waveOutReset( m_deviceHandle );
  553. }
  554. // mix a buffer up to time (time is absolute)
  555. void CAudioWaveOutput::Update( float time )
  556. {
  557. if ( !ValidDevice() )
  558. return;
  559. // reset the system
  560. if ( m_mixTime < 0 || time < m_baseTime )
  561. {
  562. m_baseTime = time;
  563. m_mixTime = 0;
  564. }
  565. // put time in our coordinate frame
  566. time -= m_baseTime;
  567. if ( time > m_mixTime )
  568. {
  569. CAudioBuffer *pBuffer = GetEmptyBuffer();
  570. // no free buffers, mixing is ahead of the playback!
  571. if ( !pBuffer || !pBuffer->hdr )
  572. {
  573. //Con_Printf( "out of buffers\n" );
  574. return;
  575. }
  576. // UNDONE: These numbers are constants
  577. // calc number of samples (2 channels * 2 bytes per sample)
  578. int sampleCount = pBuffer->hdr->dwBufferLength >> 2;
  579. m_mixTime += sampleCount * (1.0f / OUTPUT_SAMPLE_RATE);
  580. short *pSamples = reinterpret_cast<short *>(pBuffer->hdr->lpData);
  581. SilenceBuffer( pSamples, sampleCount );
  582. int tempCount = sampleCount;
  583. while ( tempCount > 0 )
  584. {
  585. if ( tempCount > m_audioDevice.MaxSampleCount() )
  586. sampleCount = m_audioDevice.MaxSampleCount();
  587. else
  588. sampleCount = tempCount;
  589. m_audioDevice.MixBegin();
  590. for ( int i = 0; i < MAX_CHANNELS; i++ )
  591. {
  592. CAudioMixer *pSource = m_sourceList[i];
  593. if ( !pSource )
  594. continue;
  595. StudioModel *model = NULL;
  596. int modelindex = pSource->GetModelIndex();
  597. if ( modelindex >= 0 )
  598. {
  599. model = models->GetStudioModel( modelindex );
  600. }
  601. else
  602. {
  603. if ( g_pPhonemeEditor->IsActiveTool() || g_pWaveBrowser->IsActiveTool() )
  604. {
  605. model = models->GetActiveStudioModel();
  606. }
  607. }
  608. if ( model && !model->m_mouth.IsSourceReferenced( pSource->GetSource() ) )
  609. {
  610. CChoreoScene *pScene = g_pChoreoView->GetScene();
  611. bool bIgnorePhonemes = pScene ? pScene->ShouldIgnorePhonemes() : false;
  612. model->m_mouth.AddSource( pSource->GetSource(), bIgnorePhonemes );
  613. if ( modelindex < 0 )
  614. {
  615. pSource->SetModelIndex( models->GetIndexForStudioModel( model ) );
  616. }
  617. }
  618. int currentsample = pSource->GetSamplePosition();
  619. bool forward = pSource->GetDirection();
  620. if ( pSource->GetActive() )
  621. {
  622. if ( !pSource->MixDataToDevice( &m_audioDevice, pSource->GetChannel(), currentsample, sampleCount, SampleRate(), forward ) )
  623. {
  624. // Source becomes inactive when last submitted sample is finally
  625. // submitted. But it lingers until it's no longer referenced
  626. pSource->SetActive( false );
  627. }
  628. else
  629. {
  630. AddToReferencedList( pSource, pBuffer );
  631. }
  632. }
  633. else
  634. {
  635. if ( !IsSourceReferencedByActiveBuffer( pSource ) )
  636. {
  637. if ( !pSource->GetAutoDelete() )
  638. {
  639. FreeChannel( i );
  640. }
  641. }
  642. else
  643. {
  644. pSource->IncrementSamples( pSource->GetChannel(), currentsample, sampleCount, SampleRate(), forward );
  645. }
  646. }
  647. }
  648. m_audioDevice.TransferBufferStereo16( pSamples, sampleCount );
  649. m_sampleIndex += sampleCount;
  650. tempCount -= sampleCount;
  651. pSamples += sampleCount * 2;
  652. }
  653. // if the buffers aren't aligned on sample boundaries, this will hard-lock the machine!
  654. pBuffer->submit_sample_count = GetOutputPosition();
  655. waveOutWrite( m_deviceHandle, pBuffer->hdr, sizeof(*(pBuffer->hdr)) );
  656. }
  657. }
  658. int CAudioWaveOutput::GetNumberofSamplesAhead( void )
  659. {
  660. ComputeSampleAheadAmount();
  661. return m_nEstimatedSamplesAhead;
  662. }
  663. float CAudioWaveOutput::GetAmountofTimeAhead( void )
  664. {
  665. ComputeSampleAheadAmount();
  666. return ( (float)m_nEstimatedSamplesAhead / (float)OUTPUT_SAMPLE_RATE );
  667. }
  668. // Find the most recent submitted sample that isn't flagged as whdr_done
  669. void CAudioWaveOutput::ComputeSampleAheadAmount( void )
  670. {
  671. m_nEstimatedSamplesAhead = 0;
  672. int newest_sample_index = -1;
  673. int newest_sample_count = 0;
  674. CAudioBuffer *buffer;
  675. if ( ValidDevice() )
  676. {
  677. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  678. {
  679. buffer = &m_buffers[ i ];
  680. if ( !buffer->submitted )
  681. continue;
  682. if ( buffer->hdr->dwFlags & WHDR_DONE )
  683. continue;
  684. if ( buffer->submit_sample_count > newest_sample_count )
  685. {
  686. newest_sample_index = i;
  687. newest_sample_count = buffer->submit_sample_count;
  688. }
  689. }
  690. }
  691. if ( newest_sample_index == -1 )
  692. return;
  693. buffer = &m_buffers[ newest_sample_index ];
  694. int currentPos = GetOutputPosition() ;
  695. m_nEstimatedSamplesAhead = currentPos - buffer->submit_sample_count;
  696. }
  697. int CAudioWaveOutput::FindSourceIndex( CAudioMixer *pSource )
  698. {
  699. for ( int i = 0; i < MAX_CHANNELS; i++ )
  700. {
  701. if ( pSource == m_sourceList[i] )
  702. {
  703. return i;
  704. }
  705. }
  706. return -1;
  707. }
  708. CAudioMixer *CAudioWaveOutput::GetMixerForSource( CAudioSource *source )
  709. {
  710. for ( int i = 0; i < MAX_CHANNELS; i++ )
  711. {
  712. if ( !m_sourceList[i] )
  713. continue;
  714. if ( source == m_sourceList[i]->GetSource() )
  715. {
  716. return m_sourceList[i];
  717. }
  718. }
  719. return NULL;
  720. }
  721. void CAudioWaveOutput::AddSource( CAudioMixer *pSource )
  722. {
  723. int slot = 0;
  724. for ( int i = 0; i < MAX_CHANNELS; i++ )
  725. {
  726. if ( !m_sourceList[i] )
  727. {
  728. slot = i;
  729. break;
  730. }
  731. }
  732. if ( m_sourceList[slot] )
  733. {
  734. FreeChannel( slot );
  735. }
  736. SetChannel( slot, pSource );
  737. pSource->SetActive( true );
  738. }
  739. void CAudioWaveOutput::StopSounds( void )
  740. {
  741. for ( int i = 0; i < MAX_CHANNELS; i++ )
  742. {
  743. if ( m_sourceList[i] )
  744. {
  745. FreeChannel( i );
  746. }
  747. }
  748. }
  749. void CAudioWaveOutput::SetChannel( int channelIndex, CAudioMixer *pSource )
  750. {
  751. if ( channelIndex < 0 || channelIndex >= MAX_CHANNELS )
  752. return;
  753. m_sourceList[channelIndex] = pSource;
  754. }
  755. void CAudioWaveOutput::FreeChannel( int channelIndex )
  756. {
  757. if ( channelIndex < 0 || channelIndex >= MAX_CHANNELS )
  758. return;
  759. if ( m_sourceList[channelIndex] )
  760. {
  761. StudioModel *model = NULL;
  762. int modelindex = m_sourceList[channelIndex]->GetModelIndex();
  763. if ( modelindex >= 0)
  764. {
  765. model = models->GetStudioModel( modelindex );
  766. }
  767. if ( model )
  768. {
  769. model->m_mouth.RemoveSource( m_sourceList[channelIndex]->GetSource() );
  770. }
  771. RemoveMixerChannelReferences( m_sourceList[channelIndex] );
  772. delete m_sourceList[channelIndex];
  773. m_sourceList[channelIndex] = NULL;
  774. }
  775. }
  776. int CAudioWaveOutput::GetOutputPosition( void )
  777. {
  778. if ( !m_deviceHandle )
  779. return 0;
  780. MMTIME mmtime;
  781. mmtime.wType = TIME_SAMPLES;
  782. waveOutGetPosition( m_deviceHandle, &mmtime, sizeof( MMTIME ) );
  783. // Convert time to sample count
  784. return ( mmtime.u.sample );
  785. }
  786. void CAudioWaveOutput::OpenDevice( void )
  787. {
  788. WAVEFORMATEX waveFormat;
  789. memset( &waveFormat, 0, sizeof(waveFormat) );
  790. // Select a PCM, 16-bit stereo playback device
  791. waveFormat.cbSize = sizeof(waveFormat);
  792. waveFormat.nAvgBytesPerSec = OUTPUT_SAMPLE_RATE * 2 * 2;
  793. waveFormat.nBlockAlign = 2 * 2; // channels * sample size
  794. waveFormat.nChannels = 2; // stereo
  795. waveFormat.nSamplesPerSec = OUTPUT_SAMPLE_RATE;
  796. waveFormat.wBitsPerSample = 16;
  797. waveFormat.wFormatTag = WAVE_FORMAT_PCM;
  798. MMRESULT errorCode = waveOutOpen( &m_deviceHandle, WAVE_MAPPER, &waveFormat, 0, 0, CALLBACK_NULL );
  799. if ( errorCode == MMSYSERR_NOERROR )
  800. {
  801. int bufferSize = 4 * ( OUTPUT_SAMPLE_RATE / OUTPUT_BUFFER_COUNT ); // total of 1 second of data
  802. // Got one!
  803. for ( int i = 0; i < OUTPUT_BUFFER_COUNT; i++ )
  804. {
  805. m_buffers[i].hdr = new WAVEHDR;
  806. m_buffers[i].hdr->lpData = new char[ bufferSize ];
  807. long align = (long)m_buffers[i].hdr->lpData;
  808. if ( align & 3 )
  809. {
  810. m_buffers[i].hdr->lpData = (char *) ( (align+3) &~3 );
  811. }
  812. m_buffers[i].hdr->dwBufferLength = bufferSize - (align&3);
  813. m_buffers[i].hdr->dwFlags = 0;
  814. if ( waveOutPrepareHeader( m_deviceHandle, m_buffers[i].hdr, sizeof(*m_buffers[i].hdr) ) != MMSYSERR_NOERROR )
  815. {
  816. ClearDevice();
  817. return;
  818. }
  819. }
  820. }
  821. else
  822. {
  823. ClearDevice();
  824. }
  825. }
  826. // factory to create a suitable audio output for this system
  827. CAudioOutput *CAudioOutput::Create( void )
  828. {
  829. // sound device is a singleton for now
  830. static CAudioOutput *pWaveOut = NULL;
  831. if ( !pWaveOut )
  832. {
  833. pWaveOut = new CAudioWaveOutput;
  834. }
  835. return pWaveOut;
  836. }
  837. struct CSoundFile
  838. {
  839. char filename[ 512 ];
  840. CAudioSource *source;
  841. long filetime;
  842. };
  843. //-----------------------------------------------------------------------------
  844. // Purpose:
  845. //-----------------------------------------------------------------------------
  846. class CFacePoserSound : public IFacePoserSound
  847. {
  848. public:
  849. ~CFacePoserSound( void );
  850. void Init( void );
  851. void Shutdown( void );
  852. void Update( float dt );
  853. void Flush( void );
  854. CAudioSource *LoadSound( const char *wavfile );
  855. void PlaySound( StudioModel *source, float volume, const char *wavfile, CAudioMixer **ppMixer );
  856. void PlaySound( CAudioSource *source, float volume, CAudioMixer **ppMixer );
  857. void PlayPartialSound( StudioModel *model, float volume, const char *wavfile, CAudioMixer **ppMixer, int startSample, int endSample );
  858. bool IsSoundPlaying( CAudioMixer *pMixer );
  859. CAudioMixer *FindMixer( CAudioSource *source );
  860. void StopAll( void );
  861. void StopSound( CAudioMixer *mixer );
  862. void RenderWavToDC( HDC dc, RECT& outrect, const Color& clr, float starttime, float endtime,
  863. CAudioSource *pWave, bool selected = false, int selectionstart = 0, int selectionend = 0 );
  864. // void InstallPhonemecallback( IPhonemeTag *pTagInterface );
  865. float GetAmountofTimeAhead( void );
  866. int GetNumberofSamplesAhead( void );
  867. CAudioOuput *GetAudioOutput( void );
  868. virtual void EnsureNoModelReferences( CAudioSource *source );
  869. private:
  870. void AddViseme( float intensity, StudioModel *model, int phoneme, float scale );
  871. void ProcessCloseCaptionData( StudioModel *model, float curtime, CSentence* sentence );
  872. void SetupWeights( void );
  873. CAudioSource *FindOrAddSound( const char *filename );
  874. CAudioOutput *m_pAudio;
  875. float m_flElapsedTime;
  876. CUtlVector < CSoundFile > m_ActiveSounds;
  877. };
  878. static CFacePoserSound g_FacePoserSound;
  879. IFacePoserSound *sound = ( IFacePoserSound * )&g_FacePoserSound;
  880. CFacePoserSound::~CFacePoserSound( void )
  881. {
  882. OutputDebugString( va( "Removing %i sounds\n", m_ActiveSounds.Count() ) );
  883. for ( int i = 0 ; i < m_ActiveSounds.Count(); i++ )
  884. {
  885. CSoundFile *p = &m_ActiveSounds[ i ];
  886. OutputDebugString( va( "Removing sound: %s\n", p->filename ) );
  887. delete p->source;
  888. }
  889. m_ActiveSounds.RemoveAll();
  890. }
  891. //-----------------------------------------------------------------------------
  892. // Purpose:
  893. //-----------------------------------------------------------------------------
  894. CAudioOuput *CFacePoserSound::GetAudioOutput( void )
  895. {
  896. return (CAudioOuput *)m_pAudio;
  897. }
  898. CAudioSource *CFacePoserSound::FindOrAddSound( const char *filename )
  899. {
  900. CSoundFile *s;
  901. int i;
  902. for ( i = 0; i < m_ActiveSounds.Count(); i++ )
  903. {
  904. s = &m_ActiveSounds[ i ];
  905. Assert( s );
  906. if ( !stricmp( s->filename, filename ) )
  907. {
  908. long filetime = filesystem->GetFileTime( filename );
  909. if ( filetime != s->filetime )
  910. {
  911. Con_Printf( "Reloading sound %s\n", filename );
  912. delete s->source;
  913. s->source = LoadSound( filename );
  914. s->filetime = filetime;
  915. }
  916. return s->source;
  917. }
  918. }
  919. i = m_ActiveSounds.AddToTail();
  920. s = &m_ActiveSounds[ i ];
  921. strcpy( s->filename, filename );
  922. s->source = LoadSound( filename );
  923. s->filetime = filesystem->GetFileTime( filename );
  924. return s->source;
  925. }
  926. void CFacePoserSound::Init( void )
  927. {
  928. m_flElapsedTime = 0.0f;
  929. m_pAudio = CAudioOutput::Create();
  930. }
  931. void CFacePoserSound::Shutdown( void )
  932. {
  933. }
  934. float CFacePoserSound::GetAmountofTimeAhead( void )
  935. {
  936. if ( !m_pAudio )
  937. return 0.0f;
  938. return m_pAudio->GetAmountofTimeAhead();
  939. }
  940. int CFacePoserSound::GetNumberofSamplesAhead( void )
  941. {
  942. if ( !m_pAudio )
  943. return 0;
  944. return m_pAudio->GetNumberofSamplesAhead();
  945. }
  946. CAudioSource *CFacePoserSound::LoadSound( const char *wavfile )
  947. {
  948. if ( !m_pAudio )
  949. return NULL;
  950. CAudioSource *wave = AudioSource_Create( wavfile );
  951. return wave;
  952. }
  953. void CFacePoserSound::PlaySound( StudioModel *model, float volume, const char *wavfile, CAudioMixer **ppMixer )
  954. {
  955. if ( m_pAudio )
  956. {
  957. CAudioSource *wave = FindOrAddSound( wavfile );
  958. if ( !wave )
  959. return;
  960. CAudioMixer *pMixer = wave->CreateMixer();
  961. if ( ppMixer )
  962. {
  963. *ppMixer = pMixer;
  964. }
  965. pMixer->SetVolume( volume );
  966. m_pAudio->AddSource( pMixer );
  967. if ( model )
  968. {
  969. pMixer->SetModelIndex( models->GetIndexForStudioModel( model ) );
  970. }
  971. }
  972. }
  973. void CFacePoserSound::PlayPartialSound( StudioModel *model, float volume, const char *wavfile, CAudioMixer **ppMixer, int startSample, int endSample )
  974. {
  975. if ( !m_pAudio )
  976. return;
  977. StopAll();
  978. CAudioSource *wave = FindOrAddSound( wavfile );
  979. if ( !wave )
  980. return;
  981. CAudioMixer *mixer = wave->CreateMixer();
  982. if ( ppMixer )
  983. {
  984. *ppMixer = mixer;
  985. }
  986. mixer->SetSamplePosition( startSample );
  987. mixer->SetLoopPosition( endSample );
  988. mixer->SetVolume( volume );
  989. m_pAudio->AddSource( mixer );
  990. }
  991. void CFacePoserSound::PlaySound( CAudioSource *source, float volume, CAudioMixer **ppMixer )
  992. {
  993. if ( ppMixer )
  994. {
  995. *ppMixer = NULL;
  996. }
  997. if ( m_pAudio )
  998. {
  999. CAudioMixer *mixer = source->CreateMixer();
  1000. if ( ppMixer )
  1001. {
  1002. *ppMixer = mixer;
  1003. }
  1004. mixer->SetVolume( volume );
  1005. m_pAudio->AddSource( mixer );
  1006. }
  1007. }
  1008. enum
  1009. {
  1010. PHONEME_CLASS_WEAK = 0,
  1011. PHONEME_CLASS_NORMAL,
  1012. PHONEME_CLASS_STRONG,
  1013. NUM_PHONEME_CLASSES
  1014. };
  1015. struct Emphasized_Phoneme
  1016. {
  1017. char *classname;
  1018. bool required;
  1019. bool valid;
  1020. CExpClass *cl;
  1021. CExpression *exp;
  1022. float *settings;
  1023. float amount;
  1024. };
  1025. static Emphasized_Phoneme g_PhonemeClasses[ NUM_PHONEME_CLASSES ] =
  1026. {
  1027. { "phonemes_weak", false },
  1028. { "phonemes", true },
  1029. { "phonemes_strong", false },
  1030. };
  1031. #define STRONG_CROSSFADE_START 0.60f
  1032. #define WEAK_CROSSFADE_START 0.40f
  1033. void ComputeBlendedSetting( Emphasized_Phoneme *classes, float emphasis_intensity )
  1034. {
  1035. // Here's the formula
  1036. // 0.5 is neutral 100 % of the default setting
  1037. // Crossfade starts at STRONG_CROSSFADE_START and is full at STRONG_CROSSFADE_END
  1038. // If there isn't a strong then the intensity of the underlying phoneme is fixed at 2 x STRONG_CROSSFADE_START
  1039. // so we don't get huge numbers
  1040. bool has_weak = classes[ PHONEME_CLASS_WEAK ].valid;
  1041. bool has_strong = classes[ PHONEME_CLASS_STRONG ].valid;
  1042. Assert( classes[ PHONEME_CLASS_NORMAL ].valid );
  1043. if ( emphasis_intensity > STRONG_CROSSFADE_START )
  1044. {
  1045. if ( has_strong )
  1046. {
  1047. // Blend in some of strong
  1048. float dist_remaining = 1.0f - emphasis_intensity;
  1049. float frac = dist_remaining / ( 1.0f - STRONG_CROSSFADE_START );
  1050. classes[ PHONEME_CLASS_NORMAL ].amount = (frac) * 2.0f * STRONG_CROSSFADE_START;
  1051. classes[ PHONEME_CLASS_STRONG ].amount = 1.0f - frac;
  1052. }
  1053. else
  1054. {
  1055. emphasis_intensity = min( emphasis_intensity, STRONG_CROSSFADE_START );
  1056. classes[ PHONEME_CLASS_NORMAL ].amount = 2.0f * emphasis_intensity;
  1057. }
  1058. }
  1059. else if ( emphasis_intensity < WEAK_CROSSFADE_START )
  1060. {
  1061. if ( has_weak )
  1062. {
  1063. // Blend in some weak
  1064. float dist_remaining = WEAK_CROSSFADE_START - emphasis_intensity;
  1065. float frac = dist_remaining / ( WEAK_CROSSFADE_START );
  1066. classes[ PHONEME_CLASS_NORMAL ].amount = (1.0f - frac) * 2.0f * WEAK_CROSSFADE_START;
  1067. classes[ PHONEME_CLASS_WEAK ].amount = frac;
  1068. }
  1069. else
  1070. {
  1071. emphasis_intensity = max( emphasis_intensity, WEAK_CROSSFADE_START );
  1072. classes[ PHONEME_CLASS_NORMAL ].amount = 2.0f * emphasis_intensity;
  1073. }
  1074. }
  1075. else
  1076. {
  1077. classes[ PHONEME_CLASS_NORMAL ].amount = 2.0f * emphasis_intensity;
  1078. }
  1079. }
  1080. void CFacePoserSound::AddViseme( float intensity, StudioModel *model, int phoneme, float scale )
  1081. {
  1082. int i;
  1083. Assert( model );
  1084. CStudioHdr *hdr = model->GetStudioHdr();
  1085. Assert( hdr );
  1086. if ( !hdr )
  1087. return;
  1088. for ( i = 0; i < NUM_PHONEME_CLASSES; i++ )
  1089. {
  1090. Emphasized_Phoneme *info = &g_PhonemeClasses[ i ];
  1091. info->valid = false;
  1092. info->exp = NULL;
  1093. info->settings = NULL;
  1094. info->amount = 0.0f;
  1095. info->cl = expressions->FindClass( info->classname, true );
  1096. if ( info->cl )
  1097. {
  1098. info->exp = info->cl->FindExpression( ConvertPhoneme( phoneme ) );
  1099. }
  1100. if ( info->required && ( !info->cl || !info->exp ) )
  1101. {
  1102. return;
  1103. }
  1104. if ( info->exp )
  1105. {
  1106. info->valid = true;
  1107. info->settings = info->exp->GetSettings();
  1108. Assert( info->settings );
  1109. }
  1110. }
  1111. ComputeBlendedSetting( g_PhonemeClasses, intensity );
  1112. // Look up the phoneme
  1113. for ( LocalFlexController_t i = LocalFlexController_t(0); i < hdr->numflexcontrollers(); i++)
  1114. {
  1115. int j = hdr->pFlexcontroller( i )->localToGlobal;
  1116. float add = 0.0f;
  1117. for ( int k = 0 ; k < NUM_PHONEME_CLASSES; k++ )
  1118. {
  1119. Emphasized_Phoneme *info = &g_PhonemeClasses[ k ];
  1120. if ( !info->valid || !info->amount )
  1121. continue;
  1122. add += info->amount * info->settings[ j ];
  1123. }
  1124. if ( add == 0.0f )
  1125. continue;
  1126. float curvalue = model->GetFlexController( i );
  1127. curvalue += add * scale;
  1128. model->SetFlexController( i, curvalue );
  1129. }
  1130. }
  1131. #define PHONEME_FILTER 0.08f
  1132. #define PHONEME_DELAY 0.0f
  1133. void CFacePoserSound::SetupWeights( void )
  1134. {
  1135. StudioModel *model;
  1136. int c = models->Count();
  1137. for ( int i = 0; i < c; i++ )
  1138. {
  1139. model = models->GetStudioModel( i );
  1140. if ( !model )
  1141. continue;
  1142. // Reset flexes
  1143. CStudioHdr *hdr = model->GetStudioHdr();
  1144. if ( !hdr )
  1145. continue;
  1146. for ( int s = 0; s < model->m_mouth.GetNumVoiceSources(); s++ )
  1147. {
  1148. CVoiceData *vd = model->m_mouth.GetVoiceSource( s );
  1149. if ( !vd || vd->ShouldIgnorePhonemes() )
  1150. continue;
  1151. CAudioSource *source = vd->GetSource();
  1152. // check for phoneme flexes
  1153. if ( !source )
  1154. continue;
  1155. CAudioMixer *mixer = FindMixer( source );
  1156. if ( !mixer )
  1157. continue;
  1158. CSentence *sentence = source->GetSentence();
  1159. if ( !sentence )
  1160. continue;
  1161. // Zero faces if needed
  1162. models->CheckResetFlexes();
  1163. float pos = (float)mixer->GetScrubPosition();
  1164. // Con_Printf( "pos %f for mixer %p\n", pos, mixer );
  1165. float soundtime = pos / source->SampleRate();
  1166. float t = soundtime - PHONEME_DELAY;
  1167. float dt = PHONEME_FILTER;
  1168. float sentence_duration = source->GetRunningLength();
  1169. float emphasis_intensity = sentence->GetIntensity( t, sentence_duration );
  1170. if ( t > 0.0f )
  1171. {
  1172. for ( int w = 0 ; w < sentence->m_Words.Count(); w++ )
  1173. {
  1174. CWordTag *word = sentence->m_Words[ w ];
  1175. if ( !word )
  1176. continue;
  1177. for ( int k = 0; k < word->m_Phonemes.Count(); k++)
  1178. {
  1179. CPhonemeTag *phoneme = word->m_Phonemes[ k ];
  1180. if ( !phoneme )
  1181. continue;
  1182. // if the filter starts within this phoneme, make sure the filter size is
  1183. // at least least as long as the current phoneme, or until the end of the next phoneme,
  1184. // whichever is smaller
  1185. if (t > phoneme->GetStartTime() && t < phoneme->GetEndTime())
  1186. {
  1187. CPhonemeTag *next = NULL;
  1188. // try next phoneme, or first phoneme of next word
  1189. if (k < word->m_Phonemes.Count()-1)
  1190. {
  1191. next = word->m_Phonemes[ k+1 ];
  1192. }
  1193. else if ( w < sentence->m_Words.Count() - 1 && sentence->m_Words[ w+1 ]->m_Phonemes.Count() )
  1194. {
  1195. next = sentence->m_Words[ w+1 ]->m_Phonemes[ 0 ];
  1196. }
  1197. // if I have a neighbor
  1198. if (next)
  1199. {
  1200. // and they're touching
  1201. if (next->GetStartTime() == phoneme->GetEndTime())
  1202. {
  1203. // no gap, so increase the blend length to the end of the next phoneme, as long as it's not longer than the current phoneme
  1204. dt = max( dt, min( next->GetEndTime() - t, phoneme->GetEndTime() - phoneme->GetStartTime() ) );
  1205. }
  1206. else
  1207. {
  1208. // dead space, so increase the blend length to the start of the next phoneme, as long as it's not longer than the current phoneme
  1209. dt = max( dt, min( next->GetStartTime() - t, phoneme->GetEndTime() - phoneme->GetStartTime() ) );
  1210. }
  1211. }
  1212. else
  1213. {
  1214. // last phoneme in list, increase the blend length to the length of the current phoneme
  1215. dt = max( dt, phoneme->GetEndTime() - phoneme->GetStartTime() );
  1216. }
  1217. }
  1218. float t1 = ( phoneme->GetStartTime() - t) / dt;
  1219. float t2 = ( phoneme->GetEndTime() - t) / dt;
  1220. if (t1 < 1.0 && t2 > 0)
  1221. {
  1222. float scale;
  1223. // clamp
  1224. if (t2 > 1)
  1225. t2 = 1;
  1226. if (t1 < 0)
  1227. t1 = 0;
  1228. // FIXME: simple box filter. Should use something fancier
  1229. scale = (t2 - t1);
  1230. AddViseme( emphasis_intensity, model, phoneme->GetPhonemeCode(), scale );
  1231. }
  1232. }
  1233. }
  1234. ProcessCloseCaptionData( model, t, sentence );
  1235. }
  1236. }
  1237. }
  1238. }
  1239. static int g_nSoundFrameCount = 0;
  1240. void CFacePoserSound::ProcessCloseCaptionData( StudioModel *model, float curtime, CSentence* sentence )
  1241. {
  1242. // closecaptionmanager->Process( g_nSoundFrameCount, model, curtime, sentence, GetCloseCaptionLanguageId() );
  1243. }
  1244. void CFacePoserSound::Update( float dt )
  1245. {
  1246. // closecaptionmanager->PreProcess( g_nSoundFrameCount );
  1247. if ( m_pAudio )
  1248. {
  1249. SetupWeights();
  1250. m_pAudio->Update( m_flElapsedTime );
  1251. }
  1252. // closecaptionmanager->PostProcess( g_nSoundFrameCount, dt );
  1253. m_flElapsedTime += dt;
  1254. g_nSoundFrameCount++;
  1255. }
  1256. void CFacePoserSound::Flush( void )
  1257. {
  1258. if ( m_pAudio )
  1259. {
  1260. m_pAudio->Flush();
  1261. }
  1262. }
  1263. void CFacePoserSound::StopAll( void )
  1264. {
  1265. int c = models->Count();
  1266. for ( int i = 0; i < c; i++ )
  1267. {
  1268. StudioModel *model = models->GetStudioModel( i );
  1269. if ( model )
  1270. {
  1271. model->m_mouth.ClearVoiceSources();
  1272. }
  1273. }
  1274. if ( m_pAudio )
  1275. {
  1276. m_pAudio->StopSounds();
  1277. }
  1278. }
  1279. void CFacePoserSound::StopSound( CAudioMixer *mixer )
  1280. {
  1281. int idx = m_pAudio->FindSourceIndex( mixer );
  1282. if ( idx != -1 )
  1283. {
  1284. m_pAudio->FreeChannel( idx );
  1285. }
  1286. }
  1287. void CFacePoserSound::RenderWavToDC( HDC dc, RECT& outrect, const Color& clr,
  1288. float starttime, float endtime, CAudioSource *pWave,
  1289. bool selected /*= false*/, int selectionstart /*= 0*/, int selectionend /*= 0*/ )
  1290. {
  1291. channel_t channel;
  1292. channel.leftvol = 127;
  1293. channel.rightvol = 127;
  1294. channel.pitch = 1.0;
  1295. if ( !pWave )
  1296. return;
  1297. CAudioWaveOutput *pWaveOutput = ( CAudioWaveOutput * )m_pAudio;
  1298. CAudioMixer *pMixer = pWave->CreateMixer();
  1299. float timeperpixel = ( endtime - starttime ) / (float)( outrect.right - outrect.left );
  1300. float samplesperpixel = timeperpixel * pWave->SampleRate();
  1301. samplesperpixel = min( samplesperpixel, (float)PAINTBUFFER_SIZE );
  1302. int intsamplesperpixel = (int)samplesperpixel;
  1303. // Determine start/stop positions
  1304. int totalsamples = (int)( pWave->GetRunningLength() * pWave->SampleRate() );
  1305. if ( totalsamples <= 0 )
  1306. return;
  1307. float selectionstarttime = pWave->GetRunningLength() * ( float )selectionstart / ( float )totalsamples;
  1308. float selectionendtime = pWave->GetRunningLength() * ( float )selectionend / ( float )totalsamples;
  1309. HPEN oldPen, pen, pen2, pen3, pen4;
  1310. pen = CreatePen( PS_SOLID, 1, ColorToRGB( Color( 175, 175, 250 ) ) );
  1311. pen2 = CreatePen( PS_SOLID, 1, ColorToRGB( clr ) );
  1312. pen3 = CreatePen( PS_SOLID, 1, ColorToRGB( Color( 127, 200, 249 ) ) );
  1313. pen4 = CreatePen( PS_SOLID, 2, ColorToRGB( Color( 0, 0, 200 ) ) );
  1314. oldPen = (HPEN)SelectObject( dc, pen );
  1315. MoveToEx( dc, outrect.left, ( outrect.bottom + outrect.top ) / 2, NULL );
  1316. LineTo( dc, outrect.right, ( outrect.bottom + outrect.top ) / 2 );
  1317. SelectObject( dc, pen2 );
  1318. // Now iterate the samples
  1319. float currenttime = 0.0f;
  1320. int pixel = 0;
  1321. int height = ( outrect.bottom - outrect.top ) / 2;
  1322. int midy = ( outrect.bottom + outrect.top ) / 2;
  1323. int bufferlen = ( intsamplesperpixel + 3 ) & ~3;
  1324. short *samples = new short[ 2 * bufferlen ];
  1325. bool drawingselection = false;
  1326. int maxsamples = max( 32, intsamplesperpixel / 16 );
  1327. int currentsample = 0;
  1328. while ( currenttime < endtime )
  1329. {
  1330. pWaveOutput->m_audioDevice.MixBegin();
  1331. int samplecount = min( maxsamples, intsamplesperpixel );
  1332. if ( !pMixer->MixDataToDevice( &pWaveOutput->m_audioDevice, &channel, currentsample, samplecount, pWave->SampleRate(), true ) )
  1333. break;
  1334. currentsample = pMixer->GetSamplePosition();
  1335. // Jump ahead by diff
  1336. int diff = intsamplesperpixel - samplecount;
  1337. if ( diff > 0 )
  1338. {
  1339. if ( !pMixer->SkipSamples( &channel, currentsample, diff, pWave->SampleRate(), true ) )
  1340. break;
  1341. }
  1342. currentsample = pMixer->GetSamplePosition();
  1343. pWaveOutput->m_audioDevice.TransferBufferStereo16( samples, samplecount );
  1344. if ( currenttime >= starttime )
  1345. {
  1346. if ( selected )
  1347. {
  1348. bool boundary = false;
  1349. bool inselection = ( currenttime >= selectionstarttime &&
  1350. currenttime <= selectionendtime );
  1351. if ( inselection )
  1352. {
  1353. if ( !drawingselection )
  1354. {
  1355. drawingselection = true;
  1356. boundary = true;
  1357. }
  1358. }
  1359. else if ( drawingselection )
  1360. {
  1361. boundary = true;
  1362. drawingselection = false;
  1363. }
  1364. if ( inselection || boundary )
  1365. {
  1366. int top, bottom;
  1367. bottom = outrect.bottom;
  1368. HPEN *usePen;
  1369. if ( boundary )
  1370. {
  1371. usePen = &pen4;
  1372. top = outrect.top;
  1373. }
  1374. else
  1375. {
  1376. usePen = &pen3;
  1377. top = outrect.bottom - 19;
  1378. }
  1379. HPEN old = (HPEN)SelectObject( dc, *usePen );
  1380. MoveToEx( dc, outrect.left + pixel, top, NULL );
  1381. LineTo( dc, outrect.left + pixel, bottom-1 );
  1382. SelectObject( dc, old );
  1383. }
  1384. }
  1385. int maxvalue = -65536;
  1386. int minvalue = 65536;
  1387. short *pData = samples;
  1388. // only take fix samples
  1389. int step = 2;
  1390. int count = 2 * samplecount;
  1391. for ( int i = 0; i < count; i+=step )
  1392. {
  1393. int val = (int)( pData[i] + pData[i+1] ) / 2;
  1394. if ( val > maxvalue )
  1395. {
  1396. maxvalue = val;
  1397. }
  1398. if ( val < minvalue )
  1399. {
  1400. minvalue = val;
  1401. }
  1402. }
  1403. float maxv = (float)( maxvalue ) / 32768.0f;
  1404. float minv = (float)( minvalue ) / 32768.0f;
  1405. MoveToEx( dc, outrect.left + pixel, midy + ( int ) ( maxv * height ), NULL );
  1406. LineTo( dc, outrect.left + pixel, midy + ( int ) ( minv * height ) );
  1407. pixel++;
  1408. }
  1409. currenttime += timeperpixel;
  1410. }
  1411. delete[] samples;
  1412. SelectObject( dc, oldPen );
  1413. DeleteObject( pen );
  1414. DeleteObject( pen2 );
  1415. DeleteObject( pen3 );
  1416. delete pMixer;
  1417. }
  1418. bool CFacePoserSound::IsSoundPlaying( CAudioMixer *pMixer )
  1419. {
  1420. if ( !m_pAudio || !pMixer )
  1421. {
  1422. return false;
  1423. }
  1424. //
  1425. int index = m_pAudio->FindSourceIndex( pMixer );
  1426. if ( index != -1 )
  1427. return true;
  1428. return false;
  1429. }
  1430. CAudioMixer *CFacePoserSound::FindMixer( CAudioSource *source )
  1431. {
  1432. if ( !m_pAudio )
  1433. return NULL;
  1434. return m_pAudio->GetMixerForSource( source );
  1435. }
  1436. void CFacePoserSound::EnsureNoModelReferences( CAudioSource *source )
  1437. {
  1438. int c = models->Count();
  1439. for ( int i = 0; i < c; i++ )
  1440. {
  1441. StudioModel *model = models->GetStudioModel( i );
  1442. if ( model->m_mouth.IsSourceReferenced( source ) )
  1443. {
  1444. model->m_mouth.RemoveSource( source );
  1445. }
  1446. }
  1447. }