Sound.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. #include "Sound.h"
  2. #include "Player.h"
  3. using namespace GSL;
  4. #ifdef WIN32
  5. extern GSLPlayer *_player;
  6. void CALLBACK AudioOutProc( HWAVEOUT hOut, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 );
  7. #endif
  8. // Inhalt der Sound Klasse aus Sound.h
  9. // Konstruktor
  10. GSLSound::GSLSound( const SoundKopf &skpf )
  11. : Thread()
  12. {
  13. kpf = skpf;
  14. dat = new Datei();
  15. dat->setDatei( kpf.pfad );
  16. #ifdef WIN32
  17. status = 0;
  18. hAudioId = 0;
  19. uAudioDelay = 0;
  20. uAudioCount = 0;
  21. uAudioPlay = 16;
  22. hAudioEvent = 0;
  23. uAudioWrite = 0;
  24. uAudioStop = 0;
  25. lAudioDone = 0;
  26. uAudioWrOk = 0;
  27. iAudioThEnd = 0;
  28. linksV = 1;
  29. rechtsV = 1;
  30. #endif
  31. }
  32. // Destruktor
  33. GSLSound::~GSLSound()
  34. {
  35. #ifdef WIN32
  36. if( status )
  37. stopSound();
  38. #endif
  39. dat->release();
  40. }
  41. // privat
  42. int GSLSound::audioOpen()
  43. {
  44. #ifdef WIN32
  45. WAVEFORMATEX sAudioWm;
  46. sAudioWm.wFormatTag = WAVE_FORMAT_PCM;
  47. sAudioWm.nChannels = kpf.channels;
  48. sAudioWm.nSamplesPerSec = kpf.sampleRate;
  49. sAudioWm.nBlockAlign = ( ( 16 * kpf.channels ) + 7 ) >> 3;
  50. sAudioWm.nAvgBytesPerSec = kpf.sampleRate * sAudioWm.nBlockAlign;
  51. sAudioWm.wBitsPerSample = 16;
  52. sAudioWm.cbSize = 0;
  53. MMRESULT uRes = waveOutOpen( &hAudioId, WAVE_MAPPER, &sAudioWm, (DWORD_PTR)AudioOutProc, 0x00000000, CALLBACK_FUNCTION );
  54. if( uRes || !hAudioId )
  55. {
  56. memset( &sAudioWm, 0, sizeof( sAudioWm ) );
  57. return 1;
  58. }
  59. uAudioDelay = 0;
  60. uAudioWrite = 0;
  61. uAudioStop = 0;
  62. lAudioDone = 0;
  63. for( uAudioCount = 0; uAudioCount < 16; uAudioCount++ )
  64. {
  65. aAudioHdr[ uAudioCount ] = (LPWAVEHDR)GlobalAllocPtr( GMEM_MOVEABLE | GMEM_SHARE, sizeof( WAVEHDR ) + 0x4000 );
  66. if( !aAudioHdr[ uAudioCount ] )
  67. break;
  68. aAudioHdr[ uAudioCount ]->dwFlags = WHDR_DONE;
  69. aAudioHdr[ uAudioCount ]->lpData = (LPSTR)aAudioHdr[ uAudioCount ] + sizeof( WAVEHDR );
  70. aAudioHdr[ uAudioCount ]->dwBufferLength = 0x4000;
  71. aAudioHdr[ uAudioCount ]->dwUser = uAudioCount;
  72. aAudioHdr[ uAudioCount ]->dwBytesRecorded = 0;
  73. aAudioHdr[ uAudioCount ]->dwLoops = 1;
  74. aAudioHdr[ uAudioCount ]->lpNext = 0;
  75. aAudioPtr[ uAudioCount ] = (char *)( aAudioHdr[ uAudioCount ] ) + sizeof( WAVEHDR );
  76. if( !waveOutPrepareHeader( hAudioId, aAudioHdr[ uAudioCount ], sizeof( WAVEHDR ) ) )
  77. continue;
  78. GlobalFreePtr( (LPCVOID)aAudioHdr[ uAudioCount ] );
  79. break;
  80. }
  81. uAudioPlay = uAudioCount - 1;
  82. if( uAudioCount < 12 )
  83. {
  84. audioClose();
  85. return 2;
  86. }
  87. hAudioEvent = CreateEvent( 0, TRUE, TRUE, 0 );
  88. if( !hAudioEvent )
  89. {
  90. audioClose();
  91. return 3;
  92. }
  93. if( waveOutGetDevCaps( (UINT_PTR)hAudioId, (LPWAVEOUTCAPSA)&sAudioCaps, sizeof( WAVEOUTCAPS ) ) )
  94. memset( &sAudioCaps, 0, sizeof( sAudioCaps ) );
  95. waveOutReset( hAudioId );
  96. waveOutSetVolume( hAudioId, 0xFFFFFFFF );
  97. #endif
  98. dat->open( Datei::Style::lesen );
  99. #ifdef WIN32
  100. uAudioWrOk = 1;
  101. #endif
  102. return 0;
  103. }
  104. int GSLSound::audioClose()
  105. {
  106. int iErr = 0;
  107. #ifdef WIN32
  108. if( !hAudioId )
  109. return 1;
  110. audioStop();
  111. while( uAudioCount > 0 )
  112. {
  113. uAudioCount--;
  114. if( waveOutUnprepareHeader( hAudioId, aAudioHdr[ uAudioCount ], sizeof( WAVEHDR ) ) )
  115. iErr = 1;
  116. if( GlobalFreePtr( (LPCVOID)aAudioHdr[ uAudioCount ] ) )
  117. iErr = 1;
  118. aAudioHdr[ uAudioCount ] = 0;
  119. aAudioPtr[ uAudioCount ] = 0;
  120. }
  121. if( waveOutClose( hAudioId ) )
  122. iErr = 1;
  123. if( !CloseHandle( hAudioEvent ) )
  124. iErr = 1;
  125. hAudioId = 0;
  126. uAudioWrite = 0;
  127. uAudioDelay = 0;
  128. uAudioPlay = uAudioCount - 1;
  129. #endif
  130. dat->close();
  131. return iErr;
  132. }
  133. int GSLSound::audioStop()
  134. {
  135. #ifdef WIN32
  136. unsigned uPos;
  137. if( !hAudioId )
  138. return 1;
  139. uAudioStop = 1;
  140. uAudioWrOk = 0;
  141. warteAufThread( 5000 );
  142. SetEvent( hAudioEvent );
  143. waveOutReset( hAudioId );
  144. if( uAudioWrite != 0 && uAudioPlay != uAudioCount - 1 )
  145. {
  146. for( uPos = 0; uPos < uAudioCount; uPos++ ) // clears all buffers
  147. {
  148. memset( aAudioHdr[ uPos ]->lpData, 0, 0x4000 );
  149. break;
  150. }
  151. }
  152. uAudioPlay = uAudioCount - 1;
  153. uAudioWrite = 0;
  154. uAudioDelay = 0;
  155. SetEvent( hAudioEvent );
  156. uAudioWrOk = 1;
  157. if( isRunning() ) // close thread
  158. {
  159. warteAufThread( 1000 );
  160. if( !iAudioThEnd )
  161. {
  162. warteAufThread( 1000 );
  163. if( run )
  164. ende();
  165. Sleep( 100 );
  166. }
  167. }
  168. #endif
  169. return 0;
  170. }
  171. int GSLSound::audioSchreiben( unsigned int uCount )
  172. {
  173. #ifdef WIN32
  174. int iDelta, i, iPos;
  175. WAVEHDR *pHeader;
  176. if( !uAudioWrOk )
  177. return 4;
  178. if( uCount > 0x4000 )
  179. return 2;
  180. if( WaitForSingleObject( hAudioEvent, 2000 ) == WAIT_FAILED )
  181. return 1;
  182. if( uAudioDelay < 8 )
  183. {
  184. aAudioSize[ uAudioDelay ] = uCount;
  185. uAudioDelay++;
  186. hAudioCs.lock(); // increase write pos
  187. uAudioWrite++;
  188. if( uAudioWrite >= uAudioCount )
  189. uAudioWrite = 0;
  190. hAudioCs.unlock();
  191. return 0;
  192. }
  193. if( uAudioDelay == 8 )
  194. {
  195. uAudioDelay++;
  196. for( i = 8; i > 0; i-- )
  197. {
  198. iPos = uAudioWrite - i;
  199. if( iPos < 0 )iPos += uAudioCount;
  200. pHeader = aAudioHdr[ iPos ];
  201. pHeader->dwBufferLength = aAudioSize[ 8 - i ];
  202. if( waveOutWrite( hAudioId, pHeader, sizeof( WAVEHDR ) ) )
  203. return 3;
  204. }
  205. }
  206. pHeader = aAudioHdr[ uAudioWrite ];
  207. pHeader->dwBufferLength = uCount;
  208. if( waveOutWrite( hAudioId, pHeader, sizeof( WAVEHDR ) ) )
  209. return 3;
  210. hAudioCs.lock();
  211. uAudioWrite++;
  212. if( uAudioWrite >= uAudioCount )
  213. uAudioWrite = 0;
  214. iDelta = uAudioPlay - uAudioWrite;
  215. if( iDelta < 0 )
  216. iDelta += uAudioCount;
  217. if( iDelta < 2 )
  218. ResetEvent( hAudioEvent );
  219. hAudioCs.unlock();
  220. #endif
  221. return 0;
  222. }
  223. int GSLSound::audioLesen( char *buff, int len )
  224. {
  225. if( dat->getLPosition() < kpf.datPos )
  226. dat->setLPosition( kpf.datPos, 0 );
  227. if( dat->getLPosition() >= kpf.datEnd )
  228. return -1;
  229. if( dat->getLPosition() + len > kpf.datEnd )
  230. len = (int)( kpf.datEnd - dat->getLPosition() );
  231. if( len > 0 )
  232. dat->lese( buff, len );
  233. #ifdef WIN32
  234. for( int i = 0; i < len; i++, buff++ )
  235. {
  236. if( i % 4 >= 2 )
  237. *buff = (char)( *buff * rechtsV );
  238. else
  239. *buff = (char)( *buff * linksV );
  240. }
  241. #endif
  242. return len;
  243. }
  244. // nicht constant
  245. void GSLSound::playSound()
  246. {
  247. #ifdef WIN32
  248. if( !status )
  249. {
  250. if( _player->addSound( dynamic_cast<GSLSound *>( getThis() ) ) )
  251. status = 1;
  252. if( !audioOpen() )
  253. start();
  254. else
  255. {
  256. _player->removeSound( this );
  257. status = 0;
  258. }
  259. }
  260. setPause( 0 );
  261. #endif
  262. }
  263. void GSLSound::setPause( bool p )
  264. {
  265. #ifdef WIN32
  266. if( p )
  267. {
  268. if( !status )
  269. playSound();
  270. if( status == 1 )
  271. {
  272. waveOutPause( hAudioId );
  273. status = 2;
  274. }
  275. }
  276. else
  277. {
  278. if( status == 2 )
  279. {
  280. waveOutRestart( hAudioId );
  281. status = 1;
  282. }
  283. }
  284. #endif
  285. }
  286. void GSLSound::stopSound()
  287. {
  288. #ifdef WIN32
  289. setPause( 0 );
  290. if( status == 1 )
  291. {
  292. status = 0;
  293. _player->removeSound( this );
  294. audioClose();
  295. }
  296. #endif
  297. }
  298. void GSLSound::warteAufSound( int zeit )
  299. {
  300. warteAufThread( zeit );
  301. }
  302. void GSLSound::setVolume( unsigned int links, unsigned int rechts )
  303. {
  304. #ifdef WIN32
  305. linksV = (float)links / 0xFFFF;
  306. rechtsV = (float)rechts / 0xFFFF;
  307. #endif
  308. }
  309. #ifdef WIN32
  310. void GSLSound::msg( UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
  311. {
  312. WAVEHDR *pHeader;
  313. int iDelta;
  314. switch( uMsg )
  315. {
  316. case WOM_DONE:
  317. pHeader = (WAVEHDR *)dwParam1;
  318. hAudioCs.lock();
  319. InterlockedExchangeAdd( (unsigned __int64 *)& lAudioDone, (__int64)pHeader->dwBufferLength );
  320. iDelta = (int)( uAudioPlay - pHeader->dwUser );
  321. if( iDelta < 0 )
  322. iDelta += uAudioCount;
  323. if( iDelta > ( (int)uAudioCount >> 1 ) )
  324. {
  325. uAudioPlay = (unsigned int)pHeader->dwUser;
  326. if( uAudioPlay >= uAudioCount )
  327. uAudioPlay = 0;
  328. iDelta = uAudioPlay - uAudioWrite;
  329. if( iDelta < 0 )
  330. iDelta += uAudioCount;
  331. if( iDelta >= 2 )
  332. SetEvent( hAudioEvent );
  333. }
  334. hAudioCs.unlock();
  335. break;
  336. }
  337. }
  338. #endif
  339. void GSLSound::thread()
  340. {
  341. #ifdef WIN32
  342. iAudioThEnd = 0;
  343. uAudioStop = 0;
  344. if( !hAudioId )
  345. return;
  346. int iCount;
  347. while( !uAudioStop && hAudioId )
  348. {
  349. iCount = audioLesen( aAudioPtr[ uAudioWrite ], 0x4000 );
  350. if( iCount <= 0 )
  351. break;
  352. audioSchreiben( iCount );
  353. }
  354. iAudioThEnd = 1;
  355. stopSound();
  356. #endif
  357. run = 0;
  358. }
  359. // zum Speichern
  360. void GSLSound::open()
  361. {
  362. #ifdef WIN32
  363. if( !status )
  364. {
  365. dat->open( Datei::Style::lesen );
  366. status = 3;
  367. }
  368. #else
  369. dat->open( Datei::Style::lesen );
  370. #endif
  371. }
  372. int GSLSound::getDaten( char *buffer, int len )
  373. {
  374. #ifdef WIN32
  375. if( status != 3 )
  376. return -1;
  377. #endif
  378. return audioLesen( buffer, len );
  379. }
  380. void GSLSound::close()
  381. {
  382. #ifdef WIN32
  383. if( status == 3 )
  384. {
  385. dat->close();
  386. status = 0;
  387. }
  388. #else
  389. dat->close();
  390. #endif
  391. }
  392. bool GSLSound::istMono() const
  393. {
  394. return kpf.channels == 1;
  395. }
  396. int GSLSound::getSampleRate() const
  397. {
  398. return kpf.sampleRate;
  399. }
  400. __int64 GSLSound::getDatLength() const
  401. {
  402. return kpf.datEnd - kpf.datPos;
  403. }
  404. // constant
  405. #ifdef WIN32
  406. HWAVEOUT GSLSound::getHandle() const
  407. {
  408. return hAudioId;
  409. }
  410. #endif
  411. // Reference Counting
  412. Thread *GSLSound::getThis()
  413. {
  414. return Thread::getThis();
  415. }
  416. Thread *GSLSound::release()
  417. {
  418. #ifdef WIN32
  419. if( ref == 2 && run )
  420. stopSound();
  421. #endif
  422. return Thread::release();
  423. }