Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
Господа, будьте снисходительны, не бросайтесь сразу штрафовать за, как вам кажется, глупые вопросы - beginners на то и beginners.
 |
Чего ж здесь неправильно? (запись звука) 24.01.03 15:15 Число просмотров: 1154
Автор: amirul <Serge> Статус: The Elderman
|
> Это фрагмент я вставил в обработчик кнопы: > { > WAVEFORMATEX m_WaveFormatEx; > memset(&m_WaveFormatEx,0x00,sizeof(m_WaveFormatEx)); > m_WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM; > m_WaveFormatEx.nChannels = 1; > m_WaveFormatEx.wBitsPerSample = 16; > m_WaveFormatEx.cbSize = 0; > m_WaveFormatEx.nSamplesPerSec = 22050; > m_WaveFormatEx.nAvgBytesPerSec = > m_WaveFormatEx.nSamplesPerSec*(m_WaveFormatEx.wBitsPerSampl > e/8); > m_WaveFormatEx.nBlockAlign = > (m_WaveFormatEx.wBitsPerSample/8)* > m_WaveFormatEx.nChannels; Когда я этим занимался все мои попытки заполнить WAVEFORMATEX вручную заканчивались неудачей (с PCM не уверен - этот формат пожалуй единственный, который не продолжает структуру), но со всеми остальными форматами грабли (ошибка неверный формат). Именно поэтому (если ты получил код - увидишь) я перечисляю все форматы, которые знает система, соответствующие некоторому критерию (собственно тегу, битовости, частоте и количеству каналов), и в колбеке на это дело забираю первый попавшийся. Все остальные поля (в том числе и расширение структуры - на зря же в конце концов введено поле cbSize :-))) ) за меня заполняет система именно так, как она знает. Если есть другие способы - я их не нашел - был в цейтноте. Да в общем и этот неплох. Для съема с телефона рекомендую GSM 6.10 (в отличие от mp3 - есть на всех системах сразу после установки) - разработан специально для сжатия голосовых данных (правда затачивался под англоязычную фонетику - но тут уж ничего не попишешь) и обладает неплохим сжатием.
> Т.е. сейчас я только пытаюсь "заставить" выполниться > callback-у по заполнению буфера. Я правильно рассуждаю?? > ( пока про остановку записи речь не идет ) > > И еще! Как вычислять размер этого буфера - ну скажем на 10 > секунд записи?
Каждый формат имеет nAvgBytesPerSec (если будешь заполнять структуру как я сказал - за тебя это поле заполнит MSACM) - это ни что иное, как Среднее число байт в секунду (вообще еще в MSDN-е глянь - по моему среднее на канал, точно не помню - давно было).
А вообще лучше не буфер на 10 секунд, а 5 буферов по секунде (тоже видно из кода). Можно не 5, но как минимум 2. Так как пока ты будешь сбрасывать его содержимое и у acm-а не будет ни одного буфера все данные будут дропиться -> отсюда щелчки в записи. С мультибуферностью: тебе приходит заполненный буфер, пока ты с ним работаешь - заполняется следующий. Соответственно, как только ты заканчиваешь работу с заполненным буфером ты его переподготавливаешь и возвращаешь системе, обязательно до того как тебе придет последний, который есть у системы, потому как опять будут разрывы и щелчки в записи. Но с этим проблем не возникает: даже с двумя одинаковыми буферами битрейт записи на винт (пропускная способность ATA) гораздо выше битрейта голосовых данных. Вообще тут есть несколько нюансов, но если наткнешься - и сам поймешь, если не наткнешься - оно и не надо. :-)))
ЗЫ: Во все места вставь GetLastError и если будут проблемы, кроме функции, которая слетела пиши с какой ошибкой она это сделала. Так гораздо легче разобраться в происходящем. А возможно тебе даже не придется писать
ЗЗЫ: Ты сырцы мои получил?
|
|
<beginners>
|
Чего ж здесь неправильно? (запись звука) 24.01.03 05:16
Автор: rom30 Статус: Незарегистрированный пользователь
|
Это фрагмент я вставил в обработчик кнопы:
{
WAVEFORMATEX m_WaveFormatEx;
memset(&m_WaveFormatEx,0x00,sizeof(m_WaveFormatEx));
m_WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
m_WaveFormatEx.nChannels = 1;
m_WaveFormatEx.wBitsPerSample = 16;
m_WaveFormatEx.cbSize = 0;
m_WaveFormatEx.nSamplesPerSec = 22050;
m_WaveFormatEx.nAvgBytesPerSec =
m_WaveFormatEx.nSamplesPerSec*(m_WaveFormatEx.wBitsPerSample/8);
m_WaveFormatEx.nBlockAlign = (m_WaveFormatEx.wBitsPerSample/8)* m_WaveFormatEx.nChannels;
HWAVEIN m_hRecord;
mmReturn = ::waveInOpen( &m_hRecord, WAVE_MAPPER,
&m_WaveFormatEx, (unsigned long)GetSafeHwnd(), 0, CALLBACK_WINDOW);
UINT RecSamples= m_WaveFormatEx.nSamplesPerSec/10;
LPWAVEHDR lpHdr = new WAVEHDR;
ZeroMemory(lpHdr, sizeof(WAVEHDR));
char* lpByte = (char*)malloc(m_WaveFormatEx.nBlockAlign*RecSamples);
lpHdr->lpData = (char *) lpByte;
lpHdr->dwBufferLength = (m_WaveFormatEx.nBlockAlign*RecSamples);
mmReturn = ::waveInPrepareHeader(m_hRecord, lpHdr, sizeof(WAVEHDR));
mmReturn = ::waveInAddBuffer(m_hRecord, lpHdr, sizeof(WAVEHDR));
mmReturn=waveInStart(MYSOUND.m_hRecord);
}
Добавил в диалог функцию-член :
LRESULT BufferFilled(WPARAM wParam, LPARAM lParam)
{
AfxMessageBox("буфер заполнился - WIM_DATA");
}
и в карту сообщений :
ON_MESSAGE(WIM_DATA, BufferFilled) - добавил "вручную" , т.е. без мастера.
Т.е. сейчас я только пытаюсь "заставить" выполниться callback-у по заполнению буфера. Я правильно рассуждаю??
( пока про остановку записи речь не идет )
И еще! Как вычислять размер этого буфера - ну скажем на 10 секунд записи?
|
 |
