Sound.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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. ref = 1;
  32. }
  33. // Destruktor
  34. GSLSound::~GSLSound()
  35. {
  36. #ifdef WIN32
  37. if( status )
  38. stopSound();
  39. #endif
  40. dat->release();
  41. }
  42. // privat
  43. int GSLSound::audioOpen()
  44. {
  45. #ifdef WIN32
  46. WAVEFORMATEX sAudioWm;
  47. sAudioWm.wFormatTag = WAVE_FORMAT_PCM;
  48. sAudioWm.nChannels = kpf.channels;
  49. sAudioWm.nSamplesPerSec = kpf.sampleRate;
  50. sAudioWm.nBlockAlign = ( ( 16 * kpf.channels ) + 7 ) >> 3;
  51. sAudioWm.nAvgBytesPerSec = kpf.sampleRate * sAudioWm.nBlockAlign;
  52. sAudioWm.wBitsPerSample = 16;
  53. sAudioWm.cbSize = 0;
  54. MMRESULT uRes = waveOutOpen( &hAudioId, WAVE_MAPPER, &sAudioWm, (DWORD_PTR)AudioOutProc, 0x00000000, CALLBACK_FUNCTION );
  55. if( uRes || !hAudioId )
  56. {
  57. memset( &sAudioWm, 0, sizeof( sAudioWm ) );
  58. return 1;
  59. }
  60. uAudioDelay = 0;
  61. uAudioWrite = 0;
  62. uAudioStop = 0;
  63. lAudioDone = 0;
  64. for( uAudioCount = 0; uAudioCount < 16; uAudioCount++ )
  65. {
  66. aAudioHdr[ uAudioCount ] = (LPWAVEHDR)GlobalAllocPtr( GMEM_MOVEABLE | GMEM_SHARE, sizeof( WAVEHDR ) + 0x4000 );
  67. if( !aAudioHdr[ uAudioCount ] )
  68. break;
  69. aAudioHdr[ uAudioCount ]->dwFlags = WHDR_DONE;
  70. aAudioHdr[ uAudioCount ]->lpData = (LPSTR)aAudioHdr[ uAudioCount ] + sizeof( WAVEHDR );
  71. aAudioHdr[ uAudioCount ]->dwBufferLength = 0x4000;
  72. aAudioHdr[ uAudioCount ]->dwUser = uAudioCount;
  73. aAudioHdr[ uAudioCount ]->dwBytesRecorded = 0;
  74. aAudioHdr[ uAudioCount ]->dwLoops = 1;
  75. aAudioHdr[ uAudioCount ]->lpNext = 0;
  76. aAudioPtr[ uAudioCount ] = (char*)( aAudioHdr[ uAudioCount ] ) + sizeof( WAVEHDR );
  77. if( !waveOutPrepareHeader( hAudioId, aAudioHdr[ uAudioCount ], sizeof( WAVEHDR ) ) )
  78. continue;
  79. GlobalFreePtr( (LPCVOID)aAudioHdr[ uAudioCount ] );
  80. break;
  81. }
  82. uAudioPlay = uAudioCount - 1;
  83. if( uAudioCount < 12 )
  84. {
  85. audioClose();
  86. return 2;
  87. }
  88. hAudioEvent = CreateEvent( 0, TRUE, TRUE, 0 );
  89. if( !hAudioEvent )
  90. {
  91. audioClose();
  92. return 3;
  93. }
  94. if( waveOutGetDevCaps( (UINT_PTR)hAudioId, (LPWAVEOUTCAPSA)&sAudioCaps, sizeof( WAVEOUTCAPS ) ) )
  95. memset( &sAudioCaps, 0, sizeof( sAudioCaps ) );
  96. waveOutReset( hAudioId );
  97. waveOutSetVolume( hAudioId, 0xFFFFFFFF );
  98. #endif
  99. dat->open( Datei::Style::lesen );
  100. #ifdef WIN32
  101. uAudioWrOk = 1;
  102. #endif
  103. return 0;
  104. }
  105. int GSLSound::audioClose()
  106. {
  107. int iErr = 0;
  108. #ifdef WIN32
  109. if( !hAudioId )
  110. return 1;
  111. audioStop();
  112. while( uAudioCount > 0 )
  113. {
  114. uAudioCount--;
  115. if( waveOutUnprepareHeader( hAudioId, aAudioHdr[ uAudioCount ], sizeof( WAVEHDR ) ) )
  116. iErr = 1;
  117. if( GlobalFreePtr( (LPCVOID)aAudioHdr[ uAudioCount ] ) )
  118. iErr = 1;
  119. aAudioHdr[ uAudioCount ] = 0;
  120. aAudioPtr[ uAudioCount ] = 0;
  121. }
  122. if( waveOutClose( hAudioId ) )
  123. iErr = 1;
  124. if( !CloseHandle( hAudioEvent ) )
  125. iErr = 1;
  126. hAudioId = 0;
  127. uAudioWrite = 0;
  128. uAudioDelay = 0;
  129. uAudioPlay = uAudioCount - 1;
  130. #endif
  131. dat->close();
  132. return iErr;
  133. }
  134. int GSLSound::audioStop()
  135. {
  136. #ifdef WIN32
  137. unsigned uPos;
  138. if( !hAudioId )
  139. return 1;
  140. uAudioStop = 1;
  141. uAudioWrOk = 0;
  142. warteAufThread( 5000 );
  143. SetEvent( hAudioEvent );
  144. waveOutReset( hAudioId );
  145. if( uAudioWrite != 0 && uAudioPlay != uAudioCount - 1 )
  146. {
  147. for( uPos = 0; uPos < uAudioCount; uPos++ ) // clears all buffers
  148. {
  149. memset( aAudioHdr[ uPos ]->lpData, 0, 0x4000 );
  150. break;
  151. }
  152. }
  153. uAudioPlay = uAudioCount - 1;
  154. uAudioWrite = 0;
  155. uAudioDelay = 0;
  156. SetEvent( hAudioEvent );
  157. uAudioWrOk = 1;
  158. if( isRunning() ) // close thread
  159. {
  160. warteAufThread( 1000 );
  161. if( !iAudioThEnd )
  162. {
  163. warteAufThread( 1000 );
  164. if( run )
  165. ende();
  166. Sleep( 100 );
  167. }
  168. }
  169. #endif
  170. return 0;
  171. }
  172. int GSLSound::audioSchreiben( unsigned int uCount )
  173. {
  174. #ifdef WIN32
  175. int iDelta, i, iPos;
  176. WAVEHDR *pHeader;
  177. if( !uAudioWrOk )
  178. return 4;
  179. if( uCount > 0x4000 )
  180. return 2;
  181. if( WaitForSingleObject( hAudioEvent, 2000 ) == WAIT_FAILED )
  182. return 1;
  183. if( uAudioDelay < 8 )
  184. {
  185. aAudioSize[ uAudioDelay ] = uCount;
  186. uAudioDelay++;
  187. hAudioCs.lock(); // increase write pos
  188. uAudioWrite++;
  189. if( uAudioWrite >= uAudioCount )
  190. uAudioWrite = 0;
  191. hAudioCs.unlock();
  192. return 0;
  193. }
  194. if( uAudioDelay == 8 )
  195. {
  196. uAudioDelay++;
  197. for( i = 8; i > 0; i-- )
  198. {
  199. iPos = uAudioWrite - i;
  200. if( iPos < 0 )iPos += uAudioCount;
  201. pHeader = aAudioHdr[ iPos ];
  202. pHeader->dwBufferLength = aAudioSize[ 8 - i ];
  203. if( waveOutWrite( hAudioId, pHeader, sizeof( WAVEHDR ) ) )
  204. return 3;
  205. }
  206. }
  207. pHeader = aAudioHdr[ uAudioWrite ];
  208. pHeader->dwBufferLength = uCount;
  209. if( waveOutWrite( hAudioId, pHeader, sizeof( WAVEHDR ) ) )
  210. return 3;
  211. hAudioCs.lock();
  212. uAudioWrite++;
  213. if( uAudioWrite >= uAudioCount )
  214. uAudioWrite = 0;
  215. iDelta = uAudioPlay - uAudioWrite;
  216. if( iDelta < 0 )
  217. iDelta += uAudioCount;
  218. if( iDelta < 2 )
  219. ResetEvent( hAudioEvent );
  220. hAudioCs.unlock();
  221. #endif
  222. return 0;
  223. }
  224. int GSLSound::audioLesen( char *buff, int len )
  225. {
  226. if( dat->getLPosition() < kpf.datPos )
  227. dat->setLPosition( kpf.datPos, 0 );
  228. if( dat->getLPosition() >= kpf.datEnd )
  229. return -1;
  230. if( dat->getLPosition() + len > kpf.datEnd )
  231. len = (int)( kpf.datEnd - dat->getLPosition() );
  232. if( len > 0 )
  233. dat->lese( buff, len );
  234. #ifdef WIN32
  235. for( int i = 0; i < len; i++, buff++ )
  236. {
  237. if( i % 4 >= 2 )
  238. *buff = (char)( *buff * rechtsV );
  239. else
  240. *buff = (char)( *buff * 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( (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
  412. // Reference Counting
  413. GSLSoundV *GSLSound::getThis()
  414. {
  415. ref++;
  416. return this;
  417. }
  418. GSLSoundV *GSLSound::release()
  419. {
  420. ref--;
  421. if( !ref )
  422. delete this;
  423. return 0;
  424. }