Solved

Sound Recording

Posted on 1998-07-15
3
338 Views
Last Modified: 2013-11-20
I am working with Visual C++ 4.2 and  WindowsNT 4.0 on a P233.
I want to implement an MFC application which record and play sounds. I would like to be able to :
- record a sound
- to play it and stop it
- to be able to reach any particular time in the audio file
The sound I want to record comes from a microphone plugged into the PC.
 Could anyone tell me what are the available functions and how to integrate it in my application?
Thanks.
0
Comment
Question by:Nicolas060297
3 Comments
 
LVL 2

Expert Comment

by:lucidity
Comment Utility
Check out the DirectX SDK, it has lots of examples for using Direct Input (which is handy for this kind of thing).
0
 
LVL 23

Accepted Solution

by:
chensu earned 200 total points
Comment Utility
There are several methods.
1. The easiest way is to use MCI commands or MCIWnd Window Class. Here is an example for recording copied from the Platform SDK documentation. There are some samples for MCI playing in Visual C++ samples.

Recording with a Waveform-Audio Device
The following example opens a waveform-audio device with a new file, records for the specified time, plays the recording, and prompts the user to save the recording if desired.

// Uses the MCI_OPEN, MCI_RECORD, and MCI_SAVE commands to record and
// save a waveform-audio file. Returns 0L if successful; otherwise,
// it returns an MCI error code.
DWORD recordWAVEFile(DWORD dwMilliSeconds)
{
    UINT wDeviceID;
    DWORD dwReturn;
    MCI_OPEN_PARMS mciOpenParms;
    MCI_RECORD_PARMS mciRecordParms;
    MCI_SAVE_PARMS mciSaveParms;
    MCI_PLAY_PARMS mciPlayParms;

    // Open a waveform-audio device with a new file for recording.
    mciOpenParms.lpstrDeviceType = "waveaudio";
    mciOpenParms.lpstrElementName = "";
    if (dwReturn = mciSendCommand(0, MCI_OPEN,
        MCI_OPEN_ELEMENT | MCI_OPEN_TYPE,
        (DWORD)(LPVOID) &mciOpenParms))
    {
        // Failed to open device; don't close it, just return error.
        return (dwReturn);
    }

    // The device opened successfully; get the device ID.
    wDeviceID = mciOpenParms.wDeviceID;

    // Begin recording and record for the specified number of
    // milliseconds. Wait for recording to complete before continuing.
    // Assume the default time format for the waveform-audio device
    // (milliseconds).
    mciRecordParms.dwTo = dwMilliSeconds;
    if (dwReturn = mciSendCommand(wDeviceID, MCI_RECORD,
        MCI_TO | MCI_WAIT, (DWORD)(LPVOID) &mciRecordParms))
    {
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
        return (dwReturn);
    }

    // Play the recording and query user to save the file.
    mciPlayParms.dwFrom = 0L;
    if (dwReturn = mciSendCommand(wDeviceID, MCI_PLAY,
        MCI_FROM | MCI_WAIT, (DWORD)(LPVOID) &mciPlayParms))
    {
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
        return (dwReturn);
    }
    if (MessageBox(hMainWnd, "Do you want to save this recording?",
        "", MB_YESNO) == IDNO)
    {
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
        return (0L);
    }

    // Save the recording to a file named TEMPFILE.WAV. Wait for
    // the operation to complete before continuing.
    mciSaveParms.lpfilename = "tempfile.wav";
    if (dwReturn = mciSendCommand(wDeviceID, MCI_SAVE,
        MCI_SAVE_FILE | MCI_WAIT, (DWORD)(LPVOID) &mciSaveParms))
    {
        mciSendCommand(wDeviceID, MCI_CLOSE, 0, NULL);
        return (dwReturn);
    }

    return (0L);
}


2. Use low-level audio functions waveIn* and waveOut* functions.
Sample: "Reverse: Play a Waveform in Reverse" for playing. Here is an example for recording copied from the Platform SDK documentation.

Example of Writing Waveform Data
The following example illustrates the steps required to allocate and set up a WAVEHDR structure and write a block of data to a waveform output device.

// Global variables.

HANDLE hData  = NULL;  // handle of waveform data memory
HPSTR  lpData = NULL;  // pointer to waveform data memory
 
