Форум программистов, компьютерный форум CyberForum.ru

Direct Sound - уровень сигнала на входе - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.75
kirpich
0 / 0 / 0
Регистрация: 06.10.2008
Сообщений: 48
14.07.2011, 01:23     Direct Sound - уровень сигнала на входе #1
Собственно, интересует сабж

Нужно с некоторой периодичностью определять уровень сигнала на линейном входе звуковой карты..

Может, кто-нибудь сталкивался с подобным?
Подскажите, плз
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
John Paramol
Сообщений: n/a
14.07.2011, 18:59     Direct Sound - уровень сигнала на входе #2
Насколько я понимаю, уровень сигнала можно рассчитать, как среднее арифметическое
значений всех амплитуд (по модулю) в выборках сигнала за данный период.
Следовательно, чем меньше будет период, а соответственно длина буфера,
тем точнее будет представлен средний уровень сигнала.
Если в децибелах, то максимальный уровень соответствует 0 db, минимальный - примерно (-96.31)db,
и удвоение амплитуды соответствует увеличению громкости на 6 db.
Надо сказать, что 1-байтовые данные представлены ввиде беззнаковых чисел (0 - 255),
тишине соответствует 128, а 2-байтовые - в виде знаковых (-32768 - 32767), тишине соответствует 0.
kirpich
0 / 0 / 0
Регистрация: 06.10.2008
Сообщений: 48
14.07.2011, 23:11  [ТС]     Direct Sound - уровень сигнала на входе #3
А можно поконкретнее, как именно добраться до значений в буфере?
Буфер создал, записывать могу, могу в файл сохранить, а вот с доступом к данным проблема..

Нужно определять уровень в каждом канале отдельно, так что в байтах запутался разом..
John Paramol
Сообщений: n/a
15.07.2011, 07:01     Direct Sound - уровень сигнала на входе #4
Интересно, как Вам удается сохранять данные в файл,
не имея к ним доступа?

Вы ведь используете функцию IDirectSoundCaptureBuffer::Lock,
которая возвращает указатели на участки буфера с данными, которые
по идее и надо сохранять в файл.

PS. Стереофонический сигнал представляется как массив чередующихся
выборок для правого и левого каналов. Например, для стереосигнала с
дискретностью 8 бит это массив двухбайтовых слов, где младший байт -
левый канал, старший - правый. Для стереосигнала с дискретностью
16 бит - массив четырехбайтовых слов, где младшее слово - левый
канал, старшее - правый.
kirpich
0 / 0 / 0
Регистрация: 06.10.2008
Сообщений: 48
15.07.2011, 19:26  [ТС]     Direct Sound - уровень сигнала на входе #5
hr = g_pWaveFile->Write( dwCaptureLength,
(BYTE*)pbCaptureData,
&dwDataWrote )

так и пишу..

а вот, как устроена эта pbCaptureData, никак найти не мог..
т.е. значение, например, младшего слова и будет уровнем сигнала?

а отрицательная часть - это, как я догадываюсь, нижняя полуволна синусоиды?
тогда напрашивается другой вопрос - чтобы из этого получить уровень сигнала, надо считать среднее за период?
John Paramol
Сообщений: n/a
16.07.2011, 07:21     Direct Sound - уровень сигнала на входе #6
> hr = g_pWaveFile->Write( dwCaptureLength,
> (BYTE*)pbCaptureData,
> &dwDataWrote )

Если бы у меня не было того же исходника, что и у Вас, я бы долго гадал,
что же это Вы мне тут показали

> т.е. значение, например, младшего слова и будет уровнем сигнала?

Не совсем. Из вышеуказанного вытекает нижеследующее:
Из этого значения надо находить амплитуду - отклонение сигнала от значения тишины,
взятое по модулю. А уровень сигнала (можно сказать, громкость) ищется через амплитуду.
Если хотите выражать в процентах - это просто: отношение текущей амплитуды
к максимальной, X 100%. Но его принято выражать в децибелах (читайте выше).
Определение в словаре: 'децибел - логарифмическая единица измерения относительного
уровня сигнала (отношения двух сигналов).'