Чего ж здесь неправильно? (запись звука) 24.01.03 15:15
Автор: amirul <Serge> Статус: The Elderman
|
> Это фрагмент я вставил в обработчик кнопы: > { > WAVEFORMATEX m_WaveFormatEx; > memset(&m_WaveFormatEx,0x00,sizeof(m_WaveFormatEx)); > m_WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM; > m_WaveFormatEx.nChannels = 1; > m_WaveFormatEx.wBitsPerSample = 16; > m_WaveFormatEx.cbSize = 0; > m_WaveFormatEx.nSamplesPerSec = 22050; > m_WaveFormatEx.nAvgBytesPerSec = > m_WaveFormatEx.nSamplesPerSec*(m_WaveFormatEx.wBitsPerSampl > e/8); > m_WaveFormatEx.nBlockAlign = > (m_WaveFormatEx.wBitsPerSample/8)* > m_WaveFormatEx.nChannels; Когда я этим занимался все мои попытки заполнить WAVEFORMATEX вручную заканчивались неудачей (с PCM не уверен - этот формат пожалуй единственный, который не продолжает структуру), но со всеми остальными форматами грабли (ошибка неверный формат). Именно поэтому (если ты получил код - увидишь) я перечисляю все форматы, которые знает система, соответствующие некоторому критерию (собственно тегу, битовости, частоте и количеству каналов), и в колбеке на это дело забираю первый попавшийся. Все остальные поля (в том числе и расширение структуры - на зря же в конце концов введено поле cbSize :-))) ) за меня заполняет система именно так, как она знает. Если есть другие способы - я их не нашел - был в цейтноте. Да в общем и этот неплох. Для съема с телефона рекомендую GSM 6.10 (в отличие от mp3 - есть на всех системах сразу после установки) - разработан специально для сжатия голосовых данных (правда затачивался под англоязычную фонетику - но тут уж ничего не попишешь) и обладает неплохим сжатием.
> Т.е. сейчас я только пытаюсь "заставить" выполниться > callback-у по заполнению буфера. Я правильно рассуждаю?? > ( пока про остановку записи речь не идет ) > > И еще! Как вычислять размер этого буфера - ну скажем на 10 > секунд записи?
Каждый формат имеет nAvgBytesPerSec (если будешь заполнять структуру как я сказал - за тебя это поле заполнит MSACM) - это ни что иное, как Среднее число байт в секунду (вообще еще в MSDN-е глянь - по моему среднее на канал, точно не помню - давно было).
А вообще лучше не буфер на 10 секунд, а 5 буферов по секунде (тоже видно из кода). Можно не 5, но как минимум 2. Так как пока ты будешь сбрасывать его содержимое и у acm-а не будет ни одного буфера все данные будут дропиться -> отсюда щелчки в записи. С мультибуферностью: тебе приходит заполненный буфер, пока ты с ним работаешь - заполняется следующий. Соответственно, как только ты заканчиваешь работу с заполненным буфером ты его переподготавливаешь и возвращаешь системе, обязательно до того как тебе придет последний, который есть у системы, потому как опять будут разрывы и щелчки в записи. Но с этим проблем не возникает: даже с двумя одинаковыми буферами битрейт записи на винт (пропускная способность ATA) гораздо выше битрейта голосовых данных. Вообще тут есть несколько нюансов, но если наткнешься - и сам поймешь, если не наткнешься - оно и не надо. :-)))
ЗЫ: Во все места вставь GetLastError и если будут проблемы, кроме функции, которая слетела пиши с какой ошибкой она это сделала. Так гораздо легче разобраться в происходящем. А возможно тебе даже не придется писать
ЗЗЫ: Ты сырцы мои получил?
|
 |  |
