First, modify the previously defined readwavefile unit and add an openresource () method to it to directly read the "wave" data in the resource file;
To avoid confusion, change the unit name readwavefile to readwave at the same time, and change the class name treadwavefile to treadwave.
{Modified readwave unit: Read the format, data, and data size of the wave from a file or resource} unit readwave; interfaceuses windows, classes, sysutils, mmsystem; typetreadwave = classprivate ffilehandle: hmmio; fformat: twaveformatex; fsize: DWORD; function getformatandsize (hfile: hmmio): Boolean; Public destructor destroy; override; function open (filename: string): Boolean function; openresource (resname: string): Boolean; function read (pdest: pointer; Size: DWORD): Boolean; // read the waveform data property format: twaveformatex read fformat; // read the format data property size: DWORD read fsize; // read the end Of the waveform data size; implementation {treadwave} destructor treadwave. destroy; begin if ffilehandle> 0 then mmioclose (ffilehandle, 0); inherited; end; function treadwave. getformatandsize (hfile: hmmio): Boolean; var ckiriff, ckifmt, ckidata: tmmckinfo; begin result: = false; If hfile = 0 Then exit; zeromemory (@ ckiriff, sizeof (tmmckinfo); mmiodescend (hfile, @ ckiriff, nil, mmio_findriff); If (ckiriff. ckid fourcc_riff) or (ckiriff. fcctype mmiostringtofourcc ('wave ', 0) Then exit; zeromemory (@ fformat, sizeof (twaveformatex); zeromemory (@ ckifmt, sizeof (tmmckinfo); ckifmt. ckid: = mmiostringtofourcc ('fmt', 0); zeromemory (@ ckidata, sizeof (tmmckinfo); ckidata. ckid: = mmiostringtofourcc ('data', 0); If (mmiodescend (hfile, @ ckifmt, @ ckiriff, timeout) = mmsyserr_noerror) Then mmioread (hfile, @ fformat, sizeof (twaveformatex); convert (hfile, @ ckifmt, 0); If (mmiodescend (hfile, @ ckidata, @ ckiriff, timeout) = mmsyserr_noerror) Then fsize: = ckidata. cksize; Result: = fformat. wformattag = wave_format_pcm; end; function treadwave. open (filename: string): Boolean; begin result: = false; if not fileexists (filename) Then exit; If ffilehandle> 0 then mmioclose (ffilehandle, 0); ffilehandle: = mmioopen (pchar (filename), nil, mmio_read); Result: = getformatandsize (ffilehandle); end; function treadwave. openresource (resname: string): Boolean; var Res: tresourcestream; mmioinfo: tmmioinfo; begin result: = false; Res: = tresourcestream. create (hinstance, resname, 'Wave '); zeromemory (@ mmioinfo, sizeof (tmmioinfo); mmioinfo. fccioproc: = fourcc_mem; mmioinfo. cchbuffer: = res. size; mmioinfo. pchbuffer: = res. memory; If ffilehandle> 0 then mmioclose (ffilehandle, 0); ffilehandle: = mmioopen (nil, @ mmioinfo, role or mmio_read); Result: = getformatandsize (ffilehandle); Res. free; end; function treadwave. read (pdest: pointer; Size: DWORD): Boolean; begin result: = mmioread (ffilehandle, pdest, size) = size; end.
The following example loads three wave files to resources:
This example fully demonstrates the features that directsound can play multiple sounds at the same time.Code:
Unit unit1; interfaceuses windows, messages, sysutils, variants, classes, graphics, controls, forms, dialogs, stdctrls; Type tform1 = Class (tform) button1: tbutton; // play the first resource button2: tbutton; // play the second resource button3: tbutton; // play the third resource button4: tbutton; // stop all checkbox1: tcheckbox; // control whether to play procedure formcreate (Sender: tobject); Procedure formdestroy (Sender: tobject); Procedure button1click (Sender: tobject); Procedure button3click (Sender: tobject ); procedure button2click (Sender: tobject); Procedure button4click (Sender: tobject); end; var form1: tform1; implementation {$ R *. DFM} uses directsound, mmsystem, readwave; // readwave is the previously redefined unit var mydsound: idirectsound8; bufs: array [0 .. 2] of idirectsoundbuffer; // buffer array, used to load three wave files in the resource file {use the resource file to create a buffer and play back} procedure playresourcewave (resname: string; var Buf: idirectsoundbuffer; loop: Boolean = false); var bufdesc: tdsbufferdesc; WAV: treadwave; P1: pointer; N1: DWORD; begin Buf: = nil; WAV: = treadwave. create; if not WAV. openresource (resname) then begin showmessage ('Open failed'); WAV. free; exit; end; zeromemory (@ bufdesc, sizeof (tdsbufferdesc); bufdesc. dwsize: = sizeof (tdsbufferdesc); bufdesc. dwflags: = dsbcaps_static; bufdesc. dwbufferbytes: = WAV. size; bufdesc. lpwfxformat: = @ WAV. format; mydsound. createsoundbuffer (bufdesc, Buf, nil); Buf. lock (0, 0, @ P1, @ N1, nil, nil, dsblock_entirebuffer); WAV. read (P1, N1); Buf. unlock (P1, N1, nil, 0); If loop then Buf. play (0, 0, dsbplay_looping) else Buf. play (0, 0, 0); WAV. free; end; {initialize device} procedure tform1.formcreate (Sender: tobject); begin directsoundcreate8 (nil, mydsound, nil); mydsound. setcooperativelevel (handle, dsscl_normal); end; {play the first resource} procedure tform1.button1click (Sender: tobject); begin playresourcewave ('wav _ 1', bufs [0], checkbox1.checked ); end; {play second resource} procedure tform1.button2click (Sender: tobject); begin playresourcewave ('wav _ 2', bufs [1], checkbox1.checked); end; {play third resource} procedure tform1.button3click (Sender: tobject); begin playresourcewave ('wav _ 3', bufs [2], checkbox1.checked); end; {stop all} procedure tform1.button4click (Sender: tobject); var I: integer; begin for I: = low (bufs) to high (bufs) do if bufs [I] nil then bufs [I]. stop; end; Procedure tform1.formdestroy (Sender: tobject); var I: integer; begin for I: = low (bufs) to high (bufs) Do bufs [I]: = nil; mydsound: = nil; end.
This Demo Video: http://files.cnblogs.com/del/DirectSound_7.rar