Sound Tutorial
Playing Sound in Windows


This code should compile fine under any C compiler, but I used Microsoft Visual C++ 6.0.   Make sure to link with libraries user32.lib (used for message boxes) and winmm.lib (used for multimedia).  This code is the simplest way to get a chunk of data to play through the sound card.  A great place to start if your just getting familiar with Window's multimedia API.

A next good tutorial is taking this program and making it stream multiple packets to your sound card, but I left that for you to discover and enjoy!

/*
    ** Simple Windows Sound Program **

    This program demonstrates how to create and play a simple sound wave
    with your default sound card. 
    
    Make sure to link into user32.lib and winmm.lib during compile.
    
    Todd Moore
    toddmoore@erols.com
*/

#include <windows.h>
#include <math.h>

#define FREQUENCY     440                 // 440hz = Musical A Note
#define BUFFERSIZE    4860                // 4k sound buffer

#define PI            3.14159265358979

// A simple way to report Sound Errors
void Message(LPCSTR message)
{
    MessageBox(NULL, message, "Sound Error", MB_OK | MB_ICONSTOP);
}


// Main entry point for Win32 Program
int WINAPI WinMain(HINSTANCE hInstance,      // handle to current instance
                   HINSTANCE hPrevInstance,  // handle to previous instance
                   LPSTR lpCmdLine,          // pointer to command line
                   int nCmdShow)             // show state of window

{    
    
    HWAVEOUT     hWaveOut;          // Handle to sound card output
    WAVEFORMATEX WaveFormat;        // The sound format
    WAVEHDR      WaveHeader;        // WAVE header for our sound data
    
    char         Data[BUFFERSIZE];  // Sound data buffer
    
    HANDLE       Done;              // Event Handle that tells us the sound has finished being played.
                                    // This is a real efficient way to put the program to sleep
                                    // while the sound card is processing the sound buffer
    double x;
    int i;

    // ** Initialize the sound format we will request from sound card **    
    WaveFormat.wFormatTag = WAVE_FORMAT_PCM;     // Uncompressed sound format
    WaveFormat.nChannels = 1;                    // 1=Mono 2=Stereo
    WaveFormat.wBitsPerSample = 8;               // Bits per sample per channel
    WaveFormat.nSamplesPerSec = 11025;           // Sample Per Second
    WaveFormat.nBlockAlign = WaveFormat.nChannels * WaveFormat.wBitsPerSample / 8;
    WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign;    
    WaveFormat.cbSize = 0;

    // ** Create our "Sound is Done" event **
    Done = CreateEvent (0, FALSE, FALSE, 0);
    
    // ** Open the audio device **
    if (waveOutOpen(&hWaveOut,0,&WaveFormat,(DWORD) Done,0,CALLBACK_EVENT) != MMSYSERR_NOERROR) 
    {        
        Message("Sound card cannot be opened.");
        return TRUE;
    }

    // ** Make the sound buffer **    
    for (i=0; i < BUFFERSIZE; i++)
    {        
        // ** Generate the sound wave based on FREQUENCY define
        // ** x will have a range of -1 to +1
        x = sin(i*2.0*PI*(FREQUENCY)/(double)WaveFormat.nSamplesPerSec); 
        
        // ** scale x to a range of 0-255 (signed char) for 8 bit sound reproduction **
        Data[i] = (char)(127*x+128);
    }
    
    
    // ** Create the wave header for our sound buffer **
    WaveHeader.lpData=Data;
    WaveHeader.dwBufferLength=BUFFERSIZE;
    WaveHeader.dwFlags=0;
    WaveHeader.dwLoops=0;
    
    // ** Prepare the header for playback on sound card **
    if (waveOutPrepareHeader(hWaveOut,&WaveHeader,sizeof(WaveHeader)) != MMSYSERR_NOERROR)
    {
        Message("Error preparing Header!");
        return TRUE;
    }
    
    // ** Play the sound! **
    ResetEvent(Done);  // Reset our Event so it is non-signaled, it will be signaled again with buffer finished

    if (waveOutWrite(hWaveOut,&WaveHeader,sizeof(WaveHeader)) != MMSYSERR_NOERROR)
    {
        Message("Error writing to sound card!");
        return TRUE;
    }

    // ** Wait until sound finishes playing
    if (WaitForSingleObject(Done,INFINITE) != WAIT_OBJECT_0)
    {
		Message("Error waiting for sound to finish");
		return TRUE;
	}

    
    // ** Unprepare our wav header **
    if (waveOutUnprepareHeader(hWaveOut,&WaveHeader,sizeof(WaveHeader)) != MMSYSERR_NOERROR)
    {
        Message("Error unpreparing header!");
        return TRUE;
    }
    
    // ** close the wav device **
    if (waveOutClose(hWaveOut) != MMSYSERR_NOERROR)
    {
        Message("Sound card cannot be closed!");
        return TRUE;
    } 

    // ** Release our event handle **
    CloseHandle(Done);

    return FALSE;
}



 
 

Privacy Policy - About TMSOFT
© 2008 TMSOFT LLC.  All rights reserved.