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 / c / playstk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-21  |  20.3 KB  |  969 lines

  1. /******************************************************************************
  2. File:      playstk.c
  3. Version:   1.00
  4. Tab stops: every 2 columns
  5. Project:   DiamondWare's Sound ToolKit for Windows
  6. Copyright: 1996 DiamondWare, Ltd.  All rights reserved.*
  7. Written:   95/12/11 by John Lundy
  8. Purpose:   Contains sample application using the WIN-STK
  9. History:   95/12/11 JCL Started
  10.            96/03/27 KW & JCL finalized for 1.0
  11.            96/05/13 JCL finalized for 1.1 (no changes)
  12.            96/05/27 JCL finalized for 1.11 (no changes)
  13.            96/07/08 JCL finalized for 1.0 (no changes)
  14.            96/09/21 KW finalized for 1.2 (WIN32_LEAN_AND_MEAN req'd for VisAge)
  15.  
  16. *Permission is expressely granted to use this program or any derivitive made
  17.  from it to registered users of the WIN-STK.
  18. ******************************************************************************/
  19.  
  20. #define WIN32_LEAN_AND_MEAN
  21. #include <windows.h>
  22. #include <commdlg.h>
  23. #include <ctype.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. #include "resource.h"
  28.  
  29. #include "dws.h"
  30.  
  31.  
  32.  
  33. #ifdef  __BORLANDC__
  34.   #pragma warn -par
  35. #endif
  36.  
  37. #if defined(__IBMC__) || defined(__IBMCPP)
  38.   #define playstk_PASCAL __stdcall
  39.   #define playstk_CALLBACK __stdcall
  40. #else
  41.   #define playstk_PASCAL PASCAL
  42.   #define playstk_CALLBACK CALLBACK
  43. #endif
  44.  
  45.  
  46.  
  47. #define SOUNDTOTAL 16
  48.  
  49.  
  50.  
  51. static WORD              volleft, volright, pitch;
  52.  
  53. static int               presentsnd=0, previoussnd=0;
  54.  
  55. static LPBYTE            sndptr[SOUNDTOTAL];
  56. static HGLOBAL           hsndptr[SOUNDTOTAL];
  57.  
  58. static HWND              sbvolleft;
  59. static HWND              sbvolright;
  60. static HWND              sbpitch;
  61. static HWND              cbswaplr;
  62.  
  63. /* variables used by the WIN-STK */
  64. static dws_DETECTRESULTS dres;
  65. static dws_DPLAY         dplay;
  66. static dws_IDEAL         ideal;
  67.  
  68.  
  69.  
  70. static void DisplayErr(char *comment)
  71. {
  72.   char  totstr[256];
  73.   char *errstr;
  74.  
  75.   switch (dws_ErrNo())
  76.   {
  77.     case dws_EZERO:
  78.     {
  79.       errstr = "dws_EZERO (Why am I here?): %s";
  80.  
  81.       break;
  82.     }
  83.     case dws_NOTINITTED:
  84.     {
  85.       errstr = "dws_NOTINITTED: %s";
  86.  
  87.       break;
  88.     }
  89.     case dws_ALREADYINITTED:
  90.     {
  91.       errstr = "dws_ALREADYINITTED: %s";
  92.  
  93.       break;
  94.     }
  95.     case dws_NOTSUPPORTED:
  96.     {
  97.       errstr = "dws_NOTSUPPORTED: %s";
  98.  
  99.       break;
  100.     }
  101.     case dws_INTERNALERROR:
  102.     {
  103.       errstr = "dws_INTERNALERROR: %s";
  104.  
  105.       break;
  106.     }
  107.     case dws_INVALIDPOINTER:
  108.     {
  109.       errstr = "dws_INVALIDPOINTER: %s";
  110.  
  111.       break;
  112.     }
  113.     case dws_RESOURCEINUSE:
  114.     {
  115.       errstr = "dws_RESOURCEINUSE: %s";
  116.  
  117.       break;
  118.     }
  119.     case dws_MEMORYALLOCFAILED:
  120.     {
  121.       errstr = "dws_MEMORYALLOCFAILED: %s";
  122.  
  123.       break;
  124.     }
  125.     case dws_SETEVENTFAILED:
  126.     {
  127.       errstr = "dws_SETEVENTFAILED: %s";
  128.  
  129.       break;
  130.     }
  131.     case dws_BUSY:
  132.     {
  133.       errstr = "dws_BUSY: %s";
  134.  
  135.       break;
  136.     }
  137.     case dws_Init_BUFTOOSMALL:
  138.     {
  139.       errstr = "dws_Init_BUFTOOSMALL: %s";
  140.  
  141.       break;
  142.     }
  143.     case dws_D_NOTADWD:
  144.     {
  145.       errstr = "dws_D_NOTADWD: %s";
  146.  
  147.       break;
  148.     }
  149.     case dws_D_NOTSUPPORTEDVER:
  150.     {
  151.       errstr = "dws_D_NOTSUPPORTEDVER: %s";
  152.  
  153.       break;
  154.     }
  155.     case dws_D_BADDPLAY:
  156.     {
  157.       errstr = "dws_D_BADDPLAY: %s";
  158.  
  159.       break;
  160.     }
  161.     case dws_DPlay_NOSPACEFORSOUND:
  162.     {
  163.       errstr = "dws_DPlay_NOSPACEFORSOUND: %s";
  164.  
  165.       break;
  166.     }
  167.     case dws_WAV2DWD_NOTAWAVE:
  168.     {
  169.       errstr = "dws_WAV2DWD_NOTAWAVE: %s";
  170.  
  171.       break;
  172.     }
  173.     case dws_WAV2DWD_UNSUPPORTEDFORMAT:
  174.     {
  175.       errstr = "dws_WAV2DWD_UNSUPPORTEDFORMAT: %s";
  176.  
  177.       break;
  178.     }
  179.     default:
  180.     {
  181.       errstr = "DEFAULT (unknown error!): %s";
  182.  
  183.       break;
  184.     }
  185.   }
  186.  
  187.   wsprintf(totstr, errstr, comment);
  188.   MessageBox(NULL, totstr, "Sound ToolKit Error", MB_ICONSTOP | MB_OK);
  189.  
  190.   /* whether it needs it, or not... */
  191.   dws_Kill();
  192.  
  193.   /* In our simple scheme, all errors are fatal. <g> */
  194.   exit(-1);
  195. }
  196.  
  197.  
  198. /* Shutdown WIN-STK */
  199. static void Kill(void)
  200. {
  201.   if (!dws_DClear())  /* stop all playing sounds */
  202.   {
  203.     DisplayErr("dws_DClear During Kill");
  204.   }
  205.  
  206.   if (!dws_MClear())  /* stop any playing music */
  207.   {
  208.     DisplayErr("dws_MClear During Kill");
  209.   }
  210.  
  211.   if (!dws_Kill())    /* stop everything else */
  212.   {
  213.     DisplayErr("dws_Kill During Kill");
  214.   }
  215. }
  216.  
  217.  
  218. /* Reinitialize WIN-STK with new digitized sampling rate */
  219. static void ChangeRate(DWORD digtyp)
  220. {
  221.   Kill();
  222.  
  223.   ideal.digtyp = digtyp;
  224.  
  225.   /* Restart it with the new rate */
  226.   if (!dws_Init(&dres, &ideal))
  227.   {
  228.     DisplayErr("dws_Init During ChangeRate");
  229.   }
  230. }
  231.  
  232.  
  233. static DWORD LoadFile(char *sndfile)
  234. {
  235.   char       txt[128];
  236.   DWORD      filesize;
  237.   #ifdef  WIN32
  238.     DWORD    tmp;
  239.     HANDLE   hfile;
  240.   #else
  241.     HFILE    hfile;
  242.     OFSTRUCT openbuff;
  243.   #endif
  244.  
  245.   if (hsndptr[presentsnd])
  246.   {
  247.     GlobalUnlock(hsndptr[presentsnd]);
  248.     GlobalFree(hsndptr[presentsnd]);
  249.   }
  250.  
  251.   #ifdef  WIN32
  252.     hfile = CreateFile(sndfile, GENERIC_READ, FILE_SHARE_READ, NULL,
  253.                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  254.  
  255.     if (hfile)
  256.     {
  257.       filesize = GetFileSize(hfile, NULL);
  258.  
  259.       hsndptr[presentsnd] = GlobalAlloc(GHND, filesize);
  260.       sndptr[presentsnd] = (LPBYTE)GlobalLock(hsndptr[presentsnd]);
  261.  
  262.       ReadFile(hfile, sndptr[presentsnd], filesize, &tmp, NULL);
  263.       CloseHandle(hfile);
  264.     }
  265.   #else
  266.     hfile = OpenFile(sndfile, &openbuff, OF_READ);
  267.  
  268.     if (hfile != HFILE_ERROR)
  269.     {
  270.       filesize = _llseek(hfile, 0L, 2);
  271.  
  272.       hsndptr[presentsnd] = GlobalAlloc(GHND, filesize);
  273.       sndptr[presentsnd] = (LPBYTE)GlobalLock(hsndptr[presentsnd]);
  274.  
  275.       _llseek(hfile, 0L, 0);
  276.       _hread(hfile, sndptr[presentsnd], filesize);
  277.  
  278.       _lclose(hfile);
  279.     }
  280.   #endif
  281.   else
  282.   {
  283.     lstrcpy(txt, "Could not load ");
  284.     lstrcat(txt, sndfile);
  285.  
  286.     MessageBox(NULL,txt,"Sound ToolKit Error",MB_OK);
  287.  
  288.     return (0);
  289.   }
  290.  
  291.   return (filesize);
  292. }
  293.  
  294.  
  295. /* Convert WAV to DWD */
  296. static int ConvertWave(char *wavefile)
  297. {
  298.   BYTE   *wavedwd;
  299.   WORD    status;
  300.   DWORD   wavesize, len, tmp;
  301.   HGLOBAL hwavedwd;
  302.  
  303.   wavesize = LoadFile(wavefile);
  304.  
  305.   if (!wavesize)
  306.   {
  307.     return (0);
  308.   }
  309.  
  310.   /* convert WAV to DWD */
  311.   tmp = len = wavesize;
  312.   status = dws_WAV2DWD(sndptr[presentsnd], &tmp, NULL);
  313.  
  314.   if (!status)
  315.   {
  316.     DisplayErr("Get Wave Size");
  317.  
  318.     return (0);
  319.   }
  320.  
  321.   hwavedwd = GlobalAlloc(GHND, tmp);
  322.   wavedwd = (BYTE*)GlobalLock(hwavedwd);
  323.   status = dws_WAV2DWD(sndptr[presentsnd], &len, wavedwd);
  324.  
  325.   if (!status)
  326.   {
  327.     GlobalUnlock(hwavedwd);
  328.     GlobalFree(hwavedwd);
  329.     DisplayErr("Wave Conversion");
  330.  
  331.     return (0);
  332.   }
  333.  
  334.   GlobalUnlock(hsndptr[presentsnd]);
  335.   GlobalFree(hsndptr[presentsnd]);
  336.  
  337.   hsndptr[presentsnd] = hwavedwd;
  338.   sndptr[presentsnd]  = wavedwd;
  339.  
  340.   return (1);
  341. }
  342.  
  343.  
  344. /* Get a new WAV, DWD, or MID file */
  345. static VOID DoNew(HWND hwnd)
  346. {
  347.   char         buffer[_MAX_PATH]="";
  348.   OPENFILENAME of;
  349.  
  350.   /* set up the OPENFILE structure, then use the appropriate common dialog */
  351.   of.lStructSize       = sizeof(OPENFILENAME);
  352.   of.hwndOwner         = NULL;
  353.  
  354.   #ifdef  WIN32
  355.     of.hInstance       = (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE);
  356.   #else
  357.     of.hInstance       = (HINSTANCE)GetWindowWord(hwnd, GWW_HINSTANCE);
  358.   #endif
  359.  
  360.   of.lpstrFilter       = "Sounds and Music\000*.WAV;*.DWD;*.MID\000\000";
  361.   of.lpstrCustomFilter = NULL;
  362.   of.nMaxCustFilter    = 0;
  363.   of.nFilterIndex      = 0;
  364.   of.lpstrFile         = buffer;
  365.   of.nMaxFile          = _MAX_PATH;
  366.   of.lpstrFileTitle    = NULL;
  367.   of.nMaxFileTitle     = 0;
  368.   of.lpstrInitialDir   = NULL;
  369.   of.lpstrTitle        = "Sound ToolKit - Open";
  370.   of.Flags             = OFN_HIDEREADONLY;
  371.   of.nFileOffset       = 0;
  372.   of.nFileExtension    = 0;
  373.   of.lpstrDefExt       = NULL;
  374.   of.lCustData         = 0;
  375.   of.lpfnHook          = NULL;
  376.   of.lpTemplateName    = NULL;
  377.  
  378.   if (GetOpenFileName(&of))
  379.   {
  380.     /* Put the filename in the list box. */
  381.     SendDlgItemMessage(hwnd, DID_LISTBOX, LB_ADDSTRING, 0, (LONG) buffer);
  382.   }
  383. }
  384.  
  385.  
  386. /* Play the selected listbox item: WAV, DWD, or MID */
  387. static VOID DoPlay(HWND hwnd)
  388. {
  389.   static char textselection[_MAX_PATH]="";
  390.   char        buffer[_MAX_PATH], *ptr;
  391.   WORD        status;
  392.   static int  newselection=1;
  393.   int         sel;
  394.   dws_MPLAY   mplay;
  395.  
  396.   /* determine which item is selected in the list box, and get the text */
  397.   sel = (int)SendDlgItemMessage(hwnd, DID_LISTBOX, LB_GETCURSEL, 0, 0);
  398.  
  399.   if (sel == LB_ERR)
  400.   {
  401.     MessageBox(NULL,
  402.                "No listbox item is selected.",
  403.                "Sound ToolKit Error",
  404.                MB_OK);
  405.     return;
  406.   }
  407.  
  408.   SendDlgItemMessage(hwnd, DID_LISTBOX, LB_GETTEXT, (int)sel, (LONG)buffer);
  409.  
  410.   /* don't reload if the same file is replayed */
  411.   if (lstrcmp(buffer, textselection) != 0)
  412.   {
  413.     newselection = 1;
  414.     lstrcpy(textselection, buffer);
  415.   }
  416.  
  417.   ptr = strrchr(buffer, '.');
  418.  
  419.   if (!ptr)
  420.   {
  421.     MessageBox(NULL,
  422.                "File name format not known",
  423.                "Sound ToolKit Error",
  424.                MB_OK);
  425.   }
  426.  
  427.   /* convert the retrieved text to lowercase */
  428.   for (sel=0 ; buffer[sel] ; sel++)
  429.   {
  430.     buffer[sel] = (char)tolower(buffer[sel]);
  431.   }
  432.  
  433.   if (lstrcmp(ptr, ".wav") == 0 || lstrcmp(ptr, ".dwd") == 0)
  434.   {
  435.     if (newselection)
  436.     {
  437.       if (lstrcmp(ptr, ".wav") == 0)
  438.       {
  439.         if (!ConvertWave(buffer))
  440.         {
  441.           return;
  442.         }
  443.       }
  444.       else if (lstrcmp(ptr, ".dwd") == 0)
  445.       {
  446.         if (!LoadFile(buffer))
  447.         {
  448.           return;
  449.         }
  450.       }
  451.  
  452.       dplay.snd = sndptr[presentsnd];
  453.     }
  454.     else
  455.     {
  456.       dplay.snd = sndptr[previoussnd];
  457.     }
  458.  
  459.     dplay.count = 1;
  460.     if (volleft >= 8)
  461.     {
  462.       dplay.lvol = (WORD)((volleft - 7) * 256);
  463.     }
  464.     else
  465.     {
  466.       dplay.lvol = (WORD)(volleft * 32);
  467.     }
  468.  
  469.     if (volright >= 8)
  470.     {
  471.       dplay.rvol = (WORD)((volright - 7) * 256);
  472.     }
  473.     else
  474.     {
  475.       dplay.rvol = (WORD)(volright * 32);
  476.     }
  477.  
  478.     if (pitch >= 8)
  479.     {
  480.       dplay.pitch = (WORD)((pitch - 7) * 256);
  481.     }
  482.     else
  483.     {
  484.       dplay.pitch = (WORD)(pitch * 32);
  485.     }
  486.  
  487.     dplay.flags = dws_dplay_SND|dws_dplay_COUNT|
  488.                   dws_dplay_LVOL|dws_dplay_RVOL|
  489.                   dws_dplay_PITCH;
  490.     status = dws_DPlay(&dplay);
  491.  
  492.     if (!status)
  493.     {
  494.       DisplayErr("dws_DPlay During DoPlay");
  495.     }
  496.  
  497.     if (newselection)
  498.     {
  499.       previoussnd = presentsnd++;
  500.       if (presentsnd >= SOUNDTOTAL) presentsnd = 0;
  501.     }
  502.  
  503.     newselection = 0;
  504.   }
  505.   else if (lstrcmp(ptr, ".mid") == 0)
  506.   {
  507.     mplay.track = (BYTE*)buffer;
  508.     mplay.count = 1;
  509.     status = dws_MPlay(&mplay);
  510.  
  511.     if (!status)
  512.     {
  513.       DisplayErr("dws_MPlay During DoPlay");
  514.     }
  515.   }
  516. }
  517.  
  518.  
  519. /* Stop the music and sound */
  520. static VOID DoStop(void)
  521. {
  522.   if (!dws_DClear())  /* stop all playing sounds */
  523.   {
  524.     DisplayErr("DoStop of Digitized Sound");
  525.   }
  526.  
  527.   if (!dws_MClear())  /* stop any playing music */
  528.   {
  529.     DisplayErr("DoStop of MIDI Music");
  530.   }
  531. }
  532.  
  533.  
  534. /* Remove selected filename from list box */
  535. static VOID DoRemove(HWND hwnd)
  536. {
  537.   char buffer[_MAX_PATH];
  538.   int  sel;
  539.  
  540.   /* determine which item is selected in the list box, and get the text */
  541.   sel = (int)SendDlgItemMessage(hwnd, DID_LISTBOX, LB_GETCURSEL, 0, 0);
  542.  
  543.   if (sel == LB_ERR)
  544.   {
  545.     MessageBox(NULL,
  546.                "No listbox item is selected.",
  547.                "Sound ToolKit Error",
  548.                MB_OK);
  549.     return;
  550.   }
  551.  
  552.   SendDlgItemMessage(hwnd, DID_LISTBOX, LB_GETTEXT, (int)sel, (LONG)buffer);
  553.   SendDlgItemMessage(hwnd, DID_LISTBOX, LB_DELETESTRING, sel, 0);
  554. }
  555.  
  556.  
  557. static VOID ScrollControl(HWND hwnd, HWND sb, int npos, int nbar)
  558. {
  559.   int val;
  560.  
  561.   val = GetScrollPos(sb, SB_CTL);
  562.  
  563.   switch (nbar)
  564.   {
  565.     case SB_LINEUP:
  566.     {
  567.       if (val)
  568.       {
  569.         val--;
  570.       }
  571.  
  572.       break;
  573.     }
  574.     case SB_LINEDOWN:
  575.     {
  576.  
  577.       if (val < 16)
  578.       {
  579.         val++;
  580.       }
  581.  
  582.       break;
  583.     }
  584.     case SB_PAGEUP:
  585.     {
  586.       val -= 2;
  587.  
  588.       if (val < 0)
  589.       {
  590.         val = 0;
  591.       }
  592.  
  593.       break;
  594.     }
  595.     case SB_PAGEDOWN:
  596.     {
  597.       val += 2;
  598.  
  599.       if (val > 16)
  600.       {
  601.         val = 16;
  602.       }
  603.  
  604.       break;
  605.     }
  606.     case SB_THUMBPOSITION:
  607.     {
  608.       val = npos;
  609.       break;
  610.     }
  611.     case SB_THUMBTRACK:
  612.     {
  613.       val = npos;
  614.       break;
  615.     }
  616.     case SB_ENDSCROLL:
  617.     {
  618.       break;
  619.     }
  620.   }
  621.  
  622.   /* set the scrollbar to its new position */
  623.   SetScrollPos(sb, SB_CTL, val, TRUE);
  624.  
  625.   /* want to Get and Set this information in playing sound */
  626.   dplay.flags = dws_dplay_SOUNDNUM|dws_dplay_LVOL|dws_dplay_RVOL|dws_dplay_PITCH;
  627.  
  628.   /*
  629.    . depending upon which scrollbar was moved, calculate the new
  630.    . volume or pitch value
  631.   */
  632.   if (sb == sbvolleft)
  633.   {
  634.     volleft = (WORD)(16 - val);
  635.  
  636.     if (!dws_DGetInfo(&dplay, NULL))
  637.     {
  638.       DisplayErr("dws_DGetInfo During Left Volume Change");
  639.     }
  640.  
  641.     if (volleft >= 8)
  642.     {
  643.       dplay.lvol = (WORD)((volleft - 7) * 256);
  644.     }
  645.     else
  646.     {
  647.       dplay.lvol = (WORD)(volleft * 32);
  648.     }
  649.  
  650.     dplay.flags = dws_dplay_SOUNDNUM|dws_dplay_LVOL;
  651.  
  652.     if (!dws_DSetInfo(&dplay, NULL))
  653.     {
  654.       DisplayErr("dws_DSetInfo During Left Volume Change");
  655.     }
  656.   }
  657.   else if (sb == sbvolright)
  658.   {
  659.     volright = (WORD)(16 - val);
  660.  
  661.     if (!dws_DGetInfo(&dplay, NULL))
  662.     {
  663.       DisplayErr("dws_DGetInfo During Right Volume Change");
  664.     }
  665.  
  666.     if (volright >= 8)
  667.     {
  668.       dplay.rvol = (WORD)((volright - 7) * 256);
  669.     }
  670.     else
  671.     {
  672.       dplay.rvol = (WORD)(volright * 32);
  673.     }
  674.  
  675.     dplay.flags = dws_dplay_SOUNDNUM|dws_dplay_RVOL;
  676.  
  677.     if (!dws_DSetInfo(&dplay, NULL))
  678.     {
  679.       DisplayErr("dws_DSetInfo During Right Volume Change");
  680.     }
  681.   }
  682.   else if (sb == sbpitch)
  683.   {
  684.     pitch = (WORD)val;
  685.  
  686.     if (!pitch)
  687.     {
  688.       pitch++;
  689.     }
  690.  
  691.     if (!dws_DGetInfo(&dplay, NULL))
  692.     {
  693.       DisplayErr("dws_DGetInfo During Pitch Change");
  694.     }
  695.  
  696.     if (pitch >= 8)
  697.     {
  698.       dplay.pitch = (WORD)((pitch - 7) * 256);
  699.     }
  700.     else
  701.     {
  702.       dplay.pitch = (WORD)(pitch * 32);
  703.     }
  704.  
  705.     dplay.flags = dws_dplay_SOUNDNUM|dws_dplay_PITCH;
  706.  
  707.     if (!dws_DSetInfo(&dplay, NULL))
  708.     {
  709.       DisplayErr("dws_DSetInfo During Pitch Change");
  710.     }
  711.   }
  712.   else
  713.   {
  714.     MessageBox(NULL,
  715.                "Unknown control reference in ScrollControl",
  716.                "Sound ToolKit Error",
  717.                MB_OK);
  718.   }
  719. }
  720.  
  721.  
  722. static LRESULT playstk_CALLBACK MainDlgProc(HWND hwnd, UINT message,
  723.                                             WPARAM wParam, LPARAM lParam)
  724. {
  725.   WORD result;
  726.   int  i;
  727.   UINT swaplr;
  728.  
  729.   switch (message)
  730.   {
  731.     case WM_INITDIALOG:
  732.     {
  733.       sbvolleft = GetDlgItem(hwnd, IDC_VOL_LEFT);
  734.       SetScrollRange(sbvolleft, SB_CTL, 0, 16, FALSE);
  735.       SetScrollPos(sbvolleft, SB_CTL, 8, FALSE);
  736.  
  737.       sbvolright = GetDlgItem(hwnd, IDC_VOL_RIGHT);
  738.       SetScrollRange(sbvolright, SB_CTL, 0, 16, FALSE);
  739.       SetScrollPos(sbvolright, SB_CTL, 8, FALSE);
  740.  
  741.       sbpitch = GetDlgItem(hwnd, IDC_PITCH);
  742.       SetScrollRange(sbpitch, SB_CTL, 1, 16, FALSE);
  743.       SetScrollPos(sbpitch, SB_CTL, 8, FALSE);
  744.  
  745.       cbswaplr = GetDlgItem(hwnd, IDC_SWAPLR);
  746.       CheckDlgButton(hwnd, IDC_SWAPLR, FALSE);
  747.  
  748.       CheckDlgButton(hwnd, IDC_RATE_11025, TRUE);
  749.       CheckDlgButton(hwnd, IDC_RATE_22050, FALSE);
  750.       CheckDlgButton(hwnd, IDC_RATE_44100, FALSE);
  751.  
  752.       volleft  = 8;
  753.       volright = 8;
  754.       pitch    = 8;
  755.  
  756.       if (!dws_DetectHardWare(&dres))
  757.       {
  758.         DisplayErr("dws_DetectHardWare During Initdialog");
  759.       }
  760.       else if (!dres.digcaps)
  761.       {
  762.         MessageBox(NULL,
  763.                    "Your computer does not support sound playback.",
  764.                    "Sound ToolKit Error", MB_OK);
  765.  
  766.         exit (-1);
  767.       }
  768.       else if (!(dres.digcaps & dws_digcap_11025_08_2))
  769.       {
  770.         MessageBox(NULL,
  771.                    "DiamondWare's Sound ToolKit for Windows\n"
  772.                    "supports sound playback on your computer.\n"
  773.                    "However, this demo requires 8-bit stereo,\n"
  774.                    "which your computer does not support."
  775.                    "Your sound hardware does not support\n"
  776.                    "11025Hz, two channel, 8 bit sound.\n"
  777.                    "This demo will not run properly on\n"
  778.                    "your computer",
  779.                    "Sound ToolKit Error", MB_OK);
  780.  
  781.         exit (-1);
  782.       }
  783.  
  784.       /* Ordered from "best" to "worst" choice for music devices */
  785.       if (dres.muscaps & dws_muscap_MAPPER)
  786.       {
  787.         result = dws_muscap_MAPPER;
  788.       }
  789.       else if (dres.muscaps & dws_muscap_FMSYNTH)
  790.       {
  791.         result = dws_muscap_FMSYNTH;
  792.       }
  793.       else if (dres.muscaps & dws_muscap_SYNTH)
  794.       {
  795.         result = dws_muscap_SYNTH;
  796.       }
  797.       else if (dres.muscaps & dws_muscap_SQSYNTH)
  798.       {
  799.         result = dws_muscap_SQSYNTH;
  800.       }
  801.       else if (dres.muscaps & dws_muscap_MIDIPORT)
  802.       {
  803.         result = dws_muscap_MIDIPORT;
  804.       }
  805.       else
  806.         result = dws_muscap_NONE;
  807.  
  808.       ideal.mustyp     = result;
  809.       ideal.digtyp     = dws_digcap_11025_08_2;
  810.       ideal.dignvoices = 6;                     //6 voices is plenty
  811.  
  812.       if (!dws_Init(&dres, &ideal))
  813.       {
  814.         DisplayErr("dws_Init During Init");
  815.       }
  816.       else
  817.       {
  818.         if (!dws_XDig(128, 128))    /*  half volume */
  819.         {
  820.           DisplayErr("dws_XDig During Initdialog");
  821.         }
  822.       }
  823.  
  824.       return (TRUE);
  825.     }
  826.     case WM_SYSCOMMAND:
  827.     {
  828.       if (wParam == SC_CLOSE)
  829.       {
  830.         Kill();
  831.  
  832.         for (i=0 ; i < SOUNDTOTAL ; i++)
  833.         {
  834.           if (hsndptr[i])
  835.           {
  836.             GlobalUnlock(hsndptr[i]);
  837.             GlobalFree(hsndptr[i]);
  838.           }
  839.         }
  840.  
  841.         EndDialog(hwnd, TRUE);
  842.  
  843.         return (TRUE);
  844.       }
  845.  
  846.       return (FALSE); /* end WM_SYSCOMMAND */
  847.     }
  848.     case WM_COMMAND:
  849.     {
  850.       switch (LOWORD(wParam))   //which control ID?
  851.       {
  852.         case DID_LISTBOX:
  853.         {
  854.           #ifdef  WIN32
  855.             if (HIWORD(wParam) == LBN_DBLCLK)
  856.           #else
  857.             if (HIWORD(lParam) == LBN_DBLCLK)
  858.           #endif
  859.           {
  860.             DoPlay(hwnd);
  861.           }
  862.  
  863.           break;
  864.         }
  865.         case DID_NEW:
  866.         {
  867.           DoNew(hwnd);
  868.  
  869.           break;
  870.         }
  871.         case DID_PLAY:
  872.         {
  873.           DoPlay(hwnd);
  874.  
  875.           break;
  876.         }
  877.         case DID_STOP:
  878.         {
  879.           DoStop();
  880.  
  881.           break;
  882.         }
  883.         case DID_REMOVE:
  884.         {
  885.           DoRemove(hwnd);
  886.  
  887.           break;
  888.         }
  889.         case IDC_SWAPLR:
  890.         {
  891.           #ifdef  WIN32
  892.             if ((HWND)lParam == cbswaplr)
  893.           #else
  894.             if ((HWND)LOWORD(lParam) == cbswaplr)
  895.           #endif
  896.           {
  897.             Kill();
  898.  
  899.             swaplr = 1 - IsDlgButtonChecked(hwnd, IDC_SWAPLR);
  900.             CheckDlgButton(hwnd, IDC_SWAPLR, swaplr);
  901.             ideal.flags = swaplr ? dws_ideal_SWAPLR : 0;
  902.  
  903.             if (!dws_Init(&dres, &ideal))
  904.             {
  905.               DisplayErr("dws_Init During Init");
  906.             }
  907.           }
  908.  
  909.           break;
  910.         }
  911.         case IDC_RATE_11025:
  912.         {
  913.           ChangeRate(dws_digcap_11025_08_2);
  914.  
  915.           break;
  916.         }
  917.         case IDC_RATE_22050:
  918.         {
  919.           ChangeRate(dws_digcap_22050_08_2);
  920.  
  921.           break;
  922.         }
  923.         case IDC_RATE_44100:
  924.         {
  925.           ChangeRate(dws_digcap_44100_08_2);
  926.  
  927.           break;
  928.         }
  929.       }
  930.  
  931.       return (TRUE);
  932.     }
  933.     case WM_VSCROLL:
  934.     {
  935.       #ifdef  WIN32
  936.         ScrollControl(hwnd, (HWND)lParam, HIWORD(wParam), LOWORD(wParam));
  937.       #else
  938.         ScrollControl(hwnd, (HWND)HIWORD(lParam), LOWORD(lParam), wParam);
  939.       #endif
  940.  
  941.       break;
  942.     }
  943.     default:
  944.     {
  945.       break;
  946.     }
  947.   }
  948.  
  949.   return (FALSE);
  950. }
  951.  
  952.  
  953. int playstk_PASCAL WinMain(HINSTANCE hinstCurrent, HINSTANCE hPrevInstance,
  954.                            LPSTR lpCmdLine, int nCmdShow)
  955. {
  956.   int result;
  957.  
  958.   #if defined(WIN32) && defined(_MSC_VER)
  959.     UNREFERENCED_PARAMETER(hPrevInstance);
  960.     UNREFERENCED_PARAMETER(lpCmdLine);
  961.     UNREFERENCED_PARAMETER(nCmdShow);
  962.   #endif
  963.  
  964.   result = DialogBox(hinstCurrent, MAKEINTRESOURCE(DID_SAMPLEDLG),
  965.                      NULL, (DLGPROC)MainDlgProc);
  966.  
  967.   return (result);
  968. }
  969.