API layer realizes voice recording

zhaozj2021-02-16  46

I have been in need. I have been looking for the source code for the recording part. The harvest is not big. Now I will open my own source code, I hope to use it for some people.

In fact, to realize the recording of sound, you can use a variety of ways (such as MCI), which I will introduce this is the level of the API, you can do more control over. For example, the audio data is required to go to the memory you specified.

Let's talk about the API to use, the recording is usually used for a type of API. The most important thing is WaveInstart (as the name refer to start recording), then WaveInstop (it can return when you specified); if You don't have to use WaveInReSet (different from STOP is that the function is not equal to it. You can return to the recording immediately. However, it is best to use WaveIngetPosition.

After saying these functions, it has to be mentioned for the function of preparing the above functions (note pairing), WaveinOpen and WaveInClose pair (the format of the audio in Waveinopen, which says for stereo and 16-bit sound quality, etc.); WaveInprepareheader and WaveinunprepareHeader pair (WaveInPrepareHeader specified for recording buffer size and first address), followed by WaveInPrepreheader to routinely call WaveinAddBuffer (the role is not detailed, not much to say).

The detailed call process can be seen below

(Previously call WaveIngetnumdevs to see if there is a device available)

WaveinOpen (here the Waveformatex Structure Specify Audio Format)

WaveInPrepareHeader (which is the LPDATA member of the WaveHDR structure specifies the buffer header address)

Waveinaddbuffer

WaveInstart

(Record ....)

WaveInstop (warning: must be buffered to return)

WaveinunprepareHeader

WaveInClose

It should be pointed out that the above code You can't stop the recording process (if you specify the buffer is very big, if you say enough recording an hour, then you will wait for an hour), if you want to stop immediately, please use it immediately The following method.

WaveInstart

(Record ....)

(After n time, the user files a stop request)

WaveIngetPosition (Keep this value, used to set the dwbytesrecorded member of the WaveHDR structure)

WaveinReset

(Reset a dwbytesrecorded member of the WaveHDR structure)

The whole process is such a few words, and the export program will be given to verify.

To explain, after the recording is recorded in normal conditions, the total amount of memory (in writing) will be saved in the dwbytesrecorded member of the WaveHDR structure, and the available audio data can of course put it in the memory buffer you specified, you are big. Waveinunpreparehead can not be used immediately.

(Supplementary one content, rough explanation. The file header format of the WAV file)

Look at the following structure, the eight bytes of the start is a structure, the first four-byte is the flag, just equal to ASCII "Riff", the second four-byte is the total file length minus 8. You can verify it. (Refer to 16) Methods for reading digital

Following the second data structure, accounting for 12 bytes. If you are a standard WAVE format file, then the two flags, the first four-byte logo is ASCII's "Wave", the second four-byte logo is ASCII "FMT" (note, There is a space), then the remaining four bytes are hidden in the size of the Waveformatex structure (refer to MSDN), should be 18 bytes. Then, of course, the value of 18 bytes of WaveFormatex structure. If you don't say it in detail, check it yourself with MSDN. (Need to note is that the last member of this Waveformatexex, talking about possible length expansion)

Behind these 18 bytes (in the old way), it should be followed by an 8-byte structure, then the beginning of "naked data", the start of this eight-byte structure is a flag, Should be equal to ASCII "DATA", then tightly followed by the size of naked data, that is, the most important part.

Ok, so, you can get the starting position of the audio data (tightly follow the data structure of the "Data" logo), and the length of the audio data. It should be that all issues are easy to solve.

However, pay attention to it is a lot of current. The WAV file will add a data structure (12 bytes), inserted behind the WaveFormatex and the data structure containing "DATA". The first four-byte of this plus structure is a flag, equal to "FACT" of the ASCII code, and then the second four-byte value is equal to 4 in most cases, and the value of the third four-byte is also equal to the audio. Naked data length. Basically, this is the case.

The source program files given below are added to the newly built VC Win32 project, and the execution effect is automatically generated after the recording is three seconds to automatically generate the MyTest.wav file for playback test (remember the default recording channel).

Not much nonsense, give the export process (in the source program to include runtimelog.cpp, see http://www.9cbs.net/develop/read_article.asp?id=17477) I hope to be useful to everyone. (Full text)

(Full text - March 27, 2003 _AM: 11:27)

// ******************* FileName: WinMain.cpp ************************ *****

/ / The source program needs to be added to the WIN32 Application of Win32 Application in VC6.

/ / Please include my custom debug class, see #include "runtimelog.cpp"

/ / For the Link option of the project, at least the following library: msvcrt.lib kernel32.lib user32.lib WinMM.LIB

#define Win32_Lean_and_mean // Say No To Mfc !!

#include

#include

#include "runtimelog.cpp"

Runtimelog log;

Char lpTemp [256] = ""

DWORD FCC (LPSTR LPSTR)

{

DWORD NUMBER = LPSTR [0] LPSTR [1] * 0x100 LPSTR [2] * 0x10000 LPSTR [3] * 0x1000000;

Return Number;

}

Int WinApi Winmain (Hinstance Hinstance, Hinstance Hprevinstance,

LPSTR LPCMDLINE, INT NCMDSHOW)

{

Createmutex (NULL, FALSE, "MyMutex");

IF (getLastError () == error_already_exists)

{Log.Write ("exissrs and exit"); log.last (); exitprocess (null);}

Log.write ("Program Start.");

Log.nobuff = true;

DWORD DATASIZE = 48000;

// Most commonly used

Waveformatex waveformat;

Waveformat.wformattag = Wave_FORMAT_PCM;

Waveformat.nchannels = 1;

Waveformat.nsamplespespec = 8000;

Waveformat.navgbytespesec = 8000;

Waveformat.nblockAlign = 1;

Waveformat.wbitsPersample = 8; // Specify record format

WAVEFORMAT.CBSIZE = 0;

WSPrintf (LPTEMP, "Waveformatex size =% lu", sizeof (Waveformatex));

Log.write (lptemp);

Hwavein m_hwavein;

WaveIngetnumdevs ()) log.write ("Wavein channel available"); Else Log.Write ("Wavein Channel");

Int res = Waveininopen (& M_HWavein, Wave_Mapper, & Waveformat, (DWORD) NULL, 0L, Callback_window; // Open Recorder

If (res == mmsyserr_noerror) log.write ("Open Wavein Success"); // Verify that the creation is successful

Else {

WSPRINTF (LPTEMP, "Open Wavein Channel Failed, Error_code = 0x% X", RES);

Log.write (lptemp);

} // End of verification creation is successful

WaveHDR M_PWaveHDR;

m_pwavehdr.lpdata = (char *) Globalock (GMEM_MOVEABLE | GMEM_SHARE, DATASIZE));

MEMSET (m_pwavehdr.lpdata, 0, datasize);

m_pwavehdr.dwbufferLength = DataSize;

m_pwavehdr.dwbytessrecorded = 0;

m_pwavehdr.dwuser = 0;

m_pwavehdr.dwflags = 0;

m_pwavehdr.dwloops = 0;

WSPrintf (LPTEMP, "WaveHDR Size =% Lu", SIZEOF (WAVEHDR));

Log.write (lptemp);

Int Resprepare = WaveinPreprePrePrehead (M_HWavein, & M_PWaveHDR, SIZEOF (WaveHDR)); // Prepare memory block recording

IF (Resprepare == mmsyserr_noerror) log.write ("Preparing for recording head files"); else {

WSPrintf (lptemp, "cannot open a recorder file, error_code = 0x% 03x", resprepare);

Log.write (lptemp);

} // end of verification open buffer

Resprepare = WaveinAddbuffer (M_HWavein, & M_PWaveHDR, SIZEOF (WaveHDR));

IF (Resprepare == mmsyserr_noerror) log.write ("Preparing for Recording Memory Success");

Else {

WSPRINTF (LPTEMP, "can not open recording buffer, error_code = 0x% 03x", resprepare);

Log.write (lptemp);

} // end of verification open buffer

Log.write (""); // Write an empty string can be branch

IF (! WaveInstart (m_hwavein)) log.write ("Start Recording"); Else Log.write ("Start Recording Failed");

SLEEP (3200);

MMTIME MMT;

mmt.wtype = time_bytes;

Log.Numberwrite ("SizeOf (mmtime =", SIZEOF (MMTIME));

Log.NumberWrite ("SIZEOF (UINT) =", SIZEOF (UINT));

IF (WaveIngetPosition (M_HWavein, & MMT, SIZEOF (MMTIME))) LOG.WRITE ("Cannot Be Audio Length");

Else Log.NumberWrite ("Today Audio Location =", mmt.u.cb);

IF (mmt.wtype == time_bytes) {log.write ("Audio Length" in Time_Bytes Format);

Else log.write ("Specifies Time_Bytes Format Audio Length");

// if (! WaveInstop (m_hwavein)) log.write ("Stop Recording"); Else Log.Write ("Stop Recording Failure");

IF (! WaveinReset) log.write ("Reset Memory Success"); Else Log.write ("Reset Memory Failure");

m_pwavehdr.dwbytessrecorded = mmt.u.cb;

DWORD NUMTOWRITE = 0; DWORD DWNUMBER = 0;

Handle FileHandle =

Createfile ("MyTest.wav", Generic_Write, File_Share_read, Null,

CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

// Memset (m_pwavehdr.lpdata, 0, datasize);

Dwnumber = FCC ("riff");

Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Dwnumber = m_pwavehdr.dwbytesrecorded 18 20; Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Dwnumber = FCC ("Wave");

Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Dwnumber = FCC ("FMT");

Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Dwnumber = 18L;

Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Writefile (FileHandle, & Waveformat, Sizeof (Waveformatex), & NumTowrite, NULL;

Dwnumber = FCC ("DATA");

Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Dwnumber = m_pwavehdr.dwbytessreded;

Writefile (FileHandle, & Dwnumber, 4, & NumTowrite, NULL);

Writefile (FileHandle, M_PWaveHDr.lpdata, m_pwavehdr.dwbytesrecorded, & numTowrite, null);

Setndoffile (FileHandle);

CloseHandle (FileHandle); FileHandle = INVALID_HANDLE_VALUE; // Take the handle

Log.Write ("should have a MyTest.wav file");

IF (WaveinunPreparehead) log.write ("Un_Prepare Header Failed"); Else Log.write ("Un_Prepare Header Success");

IF (GlobalHandle (M_PWaveHDr.lpdata)) Log.Write ("Global Free Failed"); Else Log.Write ("Global Free");

IF (res == mmsyserr_noerror) // Turn the recording device

IF (WaveInClose (m_hwavein) == mmsyserr_noerror) log.write ("Normal Close Recording Equipment");

Else Log.write ("Nomas Turn Recording Equipment");

Log.last (True);

// EXIXTPROCESS (0);

Return 0;

}

// ************************************************* ***

转载请注明原文地址:https://www.9cbs.com/read-24600.html

New Post(0)