Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Запись звука, Странный способ записи? 
:(
    Опции темы
gidm
Дата 20.3.2003, 00:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 20.3.2003

Репутация: нет
Всего: нет



Народ вод код, который позволяет записать данные с микрофона в файл. Мной замечен интересный баг, не могу понять чей мой или ... Опис ан7ие бага ниже прямо в коде.

HWAVEIN hWaveIn = NULL;
HMMIO hmmio;
MMCKINFO ckRIFF, ckFMT;
WAVEHDR waveHdr1;
WAVEHDR waveHdr2;
LPWAVEHDR address;
LPBYTE waveData1;
LPBYTE waveData2;
DWORD dwDataSize;
PCMWAVEFORMAT FAR *lpFmt;
DWORD WaveDataLength = 8000;
BOOL stop;
DWORD n;


BOOL wioRecord(HWND hwnd) {
waveData1 = (LPBYTE)GlobalAlloc(GPTR/*GMEM_FIXED | GMEM_NOCOMPACT | GMEM_NODISCARD*/, WaveDataLength);
waveData2 = (LPBYTE)GlobalAlloc(GPTR/*GMEM_FIXED | GMEM_NOCOMPACT | GMEM_NODISCARD*/, WaveDataLength);

lpFmt = (PCMWAVEFORMAT FAR *)GlobalAllocPtr(GPTR, sizeof(WAVEFORMAT));
if (lpFmt== NULL)
return (FALSE);
lpFmt->wBitsPerSample = 8;
lpFmt->wf.wFormatTag = WAVE_FORMAT_PCM;
lpFmt->wf.nChannels = 1;
lpFmt->wf.nSamplesPerSec = 22050;
lpFmt->wf.nAvgBytesPerSec = (lpFmt->wf.nChannels *
lpFmt->wf.nSamplesPerSec * lpFmt->wBitsPerSample) / 8;
lpFmt->wf.nBlockAlign = (lpFmt->wf.nChannels *
lpFmt->wBitsPerSample) / 8;

ZeroMemory(&waveHdr1, sizeof(WAVEHDR));

if (!waveHdr1.lpData) {
waveHdr1.lpData = (LPSTR)waveData1;
waveHdr1.dwBufferLength = WaveDataLength*sizeof(BYTE);
}
waveHdr1.dwFlags = 0;
waveHdr1.dwUser = 0;

ZeroMemory(&waveHdr2, sizeof(WAVEHDR));

if (!waveHdr2.lpData) {
waveHdr2.lpData = (LPSTR)waveData2;
waveHdr2.dwBufferLength = WaveDataLength*sizeof(BYTE);
}
waveHdr2.dwFlags = 0;
waveHdr2.dwUser = 0;

hmmio = mmioOpen("record.wav", NULL, MMIO_CREATE | MMIO_READWRITE);
if (hmmio == NULL)
return (FALSE);
mmioWrite(hmmio, (HPSTR)&waveHdr1, sizeof(WAVEHDR));

address = &waveHdr1;

if (waveInOpen(&hWaveIn, WAVE_MAPPER, (WAVEFORMATEX FAR *)lpFmt, (DWORD)hwnd, NULL, CALLBACK_WINDOW) != MMSYSERR_NOERROR)
return (FALSE);

if (waveInPrepareHeader(hWaveIn, &waveHdr1, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
return (FALSE);

if (waveInPrepareHeader(hWaveIn, &waveHdr2, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
return (FALSE);

if (waveInAddBuffer(hWaveIn, &waveHdr1, sizeof(WAVEHDR)) != MMSYSERR_NOERROR)
return (FALSE);

stop = FALSE;
n = 0;

if (waveInStart(hWaveIn) != MMSYSERR_NOERROR)
return (FALSE);

return (TRUE);
}

void MakeHeader() {
HGLOBAL hMem;
DWORD dwFmtSize = sizeof(PCMWAVEFORMAT);
char szData[] = "data";
char szFmt[] = "fmt ";
/*
Почему если n не уменьшить на 12 байт или уменьшить на меньшее кол-во байт, то при попытке проигрывания полученного файла, проигрыватель выдает ошибку.
Это первый баг, второй ниже.
*/
n = n - 12;
if (hmmio != NULL) {
mmioSeek(hmmio, 0, SEEK_SET);
ckRIFF.ckid = MMIO_CREATERIFF;
ckRIFF.cksize = n+36;
ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
mmioCreateChunk(hmmio, (LPMMCKINFO)&ckRIFF, MMIO_CREATERIFF);
mmioWrite(hmmio, (HPSTR)szFmt, 4);
mmioWrite(hmmio, (HPSTR)&dwFmtSize, sizeof(DWORD));
mmioWrite(hmmio, (HPSTR)lpFmt, sizeof(WAVEFORMAT));
mmioWrite(hmmio, (HPSTR)&lpFmt->wBitsPerSample, sizeof(WORD));
mmioWrite(hmmio, (HPSTR)szData, 4);
mmioWrite(hmmio, (HPSTR)&n, sizeof(DWORD));
mmioClose(hmmio, 0);
}
if (waveData1 != NULL) {
hMem = GlobalHandle(waveData1);
GlobalFree(hMem);
}
if (waveData2 != NULL) {
hMem = GlobalHandle(waveData2);
GlobalFree(hMem);
}
/*
Соответственно второй баг. Почему при выполнении GlobalFreePtr возникает ошибка ведь в wioRecord я выделил память lpFmt = (PCMWAVEFORMAT FAR *)GlobalAllocPtr(GPTR, sizeof(WAVEFORMAT)) и lpFmt != NULL
*/
if (lpFmt != NULL)
GlobalFreePtr(lpFmt);
}

void wioStopRecord() {
if (hWaveIn) {
waveInReset(hWaveIn);
//waveInUnprepareHeader(hWaveIn, &waveHdr1, sizeof(WAVEHDR));
//waveInUnprepareHeader(hWaveIn, &waveHdr2, sizeof(WAVEHDR));
waveInClose(hWaveIn);
}
}


void wioMessageRecord(HWND hwnd, unsigned msg, LPWAVEHDR hdr) {
if (msg == MM_WIM_DATA) {
int recorded;
if (address == &waveHdr1) address = &waveHdr2;
else address = &waveHdr1;
if (stop == FALSE)
waveInAddBuffer(hWaveIn, address, sizeof(WAVEHDR));
recorded = hdr->dwBytesRecorded;
mmioWrite(hmmio, (HPSTR)hdr->lpData, recorded);
n = n + recorded;
}
}

Если кто собирается проверить, то wioRecord начинает запись, wioMessageRecord вызывается при событии MM_WIM_DATA следующим способом
wioMessageRecord(hWnd, message, (LPWAVEHDR)lParam);
а wioStopRecord завершает запись, но для полноценного завершения MakeHeader должен вызываться при событии MM_WIM_CLOSE. Если кто знает помогите!!!
PM MAIL   Вверх
Step
Дата 20.3.2003, 01:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



Цитата
Почему если n не уменьшить на 12 байт или уменьшить на меньшее кол-во байт, то при попытке проигрывания полученного файла, проигрыватель выдает ошибку.
не правильно будет добавленна служебная инфа, и проигрователь не будет знать формат и параметры.


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
Step
Дата 20.3.2003, 02:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



Цитата
Соответственно второй баг. Почему при выполнении GlobalFreePtr возникает ошибка ведь в wioRecord я выделил память lpFmt = (PCMWAVEFORMAT FAR *)GlobalAllocPtr(GPTR, sizeof(WAVEFORMAT)) и lpFmt != NULL
глюк на этапе выполнения или при компиляции ?


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
gidm
Дата 20.3.2003, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 20.3.2003

Репутация: нет
Всего: нет



Второй глюк происходит во время исполнения программы при попытке завершить запись
PM MAIL   Вверх
Step
Дата 20.3.2003, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



Цитата
(PCMWAVEFORMAT FAR *)
возможно что из-за преобразования


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
gidm
Дата 21.3.2003, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 20.3.2003

Репутация: нет
Всего: нет



В предыдущей моей парограмме никаких проблем с этим преобразованием не было. Ну3 да ладно черт с ним, а по поводу первого вопроса можете проверить и сказать где косяк и почему?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0917 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.