Save wave file using waveInOpen

12,189

.WAV files contain not only raw data, but also include format and extra data, and in general are having RIFF structure.

MSDN explains writing into file e.g. here: Writing to a WAV File.

Additionally, current Windows SDK \Samples\multimedia\directshow\dmo\dmodemo\dsutil.* files have implementation of similar CWaveFile class.

Share:
12,189
Czoo
Author by

Czoo

I like understanding, building and improving systems

Updated on June 04, 2022

Comments

  • Czoo
    Czoo almost 2 years

    I am trying to record sound to a .wave file using waveInOpen and co (see here)

    Here is my code to record to a buffer and it seems to work :

    #include <Windows.h>
    #include <MMSystem.h>
    #include <iostream>
    
    using namespace std;
    
    int main(){
    
        HWAVEIN microHandle;
        WAVEHDR waveHeader;
    
        const int NUMPTS = 22050 * 10;   // 10 seconds
        int sampleRate = 22050;
        short int waveIn[NUMPTS];   // 'short int' is a 16-bit type; I request 16-bit samples below
                                    // for 8-bit capture, you'd use 'unsigned char' or 'BYTE' 8-bit types
    
        MMRESULT result = 0;
    
        WAVEFORMATEX format;
        format.wFormatTag=WAVE_FORMAT_PCM;      // simple, uncompressed format
        format.wBitsPerSample=8;                //  16 for high quality, 8 for telephone-grade
        format.nChannels=1;                     //  1=mono, 2=stereo
        format.nSamplesPerSec=sampleRate;       //  22050
        format.nAvgBytesPerSec=format.nSamplesPerSec*format.nChannels*format.wBitsPerSample/8;
                                                // = nSamplesPerSec * n.Channels * wBitsPerSample/8
        format.nBlockAlign=format.nChannels*format.wBitsPerSample/8;                    
                                                // = n.Channels * wBitsPerSample/8
        format.cbSize=0;
    
        result = waveInOpen(&microHandle, WAVE_MAPPER, &format, 0L, 0L, WAVE_FORMAT_DIRECT);
    
        if (result)
        {
            cout << "Fail step 1" << endl;
            cout << result << endl;
            Sleep(10000);
            return 0; 
        }
    
        // Set up and prepare header for input
        waveHeader.lpData = (LPSTR)waveIn;
        waveHeader.dwBufferLength = NUMPTS*2;
        waveHeader.dwBytesRecorded=0;
        waveHeader.dwUser = 0L;
        waveHeader.dwFlags = 0L;
        waveHeader.dwLoops = 0L;
        waveInPrepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR));
    
        // Insert a wave input buffer
        result = waveInAddBuffer(microHandle, &waveHeader, sizeof(WAVEHDR));
    
        if (result)
        {
            cout << "Fail step 2" << endl;
            cout << result << endl;
            Sleep(10000);
            return 0;
        }
    
        result = waveInStart(microHandle);
    
        if (result)
        {
            cout << "Fail step 3" << endl;
            cout << result << endl;
            Sleep(10000);
            return 0;
        }
    
         // Wait until finished recording
         do {} while (waveInUnprepareHeader(microHandle, &waveHeader, sizeof(WAVEHDR))==WAVERR_STILLPLAYING);
    
         waveInClose(microHandle);
    
        return 0;
    }
    

    But i didn't find any function or explanation on how to save it on disk

    Should i save the WAVEFORMATEX structure ? or are there other things to add to the wave file header ?

    The only thing is i have to use windows libraries only, i can't have to install any other

    Thank you :)