> а отрицательная часть - это, как я догадываюсь, нижняя полуволна синусоиды?
> тогда напрашивается другой вопрос - чтобы из этого получить уровень сигнала,
> надо считать среднее за период?

Какой период Вы имеете в виду - 2*Pi, или период времени, через который
необходимо получать рассчитанный уровень сигнала?
Я имел в виду второе.
(среднее синусоиды за период 2*Pi = 0
Можно конечно попробовать выдавать не средний уровень за какое-то время, а текущий,
но при частоте дискретизации даже 8000 герц он будет меняться 8000 раз в секунду.

Длину буфера следует брать небольшой еще и по той причине, что мы берем данные, уже
поступившие на вход, значит есть некоторое опоздание
(в половину длины буфера или более).

некоторые особо въедливые могут со мной поспорить;
типа если проигрывается тишина, но смещение постоянной составляющей (DC offset)
имеет место быть, ухо не будет слышать сигнал, а наш рассчитанный уровень сигнала
будет иметь некоторое значение. Но то же самое показывает, например, WaveLab
(попробуйте и убедитесь сами). Так что мы считаем правильно.
Вот и получается, что мы можем не услышать даже самый громкий звук,
на который способна наша звуковая карта

PS. последний абзац не берите в голову
-BBC-
Сообщений: n/a
16.07.2011, 11:51     Direct Sound - уровень сигнала на входе #7
Все правильно, кроме одного замечания:
необходимо брать среднеквадратичное значение,
а не амплитудное, тогда будет реальный уровень.
kirpich
0 / 0 / 0
Регистрация: 06.10.2008
Сообщений: 48
17.07.2011, 01:31  [ТС]     Direct Sound - уровень сигнала на входе #8
Насчет исходника - да, впервые с direct sound столкнулся.. надо же с чего-то начать было..

в принципе, картина теперь значительно прояснилась.. вопрос остается в эффективном способе (предполагаемая машина - П-2)

из всего вышеперечисленного - за определенный период (времени, а не 2pi) собираем максимумы амплитуд и из них выбираем среднее

вытянет ли машина?
качество звука варьируется от 8000 до 22500 (стерео)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.07.2011, 08:41     Direct Sound - уровень сигнала на входе
Еще ссылки по теме:

Подключение библиотеки Direct C++
C++ использование sound() nosound()
Вектора. Сложение и direct-list-initialization C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
John Paramol
Сообщений: n/a
19.07.2011, 08:41     Direct Sound - уровень сигнала на входе #9
Почему бы не использовать все время самую низкую частоту
дискретизации. Это параметр, от которого в большей степени
зависит длительность рассчетов. А для такой вещи как
средний уровень особая точность не нужна.

Можно опросить устройство функцией IDirectSound::GetCaps,
после этого в заполненной структуре DSCAPS поле dwFlags может
содержать флаг DSCAPS_CONTINUOUSRATE, что означает, устройство
поддерживает любые значения частоты от DSBFREQUENCY_MIN
(обычно 100 Гц) до DSBFREQUENCY_MAX (обычно 100000 Гц)
с точностью примерно 10 Гц.
Если этот флаг отсутствует, поддерживаются только стандартные
частоты: 8000, 11025, 20050 и т.д.
А можно вообще не париться и установить частоту в 8000

Насчет быстродействия,
даже при 44100 Гц, стерео, с периодичностью 0.2 секунды, потребуется
17640 рассчетов, включающих два умножения (с учетом замечания -BBC-),
несколько сложений и инкремент счетчика цикла.
Это требует ничтожных затрат процессорного времени.
Yandex
Объявления
19.07.2011, 08:41     Direct Sound - уровень сигнала на входе
Ответ Создать тему
Опции темы

Текущее время: 04:03. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru