Я новичок в голосовом кодировании, теперь мне удается записывать микрофон в файлы и сохранять каждые 10 секунд в файле с функцией SaveRecordtoFile
(без проблем)
Теперь я хочунапример, удалить из записанных данных 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% или более выходов хороши, я думаю, что это не из-за байтов или выборок