home *** CD-ROM | disk | FTP | other *** search
/ C/C++ User's Journal & Wi…eveloper's Journal Tools / C-C__Users_Journal_and_Windows_Developers_Journal_Tools_1997.iso / diamond / pas / playstk.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-07-08  |  16.2 KB  |  667 lines

  1. {***************************************************************************
  2. File:      playstk.pas
  3. Version:   1.00
  4. Tab stops: none
  5. Project:   DiamondWare's Sound ToolKit for Windows
  6. Copyright: 1996 DiamondWare, Ltd.  All rights reserved.*
  7. Written:   by David Bollinger (based on playstk.c for WIN-STK)
  8. Purpose:   Contains declarations for the DW Sound ToolKit for Windows
  9. History:   96/02/24 DB Modified for 1.0
  10.            96/03/27 JCL Finalized for 1.0
  11.            96/04/14 JCL Finalized for 1.01
  12.            96/05/13 JCL Finalized for 1.1 (no changes)
  13.            96/05/27 JCL Finalized for 1.11
  14.            96/07/08 JCL Finalized for 1.2 (no changes)
  15.  
  16. *Permission is expressly granted to use this program or any derivitive made
  17.  from it to registered users of the WIN-STK.
  18. ***************************************************************************}
  19.  
  20.  
  21.  
  22. unit PlaySTK;
  23.  
  24.  
  25. interface
  26.  
  27. uses
  28.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  29.   Forms, Dialogs, ExtCtrls, StdCtrls, FileCtrl, Buttons;
  30.  
  31. type
  32.   TForm1 = class(TForm)
  33.     Logo: TImage;
  34.     Label1: TLabel;
  35.     Label2: TLabel;
  36.     Label3: TLabel;
  37.     Label4: TLabel;
  38.     Label5: TLabel;
  39.     Label6: TLabel;
  40.     ListBox1: TListBox;
  41.     NewBtn: TButton;
  42.     PlayBtn: TButton;
  43.     StopBtn: TButton;
  44.     RemoveBtn: TButton;
  45.     sbVolLeft: TScrollBar;
  46.     sbVolRight: TScrollBar;
  47.     sbPitch: TScrollBar;
  48.     sbSwapLR: TCheckBox;
  49.     RatePanel: TPanel;
  50.     sbRate0: TRadioButton;
  51.     sbRate1: TRadioButton;
  52.     sbRate2: TRadioButton;
  53.     OpenDialog1: TOpenDialog;
  54.     procedure FormCreate(Sender: TObject);
  55.     procedure FormClose(Sender: TObject; var Action: TCloseAction);
  56.     procedure DoNew(Sender: TObject);
  57.     procedure DoPlay(Sender: TObject);
  58.     procedure DoStop(Sender: TObject);
  59.     procedure DoRemove(Sender: TObject);
  60.     procedure sbVolLeftChange(Sender: TObject);
  61.     procedure sbVolRightChange(Sender: TObject);
  62.     procedure sbPitchChange(Sender: TObject);
  63.     procedure sbSwapLRClick(Sender: TObject);
  64.     procedure sbRate0Click(Sender: TObject);
  65.     procedure sbRate1Click(Sender: TObject);
  66.     procedure sbRate2Click(Sender: TObject);
  67.   private
  68.     { Private declarations }
  69.   public
  70.     { Public declarations }
  71.     procedure DisplayErr(comment : PCHAR);
  72.     function LoadFile(sndFile : string) : boolean;
  73.     function ConvertWave(sndFile : string) : boolean;
  74.   end;
  75.  
  76.  
  77. var
  78.   Form1: TForm1;
  79.  
  80.  
  81.  
  82. implementation
  83.  
  84. {$R *.DFM}
  85. uses DWS;
  86.  
  87.  
  88. const
  89.    SOUNDTOTAL = 16;
  90.    presentsnd : integer = 0;
  91.    previoussnd : integer = 0;
  92.    newselection : boolean = True;
  93.  
  94.  
  95. var
  96.    textselection : string;
  97.    volleft, volright, pitch, swaplr, rate : WORD;
  98.    wavesize : DWORD;
  99.    wavetmp : array [0..SOUNDTOTAL-1] of PBYTE;
  100.    hwavetmp : array [0..SOUNDTOTAL-1] of THandle;
  101.    var dres : dws_DETECTRESULTS;
  102.    var ideal : dws_IDEAL;
  103.    var dplay1 : dws_DPLAYREC;
  104.    var dplay2 : dws_DPLAYREC;
  105.  
  106.  
  107.  
  108. procedure TForm1.FormCreate(Sender: TObject);
  109. var result : WORD;
  110. begin
  111.    volleft  := 8;
  112.    volright := 8;
  113.    pitch    := 8;
  114.    swaplr   := 0;
  115.    rate     := 1;
  116.  
  117.    if (dws_DetectHardWare(dres) = False) then
  118.       DisplayErr('dws_DetectHardWare - During Create');
  119.  
  120.    if ((dres.digcaps and dws_digcap_11025_08_2) = 0) then
  121.    begin
  122.       Application.MessageBox('DiamondWare''s Sound ToolKit for Windows ' +
  123.                              'supports sound playback on your computer. ' +
  124.                              'However, this demo requires 8-bit stereo, ' +
  125.                              'which your computer does not support. ' +
  126.                              'Your sound hardware does not support ' +
  127.                              '11025Hz, two channel, 8 bit sound. ' +
  128.                              'This demo will not run properly on ' +
  129.                              'your computer',
  130.                              'Sound ToolKit Error',
  131.                              MB_OK);
  132.       Halt(1);
  133.    end;
  134.  
  135.    if boolean(dres.muscaps and dws_muscap_MAPPER) then
  136.       result := dws_muscap_MAPPER
  137.    else if boolean(dres.muscaps and dws_muscap_FMSYNTH) then
  138.       result := dws_muscap_FMSYNTH
  139.    else if boolean(dres.muscaps and dws_muscap_SYNTH) then
  140.       result := dws_muscap_SYNTH
  141.    else if boolean(dres.muscaps and dws_muscap_SQSYNTH) then
  142.       result := dws_muscap_SQSYNTH
  143.    else if boolean(dres.muscaps and dws_muscap_MIDIPORT) then
  144.       result := dws_muscap_MIDIPORT
  145.    else
  146.       result := dws_muscap_NONE;
  147.  
  148.    ideal.mustyp := result;                { 0=No Music, n=Music }
  149.    ideal.digtyp := dws_digcap_11025_08_2; { everything rolled into one }
  150.    ideal.dignvoices := 16;                { number of voices (up to 16) }
  151.  
  152.    if (dws_Init(dres, ideal) = False) then
  153.       DisplayErr('dws_Init - During Create')
  154.    else if (dws_XDig(128, 128) = False) then { half volume }
  155.       DisplayErr('dws_XDig - During Create');
  156.  
  157. end;
  158.  
  159.  
  160. procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
  161. var i : integer;
  162. begin
  163.  
  164.    dws_DClear;  { stop all playing sounds }
  165.    dws_MClear;  { stop any playing music }
  166.    dws_Kill;    { stop everything else }
  167.  
  168.    for i := 0 to SOUNDTOTAL-1 do
  169.    begin
  170.       if (hwavetmp[i] <> 0) then
  171.       begin
  172.          GlobalUnlock(hwavetmp[i]);
  173.          GlobalFree(hwavetmp[i]);
  174.       end;
  175.    end;
  176. end;
  177.  
  178.  
  179. procedure TForm1.DisplayErr(comment : PCHAR);
  180. var
  181.   totstr : array[0..255] of char;
  182.   errstr : PCHAR;
  183.   status : WORD;
  184. begin
  185.   status := dws_ErrNo;
  186.   case status of
  187.     dws_EZERO:
  188.     begin
  189.       errstr := 'dws_EZERO (Why am I here?): %s';
  190.     end;
  191.     dws_NOTINITTED:
  192.     begin
  193.       errstr := 'dws_NOTINITTED: %s';
  194.     end;
  195.     dws_ALREADYINITTED:
  196.     begin
  197.       errstr := 'dws_ALREADYINITTED: %s';
  198.     end;
  199.     dws_NOTSUPPORTED:
  200.     begin
  201.       errstr := 'dws_NOTSUPPORTED: %s';
  202.     end;
  203.     dws_INTERNALERROR:
  204.     begin
  205.       errstr := 'dws_INTERNALERROR: %s';
  206.     end;
  207.     dws_INVALIDPOINTER:
  208.     begin
  209.       errstr := 'dws_INVALIDPOINTER: %s';
  210.     end;
  211.     dws_RESOURCEINUSE:
  212.     begin
  213.       errstr := 'dws_RESOURCEINUSE: %s';
  214.     end;
  215.     dws_MEMORYALLOCFAILED:
  216.     begin
  217.       errstr := 'dws_MEMORYALLOCFAILED: %s';
  218.     end;
  219.     dws_SETEVENTFAILED:
  220.     begin
  221.       errstr := 'dws_SETEVENTFAILED: %s';
  222.     end;
  223.     dws_BUSY:
  224.     begin
  225.       errstr := 'dws_BUSY: %s';
  226.     end;
  227.     dws_Init_BUFTOOSMALL:
  228.     begin
  229.       errstr := 'dws_Init_BUFTOOSMALL: %s';
  230.     end;
  231.     dws_D_NOTADWD:
  232.     begin
  233.       errstr := 'dws_D_NOTADWD: %s';
  234.     end;
  235.     dws_D_NOTSUPPORTEDVER:
  236.     begin
  237.       errstr := 'dws_D_NOTSUPPORTEDVER: %s';
  238.     end;
  239.     dws_D_BADDPLAY:
  240.     begin
  241.       errstr := 'dws_D_BADDPLAY: %s';
  242.     end;
  243.     dws_DPlay_NOSPACEFORSOUND:
  244.     begin
  245.       errstr := 'dws_DPlay_NOSPACEFORSOUND: %s';
  246.     end;
  247.     dws_WAV2DWD_NOTAWAVE:
  248.     begin
  249.       errstr := 'dws_WAV2DWD_NOTAWAVE: %s';
  250.     end;
  251.     dws_WAV2DWD_UNSUPPORTEDFORMAT:
  252.     begin
  253.       errstr := 'dws_WAV2DWD_UNSUPPORTEDFORMAT: %s';
  254.     end;
  255.     dws_M_BADMPLAY:
  256.     begin
  257.       errstr := 'dws_M_BADMPLAY: %s';
  258.     end;
  259.   else
  260.     begin
  261.       errstr := 'DEFAULT (unknown error!): %s';
  262.     end;
  263.   end;
  264.  
  265.   wvsprintf(totstr, errstr, comment);
  266.   Application.MessageBox(totstr, 'Sound ToolKit Error', MB_ICONSTOP or MB_OK);
  267.  
  268.   Halt(1);
  269. end;
  270.  
  271.  
  272. function TForm1.LoadFile(sndfile : string) : boolean;
  273. var
  274.   txt : array [0..127] of char;
  275.   stream : file;
  276. begin
  277.   sndfile := sndfile + char(0);
  278.   if (hwavetmp[presentsnd] <> 0) then
  279.   begin
  280.     GlobalUnlock(hwavetmp[presentsnd]);
  281.     GlobalFree(hwavetmp[presentsnd]);
  282.   end;
  283.  
  284.   {$I-}
  285.   AssignFile(stream, sndfile);
  286.   if (IOResult = 0) then
  287.   begin
  288.     Reset(stream, 1);
  289.     wavesize := FileSize(stream);
  290. {$ifndef WIN32}
  291.     if (wavesize > 65535) then
  292.     begin
  293.       Application.MessageBox('The selected file is too large for 16 bit ' +
  294.                              'Delphi to read. Please try another, ' +
  295.                              'smaller file.',
  296.                              'Sound ToolKit Error',MB_OK);
  297.       result := False;
  298.  
  299.       exit;
  300.     end;
  301. {$endif}
  302.     hwavetmp[presentsnd] := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE, wavesize);
  303.     wavetmp[presentsnd] := PBYTE(GlobalLock(hwavetmp[presentsnd]));
  304.  
  305.     BlockRead(stream, wavetmp[presentsnd]^, wavesize);
  306.     CloseFile(stream);
  307.   end
  308.   {$I+}
  309.   else
  310.   begin
  311.     StrCopy(txt, 'Could not get size of ');
  312.     StrCat(txt, @sndfile[1]);
  313.  
  314.     Application.MessageBox(txt, 'Sound ToolKit Error', MB_OK);
  315.  
  316.     result := False;
  317.  
  318.     exit;
  319.   end;
  320.   result := True;
  321. end;
  322.  
  323.  
  324. function TForm1.ConvertWave(sndFile : string) : boolean;
  325. var
  326.   txt : array [0..127] of char;
  327.   wavedwd : PBYTE;
  328.   status : WORDBOOL;
  329.   len, tmp : DWORD;
  330.   hwavedwd : THandle;
  331. begin
  332.   sndfile := sndfile + char(0);
  333.   result := False;
  334.  
  335.   if (not LoadFile(sndfile)) then exit;
  336.  
  337.   tmp := wavesize;
  338.   len := wavesize;
  339.  
  340.   status := dws_WAV2DWD(wavetmp[presentsnd], tmp, Nil);
  341.  
  342.   if (status = False) then
  343.   begin
  344.     StrCopy(txt, 'Could not get size of ');
  345.     StrCat(txt, @sndfile[1]);
  346.  
  347.     Application.MessageBox(txt, 'Sound ToolKit Error', MB_OK);
  348.  
  349.     result := False;
  350.  
  351.     exit;
  352.   end;
  353.  
  354.   hwavedwd := GlobalAlloc(GMEM_MOVEABLE, tmp);
  355.   wavedwd := PBYTE(GlobalLock(hwavedwd));
  356.   status := dws_WAV2DWD(waveTmp[presentsnd], len, wavedwd);
  357.  
  358.   if (status = False) then
  359.   begin
  360.     GlobalUnlock(hwavedwd);
  361.     GlobalFree(hwavedwd);
  362.  
  363.     Application.MessageBox('Unable to convert WAV to internal format',
  364.                            'Sound ToolKit Error',
  365.                            MB_OK);
  366.     result := False;
  367.  
  368.     exit;
  369.   end;
  370.  
  371.   GlobalUnlock(hwavetmp[presentsnd]);
  372.   GlobalFree(hwavetmp[presentsnd]);
  373.  
  374.   hwavetmp[presentsnd] := hwavedwd;
  375.   wavetmp[presentsnd] := wavedwd;
  376.  
  377.   result := True;
  378. end;
  379.  
  380.  
  381. procedure TForm1.DoNew(Sender: TObject);
  382. begin
  383.   if OpenDialog1.Execute = True then
  384.     ListBox1.Items.Add(OpenDialog1.Filename);
  385. end;
  386.  
  387.  
  388. procedure TForm1.DoPlay(Sender: TObject);
  389. var
  390.   buffer, extension : string;
  391.   sel : integer;
  392.   status : WORDBOOL;
  393.   mplay : dws_MPLAYREC;
  394. begin
  395.   if (ListBox1.ItemIndex = -1) then
  396.   begin
  397.     Application.MessageBox('No listbox item is selected.',
  398.                            'Sound ToolKit Error',
  399.                            MB_OK);
  400.  
  401.     exit;
  402.   end;
  403.  
  404.   presentsnd := ListBox1.ItemIndex;
  405.   buffer := ListBox1.Items[presentsnd];
  406.  
  407.   if (buffer <> textselection) then
  408.   begin
  409.     newselection := True;
  410.     textselection := buffer;
  411.   end;
  412.  
  413.   { convert the retrieved text to lowercase }
  414.   for sel := 1 to length(buffer) do
  415.     if (buffer[sel] in ['A'..'Z']) then
  416.       buffer[sel] := char(integer(buffer[sel]) + 32);
  417.  
  418.   extension := ExtractFileExt(buffer);
  419.  
  420.   if ((extension <> '.wav') and (extension <> '.dwd') and (extension <> '.mid')) then
  421.   begin
  422.     Application.MessageBox('File name format not known',
  423.                            'Sound ToolKit Error',
  424.                            MB_OK);
  425.  
  426.     exit;
  427.   end;
  428.  
  429.   if ((extension = '.wav') or (extension = '.dwd')) then
  430.   begin
  431.     if (newselection) then
  432.     begin
  433.       if (extension = '.wav') then
  434.       begin
  435.         if (not ConvertWave(buffer)) then exit;
  436.       end
  437.       else if (extension = '.dwd') then
  438.       begin
  439.         if (not LoadFile(buffer)) then exit;
  440.       end;
  441.  
  442.       dplay1.snd := wavetmp[presentsnd];
  443.     end
  444.     else
  445.       dplay1.snd := wavetmp[previoussnd];
  446.  
  447.     dplay1.count := 1;
  448.  
  449.     if (volleft >= 8) then
  450.       dplay1.lvol := WORD((volleft - 7) * 256)
  451.     else
  452.       dplay1.lvol := WORD(volleft * 32);
  453.  
  454.     if (volright >= 8) then
  455.       dplay1.rvol := WORD((volright - 7) * 256)
  456.     else
  457.       dplay1.rvol := WORD(volright * 32);
  458.  
  459.     if (pitch >= 8) then
  460.       dplay1.pitch := WORD((pitch - 7) * 256)
  461.     else
  462.       dplay1.pitch := WORD(pitch * 32);
  463.  
  464.     dplay1.flags := DWORD(dws_dplay_SND or dws_dplay_COUNT or dws_dplay_LVOL or dws_dplay_RVOL or dws_dplay_PITCH);
  465.  
  466.     status := dws_DPlay(dplay1);
  467.  
  468.     if (status = False) then
  469.       DisplayErr('dws_DPlay - During DoNew');
  470.  
  471.     if (newselection) then
  472.     begin
  473.       previoussnd := presentsnd;
  474.       inc(presentsnd);
  475.       if (presentsnd >= SOUNDTOTAL) then
  476.           presentsnd := 0;
  477.     end;
  478.  
  479.     newselection := False;
  480.   end
  481.  
  482.   else if (extension = '.mid') then
  483.   begin
  484.     buffer := buffer + char(0);
  485.     mplay.track := Addr(buffer[1]);
  486.     mplay.count := 1;
  487.  
  488.     status := dws_MPlay(mplay);
  489.     if (status = False) then
  490.       DisplayErr('dws_MPlay - During DoNew');
  491.  
  492.   end;
  493. end;
  494.  
  495.  
  496. procedure TForm1.DoStop(Sender: TObject);
  497. begin
  498.  
  499.   dws_MClear;
  500.   dws_DClear;
  501.  
  502. end;
  503.  
  504.  
  505. procedure TForm1.DoRemove(Sender: TObject);
  506. begin
  507.   if (ListBox1.ItemIndex = -1) then
  508.     Application.MessageBox('No listbox item is selected.', 'Sound ToolKit Error', mb_OK)
  509.   else
  510.     ListBox1.Items.Delete(ListBox1.ItemIndex);
  511. end;
  512.  
  513.  
  514. procedure TForm1.sbSwapLRClick(Sender: TObject);
  515. var result : WORDBOOL;
  516. begin
  517.   swaplr := WORD(sbSwapLR.Checked);
  518.  
  519.   dws_DClear; { stop all playing sounds }
  520.   dws_MClear; { stop any playing music }
  521.   dws_Kill;   { stop everything else }
  522.  
  523.   if (swaplr <> 0) then
  524.     ideal.flags := dws_ideal_SWAPLR
  525.   else
  526.     ideal.flags := 0;
  527.  
  528.   result := dws_Init(dres, ideal);
  529.  
  530.   if (result = False) then
  531.     DisplayErr('dws_Init - During SwapLR');
  532.  
  533. end;
  534.  
  535.  
  536. procedure TForm1.sbRate0Click(Sender: TObject);
  537. var result : WORDBOOL;
  538. begin
  539.   rate := 0;
  540.  
  541.   dws_DClear; { stop all playing sounds }
  542.   dws_MClear; { stop any playing music }
  543.   dws_Kill;   { stop everything else }
  544.  
  545.   ideal.digtyp := dws_digcap_11025_08_2; { everything rolled into one }
  546.   result := dws_Init(dres, ideal);
  547.  
  548.   if (result = False) then
  549.     DisplayErr('dws_Init - During Rate 11025');
  550.  
  551. end;
  552.  
  553.  
  554. procedure TForm1.sbRate1Click(Sender: TObject);
  555. var result : WORDBOOL;
  556. begin
  557.   rate := 1;
  558.  
  559.   dws_DClear; { stop all playing sounds }
  560.   dws_MClear; { stop any playing music }
  561.   dws_Kill;   { stop everything else }
  562.  
  563.   ideal.digtyp := dws_digcap_22050_08_2; { everything rolled into one }
  564.   result := dws_Init(dres, ideal);
  565.  
  566.   if (result = False) then
  567.     DisplayErr('dws_Init - During Rate 22050');
  568.  
  569. end;
  570.  
  571.  
  572. procedure TForm1.sbRate2Click(Sender: TObject);
  573. var result : WORDBOOL;
  574. begin
  575.   rate := 2;
  576.  
  577.   dws_DClear; { stop all playing sounds }
  578.   dws_MClear; { stop any playing music }
  579.   dws_Kill;   { stop everything else }
  580.  
  581.   ideal.digtyp := dws_digcap_44100_08_2; { everything rolled into one }
  582.   result := dws_Init(dres, ideal);
  583.  
  584.   if (result = False) then
  585.     DisplayErr('dws_Init - During Rate 44100');
  586.  
  587. end;
  588.  
  589.  
  590. procedure TForm1.sbVolLeftChange(Sender: TObject);
  591. var result : WORDBOOL;
  592. begin
  593.   volleft := WORD(16 - sbVolLeft.Position);
  594.   dplay1.flags := dws_dplay_SOUNDNUM or dws_dplay_LVOL;
  595.   dplay2.flags := 0;
  596.  
  597.   result := dws_DGetInfo(dplay1, dplay2);
  598.  
  599.   if (result = False) then
  600.     DisplayErr('dws_DGetInfo - During VolLeftChange');
  601.  
  602.   if (volleft >= 8) then
  603.     dplay1.lvol := WORD((volleft - 7) * 256)
  604.   else
  605.     dplay1.lvol := WORD(volleft * 32);
  606.  
  607.   result := dws_DSetInfo(dplay1, dplay2);
  608.  
  609.   if (result = False) then
  610.     DisplayErr('dws_DSetInfo - During VolLeftChange');
  611.  
  612. end;
  613.  
  614.  
  615. procedure TForm1.sbVolRightChange(Sender: TObject);
  616. var result : WORDBOOL;
  617. begin
  618.   volright := WORD(16 - sbVolRight.Position);
  619.   dplay1.flags := dws_dplay_SOUNDNUM or dws_dplay_RVOL;
  620.   dplay2.flags := 0;
  621.  
  622.   result := dws_DGetInfo(dplay1, dplay2);
  623.  
  624.   if (result = False) then
  625.     DisplayErr('dws_DGetInfo - During VolRightChange');
  626.  
  627.   if (volright >= 8) then
  628.     dplay1.rvol := WORD((volright - 7) * 256)
  629.   else
  630.     dplay1.rvol := WORD(volright * 32);
  631.  
  632.   result := dws_DSetInfo(dplay1, dplay2);
  633.  
  634.   if (result = False) then
  635.     DisplayErr('dws_SGetInfo - During VolRightChange');
  636.  
  637. end;
  638.  
  639.  
  640. procedure TForm1.sbPitchChange(Sender: TObject);
  641. var result : WORDBOOL;
  642. begin
  643.   pitch := WORD(sbPitch.Position);
  644.   dplay1.flags := dws_dplay_SOUNDNUM or dws_dplay_PITCH;
  645.   dplay2.flags := 0;
  646.  
  647.   result := dws_DGetInfo(dplay1, dplay2);
  648.  
  649.   if (result = False) then
  650.     DisplayErr('dws_DGetInfo - During PitchChange');
  651.  
  652.   if (pitch = 0) then inc(pitch);
  653.  
  654.   if (pitch >= 8) then
  655.     dplay1.pitch := WORD((pitch - 7) * 256)
  656.   else
  657.     dplay1.pitch := WORD(pitch * 32);
  658.  
  659.   result := dws_DSetInfo(dplay1, dplay2);
  660.  
  661.   if (result = False) then
  662.     DisplayErr('dws_DSetInfo - During PitchChange');
  663.  
  664. end;
  665.  
  666. end.
  667.