void WriteWaveData(void)
{
    HWAVEOUT    hWaveOut;
    HGLOBAL     hWaveHdr;
    LPWAVEHDR   lpWaveHdr;
    HMMIO       hmmio;
    UINT        wResult;
    HANDLE      hFormat;
    WAVEFORMAT  *pFormat;
    DWORD       dwDataSize;

    // Open a waveform device for output using window callback.

    if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
                    (LPWAVEFORMAT)pFormat,
                    (LONG)hwndApp, 0L, CALLBACK_WINDOW))
    {
        MessageBox(hwndApp,
                   "Failed to open waveform output device.",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
        LocalUnlock(hFormat);
        LocalFree(hFormat);
        mmioClose(hmmio, 0);
        return;
    }
 
    // Allocate and lock memory for the waveform data.
 
    hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, dwDataSize );
    if (!hData)
    {
        MessageBox(hwndApp, "Out of memory.",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
        mmioClose(hmmio, 0);
        return;
    }
    if ((lpData = GlobalLock(hData)) == NULL)
    {
        MessageBox(hwndApp, "Failed to lock memory for data chunk.",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
        GlobalFree(hData);
        mmioClose(hmmio, 0);
        return;
    }
 
    // Read the waveform data subchunk.
 
    if(mmioRead(hmmio, (HPSTR) lpData, dwDataSize) != (LRESULT)dwDataSize)
    {
        MessageBox(hwndApp, "Failed to read data chunk.",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
        GlobalUnlock(hData);
        GlobalFree(hData);
        mmioClose(hmmio, 0);
        return;
    }
 
    // Allocate and lock memory for the header.

    hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
        (DWORD) sizeof(WAVEHDR));
    if (hWaveHdr == NULL)
    {
        GlobalUnlock(hData);
        GlobalFree(hData);
        MessageBox(hwndApp, "Not enough memory for header.",
            NULL, MB_OK | MB_ICONEXCLAMATION);
        return;
    }
 
    lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr);
    if (lpWaveHdr == NULL)
    {
        GlobalUnlock(hData);
        GlobalFree(hData);
        MessageBox(hwndApp,
            "Failed to lock memory for header.",
            NULL, MB_OK | MB_ICONEXCLAMATION);
        return;
    }
 
    // After allocation, set up and prepare header.
 
    lpWaveHdr->lpData = lpData;
    lpWaveHdr->dwBufferLength = dwDataSize;
    lpWaveHdr->dwFlags = 0L;
    lpWaveHdr->dwLoops = 0L;
    waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
 
    // Now the data block can be sent to the output device. The
    // waveOutWrite function returns immediately and waveform
    // data is sent to the output device in the background.
 
    wResult = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR));
    if (wResult != 0)
    {
        waveOutUnprepareHeader(hWaveOut, lpWaveHdr,
                               sizeof(WAVEHDR));
        GlobalUnlock( hData);
        GlobalFree(hData);
        MessageBox(hwndApp, "Failed to write block to device",
                   NULL, MB_OK | MB_ICONEXCLAMATION);
        return;
    }
}

Processing the MM_WOM_DONE Message
The following example shows how to process the MM_WOM_DONE message. This example assumes the application does not play multiple data blocks, so it can close the output device after playing a single data block.

// WndProc--Main window procedure.
LRESULT FAR PASCAL WndProc(HWND hWnd, UINT msg, WPARAM wParam,
    LPARAM lParam)
{
switch (msg)
{
    case MM_WOM_DONE:
 
    // A waveform-audio data block has been played and
    // can now be freed.
    waveOutUnprepareHeader((HWAVEOUT) wParam,
        (LPWAVEHDR) lParam, sizeof(WAVEHDR) );
   
    // Free hData memory.
   
    waveOutClose((HWAVEOUT) wParam);
    break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}


3. Use DirectX 5 or later which come with IDirectSound and IDirectSoundCapture interfaces. There are a lot of samples in the SDK.

By the way, DirectInput provides support for input devices including the mouse, keyboard, and joystick, as well as for force-feedback (input/output) devices, but not sound devices.
0
 

Author Comment

by:Nicolas060297
Comment Utility
Thanks for your answer.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
ADO Memory leak with DELPHI 2007 37 153
Error on moodle after upgrade 3 105
Generic progress indicator 6 109
fizzArray  challenge 1 47
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now