OAUDIO.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OAUDIO.CPP
  21. //Description : Object Midi Audio and Digitized Sound
  22. //Ownership : Gilbert
  23. #include <windows.h>
  24. #include <windowsx.h>
  25. #include <commdlg.h>
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <direct.h>
  30. #include <mmsystem.h>
  31. #include <string.h>
  32. #include <limits.h>
  33. #include <OSYS.h>
  34. #include <OBOX.h>
  35. #include <OAUDIO.h>
  36. #include <OVGALOCK.h>
  37. //---------------- Define constant ------------------//
  38. //
  39. // DirectSoundBuffer size = LWAV_STREAM_BUFSIZ * LWAV_BANKS
  40. // if it is going to play a high transfer rate wave
  41. // (e.g. 16-bit 44.1kHz Stereo), increase LWAV_STREAM_BUFSIZ
  42. //
  43. //---------------------------------------------------//
  44. #define LWAV_STREAM_BUFSIZ 0x1000
  45. #define LWAV_BANKS 4
  46. #define LOOPWAV_STREAM_BUFSIZ 0x1000
  47. #define LOOPWAV_BANKS 4
  48. #ifndef DSBCAPS_CTRLDEFAULT
  49. #define DSBCAPS_CTRLDEFAULT (DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME)
  50. #endif
  51. //---------- Define static variables ---------//
  52. static MCI_PLAY_PARMS mci_play;
  53. static MCI_OPEN_PARMS mci_open;
  54. static MCI_SET_PARMS mci_set;
  55. //--------- Begin of function wavefile_offset -------//
  56. //
  57. // find the "data" tag in a wave file
  58. //
  59. static char * wavefile_data(char *wavfile_buf)
  60. {
  61. //----- position at WAVEfmt tag size ------//
  62. char *p = wavfile_buf+0x10;
  63. DWORD tagSize=*(DWORD *)p;
  64. //-------- go to next tag field -----------//
  65. for( p += sizeof(DWORD)+tagSize; strncmp(p, "data", 4) != 0;
  66. p += sizeof(DWORD)+tagSize)
  67. {
  68. p += 4; // pointing at size of tag field
  69. tagSize = *(DWORD *)p; // get the size of this tage field
  70. if(p - wavfile_buf > 128)
  71. return NULL;
  72. }
  73. //----- p pointing at the start of "data" tag ------//
  74. return p;
  75. }
  76. //--------- End of function wavefile_offset------------//
  77. //--------- Begin of function Audio::Audio ----------//
  78. Audio::Audio()
  79. {
  80. init_flag = 0;
  81. }
  82. //--------- Begin of function Audio::Audio ----------//
  83. //--------- Begin of function Audio::~Audio ----------//
  84. Audio::~Audio()
  85. {
  86. deinit();
  87. }
  88. //--------- Begin of function Audio::~Audio ----------//
  89. //--------- Begin of function Audio::init ----------//
  90. //
  91. // Initialize the mid driver
  92. //
  93. // return : <int> 1 - initialized successfully
  94. // 0 - init fail
  95. //
  96. int Audio::init()
  97. {
  98. //-------- init vars -----------//
  99. run_yield = 0;
  100. mid_init_flag = 0; // the init flag is on when the driver is initialized successfully
  101. wav_init_flag = 0;
  102. cd_init_flag = 0;
  103. mid_flag = 1;
  104. wav_flag = 1;
  105. cd_flag = 1;
  106. mid_buf = NULL;
  107. wav_buf = NULL;
  108. mid_buf_size = 0;
  109. wav_buf_size = 0;
  110. int i;
  111. for(i = 0; i < MAX_WAV_CHANNEL; ++i)
  112. {
  113. lp_wav_ch_dsb[i] = NULL;
  114. wav_serial_no[i] = 0;
  115. }
  116. max_lwav_serial_no = 0;
  117. for(i=0; i < MAX_LONG_WAV_CH; ++i)
  118. {
  119. lp_lwav_ch_dsb[i] = NULL;
  120. lwav_serial_no[i] = 0;
  121. lwav_fileptr[i] = NULL;
  122. }
  123. max_lwav_serial_no = 0;
  124. for(i=0; i < MAX_LOOP_WAV_CH; ++i)
  125. {
  126. lp_loop_ch_dsb[i] = NULL;
  127. loopwav_fileptr[i] = NULL;
  128. }
  129. // wav_volume = 0;
  130. wav_volume = 100; // 0(slient) - 100(loudest)
  131. //--------- init devices ----------//
  132. if( init_wav() )
  133. {
  134. wav_res.init( DIR_RES"A_WAVE2.RES", 0, 0 ); // 2nd 0-don't read all, 3rd 0-don't use vga buffer
  135. wav_buf = mem_add(DEFAULT_WAV_BUF_SIZE);
  136. wav_buf_size = DEFAULT_WAV_BUF_SIZE;
  137. }
  138. /*
  139. if( init_mid() )
  140. {
  141. mid_res.init( DIR_RES"A_MIDI.RES", 0, 0 ); // 2nd 0-don't read all, 3rd 0-don't use vga buffer
  142. mid_buf = mem_add(DEFAULT_MID_BUF_SIZE);
  143. mid_buf_size = DEFAULT_MID_BUF_SIZE;
  144. }
  145. */
  146. init_cd();
  147. //----------------------------------//
  148. init_flag = wav_init_flag || cd_init_flag;
  149. return 1;
  150. }
  151. //--------- End of function Audio::init ----------//
  152. //--------- Begin of function Audio::deinit ----------//
  153. void Audio::deinit()
  154. {
  155. if( init_flag )
  156. {
  157. //------- deinit vars --------//
  158. run_yield = 0;
  159. init_flag = 0;
  160. //------- deinit devices -------//
  161. deinit_wav();
  162. deinit_mid();
  163. deinit_cd();
  164. }
  165. }
  166. //--------- End of function Audio::deinit ----------//
  167. //--------- Begin of function Audio::init_wav ----------//
  168. //
  169. // Initialize digitized wav driver
  170. //
  171. // return : <int> 1 - initialized successfully
  172. // 0 - init fail
  173. //
  174. int Audio::init_wav()
  175. {
  176. if( wav_init_flag )
  177. return 1;
  178. //-------- create DirectSound object -------//
  179. HRESULT rc=DirectSoundCreate(NULL, &lp_direct_sound, NULL);
  180. //------------------------------------------//
  181. if( rc==DS_OK ) // Create succeeded
  182. {
  183. lp_direct_sound->SetCooperativeLevel(sys.main_hwnd, DSSCL_NORMAL);
  184. wav_init_flag=1;
  185. }
  186. return wav_init_flag;
  187. }
  188. //--------- End of function Audio::init_wav ----------//
  189. //--------- Begin of function Audio::init_mid ----------//
  190. //
  191. // Initialize MIDI mid driver
  192. //
  193. // return : <int> 1 - initialized successfully
  194. // 0 - init fail
  195. //
  196. int Audio::init_mid()
  197. {
  198. if( mid_init_flag )
  199. return 1;
  200. //.. insert code here ...//
  201. mid_init_flag=1;
  202. return 1;
  203. }
  204. //--------- End of function Audio::init_mid ----------//
  205. //--------- Begin of function Audio::init_cd ----------//
  206. //
  207. // Initialize the audio CD player
  208. //
  209. // return : <int> 1 - initialized successfully
  210. // 0 - init fail
  211. //
  212. int Audio::init_cd()
  213. {
  214. mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;
  215. if( mciSendCommand( NULL, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID,
  216. (DWORD) (LPVOID) &mci_open) == 0 ||
  217. mciSendCommand( NULL, MCI_OPEN, MCI_OPEN_TYPE |
  218. MCI_OPEN_TYPE_ID | MCI_OPEN_SHAREABLE,
  219. (DWORD) (LPVOID) &mci_open)== 0 )
  220. {
  221. mci_set.dwTimeFormat = MCI_FORMAT_TMSF;
  222. mciSendCommand( mci_open.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT,
  223. (DWORD) (LPVOID) &mci_set);
  224. cd_init_flag = 1;
  225. return 1;
  226. }
  227. cd_init_flag = 0;
  228. return 0;
  229. }
  230. //--------- End of function Audio::init_cd ----------//
  231. //--------- Begin of function Audio::deinit_cd ----------//
  232. void Audio::deinit_cd()
  233. {
  234. if( cd_init_flag )
  235. {
  236. stop_cd();
  237. mciSendString ("close cdaudio", NULL, 0, NULL);
  238. cd_init_flag = 0;
  239. }
  240. }
  241. //--------- End of function Audio::deinit_cd ----------//
  242. //--------- Begin of function Audio::deinit_wav ----------//
  243. void Audio::deinit_wav()
  244. {
  245. stop_wav();
  246. if( wav_buf )
  247. {
  248. mem_del(wav_buf);
  249. wav_buf = NULL;
  250. }
  251. if(wav_init_flag)
  252. {
  253. lp_direct_sound->Release();
  254. wav_init_flag = 0;
  255. }
  256. }
  257. //--------- End of function Audio::deinit_wav ----------//
  258. //--------- Begin of function Audio::deinit_mid ----------//
  259. void Audio::deinit_mid()
  260. {
  261. if( !mid_init_flag )
  262. return;
  263. stop_mid();
  264. //.. insert code here ...//
  265. mem_del(mid_buf);
  266. mid_buf = NULL;
  267. mid_init_flag = 0;
  268. }
  269. //--------- End of function Audio::deinit_mid ----------//
  270. //------- Begin of function Audio::play_mid -------//
  271. //
  272. // Play a midi mid from the mid resource file
  273. //
  274. // <char*> midName = name of the mid in the resource file
  275. //
  276. // return : <int> 1 - mid loaded and is playing
  277. // 0 - mid not played
  278. //
  279. int Audio::play_mid(char* midName)
  280. {
  281. if( !mid_init_flag || !mid_flag ) // a initialized and workable midi device can be disabled by user setting
  282. return 0;
  283. stop_mid(); // stop currently playing mid if any
  284. //------ Load mid file -------//
  285. int dataSize;
  286. File* filePtr = mid_res.get_file(midName, dataSize);
  287. if( !filePtr )
  288. return 0;
  289. if( dataSize > mid_buf_size )
  290. {
  291. mid_buf_size = dataSize;
  292. mid_buf = mem_resize( mid_buf, mid_buf_size );
  293. }
  294. if( !filePtr->file_read( mid_buf, dataSize ) )
  295. return 0;
  296. //-------- Play mid file --------//
  297. //.. insert code here ...//
  298. return 1;
  299. }
  300. //------- End of function Audio::play_mid -------//
  301. //------- Begin of function Audio::stop_mid -------//
  302. //
  303. void Audio::stop_mid()
  304. {
  305. if( !mid_init_flag || !mid_flag )
  306. return;
  307. //.. insert code here ...//
  308. mciSendCommand(mci_open.wDeviceID, MCI_STOP, NULL, NULL);
  309. }
  310. //------- End of function Audio::stop_mid -------//
  311. //------- Begin of function Audio::play_wav -------//
  312. //
  313. // Play digitized wav from the wav resource file
  314. //
  315. // <char*> wavName = name of the wav in the resource file
  316. // long vol = volume (0 to 100)
  317. // long pan = pan (-10000 to 10000)
  318. //
  319. // return : <int> non-zero - wav loaded and is playing, return a serial no. to be referred in stop_wav and is_wav_playing
  320. // 0 - wav not played
  321. //
  322. int Audio::play_wav(char* wavName, DsVolume dsVolume)
  323. {
  324. /*
  325. //---- redirect to play_long_wav -------//
  326. String str;
  327. str = DIR_SOUND;
  328. str += wavName;
  329. str += ".WAV";
  330. if( m.is_file_exist(str) )
  331. return play_long_wav(str);
  332. else
  333. return 0;
  334. //------------------------------------//
  335. */
  336. if( !wav_init_flag || !wav_flag ) // a initialized and workable midi device can be disabled by user setting
  337. return 0;
  338. //-------- Load wav file header-------//
  339. int dataSize;
  340. DWORD wavDataOffset, wavDataLength;
  341. File* filePtr = wav_res.get_file(wavName, dataSize);
  342. if( !filePtr )
  343. return 0;
  344. // load small part of the wave file (first 128 bytes) enough to hold
  345. // the hold header
  346. //#define LOAD_FULL_WAVE
  347. #ifdef LOAD_FULL_WAVE
  348. if( dataSize > wav_buf_size )
  349. {
  350. wav_buf_size = dataSize;
  351. wav_buf = mem_resize( wav_buf, wav_buf_size );
  352. }
  353. if( !filePtr->file_read( wav_buf, dataSize))
  354. #else
  355. if( !filePtr->file_read( wav_buf, 128 ) )
  356. #endif
  357. return 0;
  358. // short-cut to test play_resided_wave()
  359. #ifdef LOAD_FULL_WAVE
  360. return play_resided_wav(wav_buf);
  361. #endif
  362. // determine the wave data offset and length
  363. char * dataTag = wavefile_data(wav_buf);
  364. if (!dataTag)
  365. {
  366. err_now("Invalid wave file format");
  367. return 0; // invalid RIFF WAVE format
  368. }
  369. wavDataOffset = (dataTag - wav_buf) + 4 + sizeof(DWORD);
  370. wavDataLength = *(DWORD *)(dataTag+4);
  371. #ifndef LOAD_FULL_WAVE
  372. // seek to the start of wave data
  373. filePtr->file_seek(wavDataOffset-128,FILE_CURRENT);
  374. #endif
  375. //------- Create DirectSoundBuffer to store a wave ------//
  376. LPDIRECTSOUNDBUFFER lpDsb;
  377. DSBUFFERDESC dsbDesc;
  378. HRESULT hr;
  379. DWORD dsbStatus;
  380. // set up DSBUFFERDESC structure
  381. memset(&dsbDesc, 0, sizeof(DSBUFFERDESC)); // zero it out
  382. dsbDesc.dwSize = sizeof(DSBUFFERDESC);
  383. dsbDesc.dwFlags = DSBCAPS_CTRLDEFAULT; // Need defaul controls (pan, volume, frequency)
  384. dsbDesc.dwBufferBytes = wavDataLength;
  385. dsbDesc.lpwfxFormat = (LPWAVEFORMATEX) (wav_buf+0x14);
  386. // ------- assign buffer to a channel number ----------//
  387. lpDsb = NULL;
  388. int chanNum;
  389. for( chanNum = 0; chanNum < MAX_WAV_CHANNEL; ++chanNum)
  390. if(lp_wav_ch_dsb[chanNum] == NULL || (lp_wav_ch_dsb[chanNum]->GetStatus(&dsbStatus),
  391. !(dsbStatus & DSBSTATUS_PLAYING)))
  392. {
  393. if(lp_wav_ch_dsb[chanNum])
  394. {
  395. lp_wav_ch_dsb[chanNum]->Release();
  396. lp_wav_ch_dsb[chanNum] = NULL;
  397. }
  398. // found an idle channel, create DirectSoundBuffer
  399. hr = lp_direct_sound->CreateSoundBuffer(&dsbDesc, &lpDsb, NULL);
  400. if (DS_OK != hr)
  401. {
  402. // failed!
  403. err_now("Cannot create DirectSoundBuffer");
  404. return 0;
  405. }
  406. lp_wav_ch_dsb[chanNum] = lpDsb;
  407. break;
  408. }
  409. if( chanNum >= MAX_WAV_CHANNEL)
  410. {
  411. return 0;
  412. }
  413. // Note : if not found, just play the sound, don't play the sound
  414. // increase MAX_WAV_CHANNEL
  415. //------- copy sound data to DirectSoundBuffer--------//
  416. // unlock vga_front
  417. VgaFrontLock vgaLock;
  418. // lock the buffer first
  419. LPVOID lpvPtr1;
  420. DWORD dwBytes1;
  421. LPVOID lpvPtr2;
  422. DWORD dwBytes2;
  423. hr = lpDsb->Lock(0, wavDataLength, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
  424. if(DS_OK != hr)
  425. {
  426. // fail to lock
  427. err_now("Cannot lock DirectSoundBuffer");
  428. return 0;
  429. }
  430. // write to pointers
  431. #ifdef LOAD_FULL_WAVE
  432. memcpy(lpvPtr1, wav_buf+wavDataOffset, dwBytes1);
  433. #else
  434. filePtr->file_read(lpvPtr1, dwBytes1);
  435. #endif
  436. if(lpvPtr2)
  437. {
  438. #ifdef LOAD_FULL_WAVE
  439. memcpy(lpvPtr2, wav_buf+wavDataOffset+dwBytes1, dwBytes2);
  440. #else
  441. filePtr->file_read(lpvPtr2, dwBytes2);
  442. #endif
  443. }
  444. // unlock data back
  445. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  446. if(DS_OK != hr)
  447. {
  448. // fail to unlock
  449. err_now("Cannot unlock DirectSoundBuffer");
  450. return 0;
  451. }
  452. //------- Set volume and pan -----------//
  453. lpDsb->SetVolume(dsVolume.ds_vol);
  454. lpDsb->SetPan(dsVolume.ds_pan);
  455. //------- Play wav file --------//
  456. if(lpDsb->Play(0, 0, 0) != DS_OK)
  457. {
  458. // fail to play
  459. err_now("Cannot play DirectSoundBuffer");
  460. return 0;
  461. }
  462. return wav_serial_no[chanNum] = assign_serial(max_wav_serial_no);
  463. }
  464. //------- End of function Audio::play_wav -------//
  465. //------- Begin of function Audio::play_wav -------//
  466. //
  467. // Play digitized wav from the wav resource file
  468. //
  469. // short resIdx = index of wave file in A_WAVE2.RES
  470. // long vol = volume (0 to 100)
  471. // long pan = pan (-10000 to 10000)
  472. //
  473. // return : <int> 1 - wav loaded and is playing
  474. // 0 - wav not played
  475. //
  476. int Audio::play_wav(short resIdx, DsVolume dsVolume)
  477. {
  478. if( !wav_init_flag || !wav_flag ) // a initialized and workable midi device can be disabled by user setting
  479. return 0;
  480. //-------- Load wav file header-------//
  481. int dataSize;
  482. DWORD wavDataOffset, wavDataLength;
  483. File* filePtr = wav_res.get_file(resIdx, dataSize);
  484. if( !filePtr )
  485. return 0;
  486. // load small part of the wave file (first 128 bytes) enough to hold
  487. // the hold header
  488. #ifdef LOAD_FULL_WAVE
  489. if( dataSize > wav_buf_size )
  490. {
  491. wav_buf_size = dataSize;
  492. wav_buf = mem_resize( wav_buf, wav_buf_size );
  493. }
  494. if( !filePtr->file_read( wav_buf, dataSize))
  495. #else
  496. if( !filePtr->file_read( wav_buf, 128 ) )
  497. #endif
  498. return 0;
  499. // short-cut to test play_resided_wave()
  500. #ifdef LOAD_FULL_WAVE
  501. return play_resided_wav(wav_buf);
  502. #endif
  503. // determine the wave data offset and length
  504. char * dataTag = wavefile_data(wav_buf);
  505. if (!dataTag)
  506. {
  507. err_now("Invalid wave file format");
  508. return 0; // invalid RIFF WAVE format
  509. }
  510. wavDataOffset = (dataTag - wav_buf) + 4 + sizeof(DWORD);
  511. wavDataLength = *(DWORD *)(dataTag+4);
  512. #ifndef LOAD_FULL_WAVE
  513. // seek to the start of wave data
  514. filePtr->file_seek(wavDataOffset-128,FILE_CURRENT);
  515. #endif
  516. //------- Create DirectSoundBuffer to store a wave ------//
  517. LPDIRECTSOUNDBUFFER lpDsb;
  518. DSBUFFERDESC dsbDesc;
  519. HRESULT hr;
  520. DWORD dsbStatus;
  521. // set up DSBUFFERDESC structure
  522. memset(&dsbDesc, 0, sizeof(DSBUFFERDESC)); // zero it out
  523. dsbDesc.dwSize = sizeof(DSBUFFERDESC);
  524. dsbDesc.dwFlags = DSBCAPS_CTRLDEFAULT; // Need defaul controls (pan, volume, frequency)
  525. dsbDesc.dwBufferBytes = wavDataLength;
  526. dsbDesc.lpwfxFormat = (LPWAVEFORMATEX) (wav_buf+0x14);
  527. // ------- assign buffer to a channel number ----------//
  528. lpDsb = NULL;
  529. int chanNum;
  530. for( chanNum = 0; chanNum < MAX_WAV_CHANNEL; ++chanNum)
  531. if(lp_wav_ch_dsb[chanNum] == NULL || (lp_wav_ch_dsb[chanNum]->GetStatus(&dsbStatus),
  532. !(dsbStatus & DSBSTATUS_PLAYING)))
  533. {
  534. if(lp_wav_ch_dsb[chanNum])
  535. {
  536. lp_wav_ch_dsb[chanNum]->Release();
  537. lp_wav_ch_dsb[chanNum] = NULL;
  538. }
  539. // found an idle channel, create DirectSoundBuffer
  540. hr = lp_direct_sound->CreateSoundBuffer(&dsbDesc, &lpDsb, NULL);
  541. if (DS_OK != hr)
  542. {
  543. // failed!
  544. err_now("Cannot create DirectSoundBuffer");
  545. return 0;
  546. }
  547. lp_wav_ch_dsb[chanNum] = lpDsb;
  548. break;
  549. }
  550. if( chanNum >= MAX_WAV_CHANNEL)
  551. {
  552. return 0;
  553. }
  554. // Note : if not found, just play the sound, don't play the sound
  555. // increase MAX_WAV_CHANNEL
  556. //------- copy sound data to DirectSoundBuffer--------//
  557. // unlock vga_front
  558. VgaFrontLock vgaLock;
  559. // lock the buffer first
  560. LPVOID lpvPtr1;
  561. DWORD dwBytes1;
  562. LPVOID lpvPtr2;
  563. DWORD dwBytes2;
  564. hr = lpDsb->Lock(0, wavDataLength, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
  565. if(DS_OK != hr)
  566. {
  567. // fail to lock
  568. err_now("Cannot lock DirectSoundBuffer");
  569. return 0;
  570. }
  571. // write to pointers
  572. #ifdef LOAD_FULL_WAVE
  573. memcpy(lpvPtr1, wav_buf+wavDataOffset, dwBytes1);
  574. #else
  575. filePtr->file_read(lpvPtr1, dwBytes1);
  576. #endif
  577. if(lpvPtr2)
  578. {
  579. #ifdef LOAD_FULL_WAVE
  580. memcpy(lpvPtr2, wav_buf+wavDataOffset+dwBytes1, dwBytes2);
  581. #else
  582. filePtr->file_read(lpvPtr2, dwBytes2);
  583. #endif
  584. }
  585. // unlock data back
  586. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  587. if(DS_OK != hr)
  588. {
  589. // fail to unlock
  590. err_now("Cannot unlock DirectSoundBuffer");
  591. return 0;
  592. }
  593. //------- Set volume and pan -----------//
  594. lpDsb->SetVolume(dsVolume.ds_vol);
  595. lpDsb->SetPan(dsVolume.ds_pan);
  596. //------- Play wav file --------//
  597. if(lpDsb->Play(0, 0, 0) != DS_OK)
  598. {
  599. // fail to play
  600. err_now("Cannot play DirectSoundBuffer");
  601. return 0;
  602. }
  603. return wav_serial_no[chanNum] = assign_serial(max_wav_serial_no);
  604. }
  605. //------- End of function Audio::play_wav -------//
  606. //------- Begin of function Audio::play_resided_wav -------//
  607. //
  608. // Play digitized wav from the wav file in memory
  609. //
  610. // <char*> wavBuf = point to the wav in memory
  611. // long vol = volume (0 to 100)
  612. // long pan = pan (-10000 to 10000)
  613. //
  614. // return : <int> 1 - wav loaded and is playing
  615. // 0 - wav not played
  616. //
  617. int Audio::play_resided_wav(char* wavBuf, DsVolume dsVolume)
  618. {
  619. if( !wav_init_flag || !wav_flag ) // a initialized and workable midi device can be disabled by user setting
  620. return 0;
  621. //-------- Load wav file header-------//
  622. DWORD wavDataOffset, wavDataLength;
  623. // determine the wave data offset and length
  624. char * dataTag = wavefile_data(wavBuf);
  625. if (!dataTag)
  626. {
  627. err_now("Invalid wave file format");
  628. return 0; // invalid RIFF WAVE format
  629. }
  630. wavDataOffset = (dataTag - wavBuf) + 4 + sizeof(DWORD);
  631. wavDataLength = *(DWORD *)(dataTag+4);
  632. //------- Create DirectSoundBuffer to store a wave ------//
  633. LPDIRECTSOUNDBUFFER lpDsb;
  634. DSBUFFERDESC dsbDesc;
  635. HRESULT hr;
  636. DWORD dsbStatus;
  637. // set up DSBUFFERDESC structure
  638. memset(&dsbDesc, 0, sizeof(DSBUFFERDESC)); // zero it out
  639. dsbDesc.dwSize = sizeof(DSBUFFERDESC);
  640. dsbDesc.dwFlags = DSBCAPS_CTRLDEFAULT; // Need defaul controls (pan, volume, frequency)
  641. dsbDesc.dwBufferBytes = wavDataLength;
  642. dsbDesc.lpwfxFormat = (LPWAVEFORMATEX) (wavBuf+0x14);
  643. // ------- assign buffer to a channel number ----------//
  644. lpDsb = NULL;
  645. int chanNum;
  646. for( chanNum = 0; chanNum < MAX_WAV_CHANNEL; ++chanNum)
  647. if(lp_wav_ch_dsb[chanNum] == NULL || (lp_wav_ch_dsb[chanNum]->GetStatus(&dsbStatus),
  648. !(dsbStatus & DSBSTATUS_PLAYING)))
  649. {
  650. if(lp_wav_ch_dsb[chanNum])
  651. {
  652. lp_wav_ch_dsb[chanNum]->Release();
  653. lp_wav_ch_dsb[chanNum] = NULL;
  654. }
  655. // found an idle channel, create DirectSoundBuffer
  656. hr = lp_direct_sound->CreateSoundBuffer(&dsbDesc, &lpDsb, NULL);
  657. if (DS_OK != hr)
  658. {
  659. // failed!
  660. err_now("Cannot create DirectSoundBuffer");
  661. return 0;
  662. }
  663. lp_wav_ch_dsb[chanNum] = lpDsb;
  664. break;
  665. }
  666. if( chanNum >= MAX_WAV_CHANNEL)
  667. {
  668. return 0;
  669. }
  670. // Note : if not found, just play the sound, don't play the sound
  671. // increase MAX_WAV_CHANNEL
  672. //------- copy sound data to DirectSoundBuffer--------//
  673. // unlock vga_front
  674. VgaFrontLock vgaLock;
  675. // lock the buffer first
  676. LPVOID lpvPtr1;
  677. DWORD dwBytes1;
  678. LPVOID lpvPtr2;
  679. DWORD dwBytes2;
  680. hr = lpDsb->Lock(0, wavDataLength, &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
  681. if(DS_OK != hr)
  682. {
  683. // fail to lock
  684. err_now("Cannot lock DirectSoundBuffer");
  685. return 0;
  686. }
  687. // write to pointers
  688. memcpy(lpvPtr1, wavBuf+wavDataOffset, dwBytes1);
  689. if(lpvPtr2)
  690. {
  691. memcpy(lpvPtr2, wavBuf+wavDataOffset+dwBytes1, dwBytes2);
  692. }
  693. // unlock data back
  694. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  695. if(DS_OK != hr)
  696. {
  697. // fail to unlock
  698. err_now("Cannot unlock DirectSoundBuffer");
  699. return 0;
  700. }
  701. //------- Set volume -----------//
  702. lpDsb->SetVolume(dsVolume.ds_vol);
  703. lpDsb->SetPan(dsVolume.ds_pan);
  704. //------- Play wav file --------//
  705. if(lpDsb->Play(0, 0, 0) != DS_OK)
  706. {
  707. // fail to play
  708. err_now("Cannot play DirectSoundBuffer");
  709. return 0;
  710. }
  711. return wav_serial_no[chanNum] = assign_serial(max_wav_serial_no);
  712. }
  713. //------- End of function Audio::play_resided_wav -------//
  714. // ###### begin Gilbert 6/12 ########//
  715. //------- Begin of function Audio::get_free_wav_ch --------//
  716. int Audio::get_free_wav_ch()
  717. {
  718. int count = 0;
  719. DWORD dsbStatus;
  720. for( int chanNum = 0; chanNum < MAX_WAV_CHANNEL; ++chanNum)
  721. {
  722. if( lp_wav_ch_dsb[chanNum] != NULL && (lp_wav_ch_dsb[chanNum]->GetStatus(&dsbStatus),
  723. !(dsbStatus & DSBSTATUS_PLAYING)) )
  724. {
  725. lp_wav_ch_dsb[chanNum]->Release();
  726. lp_wav_ch_dsb[chanNum] = NULL;
  727. }
  728. if( !lp_wav_ch_dsb[chanNum] )
  729. count++;
  730. }
  731. return count;
  732. }
  733. //------- End of function Audio::get_free_wav_ch --------//
  734. // ###### end Gilbert 6/12 ########//
  735. //------- Begin of function Audio::stop_wav ------------//
  736. //
  737. // stop a short sound effect started by play_wav or play_resided_wav
  738. //
  739. // <int> the serial no returned by play_wav or play_resided_wav
  740. //
  741. // return 1 - channel is found and stopped / channel not found
  742. // return 0 - cannot stop the channel
  743. //
  744. int Audio::stop_wav(int serial)
  745. {
  746. for( int chanNum = 0; chanNum < MAX_WAV_CHANNEL; ++chanNum)
  747. {
  748. if(lp_wav_ch_dsb[chanNum] != NULL && wav_serial_no[chanNum] == serial)
  749. {
  750. lp_wav_ch_dsb[chanNum]->Stop();
  751. lp_wav_ch_dsb[chanNum]->Release();
  752. lp_wav_ch_dsb[chanNum] = NULL;
  753. wav_serial_no[chanNum] = 0;
  754. return 1;
  755. }
  756. }
  757. return 0;
  758. }
  759. //------- End of function Audio::stop_wav ------------//
  760. //------- Begin of function Audio::is_wav_playing ------------//
  761. //
  762. // return wheather a short sound effect is stopped
  763. //
  764. // <int> the serial no returned by play_wav or play_resided_wav
  765. //
  766. int Audio::is_wav_playing(int serial)
  767. {
  768. DWORD dsbStatus;
  769. for( int chanNum = 0; chanNum < MAX_WAV_CHANNEL; ++chanNum)
  770. {
  771. if(lp_wav_ch_dsb[chanNum] != NULL && wav_serial_no[chanNum] == serial
  772. && lp_wav_ch_dsb[chanNum]->GetStatus(&dsbStatus) )
  773. {
  774. return dsbStatus & DSBSTATUS_PLAYING;
  775. }
  776. }
  777. return 0;
  778. }
  779. //------- End of function Audio::is_wav_playing ------------//
  780. //------- Begin of function Audio::play_long_wav --------//
  781. //
  782. // Play digitized wav from the wav file
  783. // suitable for very large wave file
  784. //
  785. // <char*> wavName = name of the wave file
  786. //
  787. // return : <int> 1 - wav loaded and is playing
  788. // 0 - wav not played
  789. // note : it uses streaming DirectSoundBuffer
  790. // Audio::yield() keeps on feeding data to it
  791. // Create a DirectSoundBuffer of size lwav_buf_size[c]*LWAV_BANKS
  792. // divide into LWAV_BANKS parts. Each time Audio::yield() is called,
  793. // load wave file into one part. lwav_bank[c] record which part to be
  794. // filled next for channel c.
  795. int Audio::play_long_wav(char *wavName, DsVolume dsVolume)
  796. {
  797. if( !wav_init_flag || !wav_flag ) // a initialized and workable midi device can be disabled by user setting
  798. return 0;
  799. //-------- Load wav file header-------//
  800. DWORD wavDataOffset,wavDataLength;
  801. if( LWAV_STREAM_BUFSIZ*LWAV_BANKS > wav_buf_size )
  802. {
  803. wav_buf_size = LWAV_STREAM_BUFSIZ*LWAV_BANKS;
  804. wav_buf = mem_resize( wav_buf, wav_buf_size );
  805. }
  806. // File* filePtr = (File *)mem_add(sizeof(File)); // new File;
  807. File* filePtr = new File; // new File;
  808. if(!filePtr->file_open(wavName,0,0))
  809. {
  810. char errmsg[60];
  811. sprintf(errmsg, "Cannot open %s", wavName);
  812. box.msg(errmsg);
  813. delete filePtr;
  814. return 0;
  815. }
  816. if( !filePtr )
  817. {
  818. delete filePtr;
  819. return 0;
  820. }
  821. // load small part of the wave file (first 128 bytes) enough to hold
  822. // the hold header
  823. if( !filePtr->file_read( wav_buf, 128 ) )
  824. {
  825. delete filePtr;
  826. return 0;
  827. }
  828. // determine the wave data offset
  829. char * dataTag = wavefile_data(wav_buf);
  830. if (!dataTag)
  831. {
  832. err_now("Invalid wave file format");
  833. delete filePtr;
  834. return 0; // invalid RIFF WAVE format
  835. }
  836. wavDataOffset = (dataTag - wav_buf) + 4 + sizeof(DWORD);
  837. wavDataLength = *(DWORD *)(dataTag+4);
  838. // seek to the start of wave data
  839. long temp1 = filePtr->file_seek(wavDataOffset,FILE_BEGIN);
  840. WORD OptBufferSize=LWAV_STREAM_BUFSIZ,
  841. MinRemainder =(WORD)(wavDataLength % (OptBufferSize * LWAV_BANKS));
  842. //------- find out the best buffer size -------//
  843. // store it in OptBufferSize
  844. // criteria : below or equal to LWAV_STREAM_BUFSIZ and
  845. // minimize wavDataLength % (OptBufferSize * LWAV_BANKS)
  846. // i.e. minimize the truncation to the wave file
  847. for(WORD TryBufSiz=LWAV_STREAM_BUFSIZ-0x200; TryBufSiz <= LWAV_STREAM_BUFSIZ;
  848. TryBufSiz+=0x20)
  849. {
  850. WORD TryRemainder = (WORD)(wavDataLength % (TryBufSiz * LWAV_BANKS));
  851. if(TryRemainder < MinRemainder)
  852. {
  853. MinRemainder = TryRemainder;
  854. OptBufferSize = TryBufSiz;
  855. }
  856. }
  857. //------- Create DirectSoundBuffer to store a wave ------//
  858. LPDIRECTSOUNDBUFFER lpDsb;
  859. DSBUFFERDESC dsbDesc;
  860. HRESULT hr;
  861. DWORD dsbStatus;
  862. // set up DSBUFFERDESC structure
  863. memset(&dsbDesc, 0, sizeof(DSBUFFERDESC)); // zero it out
  864. dsbDesc.dwSize = sizeof(DSBUFFERDESC);
  865. dsbDesc.dwFlags = DSBCAPS_CTRLDEFAULT; // Need defaul controls (pan, volume, frequency)
  866. dsbDesc.dwBufferBytes = OptBufferSize * LWAV_BANKS;
  867. dsbDesc.lpwfxFormat = (LPWAVEFORMATEX) (wav_buf+0x14);
  868. // ------- assign buffer to a channel number ----------//
  869. lpDsb = NULL;
  870. int chanNum;
  871. for( chanNum = 0; chanNum < MAX_LONG_WAV_CH; ++chanNum)
  872. if(lp_lwav_ch_dsb[chanNum] == NULL || (lp_lwav_ch_dsb[chanNum]->GetStatus(&dsbStatus),
  873. !(dsbStatus & DSBSTATUS_PLAYING)))
  874. {
  875. if(lp_lwav_ch_dsb[chanNum])
  876. {
  877. lp_lwav_ch_dsb[chanNum]->Release();
  878. lp_lwav_ch_dsb[chanNum] = NULL;
  879. // mem_del(lwav_fileptr[chanNum]); // delete lwav_fileptr[chanNum];
  880. delete lwav_fileptr[chanNum];
  881. lwav_fileptr[chanNum] = NULL;
  882. }
  883. // found an idle channel, create DirectSoundBuffer
  884. hr = lp_direct_sound->CreateSoundBuffer(&dsbDesc, &lpDsb, NULL);
  885. if (DS_OK != hr)
  886. {
  887. // failed!
  888. err_now("Cannot create Stream DirectSoundBuffer");
  889. delete filePtr;
  890. return 0;
  891. }
  892. lp_lwav_ch_dsb[chanNum] = lpDsb;
  893. lwav_fileptr[chanNum] = filePtr; // no need to delete filePtr any more
  894. lwav_bank[chanNum] = 0;
  895. lwav_bufsiz[chanNum] = OptBufferSize;
  896. break;
  897. }
  898. if( chanNum >= MAX_LONG_WAV_CH)
  899. {
  900. delete filePtr;
  901. return 0;
  902. }
  903. // Note : if not found, just play the sound, don't play the sound
  904. // increase MAX_LONG_WAV_CH
  905. //------- copy sound data to DirectSoundBuffer--------//
  906. // unlock vga_front
  907. VgaFrontLock vgaLock;
  908. // lock the buffer first
  909. LPVOID lpvPtr1;
  910. DWORD dwBytes1;
  911. LPVOID lpvPtr2;
  912. DWORD dwBytes2;
  913. // load wave data into buffer
  914. // load data before lock DirectSoundBuffer in case the wave file
  915. // is very short
  916. DWORD startPos = filePtr->file_pos();
  917. if( !filePtr->file_read(wav_buf, OptBufferSize*LWAV_BANKS))
  918. {
  919. // file error
  920. err_now("Missing wave file");
  921. return 0;
  922. }
  923. DWORD readStreamSize = filePtr->file_pos() - startPos;
  924. DWORD playFlag = DSBPLAY_LOOPING;
  925. hr = lpDsb->Lock(0, OptBufferSize*LWAV_BANKS, &lpvPtr1, &dwBytes1,
  926. &lpvPtr2, &dwBytes2, 0);
  927. if(DS_OK != hr)
  928. {
  929. // fail to lock
  930. err_now("Cannot lock DirectSoundBuffer");
  931. return 0;
  932. }
  933. // write to pointers
  934. memcpy(lpvPtr1, wav_buf, min(dwBytes1, readStreamSize));
  935. if( dwBytes1 > readStreamSize )
  936. { // end of file, fill the remaining with zero
  937. memset((char *)lpvPtr1+readStreamSize, 0, dwBytes1 - readStreamSize);
  938. playFlag &= ~DSBPLAY_LOOPING;
  939. }
  940. else
  941. {
  942. readStreamSize -= dwBytes1;
  943. if(lpvPtr2 && dwBytes2 > 0)
  944. {
  945. memcpy(lpvPtr2, wav_buf+dwBytes1, min(dwBytes2, readStreamSize));
  946. if( dwBytes2 > readStreamSize )
  947. { // end of file, fill the remaining with zero
  948. memset((char *)lpvPtr2+readStreamSize, 0 , dwBytes2 - readStreamSize);
  949. playFlag &= ~DSBPLAY_LOOPING;
  950. }
  951. }
  952. }
  953. // unlock data back
  954. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  955. if(DS_OK != hr)
  956. {
  957. // fail to unlock
  958. err_now("Cannot unlock DirectSoundBuffer");
  959. return 0;
  960. }
  961. //------- Set volume -----------//
  962. lpDsb->SetVolume(dsVolume.ds_vol);
  963. lpDsb->SetPan(dsVolume.ds_pan);
  964. //------- Play wav file --------//
  965. if(lpDsb->Play(0, 0, playFlag) != DS_OK)
  966. {
  967. // fail to play
  968. err_now("Cannot play DirectSoundBuffer");
  969. return 0;
  970. }
  971. run_yield = 1;
  972. return lwav_serial_no[chanNum] = assign_serial(max_lwav_serial_no);
  973. }
  974. //------- End of function Audio::play_long_wav ----------//
  975. //------- Begin of function Audio::stop_long_wav ------------//
  976. //
  977. // stop a short sound effect started by play_long_wav
  978. //
  979. // <int> the serial no returned by play_long_wav
  980. //
  981. // return 1 - channel is found and stopped / channel not found
  982. // return 0 - cannot stop the channel
  983. //
  984. int Audio::stop_long_wav(int serial)
  985. {
  986. for( int chanNum = 0; chanNum < MAX_LONG_WAV_CH; ++chanNum)
  987. {
  988. if(lp_lwav_ch_dsb[chanNum] != NULL && lwav_serial_no[chanNum] == serial)
  989. {
  990. lp_lwav_ch_dsb[chanNum]->Stop();
  991. lp_lwav_ch_dsb[chanNum]->Release();
  992. lp_lwav_ch_dsb[chanNum] = NULL;
  993. delete lwav_fileptr[chanNum];
  994. lwav_fileptr[chanNum] = NULL;
  995. lwav_serial_no[chanNum] = 0;
  996. return 1;
  997. }
  998. }
  999. return 0;
  1000. }
  1001. //------- End of function Audio::stop_long_wav ------------//
  1002. //------- Begin of function Audio::is_long_wav_playing ------------//
  1003. //
  1004. // return wheather a short sound effect is stopped
  1005. //
  1006. // <int> the serial no returned by play_wav or play_resided_wav
  1007. //
  1008. int Audio::is_long_wav_playing(int serial)
  1009. {
  1010. DWORD dsbStatus;
  1011. for( int chanNum = 0; chanNum < MAX_LONG_WAV_CH; ++chanNum)
  1012. {
  1013. if(lp_lwav_ch_dsb[chanNum] != NULL && lwav_serial_no[chanNum] == serial
  1014. && lp_lwav_ch_dsb[chanNum]->GetStatus(&dsbStatus) == DS_OK )
  1015. {
  1016. return dsbStatus & DSBSTATUS_PLAYING;
  1017. }
  1018. }
  1019. return 0;
  1020. }
  1021. //------- End of function Audio::is_long_wav_playing ------------//
  1022. //--------------- Begin of Audio::vol_multiply --------------//
  1023. long Audio::vol_multiply(int relVolume)
  1024. {
  1025. long dsVolume = (wav_volume * relVolume) - 10000;
  1026. if( dsVolume > 0 )
  1027. dsVolume = 0;
  1028. else if( dsVolume < -10000 )
  1029. dsVolume = -10000;
  1030. return dsVolume;
  1031. }
  1032. //--------------- End of Audio::vol_multiply --------------//
  1033. //--------------- Begin of Audio::vol_divide --------------//
  1034. int Audio::vol_divide(long dsVolume)
  1035. {
  1036. if( wav_volume == 0)
  1037. return 0;
  1038. int relVolume = (dsVolume + 10000) / wav_volume;
  1039. if( relVolume < 0)
  1040. relVolume = 0;
  1041. else if( relVolume > 100 )
  1042. relVolume = 100;
  1043. return relVolume;
  1044. }
  1045. //--------------- End of Audio::vol_divide --------------//
  1046. //------- Begin of function Audio::play_loop_wav -------//
  1047. //
  1048. // Play digitized wav from the wav resource file
  1049. //
  1050. // <char*> wavName = name of the wav in the resource file
  1051. // int repeatOffset = offset of wave data to play on repeat
  1052. // i.e. 0 to start of wave data
  1053. //
  1054. // return : <int> channel number (1 - MAX_LOOP_WAV_CH)
  1055. // 0 not played
  1056. //
  1057. int Audio::play_loop_wav(char *wavName, int repeatOffset, DsVolume dsVolume)
  1058. {
  1059. if( !wav_init_flag || !wav_flag ) // a initialized and workable midi device can be disabled by user setting
  1060. return 0;
  1061. //-------- Load wav file header-------//
  1062. DWORD wavDataOffset,wavDataLength;
  1063. // File* filePtr = (File *)mem_add(sizeof(File)); // new File;
  1064. File* filePtr = new File;
  1065. if(!filePtr->file_open(wavName,0,0))
  1066. {
  1067. char errmsg[60];
  1068. sprintf(errmsg, "Cannot open %s", wavName);
  1069. box.msg(errmsg);
  1070. delete filePtr;
  1071. return 0;
  1072. }
  1073. if( !filePtr )
  1074. return 0;
  1075. // load small part of the wave file (first 128 bytes) enough to hold
  1076. // the hold header
  1077. if( !filePtr->file_read( wav_buf, 128 ) )
  1078. {
  1079. delete filePtr;
  1080. return 0;
  1081. }
  1082. // determine the wave data offset
  1083. char * dataTag = wavefile_data(wav_buf);
  1084. if (!dataTag)
  1085. {
  1086. err_now("Invalid wave file format");
  1087. delete filePtr;
  1088. return 0; // invalid RIFF WAVE format
  1089. }
  1090. wavDataOffset = (dataTag - wav_buf) + 4 + sizeof(DWORD);
  1091. wavDataLength = *(DWORD *)(dataTag+4);
  1092. // seek to the start of wave data
  1093. long temp1 = filePtr->file_seek(wavDataOffset,FILE_BEGIN);
  1094. WORD OptBufferSize=LOOPWAV_STREAM_BUFSIZ;
  1095. //------- Create DirectSoundBuffer to store a wave ------//
  1096. LPDIRECTSOUNDBUFFER lpDsb;
  1097. DSBUFFERDESC dsbDesc;
  1098. HRESULT hr;
  1099. DWORD dsbStatus;
  1100. // set up DSBUFFERDESC structure
  1101. memset(&dsbDesc, 0, sizeof(DSBUFFERDESC)); // zero it out
  1102. dsbDesc.dwSize = sizeof(DSBUFFERDESC);
  1103. dsbDesc.dwFlags = DSBCAPS_CTRLDEFAULT; // Need defaul controls (pan, volume, frequency)
  1104. dsbDesc.dwBufferBytes = OptBufferSize * LWAV_BANKS;
  1105. dsbDesc.lpwfxFormat = (LPWAVEFORMATEX) (wav_buf+0x14);
  1106. // ------- assign buffer to a channel number ----------//
  1107. lpDsb = NULL;
  1108. int chanNum;
  1109. for( chanNum = 0; chanNum < MAX_LOOP_WAV_CH; ++chanNum)
  1110. if(lp_loop_ch_dsb[chanNum] == NULL || (lp_loop_ch_dsb[chanNum]->GetStatus(&dsbStatus),
  1111. !(dsbStatus & DSBSTATUS_PLAYING)))
  1112. {
  1113. if(lp_loop_ch_dsb[chanNum])
  1114. {
  1115. lp_loop_ch_dsb[chanNum]->Release();
  1116. lp_loop_ch_dsb[chanNum] = NULL;
  1117. // mem_del(loopwav_fileptr[chanNum]); // delete lwav_fileptr[chanNum];
  1118. delete loopwav_fileptr[chanNum];
  1119. loopwav_fileptr[chanNum] = NULL;
  1120. }
  1121. // found an idle channel, create DirectSoundBuffer
  1122. hr = lp_direct_sound->CreateSoundBuffer(&dsbDesc, &lpDsb, NULL);
  1123. if (DS_OK != hr)
  1124. {
  1125. // failed!
  1126. err_now("Cannot create Stream DirectSoundBuffer");
  1127. return 0;
  1128. }
  1129. lp_loop_ch_dsb[chanNum] = lpDsb;
  1130. loopwav_fileptr[chanNum] = filePtr; // no need to delete filePtr any more
  1131. loopwav_bank[chanNum] = 0;
  1132. repeat_offset[chanNum] = wavDataOffset + repeatOffset;
  1133. loopwav_fade_rate[chanNum] = 0;
  1134. break;
  1135. }
  1136. if( chanNum >= MAX_LOOP_WAV_CH)
  1137. {
  1138. delete filePtr;
  1139. return 0;
  1140. }
  1141. // Note : if not found, just play the sound, don't play the sound
  1142. //------- copy sound data to DirectSoundBuffer--------//
  1143. // unlock vga_front
  1144. VgaFrontLock vgaLock;
  1145. // lock the buffer first
  1146. LPVOID lpvPtr1;
  1147. DWORD dwBytes1;
  1148. LPVOID lpvPtr2;
  1149. DWORD dwBytes2;
  1150. // load wave data into buffer
  1151. // load data before lock DirectSoundBuffer in case the wave file
  1152. // is very short
  1153. DWORD startPos = filePtr->file_pos();
  1154. if( !filePtr->file_read(wav_buf, OptBufferSize*LOOPWAV_BANKS))
  1155. {
  1156. // file error
  1157. err_now("Missing wave file");
  1158. return 0;
  1159. }
  1160. DWORD readStreamSize = filePtr->file_pos() - startPos;
  1161. DWORD playFlag = DSBPLAY_LOOPING;
  1162. hr = lpDsb->Lock(0, OptBufferSize*LOOPWAV_BANKS, &lpvPtr1, &dwBytes1,
  1163. &lpvPtr2, &dwBytes2, 0);
  1164. if(DS_OK != hr)
  1165. {
  1166. // fail to lock
  1167. err_now("Cannot lock DirectSoundBuffer");
  1168. return 0;
  1169. }
  1170. // write to pointers, assume wave file repeating size is
  1171. // larger than OptBufferSize * LOOPWAV_BANKS
  1172. memcpy(lpvPtr1, wav_buf, min(dwBytes1, readStreamSize));
  1173. if( dwBytes1 < readStreamSize )
  1174. {
  1175. readStreamSize -= dwBytes1;
  1176. if(lpvPtr2 && dwBytes2 > 0)
  1177. {
  1178. memcpy(lpvPtr2, wav_buf+dwBytes1, min(dwBytes2, readStreamSize));
  1179. }
  1180. }
  1181. // unlock data back
  1182. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  1183. if(DS_OK != hr)
  1184. {
  1185. // fail to unlock
  1186. err_now("Cannot unlock DirectSoundBuffer");
  1187. return 0;
  1188. }
  1189. //------- Set volume -----------//
  1190. lpDsb->SetVolume(dsVolume.ds_vol);
  1191. lpDsb->SetPan(dsVolume.ds_pan);
  1192. //------- Play wav file --------//
  1193. if(lpDsb->Play(0, 0, playFlag) != DS_OK)
  1194. {
  1195. // fail to play
  1196. err_now("Cannot play DirectSoundBuffer");
  1197. return 0;
  1198. }
  1199. run_yield = 1;
  1200. return chanNum+1;
  1201. }
  1202. //------- End of function Audio::play_loop_wav ---------//
  1203. //------- Begin of function Audio::volume_loop_wav -------//
  1204. void Audio::volume_loop_wav(int ch, DsVolume dsVolume)
  1205. {
  1206. int chanNum = ch-1;
  1207. if( chanNum < 0 || chanNum >= MAX_LOOP_WAV_CH)
  1208. return;
  1209. if(lp_loop_ch_dsb[chanNum])
  1210. {
  1211. lp_loop_ch_dsb[chanNum]->SetVolume(dsVolume.ds_vol);
  1212. lp_loop_ch_dsb[chanNum]->SetPan(dsVolume.ds_pan);
  1213. // stop fading
  1214. loopwav_fade_rate[chanNum] = 0;
  1215. }
  1216. }
  1217. //------- End of function Audio::volume_loop_wav -------//
  1218. //------- Begin of function Audio::fade_out_loop_wav -------//
  1219. //
  1220. // <int> fadeRate, time for volume 100 wave drop to slience
  1221. //
  1222. void Audio::fade_out_loop_wav(int ch, int fadeRate)
  1223. {
  1224. int chanNum = ch-1;
  1225. if( chanNum < 0 || chanNum >= MAX_LOOP_WAV_CH)
  1226. return;
  1227. if(lp_loop_ch_dsb[chanNum])
  1228. {
  1229. loopwav_fade_rate[chanNum] = fadeRate;
  1230. loopwav_fade_time[chanNum] = m.get_time();
  1231. }
  1232. }
  1233. //------- End of function Audio::fade_out_loop_wav -------//
  1234. //------- Begin of function Audio::get_loop_wav_volume -------//
  1235. DsVolume Audio::get_loop_wav_volume(int ch)
  1236. {
  1237. int chanNum = ch-1;
  1238. if( chanNum < 0 || chanNum >= MAX_LOOP_WAV_CH)
  1239. {
  1240. RelVolume rel = RelVolume(0,0);
  1241. return DsVolume(rel);
  1242. }
  1243. LONG volume;
  1244. LONG pan;
  1245. LPDIRECTSOUNDBUFFER lpDsb= lp_loop_ch_dsb[chanNum];
  1246. if( lpDsb && lpDsb->GetVolume(&volume) == DS_OK &&
  1247. lpDsb->GetPan(&pan) == DS_OK )
  1248. {
  1249. return DsVolume(volume, pan);
  1250. }
  1251. RelVolume rel = RelVolume(0,0);
  1252. return DsVolume(rel);
  1253. }
  1254. //------- End of function Audio::get_loop_wav_volume -------//
  1255. //------- Begin of function Audio::is_loop_wav_fading -------//
  1256. int Audio::is_loop_wav_fading(int ch)
  1257. {
  1258. int chanNum = ch-1;
  1259. if( chanNum < 0 || chanNum >= MAX_LOOP_WAV_CH)
  1260. return 0;
  1261. return lp_loop_ch_dsb[chanNum] && loopwav_fade_rate[chanNum];
  1262. }
  1263. //------- End of function Audio::is_loop_wav_fading -------//
  1264. //------- Begin of function Audio::yield ---------------//
  1265. void Audio::yield()
  1266. {
  1267. #ifndef WIN32
  1268. // unlock vga_front
  1269. VgaFrontLock vgaLock;
  1270. #endif
  1271. if( !run_yield)
  1272. return;
  1273. run_yield = 0; // suspend recursive Audio::yield();
  1274. #ifdef WIN32
  1275. // unlock vga_front
  1276. VgaFrontLock vgaLock;
  1277. #endif
  1278. // set break point beyond this point
  1279. int i;
  1280. for(i = 0; i < MAX_LONG_WAV_CH; ++i)
  1281. {
  1282. if( !lp_lwav_ch_dsb[i] )
  1283. continue;
  1284. // if a wav is not play, or buffer lost, stop it
  1285. LPDIRECTSOUNDBUFFER& lpDsb = lp_lwav_ch_dsb[i];
  1286. DWORD dsbStatus;
  1287. if( lpDsb->GetStatus(&dsbStatus) != DS_OK)
  1288. err_here();
  1289. if( !(dsbStatus & DSBSTATUS_PLAYING) ||
  1290. (dsbStatus & DSBSTATUS_BUFFERLOST) && lpDsb->Restore() != DS_OK )
  1291. {
  1292. lpDsb->Stop();
  1293. lpDsb->Release();
  1294. lpDsb = NULL;
  1295. // mem_del(lwav_fileptr[i]);
  1296. delete lwav_fileptr[i];
  1297. lwav_fileptr[i] = NULL;
  1298. continue;
  1299. }
  1300. char writeTooFast = 1;
  1301. // buffer lost, succeeded in restoring
  1302. if( dsbStatus & DSBSTATUS_BUFFERLOST )
  1303. {
  1304. writeTooFast = 0;
  1305. }
  1306. else
  1307. {
  1308. // perform flow control
  1309. DWORD tmpPlayCursor, tmpWriteCursor;
  1310. if( lpDsb->GetCurrentPosition(&tmpPlayCursor, &tmpWriteCursor) == DS_OK)
  1311. {
  1312. writeTooFast = ((short)(tmpPlayCursor / lwav_bufsiz[i]) == lwav_bank[i]);
  1313. }
  1314. }
  1315. if(!writeTooFast)
  1316. {
  1317. // lock a channel for lwav_bufsiz[i]
  1318. LPVOID lpvPtr1;
  1319. DWORD dwBytes1;
  1320. LPVOID lpvPtr2;
  1321. DWORD dwBytes2;
  1322. File *filePtr = lwav_fileptr[i];
  1323. HRESULT hr = lpDsb->Lock(lwav_bank[i]*lwav_bufsiz[i], lwav_bufsiz[i],
  1324. &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
  1325. lwav_bank[i] = (lwav_bank[i] + 1) % LWAV_BANKS; // next bank to fill
  1326. if(DS_OK != hr)
  1327. {
  1328. // fail to lock
  1329. err_now("Cannot lock DirectSoundBuffer");
  1330. run_yield = 1;
  1331. return;
  1332. }
  1333. long startPos;
  1334. long readStreamSize;
  1335. DWORD playFlag = DSBPLAY_LOOPING;
  1336. // write to pointers
  1337. startPos = filePtr->file_pos();
  1338. // filePtr->file_read(wav_buf, dwBytes1);
  1339. // readStreamSize = filePtr->file_pos() - startPos; // bytes read in
  1340. // memcpy(lpvPtr1, wav_buf, readStreamSize);
  1341. filePtr->file_read(lpvPtr1, dwBytes1);
  1342. readStreamSize = filePtr->file_pos() - startPos; // bytes read in
  1343. if((long)dwBytes1 > readStreamSize)
  1344. { // end of file, fill the remaining with zero
  1345. // memset((char *)lpvPtr1+readStreamSize, 0, dwBytes1 - readStreamSize);
  1346. playFlag &= ~DSBPLAY_LOOPING; // clear DSBPLAY_LOOPING
  1347. }
  1348. else
  1349. {
  1350. if( lpvPtr2 && dwBytes2 > 0)
  1351. {
  1352. startPos = filePtr->file_pos();
  1353. filePtr->file_read(lpvPtr2, dwBytes2);
  1354. readStreamSize = filePtr->file_pos() - startPos; // bytes read in
  1355. if((long)dwBytes2 > readStreamSize)
  1356. { // end of file
  1357. // memset((char *)lpvPtr2+readStreamSize, 0, dwBytes2 - readStreamSize);
  1358. playFlag &= ~DSBPLAY_LOOPING; // clear DSBPLAY_LOOPING
  1359. }
  1360. }
  1361. }
  1362. // unlock data back
  1363. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  1364. if(DS_OK != hr)
  1365. {
  1366. // fail to unlock
  1367. err_now("Cannot unlock DirectSoundBuffer");
  1368. run_yield = 1;
  1369. return;
  1370. }
  1371. // load file into a channel, on last stream, don't loop back
  1372. //------- Play wav file --------//
  1373. if(lpDsb->Play(0, 0, playFlag) != DS_OK)
  1374. {
  1375. // fail to play
  1376. err_now("Cannot play DirectSoundBuffer");
  1377. run_yield = 1;
  1378. return;
  1379. }
  1380. }
  1381. }
  1382. for(i = 0; i < MAX_LOOP_WAV_CH; ++i)
  1383. {
  1384. if( !lp_loop_ch_dsb[i] )
  1385. continue;
  1386. // if a channel is not playing, or can't restore release it
  1387. LPDIRECTSOUNDBUFFER& lpDsb = lp_loop_ch_dsb[i];
  1388. DWORD dsbStatus;
  1389. if( lpDsb->GetStatus(&dsbStatus) != DS_OK )
  1390. err_here();
  1391. if( !(dsbStatus & DSBSTATUS_PLAYING) ||
  1392. (dsbStatus & DSBSTATUS_BUFFERLOST) && lpDsb->Restore() != DS_OK )
  1393. {
  1394. lpDsb->Stop();
  1395. lpDsb->Release();
  1396. lpDsb = NULL;
  1397. // mem_del(loopwav_fileptr[i]);
  1398. delete loopwav_fileptr[i];
  1399. loopwav_fileptr[i] = NULL;
  1400. continue;
  1401. }
  1402. char writeTooFast = 1;
  1403. // buffer lost, succeeded in restoring
  1404. if( dsbStatus & DSBSTATUS_BUFFERLOST )
  1405. {
  1406. writeTooFast = 0;
  1407. }
  1408. else
  1409. {
  1410. // perform flow control
  1411. DWORD tmpPlayCursor, tmpWriteCursor;
  1412. if( lpDsb->GetCurrentPosition(&tmpPlayCursor, &tmpWriteCursor) == DS_OK)
  1413. {
  1414. writeTooFast = ((short)(tmpPlayCursor / LOOPWAV_STREAM_BUFSIZ) == loopwav_bank[i]);
  1415. }
  1416. }
  1417. if(!writeTooFast)
  1418. {
  1419. // lock a channel for loopwav_bufsiz[i]
  1420. LPVOID lpvPtr1;
  1421. DWORD dwBytes1;
  1422. LPVOID lpvPtr2;
  1423. DWORD dwBytes2;
  1424. File *filePtr = loopwav_fileptr[i];
  1425. HRESULT hr = lpDsb->Lock(loopwav_bank[i]*LOOPWAV_STREAM_BUFSIZ, LOOPWAV_STREAM_BUFSIZ,
  1426. &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, 0);
  1427. loopwav_bank[i] = (loopwav_bank[i] + 1) % LOOPWAV_BANKS; // next bank to fill
  1428. if(DS_OK != hr)
  1429. {
  1430. // fail to lock
  1431. err_now("Cannot lock DirectSoundBuffer");
  1432. run_yield = 1;
  1433. return;
  1434. }
  1435. long startPos;
  1436. long readStreamSize;
  1437. DWORD playFlag = DSBPLAY_LOOPING;
  1438. // write to pointers
  1439. startPos = filePtr->file_pos();
  1440. filePtr->file_read(lpvPtr1, dwBytes1);
  1441. readStreamSize = filePtr->file_pos() - startPos; // bytes read in
  1442. if((long)dwBytes1 > readStreamSize)
  1443. { // end of file, seek to beginning and read again
  1444. filePtr->file_seek(repeat_offset[i]);
  1445. filePtr->file_read((char *)lpvPtr1+readStreamSize, dwBytes1-readStreamSize);
  1446. }
  1447. // unlock data back
  1448. hr = lpDsb->Unlock(lpvPtr1, dwBytes1, lpvPtr2, dwBytes2);
  1449. if(DS_OK != hr)
  1450. {
  1451. // fail to unlock
  1452. err_now("Cannot unlock DirectSoundBuffer");
  1453. run_yield = 1;
  1454. return;
  1455. }
  1456. // set volume if fading
  1457. if( loopwav_fade_rate[i] )
  1458. {
  1459. DWORD nextFadeTime = m.get_time();
  1460. LONG volume;
  1461. if( DS_OK == (hr = lpDsb->GetVolume(&volume)) )
  1462. {
  1463. // calculate new volume
  1464. volume -= (nextFadeTime - loopwav_fade_time[i]) * loopwav_fade_rate[i];
  1465. if( volume < DSBVOLUME_MIN )
  1466. volume = DSBVOLUME_MIN;
  1467. else if( volume > DSBVOLUME_MAX )
  1468. volume = DSBVOLUME_MAX;
  1469. if( DS_OK == (hr = lpDsb->SetVolume(volume)) )
  1470. {
  1471. loopwav_fade_time[i] = nextFadeTime;
  1472. }
  1473. }
  1474. }
  1475. // load file into a channel, on last stream, don't loop back
  1476. //------- Play wav file --------//
  1477. if(lpDsb->Play(0, 0, playFlag) != DS_OK)
  1478. {
  1479. // fail to play
  1480. err_now("Cannot play DirectSoundBuffer");
  1481. run_yield = 1;
  1482. return;
  1483. }
  1484. }
  1485. }
  1486. run_yield = 1; // resume Audio::yield();
  1487. }
  1488. //------- End of function Audio::yield ---------------//
  1489. //------- Begin of function Audio::stop_wav -------//
  1490. //
  1491. void Audio::stop_wav()
  1492. {
  1493. if( !wav_init_flag || !wav_flag )
  1494. return;
  1495. // ---------- stop all short wave ------------- //
  1496. int i;
  1497. for(i = 0; i < MAX_WAV_CHANNEL; ++i)
  1498. if(lp_wav_ch_dsb[i])
  1499. {
  1500. lp_wav_ch_dsb[i]->Stop();
  1501. lp_wav_ch_dsb[i]->Release();
  1502. lp_wav_ch_dsb[i] = NULL;
  1503. }
  1504. // ----------- stop all long wave ------------- //
  1505. stop_long_wav();
  1506. // ------------ stop all loop wave ------------//
  1507. for(i = 1; i <= MAX_LOOP_WAV_CH; ++i)
  1508. {
  1509. stop_loop_wav(i);
  1510. }
  1511. }
  1512. //------- End of function Audio::stop_wav -------//
  1513. //------- Begin of function Audio::stop_long_wav -------//
  1514. //
  1515. void Audio::stop_long_wav()
  1516. {
  1517. if( !wav_init_flag || !wav_flag )
  1518. return;
  1519. for(int i = 0; i < MAX_LONG_WAV_CH; ++i)
  1520. if(lp_lwav_ch_dsb[i])
  1521. {
  1522. lp_lwav_ch_dsb[i]->Stop();
  1523. lp_lwav_ch_dsb[i]->Release();
  1524. lp_lwav_ch_dsb[i] = NULL;
  1525. // mem_del(lwav_fileptr[i]);
  1526. delete lwav_fileptr[i];
  1527. lwav_fileptr[i] = NULL;
  1528. }
  1529. }
  1530. //------- End of function Audio::stop_long_wav -------//
  1531. //------- Begin of function Audio::stop_loop_wav -------//
  1532. void Audio::stop_loop_wav(int ch)
  1533. {
  1534. int chanNum = ch-1;
  1535. if( chanNum < 0 || chanNum >= MAX_LOOP_WAV_CH)
  1536. return;
  1537. if(lp_loop_ch_dsb[chanNum])
  1538. {
  1539. lp_loop_ch_dsb[chanNum]->Stop();
  1540. lp_loop_ch_dsb[chanNum]->Release();
  1541. lp_loop_ch_dsb[chanNum] = NULL;
  1542. // mem_del(loopwav_fileptr[chanNum]); // delete lwav_fileptr[chanNum];
  1543. delete loopwav_fileptr[chanNum];
  1544. loopwav_fileptr[chanNum] = NULL;
  1545. }
  1546. }
  1547. //------- End of function Audio::stop_loop_wav ---------//
  1548. //------- Begin of function Audio::play_cd -------//
  1549. //
  1550. // <int> trackId - the id. of the CD track to play.
  1551. //
  1552. int Audio::play_cd(int trackId, int volume)
  1553. {
  1554. if( !cd_init_flag || !cd_flag )
  1555. return 0;
  1556. // ###### begin Gilbert 3/10 ########//
  1557. MCIERROR mciError;
  1558. DWORD maxTrack = 99;
  1559. // Get the number of tracks;
  1560. // limit to number that can be displayed (20).
  1561. MCI_STATUS_PARMS mciStatusParms;
  1562. mciStatusParms.dwItem = MCI_STATUS_NUMBER_OF_TRACKS;
  1563. mciError = mciSendCommand(mci_open.wDeviceID, MCI_STATUS,
  1564. MCI_STATUS_ITEM, (DWORD)(LPVOID) &mciStatusParms);
  1565. if( !mciError )
  1566. maxTrack = mciStatusParms.dwReturn;
  1567. //--- Send an MCI_PLAY command to the CD Audio driver ---//
  1568. mci_open.lpstrDeviceType = (LPCSTR) MCI_DEVTYPE_CD_AUDIO;
  1569. mci_play.dwFrom = MCI_MAKE_TMSF(trackId , 0, 0, 0);
  1570. mci_play.dwTo = MCI_MAKE_TMSF(trackId+1, 0, 0, 0);
  1571. DWORD cmdFlag = MCI_FROM;
  1572. if( (DWORD) trackId < maxTrack )
  1573. cmdFlag |= MCI_TO; // if MCI_TO is missing, play until the end
  1574. mciError = mciSendCommand( mci_open.wDeviceID, MCI_PLAY, cmdFlag,
  1575. (DWORD) (LPVOID) &mci_play);
  1576. if( mciError )
  1577. return 0;
  1578. return 1;
  1579. // ###### end Gilbert 3/10 ########//
  1580. }
  1581. //------- End of function Audio::play_cd -------//
  1582. //------- Begin of function Audio::stop_cd -------//
  1583. //
  1584. void Audio::stop_cd()
  1585. {
  1586. if( !cd_init_flag || !cd_flag )
  1587. return;
  1588. DWORD dwResult;
  1589. dwResult = mciSendCommand(mci_open.wDeviceID, MCI_STOP,
  1590. MCI_WAIT, (DWORD)(LPVOID)NULL);
  1591. }
  1592. //------- End of function Audio::stop_cd -------//
  1593. //------- Begin of function Audio::is_mid_playing -------//
  1594. //
  1595. int Audio::is_mid_playing()
  1596. {
  1597. if( !mid_init_flag || !mid_flag ) // a initialized and workable midi device can be disabled by user setting
  1598. return 0;
  1599. //... insert code here ...//
  1600. return 0;
  1601. }
  1602. //------- End of function Audio::is_mid_playing -------//
  1603. //------- Begin of function Audio::is_wav_playing -------//
  1604. //
  1605. int Audio::is_wav_playing()
  1606. {
  1607. int playingChannelCount = 0;
  1608. DWORD dwStatus;
  1609. if( !wav_init_flag || !wav_flag ) // a initialized and workable midi device can be disabled by user setting
  1610. return 0;
  1611. //------ find any wav channel is playing -----//
  1612. // update lp_wav_ch_dsb[x] if necessary
  1613. for(int ch=0; ch < MAX_WAV_CHANNEL; ++ch)
  1614. if( lp_wav_ch_dsb[ch])
  1615. if( lp_wav_ch_dsb[ch]->GetStatus(&dwStatus) == DS_OK)
  1616. if (dwStatus & DSBSTATUS_PLAYING )
  1617. // a channel is playing
  1618. playingChannelCount++;
  1619. else
  1620. // is not playing, clear it
  1621. lp_wav_ch_dsb[ch] = NULL;
  1622. else
  1623. // GetStatus not ok, clear it
  1624. lp_wav_ch_dsb[ch] = NULL;
  1625. else
  1626. {
  1627. // nothing
  1628. }
  1629. return (playingChannelCount > 0);
  1630. }
  1631. //------- End of function Audio::is_wav_playing -------//
  1632. //------- Begin of function Audio::is_cd_playing -------//
  1633. //
  1634. int Audio::is_cd_playing()
  1635. {
  1636. if( !cd_init_flag || !cd_flag ) // a initialized and workable midi device can be disabled by user setting
  1637. return 0;
  1638. MCI_STATUS_PARMS status;
  1639. DWORD dwResult;
  1640. //
  1641. // get the current status
  1642. //
  1643. status.dwItem = MCI_STATUS_MODE;
  1644. dwResult = mciSendCommand(mci_open.wDeviceID, MCI_STATUS,
  1645. MCI_WAIT | MCI_STATUS_ITEM, (DWORD)(LPVOID)&status);
  1646. if (dwResult == 0)
  1647. return status.dwReturn == MCI_MODE_PLAY;
  1648. return 0;
  1649. }
  1650. //------- End of function Audio::is_cd_playing -------//
  1651. //----------------- Begin of Audio::toggle_mid -----------------//
  1652. //
  1653. void Audio::toggle_mid(int midFlag)
  1654. {
  1655. if( !midFlag )
  1656. stop_mid();
  1657. mid_flag = midFlag;
  1658. }
  1659. //------------------- End of Audio::toggle_mid ------------------//
  1660. //----------------- Begin of Audio::toggle_wav -----------------//
  1661. //
  1662. void Audio::toggle_wav(int wavFlag)
  1663. {
  1664. if( !wavFlag )
  1665. stop_wav();
  1666. wav_flag = wavFlag;
  1667. }
  1668. //------------------- End of Audio::toggle_wav ------------------//
  1669. //----------------- Begin of Audio::toggle_cd -----------------//
  1670. //
  1671. void Audio::toggle_cd(int cdFlag)
  1672. {
  1673. if( !cdFlag )
  1674. stop_cd();
  1675. cd_flag = cdFlag;
  1676. }
  1677. //------------------- End of Audio::toggle_cd ------------------//
  1678. //-------------- Begin of Audio::set_mid_volume -------------//
  1679. //
  1680. // Set mid volume
  1681. //
  1682. // <int> midVolume = mid volume, 0-100
  1683. //
  1684. void Audio::set_mid_volume(int midVolume)
  1685. {
  1686. if( !mid_init_flag )
  1687. return;
  1688. //.. insert code here ...//
  1689. }
  1690. //--------------- End of Audio::set_mid_volume --------------//
  1691. //-------------- Begin of Audio::set_wav_volume -------------//
  1692. //
  1693. // Set wav volume
  1694. //
  1695. // <int> wavVolume = wav volume, 0-100
  1696. //
  1697. void Audio::set_wav_volume(int wavVolume)
  1698. {
  1699. if( !wav_init_flag )
  1700. return;
  1701. LONG dsVolume;
  1702. long dsVolDiff = (wavVolume - wav_volume) * 100;
  1703. // change volume for all channels
  1704. int i;
  1705. for( i = 0; i < MAX_WAV_CHANNEL; ++i)
  1706. {
  1707. if( lp_wav_ch_dsb[i] &&
  1708. lp_wav_ch_dsb[i]->GetVolume(&dsVolume) == DS_OK)
  1709. {
  1710. dsVolume += dsVolDiff;
  1711. if( dsVolume > DSBVOLUME_MAX )
  1712. dsVolume = DSBVOLUME_MAX;
  1713. if( dsVolume < DSBVOLUME_MIN )
  1714. dsVolume = DSBVOLUME_MIN;
  1715. lp_wav_ch_dsb[i]->SetVolume(dsVolume);
  1716. }
  1717. }
  1718. for( i = 0; i < MAX_LONG_WAV_CH; ++i)
  1719. {
  1720. if( lp_lwav_ch_dsb[i] &&
  1721. lp_lwav_ch_dsb[i]->GetVolume(&dsVolume) == DS_OK)
  1722. {
  1723. dsVolume += dsVolDiff;
  1724. if( dsVolume > DSBVOLUME_MAX )
  1725. dsVolume = DSBVOLUME_MAX;
  1726. if( dsVolume < DSBVOLUME_MIN )
  1727. dsVolume = DSBVOLUME_MIN;
  1728. lp_lwav_ch_dsb[i]->SetVolume(dsVolume);
  1729. }
  1730. }
  1731. for( i = 0; i < MAX_LOOP_WAV_CH; ++i)
  1732. {
  1733. if( lp_loop_ch_dsb[i] &&
  1734. lp_loop_ch_dsb[i]->GetVolume(&dsVolume) == DS_OK)
  1735. {
  1736. dsVolume += dsVolDiff;
  1737. if( dsVolume > DSBVOLUME_MAX )
  1738. dsVolume = DSBVOLUME_MAX;
  1739. if( dsVolume < DSBVOLUME_MIN )
  1740. dsVolume = DSBVOLUME_MIN;
  1741. lp_loop_ch_dsb[i]->SetVolume(dsVolume);
  1742. }
  1743. }
  1744. wav_volume = wavVolume;
  1745. }
  1746. //--------------- End of Audio::set_wav_volume --------------//
  1747. //-------------- Begin of Audio::set_cd_volume -------------//
  1748. //
  1749. // Set cd volume
  1750. //
  1751. // <int> cdVolume = cd volume, 0-100
  1752. //
  1753. void Audio::set_cd_volume(int cdVolume)
  1754. {
  1755. if( !cd_init_flag )
  1756. return;
  1757. //.. insert code here ...//
  1758. }
  1759. //--------------- End of Audio::set_cd_volume --------------//
  1760. //-------------- Begin of function Audio::assign_serial ----------//
  1761. int Audio::assign_serial(int &s)
  1762. {
  1763. if( s == INT_MAX)
  1764. return s = 1;
  1765. return ++s;
  1766. }
  1767. //-------------- End of function Audio::assign_serial ----------//
  1768. // ------------ Begin of function Audio::volume_long_wav -------//
  1769. void Audio::volume_long_wav(int serial, DsVolume dsVolume)
  1770. {
  1771. if( is_long_wav_playing(serial) )
  1772. {
  1773. for( int chanNum = 0; chanNum < MAX_LONG_WAV_CH; ++chanNum)
  1774. {
  1775. if(lp_lwav_ch_dsb[chanNum] != NULL && lwav_serial_no[chanNum] == serial )
  1776. {
  1777. lp_lwav_ch_dsb[chanNum]->SetVolume(dsVolume.ds_vol);
  1778. // lp_lwav_ch_dsb[chanNum]->SetPan(dsVolume.ds_pan);
  1779. break;
  1780. }
  1781. }
  1782. }
  1783. }
  1784. // ------------ End of function Audio::volume_long_wav -------//