Чего ж здесь неправильно? (запись звука) 24.01.03 23:15
Автор: rom30 Статус: Незарегистрированный пользователь
|
Для съема с телефона рекомендую GSM 6.10 (в
Я же ведь только разбираюсь. А что это такое GSM...
И это "за тебя это поле заполнит MSACM)"
ЗЗЫ: Ты сырцы мои получил?
Угу!
Сейчас начну разбираться!
Спасибо
|
 |  |  |
Чего ж здесь неправильно? (запись звука) 25.01.03 18:16
Автор: amirul <Serge> Статус: The Elderman
|
> Для съема с телефона рекомендую GSM 6.10 (в > Я же ведь только разбираюсь. А что это такое GSM... WAVE_FORMAT_GSM610 из mmreg.h - тег (wFormatTag) для WAVEFORMATEX, когда открываешь устройство. Кодек поддерживающий формат сжатия GSM 6.10. Я не интересовался разработчиками и спецификациями - думаю несложно найти в инете, но стоит учесть, что сейчас все мобилы (почти все) работают на этом кодеке. Сжатие с потерями, основанное на статистике распределения частот в английском языке и на чувствительности уха к разным частотам и интенсивностям. В общем разработан специально для телефонии и при этом - стандартный кодек: как кодирование, так и декодирование есть в любой винде (скорее всего тоже "почти" любой, но я не разбирался с какой частью винды он ставится). mp3 кодеки есть не у всех, у кого есть - только декодирующие, у кого с поддержкой кодирования - фраунгоферовский кодек с низким битрейтом (хотя для записи телефона это не критично)
> И это "за тебя это поле заполнит MSACM)" MS Audio Compression Manager - функции начинаются на acm. Собственно точка пересечения с wave и mmio функциями - это этот самый формат WAVEFORMATEX. Короче, когда открываешь аудиоустройство и указываешь формат, то он на лету будет пропускаться через кодек, а в буферах ты будешь получать уже сжатые данные. Заполнять формат самому не стоит - лучше предоставить это acm-у - он лучше знает какие кодеки есть в системе.
> ЗЗЫ: Ты сырцы мои получил? > Угу! > Сейчас начну разбираться! > Спасибо Ага
|
|
|