Sound.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  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. short *ucb = (short *)buff;
  235. for( int i = 0; i < len / 2; i++, ucb++ )
  236. {
  237. if( i % 2 == 1 )
  238. *ucb = (short)( *ucb * rechtsV );
  239. else
  240. *ucb = (short)( *ucb * linksV );
  241. }
  242. #endif
  243. return len;
  244. }
  245. // nicht constant
  246. void GSLSound::playSound()
  247. {
  248. #ifdef WIN32
  249. if( !status )
  250. {
  251. if( _player->addSound( dynamic_cast<GSLSound *>( getThis() ) ) )
  252. status = 1;
  253. if( !audioOpen() )
  254. start();
  255. else
  256. {
  257. _player->removeSound( this );
  258. status = 0;
  259. }
  260. }
  261. setPause( 0 );
  262. #endif
  263. }
  264. void GSLSound::setPause( bool p )
  265. {
  266. #ifdef WIN32
  267. if( p )
  268. {
  269. if( !status )
  270. playSound();
  271. if( status == 1 )
  272. {
  273. waveOutPause( hAudioId );
  274. status = 2;
  275. }
  276. }
  277. else
  278. {
  279. if( status == 2 )
  280. {
  281. waveOutRestart( hAudioId );
  282. status = 1;
  283. }
  284. }
  285. #endif
  286. }
  287. void GSLSound::stopSound()
  288. {
  289. #ifdef WIN32
  290. setPause( 0 );
  291. if( status == 1 )
  292. {
  293. status = 0;
  294. _player->removeSound( this );
  295. audioClose();
  296. }
  297. #endif
  298. }
  299. void GSLSound::warteAufSound( int zeit )
  300. {
  301. warteAufThread( zeit );
  302. }
  303. void GSLSound::setVolume( unsigned int links, unsigned int rechts )
  304. {
  305. #ifdef WIN32
  306. linksV = (float)links / 0xFFFF;
  307. rechtsV = (float)rechts / 0xFFFF;
  308. #endif
  309. }
  310. #ifdef WIN32
  311. void GSLSound::msg( UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2 )
  312. {
  313. WAVEHDR *pHeader;
  314. int iDelta;
  315. switch( uMsg )
  316. {
  317. case WOM_DONE:
  318. pHeader = (WAVEHDR *)dwParam1;
  319. hAudioCs.lock();
  320. InterlockedExchangeAdd( (unsigned __int64 *)&lAudioDone, (__int64)pHeader->dwBufferLength );
  321. iDelta = (int)( uAudioPlay - pHeader->dwUser );
  322. if( iDelta < 0 )
  323. iDelta += uAudioCount;
  324. if( iDelta > ( (int)uAudioCount >> 1 ) )
  325. {
  326. uAudioPlay = (unsigned int)pHeader->dwUser;
  327. if( uAudioPlay >= uAudioCount )
  328. uAudioPlay = 0;
  329. iDelta = uAudioPlay - uAudioWrite;
  330. if( iDelta < 0 )
  331. iDelta += uAudioCount;
  332. if( iDelta >= 2 )
  333. SetEvent( hAudioEvent );
  334. }
  335. hAudioCs.unlock();
  336. break;
  337. }
  338. }
  339. #endif
  340. void GSLSound::thread()
  341. {
  342. #ifdef WIN32
  343. iAudioThEnd = 0;
  344. uAudioStop = 0;
  345. if( !hAudioId )
  346. return;
  347. int iCount;
  348. while( !uAudioStop && hAudioId )
  349. {
  350. iCount = audioLesen( aAudioPtr[ uAudioWrite ], 0x4000 );
  351. if( iCount <= 0 )
  352. break;
  353. audioSchreiben( iCount );
  354. }
  355. iAudioThEnd = 1;
  356. stopSound();
  357. #endif
  358. run = 0;
  359. }
  360. // zum Speichern
  361. void GSLSound::open()
  362. {
  363. #ifdef WIN32
  364. if( !status )
  365. {
  366. dat->open( Datei::Style::lesen );
  367. status = 3;
  368. }
  369. #else
  370. dat->open( Datei::Style::lesen );
  371. #endif
  372. }
  373. int GSLSound::getDaten( char *buffer, int len )
  374. {
  375. #ifdef WIN32
  376. if( status != 3 )
  377. return -1;
  378. #endif
  379. return audioLesen( buffer, len );
  380. }
  381. void GSLSound::close()
  382. {
  383. #ifdef WIN32
  384. if( status == 3 )
  385. {
  386. dat->close();
  387. status = 0;
  388. }
  389. #else
  390. dat->close();
  391. #endif
  392. }
  393. bool GSLSound::istMono() const
  394. {
  395. return kpf.channels == 1;
  396. }
  397. int GSLSound::getSampleRate() const
  398. {
  399. return kpf.sampleRate;
  400. }
  401. __int64 GSLSound::getDatLength() const
  402. {
  403. return kpf.datEnd - kpf.datPos;
  404. }
  405. // constant
  406. #ifdef WIN32
  407. HWAVEOUT GSLSound::getHandle() const
  408. {
  409. return hAudioId;
  410. }
  411. #endif