我是语音编码的新手,现在我成功地在文件中录制了麦克风,并使用SaveRecordtoFile
功能将每10秒保存在一个文件中(这样做毫无问题)
现在,我想从记录的数据中删除2秒,这样我的输出将是8秒而不是10秒,在randomTime
数组0
中,我想成为的秒数删除...
在for循环中,我将waveHeader->lpData
的数据复制到新缓冲区if (randomTime[i] == '1')
10秒:
将第二个数字3和7的数据删除为randomTime[10] = "110111011"
这似乎是一个正确的算法,应该可以工作,但问题是输出,一些输出很好(大约70%或更多),但其中一些损坏了
输出应如下所示:
但某些输出(约30%或更少)已损坏,如下所示:
我认为我的代码有误,但是我调试了几天代码却不明白是什么问题?
这是我的代码:
#include <Windows.h>
#include <atlstr.h>
#pragma comment(lib,"Winmm.lib")
int SetWaveFormat(WAVEFORMATEX* wf,int wFormatTag,int nChannels,int nSamplesPerSec, int nBlockAlign, int wBitsPerSample, int cbSize)
{
int res;
wf->wFormatTag = wFormatTag;
wf->nChannels = nChannels;
wf->nSamplesPerSec = nSamplesPerSec;
wf->nBlockAlign = nBlockAlign;
wf->wBitsPerSample = wBitsPerSample;
wf->cbSize = cbSize;
wf->nAvgBytesPerSec = nChannels * nSamplesPerSec * wBitsPerSample / 8;
return 0;
}
int OpenWaveIn(HWAVEIN* hWaveIn, WAVEFORMATEX* wf)
{
int res;
char lpTemp[256];
res = waveInGetNumDevs();
if (! res )
{
//_debug_print("Access WaveIn channel FAILED!",1);
return -1;
}
else
{
//_debug_print("Access WaveIn channel SUCCEED!");
}
// Open wave input channel
res = waveInOpen(hWaveIn,WAVE_MAPPER, wf, (DWORD)NULL,0L,CALLBACK_WINDOW);
if ( res != MMSYSERR_NOERROR )
{
sprintf(lpTemp, "Open wave input channel FAILED, rror_Code = 0x%x", res );
return -1;
}
else
{
//_debug_print("Open wave input channel SUCCEED!");
}
return 0;
}
// Prepare Wave In Header and allocate memory
int PrepareWaveIn(HWAVEIN* hWaveIn, WAVEHDR* waveHeader, DWORD dataSize)
{
int res;
char lpTemp[256];
waveHeader->dwBufferLength = dataSize;
waveHeader->dwBytesRecorded = 0;
waveHeader->dwUser = 0;
waveHeader->dwFlags = 0;
waveHeader->dwLoops = 0;
waveHeader->lpData = (char *)GlobalLock( GlobalAlloc(GMEM_MOVEABLE|GMEM_SHARE, dataSize));
memset(waveHeader->lpData, 0, dataSize );
// Prepare Header
res = waveInPrepareHeader(*hWaveIn, waveHeader, sizeof(WAVEHDR) );
if ( res != MMSYSERR_NOERROR)
{
sprintf(lpTemp, "Cannot prepare wave in header, ror_Code = 0x%03X", res );
//_debug_print(lpTemp,1);
return -1;
}
else
{
//_debug_print("Prepare wave in header SUCCEED!");
}
res = waveInAddBuffer( *hWaveIn, waveHeader, sizeof(WAVEHDR) );
if ( res != MMSYSERR_NOERROR)
{
sprintf(lpTemp, "Cannot add buffer for wave in, ror_Code = 0x%03X", res );
//_debug_print(lpTemp,1);
return -1;
}
else
{
//_debug_print("Add buffer for wave in SUCCEED!");
}
return 0;
}
// Start recording speech
int StartRecord(HWAVEIN* hWaveIn)
{
int res;
res = waveInStart(*hWaveIn);
if(res != MMSYSERR_NOERROR)
{
//_debug_print("Start recording FAILED!",1);
return -1;
}
else
{
//_debug_print("Start recording...",1);
}
return 0;
}
// Stop recording speech
int StopRecord(HWAVEIN* hWaveIn, MMTIME* mmTime)
{
int res;
res = waveInGetPosition(*hWaveIn, mmTime, sizeof(MMTIME));
if(res != MMSYSERR_NOERROR)
{
//_debug_print("Get Position of wave in FAILED!",1);
return -1;
}
else
{
//_debug_print("Get Position of wave in SUCCEED!");
}
res = waveInStop(*hWaveIn);
if(res != MMSYSERR_NOERROR)
{
//_debug_print("Stop recording FAILED!",1);
return -1;
}
else
{
//_debug_print("Stop recording SUCCEED!");
}
res = waveInReset(*hWaveIn);
if(res != MMSYSERR_NOERROR)
{
//_debug_print("Reset wave in memory FAILED!",1);
return -1;
}
else
{
//_debug_print("Reset wave in memory SUCCEED!");
}
return 0;
}
// str2num
DWORD FCC(LPSTR lpStr)
{
DWORD Number = lpStr[0] + lpStr[1] *0x100 + lpStr[2] *0x10000 + lpStr[3] *0x1000000 ;
return Number;
}
// Save recorded speech to file
int SaveRecordtoFile(const char* fileName, WAVEFORMATEX* wf, HWAVEIN* hWaveIn, WAVEHDR* waveHeader, MMTIME* mmTime)
{
int res;
DWORD NumToWrite=0;
DWORD dwNumber = 0;
DWORD dwSamplePerSec = 0;
LPBYTE NewBuff;
DWORD dwNewBuffLen = 0;
//-----------------------------------------------------------------------------------
// delete for example 2 seconds from the recorded data
dwSamplePerSec = waveHeader->dwBytesRecorded / 10; // 10 Secs
dwNewBuffLen = dwSamplePerSec * 8;
NewBuff = (LPBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewBuffLen);
memset(NewBuff, NULL, dwNewBuffLen);
CHAR randomTime[10] = "110111011";
int m = 0;
for (int i=0; i<10; i++)
{
if (randomTime[i] == '1')
{
memcpy_s(NewBuff + (m*dwSamplePerSec), dwNewBuffLen, waveHeader->lpData + (i*dwSamplePerSec), dwSamplePerSec);
m++;
}
}
//-----------------------------------------------------------------------------------
/*waveHeader->dwBytesRecorded = mmTime->u.cb;*/
HANDLE FileHandle = CreateFile(CString(fileName), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
dwNumber = FCC("RIFF");
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = /*waveHeader->dwBytesRecorded*/dwNewBuffLen + 12 + sizeof(WAVEFORMATEX) + 18 + 8;
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 = sizeof(WAVEFORMATEX);
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
WriteFile(FileHandle, wf, sizeof(WAVEFORMATEX), &NumToWrite, NULL);
dwNumber = FCC("data");
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
dwNumber = /*waveHeader->dwBytesRecorded*/dwNewBuffLen;
WriteFile(FileHandle, &dwNumber, 4, &NumToWrite, NULL);
WriteFile(FileHandle, NewBuff, dwNewBuffLen, &NumToWrite, NULL);
HeapFree(GetProcessHeap(), 0, NewBuff);
NewBuff = NULL;
SetEndOfFile( FileHandle );
CloseHandle( FileHandle );
FileHandle = INVALID_HANDLE_VALUE;
return 0;
}
// Release wave in memory
int ReleaseWaveIn(HWAVEIN* hWaveIn, WAVEHDR* waveHeader)
{
int res;
res = waveInUnprepareHeader(*hWaveIn, waveHeader, sizeof(WAVEHDR));
if ( res != MMSYSERR_NOERROR )
{
//_debug_print("UnPrepare Wave In Header FAILED!",1);
return -1;
}
else
{
//_debug_print("UnPrepare Wave In Header SUCCEED!");
}
res = (int)GlobalFree(GlobalHandle( waveHeader->lpData ));
if ( res != MMSYSERR_NOERROR )
{
//_debug_print("Global Free FAILED!",1);
return -1;
}
else
{
//_debug_print("Global Free SUCCEED!");
}
return 0;
}
// Close Wave in channel
int CloseWaveIn(HWAVEIN* hWaveIn)
{
int res;
res = waveInClose(*hWaveIn);
if(res != MMSYSERR_NOERROR)
{
//_debug_print("Close wave in FAILED!",1);
}
else
{
//_debug_print("Close wave in SUCCEED!");
}
return 0;
}
int main()
{
int numOfFiles = 0;
// Set wave format when sampling the audio
WAVEFORMATEX wf;
SetWaveFormat(&wf,1,2,48000,4,16,18);
// Open wave input channel
HWAVEIN hWaveIn;
OpenWaveIn(&hWaveIn,&wf);
while (TRUE)
{
// Prepare Wave In Header and allocate memory
WAVEHDR waveHdr;
DWORD dataSize = 192000000;
PrepareWaveIn(&hWaveIn, &waveHdr, dataSize);
// Start recording
StartRecord(&hWaveIn);
Sleep(10000);
// Stop recording
MMTIME mmt;
StopRecord(&hWaveIn, &mmt);
CHAR FileName[MAX_PATH] = {};
wsprintfA(FileName, "Record-%d.wav", numOfFiles);
SaveRecordtoFile(FileName, &wf, &hWaveIn, &waveHdr, &mmt);
numOfFiles++;
ReleaseWaveIn(&hWaveIn, &waveHdr);
}
CloseWaveIn(&hWaveIn);
return 0;
}
在某些地方,我应该复制示例而不是字节,但由于我对此并不专业,所以我不知道如何处理示例,我以某种方式更改了代码,但效果不佳>
1:
//-----------------------------------------------------------------------------------
// delete for example 2 seconds from the recorded data
dwSamplePerSec = waveHeader->dwBytesRecorded / 10; // 10 Secs
dwNewBuffLen = dwSamplePerSec * 8;
NewBuff = (LPBYTE) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwNewBuffLen);
memset(NewBuff, NULL, dwNewBuffLen);
CHAR randomTime[10] = "110111011";
int m = 0;
BYTE* pData = (BYTE*)(waveHeader->lpData);
for (int i=0; i<10; i++)
{
if (randomTime[i] == '1')
{
for (DWORD index = 0; index < dwSamplePerSec; index++)
{
short left = *(short*)pData; pData+=2;
short right = *(short*)pData; pData+=2;
//memcpy_s(NewBuff + (m*dwSamplePerSec), dwNewBuffLen, (SHORT *)waveHeader->lpData + (i*dwSamplePerSec), dwSamplePerSec);
}
m++;
}
}
//-----------------------------------------------------------------------------------
2:
int x = 0;
BYTE* pData = (BYTE*)(waveHeader->lpData);
for (int i=0; i<10; i++)
{
if (randomTime[i] == '1')
{
for (DWORD index = 0; index < dwSamplePerSec; index++)
{
//short int* pSamples = (short int *) (pData);
short right = *(short*)pData; //pData+=2;
//memcpy_s(NewBuff + (m*dwSamplePerSec), dwNewBuffLen, (SHORT *)waveHeader->lpData + (i*dwSamplePerSec), dwSamplePerSec);
float pDataSample = (*pData - 32768) / 32768.0f;
if (fabs(pDataSample) > 0.25f)
NewBuff[x] = /*pSamples;// **/ right;
//pData++;
else
NewBuff[x] = *pData;
//NewBuff[x] = pDataSample;// + right;
x++;
pData++;
}
m++;
}
else
{
pData = pData + (/*4 * */dwSamplePerSec);
}
}
并且我的70%或更多的输出都很好,我认为这不是因为字节或样本
答案 0 :(得分:1)
您的代码可能会分解一个样本,之后流不同步,您会听到很大的声音。
如何发生?您的样本大小为4个字节。因此,切勿复制任何不是4的倍数的内容。10秒的音频将占用10x48000×4 = 1920000字节。但是Sleep(10000)
将始终接近10秒,但不完全是10秒。这样就可以得到1920012字节。然后,您可以这样做:
dwSamplePerSec = waveHeader->dwBytesRecorded / 10; // 10 Secs
返回192001(不是4的倍数),并且蒸汽不同步。如果幸运的话,您会在10秒内收到1920040字节,并且在除以10后仍然是4的倍数,就可以了。