📄 general.cpp
字号:
#include "stdafx.h"
#include "General.h"
#include <mmsystem.h>
VOID RecordWave(HWND hWnd);
VOID CreateRiff(LPSTR);
LONG CALLBACK WaveIOProc(LPMMIOINFO lpmmioInfo, UINT uMsg,
LPARAM lParam1, LPARAM lParam2);
VOID CALLBACK waveInProc( HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
extern char msg[MSG_LEN+1];
extern HWAVEIN hwi;
extern WAVEHDR wavehdr;
extern WAVEFORMATEX wfx;
extern MMRESULT rc;
BOOL ShellGetPath(HANDLE hDlg, char lpszPath[]);
VOID CALLBACK waveInProc( HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
{
// post message to process this input block received
// NOTE: callback cannot call other waveform functions
//....................................................
if (uMsg == WIM_DATA)
PostMessage((HWND)dwInstance, USR_INBLOCK, 0, dwParam1);
}
VOID RecordWave(HWND hWnd)
{
WAVEINCAPS wic;
hwi = NULL;
rc = waveInGetDevCaps(0, &wic, sizeof(wic));
if (rc == MMSYSERR_NOERROR)
{
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0;
// open waveform input device
//...........................
rc = waveInOpen(&hwi, 0, &wfx, (DWORD)(VOID*)waveInProc, (DWORD)hWnd,
CALLBACK_FUNCTION);
if (rc != MMSYSERR_NOERROR)
{
waveInGetErrorText(rc, msg, MSG_LEN),
MessageBox(hWnd, msg, NULL, MB_OK);
return;
}
}
// prepare buffer block
//.....................
rc = waveInPrepareHeader(hwi, &wavehdr, sizeof(WAVEHDR));
// add buffer to the input queue
if (rc == MMSYSERR_NOERROR)
rc = waveInAddBuffer(hwi, &wavehdr, sizeof(WAVEHDR));
if (rc != MMSYSERR_NOERROR)
{
waveInGetErrorText(rc, msg, MSG_LEN);
waveInClose(hwi);
MessageBox(hWnd, msg, NULL, MB_OK);
return;
}
// start recording
//................
rc = waveInStart(hwi);
}
VOID CreateRiff(LPSTR NameStr)
{
HMMIO hmmio; // file handle for open file
MMCKINFO ciRiffChunk; // main RIFF chunk information
MMCKINFO ciSubChunk; // subchunk information
LONG nVersion; // custom I/O proc version
MMIOINFO mmioInfo;
// rename a prev. 'new.wav' file (if one exists)
// to 'new.bak'
//..............................................
// mmioRename("new.wav", "new.bak", NULL, 0);
// open the wave file using an internal I/O buffer
//................................................
mmioInfo.dwFlags = 0;
mmioInfo.fccIOProc = mmioStringToFOURCC("WAV ", 0);
mmioInfo.pIOProc = (LPMMIOPROC)WaveIOProc;
mmioInfo.wErrorRet = 0;
mmioInfo.htask = 0;
mmioInfo.cchBuffer = 0;
mmioInfo.pchBuffer = 0;
mmioInfo.pchNext = 0;
mmioInfo.pchEndRead = 0;
mmioInfo.pchEndWrite = 0;
mmioInfo.lBufOffset = 0;
mmioInfo.lDiskOffset = 0;
mmioInfo.adwInfo[0] = 0;
mmioInfo.adwInfo[1] = 0;
mmioInfo.adwInfo[2] = 0;
mmioInfo.adwInfo[3] = 0;
mmioInfo.dwReserved1 = 0;
mmioInfo.dwReserved2 = 0;
mmioInfo.hmmio = 0;
hmmio = mmioOpen(NameStr, &mmioInfo,
MMIO_CREATE | MMIO_WRITE | MMIO_ALLOCBUF);
if(!hmmio)
{
MessageBox(NULL, "Failed to open file.", NULL, MB_OK);
return;
}
// attempt to increase the size of the buffer to 128K
//...................................................
mmioSetBuffer(hmmio, NULL, 131072, 0);
// get customer I/O proc version number and display it
//....................................................
nVersion = mmioSendMessage(hmmio, USR_MMIOM_PROC_VERSION, 0, 0);
sprintf(msg, "Custom I/O procedure version: %ld.%ld installed",
HIWORD(nVersion), LOWORD(nVersion));
// SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)msg);
// create main 'RIFF' chunk
//.........................
mmioSeek(hmmio, 0, SEEK_SET); // reset to beginning of file.
ciRiffChunk.fccType = mmioFOURCC('W', 'A', 'V', 'E');
ciRiffChunk.cksize = 0L; // mmio will determine corect size
rc = mmioCreateChunk(hmmio, &ciRiffChunk, MMIO_CREATERIFF);
// create 'fmt' chunk
//...................
ciSubChunk.ckid = mmioStringToFOURCC("fmt ", 0);
ciSubChunk.cksize = sizeof(WAVEFORMATEX);
rc = mmioCreateChunk(hmmio, &ciSubChunk, 0);
rc = mmioWrite(hmmio, (HPSTR)&wfx, sizeof(WAVEFORMATEX));
// ascend out of 'fmt' chunk back to the main 'RIFF' chunk
//........................................................
rc = mmioAscend(hmmio, &ciSubChunk, 0);
// create 'data' chunk
// if the cksize is incorrect, when we ascend out of the chunk,
// the cksize will be updated to it's actual size
//.............................................................
ciSubChunk.ckid = mmioStringToFOURCC("data", 0);
ciSubChunk.cksize = DATABLOCK_SIZE;
rc = mmioCreateChunk(hmmio, &ciSubChunk, 0);
// okay, now lets write the data to the buffer the hard
// way (manually) without the mmioWrite() function.
// The following loop only moves one byte at a time to
// simplify the example.
// If we were going to write the data using the write
// statement, it would look like the following:
// mmioWrite(hmmio, (HPSTR)wavehdr.lpData,
// (LONG)wavehdr.dwBytesRecorded);
//.....................................................
/*{
LONG i;
mmioGetInfo(hmmio, &mmioInfo, 0);
for (i = 0; i < (LONG)wavehdr.dwBytesRecorded; i++)
{
if (mmioInfo.pchNext == mmioInfo.pchEndWrite)
{
mmioInfo.dwFlags |= MMIO_DIRTY; // we have modified the buffer
mmioAdvance(hmmio, &mmioInfo, MMIO_WRITE);
}
*(mmioInfo.pchNext)++ = (BYTE) *(wavehdr.lpData+i);
}
//mmioWrite(hmmio, (HPSTR)wavehdr.lpData,(LONG)wavehdr.dwBytesRecorded);
mmioInfo.dwFlags |= MMIO_DIRTY; // we have modified the buffer
mmioSetInfo(hmmio, &mmioInfo, 0);
}*/
mmioWrite(hmmio, (HPSTR)wavehdr.lpData,(LONG)wavehdr.dwBytesRecorded);
// ascend out of 'data' chunk back to the main 'RIFF' chunk
// this corrects the chunk length if not correctly
// specified when the chunk was created.
//.........................................................
rc = mmioAscend(hmmio, &ciSubChunk, 0);
// ascend out of the main 'RIFF' chunk
//....................................
rc = mmioAscend(hmmio, &ciRiffChunk, 0);
// flush buffer and close file
//............................
rc = mmioFlush(hmmio, 0);
rc = mmioClose(hmmio, 0);
AfxMessageBox("Recording Over!");
// SendMessage(hListBox, LB_ADDSTRING, 0,
// (LPARAM)"RIFF WAVE file 'new.wav' created.");
}
LONG CALLBACK WaveIOProc(LPMMIOINFO lpmmioInfo, UINT uMsg,
LPARAM lParam1, LPARAM lParam2)
{
static int file = 0;
int nFlag;
int nStatus;
LONG lStatus;
switch(uMsg)
{
// Open
//.....
case MMIOM_OPEN:
if (lpmmioInfo->dwFlags & MMIO_READ)
nFlag = OF_READ;
else if (lpmmioInfo->dwFlags & MMIO_WRITE)
nFlag = OF_WRITE;
else if (lpmmioInfo->dwFlags & MMIO_CREATE)
{
file = _lcreat((LPSTR)lParam1, 0);
if (file == -1)
return(MMIOERR_CANNOTOPEN);
else
{
lpmmioInfo->lDiskOffset = 0;
return(0);
}
}
else // default
{
nFlag = OF_READWRITE;
}
file = _lopen((LPSTR)lParam1, nFlag);
if (file == -1)
{
if (lpmmioInfo->dwFlags & MMIO_WRITE)
{
file = _lcreat((LPSTR)lParam1, 0);
}
}
if (file == -1)
return(MMIOERR_CANNOTOPEN);
else
{
lpmmioInfo->lDiskOffset = 0;
return(0);
}
break;
// Close
//......
case MMIOM_CLOSE:
return( _lclose(file) );
// Read
//.....
case MMIOM_READ:
nStatus = _lread(file, (LPSTR)lParam1, (int)lParam2);
lpmmioInfo->lDiskOffset += (int)lParam2;
return( (LONG)nStatus );
// Write
//......
case MMIOM_WRITE:
case MMIOM_WRITEFLUSH:
nStatus = _lwrite(file, (LPSTR)lParam1, (int)lParam2);
lpmmioInfo->lDiskOffset += (int)lParam2;
return( (LONG)nStatus );
// Seek
//.....
case MMIOM_SEEK:
lStatus = _llseek(file, (LONG)lParam1, (int)lParam2);
lpmmioInfo->lDiskOffset = lStatus;
return(lStatus);
// Version (custom message)
//.........................
case USR_MMIOM_PROC_VERSION:
return( MAKELONG(0, 1)); // version 1.00
}
return(0);
}
BOOL ShellGetPath(HANDLE hDlg, char lpszPath[])
{
BOOL bRet;
char szPath[MAX_PATH];
LPITEMIDLIST lpil;
HGLOBAL hgMem;
BROWSEINFO bi;
bi.hwndOwner=(HWND) hDlg;
bi.pidlRoot = NULL;
bi.pszDisplayName = szPath;
bi.lpszTitle = "Select Folder";
bi.ulFlags = BIF_RETURNONLYFSDIRS;
bi.lpfn = NULL;
bi.lParam = 0L;
bi.iImage = 0;
lpil = SHBrowseForFolder(&bi);
if(lpil == NULL)
return FALSE;
bRet = SHGetPathFromIDList(lpil, lpszPath);
hgMem = GlobalHandle(lpil);
GlobalFree(hgMem);
return bRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -