home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / win_lrn / sound / soundx.c < prev    next >
C/C++ Source or Header  |  1988-08-10  |  9KB  |  266 lines

  1. /***********************************************************************
  2.  *** Functions demonstrated: (all of them...)
  3.  ***        CloseSound, OpenSound,                   
  4.  ***        StartSound, StopSound,         
  5.  ***        CountVoiceNotes, SetVoiceNote,
  6.  ***        SetVoiceSound, SetSoundNoise, 
  7.  ***        SetVoiceQueueSize, SetVoiceAccent,
  8.  ***        SetVoiceEnvelope, SetVoiceThreshold,
  9.  ***        GetThresholdEvent, GetThresholdStatus,
  10.  ***        SyncAllVoices, WaitSoundState.            
  11.  ***                                
  12.  *** Note that the files are not named SOUND.  This is because    
  13.  *** Windows has an internal driver named sound and will not accept 
  14.  *** sound as an application name.                    
  15.  ************************************************************************/
  16.  
  17. #include <windows.h>
  18. #include <stdio.h>
  19. #include "soundx.h"
  20.  
  21. long FAR PASCAL SoundWndProc (HWND, unsigned, WORD, LONG);
  22.  
  23. int PASCAL WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  24.     HANDLE    hInstance, hPrevInstance;
  25.     LPSTR    lpszCmdLine;
  26.     int     nCmdShow;
  27.     {
  28.     HWND    hWnd;
  29.     MSG     msg;
  30.     WNDCLASS    wndclass;
  31.  
  32.     if (!hPrevInstance)
  33.     {
  34.     wndclass.style        = CS_HREDRAW | CS_VREDRAW;
  35.     wndclass.lpfnWndProc    = SoundWndProc;
  36.     wndclass.cbClsExtra    = 0;
  37.     wndclass.cbWndExtra    = 0;
  38.     wndclass.hInstance    = hInstance;
  39.     wndclass.hIcon        = LoadIcon(NULL, IDI_ASTERISK);
  40.     wndclass.hCursor    = LoadCursor(NULL,  IDC_ARROW);
  41.     wndclass.hbrBackground    = GetStockObject (WHITE_BRUSH);
  42.     wndclass.lpszMenuName    = "SoundMenu";
  43.     wndclass.lpszClassName    = "Sound";
  44.  
  45.     if (!RegisterClass(&wndclass) )
  46.         return FALSE;
  47.     }
  48.  
  49.     hWnd = CreateWindow("Sound", "Sound Window",
  50.         WS_MINIMIZEBOX | WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU,
  51.         270, 130, 40, 54, NULL, NULL, hInstance, NULL);
  52.  
  53.     ShowWindow(hWnd, nCmdShow);
  54.     UpdateWindow(hWnd);
  55.  
  56.     while (GetMessage(&msg, NULL, 0,0 ))
  57.     {
  58.     TranslateMessage(&msg);
  59.     DispatchMessage(&msg);
  60.     }
  61.  
  62.     return msg.wParam;
  63.     }
  64.  
  65. long FAR PASCAL SoundWndProc (hWnd, iMessage, wParam, lParam)
  66.     HWND      hWnd;
  67.     unsigned      iMessage;
  68.     WORD      wParam;
  69.     LONG      lParam;
  70.     {
  71.     char     szJunk[40];      /* Buffer fo MessageBoxes        */
  72.     unsigned int nIndex;      /* Generic index counter        */
  73.     static int     nNoise=0,      /* Noise parameter            */
  74.          nCount=0;      /* Number returned from GetVoiceNotes */
  75.     static BOOL  bThresh=FALSE,   /* SetVoiceThreshold flag        */
  76.          bEnv=FALSE;      /* SetVoiceEnvelope flag        */
  77.  
  78.     /* Notes from The Appassionata                    */
  79.     static int     nNotes[60]={45,42,38,45,38,47,43,38,45,42,38,45,
  80.                  38,45,40,47,45,40,38,40,37,45,40,37,
  81.                  45,42,38,45,42,50,45,42,50,45,42,50,
  82.                  43,50,47,43,50,45,42,50,42,50,44,50,
  83.                  40,49,45,40,49,45,40,49,50,45,40,33};
  84.  
  85.     switch (iMessage)
  86.     {
  87.     case WM_DESTROY:
  88.         PostQuitMessage(0);
  89.         /* fall through */
  90.  
  91.     /* Release resources if focus is lost or window is iconized    */
  92.     /* or ended.  Remove these and a constant sound will continue    */
  93.     /* for a time even if the window is no longer around.  The bad    */
  94.     /* part is that sound resources are not released and that can    */
  95.     /* screw up DOS as well as Windows.                */
  96.     case WM_KILLFOCUS:
  97.     case WM_SETVISIBLE:
  98.         CloseSound();
  99.         StopSound();
  100.         break;
  101.  
  102.     /* Open sound resources if window is opened or obtains the focus*/
  103.     case WM_SETFOCUS:
  104.         OpenSound();
  105.         break;
  106.  
  107.     case WM_COMMAND:
  108.         /* Set number of notes in queue.  Windows only has multiple */
  109.         /* voice capability if the computer has sound hardware.    */
  110.         SetVoiceQueueSize(1, 600);
  111.  
  112.         switch (wParam)
  113.         {
  114.         case ID_NOTES:
  115.             /* Set temp, volume, and style of notes.  For the    */
  116.             /* most part, the tempo parameter (2nd) is the only */
  117.             /* effective value on machines without additional    */
  118.             /* sound hardware (volume is ineffective).        */
  119.             SetVoiceAccent(1, 220, 20, S_NORMAL, 0);
  120.  
  121.             /* Set the number of notes in threshold to 30.  This*/
  122.             /* causes the threshold flag to be set when the    */
  123.             /* number of remaining notes falls below 30.    */
  124.             if (bThresh)
  125.             SetVoiceThreshold(1, 30);
  126.  
  127.             /* Set an envelope                    */
  128.             SetVoiceEnvelope(1, bEnv, 3);
  129.  
  130.             /* Set notes in queue.  Note 0 is a rest, note 1 is */
  131.             /* two octaves below middle C.  Concert A (440Hz) is*/
  132.             /* 34.  To prove this, do SetVoiceNote(1,34,1,0)    */
  133.             /* and SetVoiceSound(1,440L*65536L, 300).  The tones*/
  134.             /* are equivalent.                    */
  135.             for (nIndex=84; nIndex > 0; nIndex -=1 )
  136.             SetVoiceNote(1, nIndex, 250, 0);
  137.  
  138.             /* Play the sound                    */
  139.             StartSound();
  140.  
  141.             /* Retain the count of notes            */
  142.             nCount=CountVoiceNotes(1);
  143.             break;
  144.  
  145.         case ID_SOUND:
  146.             /* Set sounds in queue.  Second parameter to    */
  147.             /* SetVoiceSound is a LONG, not an int as stated in */
  148.             /* the documentation. Also, the documentation states*/
  149.             /* that the high-order word of the second parameter */
  150.             /* is the frequency in Kilohertz.  However, it is    */
  151.             /* actually in Hertz.  Otherwise, this routine would*/
  152.             /* produce very minimal audible sound.        */
  153.  
  154.             for (nIndex=750; nIndex >=1; nIndex -=3)
  155.             SetVoiceSound(1, (unsigned long)(nIndex*65536L), 3);
  156.  
  157.             StartSound();
  158.             nCount=0;
  159.  
  160.             /* Wait until all sounds have been played        */
  161.             WaitSoundState(S_QUEUEEMPTY);
  162.             break;
  163.  
  164.         case ID_NOISE:
  165.             /* Start noise. Must StartSound after SetSoundNoise.*/
  166.             /* Full use of this function requires other sound    */
  167.             /* drivers not available on standard machines.    */
  168.             StopSound();
  169.             SetSoundNoise(nNoise++, 100);
  170.             StartSound();
  171.             nCount=0;
  172.             for (nIndex=0; nIndex < 65535; nIndex++); /* pause    */
  173.             StopSound();
  174.             nNoise &=7;
  175.             break;
  176.  
  177.         case LUDWIG:
  178.             /* Play beginning of second movement to the Andante */
  179.             /* in Beethoven's Appassionata.                     */
  180.             StopSound();
  181.             SetVoiceAccent(1, 70, 120, S_LEGATO, 0);
  182.             SetVoiceEnvelope(1, bEnv, 3);
  183.             if (bThresh)
  184.             SetVoiceThreshold(1, 30);
  185.  
  186.             /* Set notes from the data array.            */
  187.             for (nIndex=0; nIndex<60; nIndex++)
  188.             SetVoiceNote(1, nNotes[nIndex], 16, 0);
  189.  
  190.             SetVoiceNote(1,50,4,0); /* Longer final note.    */
  191.  
  192.             /* Start sound.  Continues playing until it done,    */
  193.             /* the window is detroyed, loses the input focus,    */
  194.             /* or iconized.  WaitSoundState can be used to wait */
  195.             /* until the sound is finished.            */
  196.             StartSound();
  197.             nCount=CountVoiceNotes(1);
  198.             break;
  199.  
  200.         case ID_COUNT:
  201.             /* Show the current value of nCount. GetVoiceNotes    */
  202.             /* only counts notes, not sounds, envelopes, etc.    */
  203.             sprintf(szJunk, "Notes=%d", nCount);
  204.             MessageBox(hWnd, szJunk, "CountVoiceNotes", MB_OK);
  205.             break;
  206.  
  207.         case ID_SYNC:
  208.             /* SyncAllVoices is really only effective with    */
  209.             /* multivoice support. On standard machines this    */
  210.             /* function is not successful.            */
  211.             if (SyncAllVoices())
  212.             MessageBox(hWnd, "SyncAllVoices successful.",
  213.                    "SyncAllVoices", MB_OK);
  214.             else
  215.             MessageBox(hWnd, "SyncAllVoices unsuccessful.",
  216.                    "SyncAllVoices", MB_OK);
  217.             break;
  218.  
  219.         case ID_ENV:
  220.             bEnv=!bEnv;
  221.             if(bEnv)
  222.             MessageBox(hWnd, "Envelope ON",
  223.                    "SetVoiceThreshold", MB_OK);
  224.             else
  225.             MessageBox(hWnd, "Envelope OFF",
  226.                    "SetVoiceThreshold", MB_OK);
  227.  
  228.             break;
  229.  
  230.         case ID_EVENT:
  231.             /* Returns a pointer to an int            */
  232.             sprintf(szJunk, "returns: %d", *(GetThresholdEvent()));
  233.             MessageBox(hWnd, szJunk, "GetThresholdEvent", MB_OK);
  234.             break;
  235.  
  236.         case ID_STATUS:
  237.             /* GetThresholdStatus retrieves an int.  Each bit    */
  238.             /* has the status for each voice.            */
  239.             /* If a bit is set, the the threshold level for    */
  240.             /* that voice has been reached.            */
  241.             if (GetThresholdStatus())
  242.             MessageBox(hWnd, "Threshold reached.",
  243.                    "GetThresholdStatus", MB_OK);
  244.             else
  245.             MessageBox(hWnd, "Threshold not reached.",
  246.                    "GetThresholdStatus", MB_OK);
  247.  
  248.             break;
  249.  
  250.         case ID_SETVT:
  251.             /* Here a flag is toggled for NOTES and LUDWIG.    */
  252.             bThresh=!bThresh;
  253.             if(bThresh)
  254.             MessageBox(hWnd, "Threshold ON",
  255.                    "SetVoiceThreshold", MB_OK);
  256.             else
  257.             MessageBox(hWnd, "Threshold OFF",
  258.                    "SetVoiceThreshold", MB_OK);
  259.             break;
  260.         }
  261.     default:
  262.         return (DefWindowProc(hWnd, iMessage, wParam, lParam));
  263.     }
  264.     return 0L;
  265.     }
  266.