![]() |
Модераторы: Partizan, gambit |
![]() ![]() ![]() |
|
tolan96 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
С наступающим, товарищи.
![]() Я хочу полететь в космос, стать президентом и самая главная цель в жизни - узнать, как определить частоту и, соответственно, ноту полученного звукового сигнала, скажем с микрофона. Решил создать проект в C# с использованием DirectX.DirectSound. Разобрал пару примеров по DirectSound вложенных в DirectSDK и остановился на примере "CaptureSound". В нем данные из буфера считываются методом Read:
То есть мы получаем массив байт. И вот вопрос: "Как в этом массиве байт определить ноту?". P.S. Я не ветеран в программировании, так что хотелось бы объяснений поподробнее... ![]() |
|||
|
||||
Ivankult |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 181 Регистрация: 8.9.2008 Репутация: нет Всего: нет |
С наступающим! Действительно пора новую ветку открывать:про звуко запись-чтение и обработку)) 5 тема за неделю!
Итак. Во первых-определи сколькими байтами кодируется 1 миллисекунда записи. Затем дели всю запись на равные куски каждый из которых равен 1 мСек. Затем создай массив эталона(каждую ноту запиши раза 4-5, все эталоны по длине равны 1 мСек). Потом берешь один кусок записи и сравниваешь с эталонами. Считаешь процент совпадения с эталоном. у какой ноты средний процент выше-та и нота. Поколдуй с допустимым процентом совпадения. Должно работать. Отпишись потом, что получится. --------------------
Стив Макконнелл: «Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете». |
|||
|
||||
tolan96 |
|
||||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
Хм...кажется представляю себе, как это должно выглядеть.
Вопрос на счет определения размера одной миллисекунды. Имеем к примеру: ![]()
Так вот, размер одной миилисекунды это:
Правильно я понимаю? Поправьте, если не так...пожалуйста... ![]() |
||||
|
|||||
tolan96 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
И еще. Идея с созданием семплов и сравнением с ними нашего семпла не подходит...так как должна отображаться полученная частота (как в гитарном тюнере), а не просто указываться, совпала ли нота или нет. К примеру я гитару подношу к микрофону, дергую струну и программа должна отобразить воспроизведенную частоту. Так собственно вопрос с самого начала стоял "Как узнать частоту получаемого звука?".
P.S. Извините, если запутал. |
|||
|
||||
Ivankult |
|
|||
Бывалый ![]() Профиль Группа: Участник Сообщений: 181 Регистрация: 8.9.2008 Репутация: нет Всего: нет |
Ну, меня вы не запутали. Методом сравнения с семплом можно определить примерную частоту с некоторой точностью(чем больше семплов тем больше точность). А стандартных методов не знаю(
--------------------
Стив Макконнелл: «Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете». |
|||
|
||||
Heinzz |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 381 Регистрация: 12.12.2008 Где: .net Репутация: 5 Всего: 9 |
Стандартных методов не знаю.
Мое предложение - выдернуть небольшой кусок сигнала (частота ведь может "плавать"), аппроксимировать его сплайнами, разложить полученную функцию в ряд Фурье => члены ряда будут представлять собой гармоники, член с максимальным коэффициентом = основная частота. зы я в математике не силен, но мне кажется что этот путь возможен. Главное найти математические библиотеки для этого, если не найдете прикручивайте MatLab/MatCad. |
|||
|
||||
tolan96 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
Пришла в голову идея:
В DirectSound у буфера воспроизведения есть такие параметры как: 1)Frequency (частота) 2)Volume (громкость) Так вот. Может сработать переброс данных из буфера записи в буфер воспроизведения, и в нём уже смотреть полученную частоту. Но, помнится, у меня была проблема с созданием буфера воспроизведения, все параметры ему ставил, а компилятор ругался : "Значение не попадает в заданный диапозон". Искал решение проблемы, но находил только людей, натыкавшихся на те же грабли, а тех, кто подсказал бы как эти грабли обойти - небыло... ![]() |
|||
|
||||
tolan96 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
Нннннет, не то...Эта Frequency то же самое, что и параметр у звукового формата (SamplesPerSecond). Чтож попробую кое что дугое...
|
|||
|
||||
tolan96 |
|
||||||||||||||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
Эх товарищи...
![]() Нашел один пример гитарного тюнера и разобрал его. Но только потом заметил, что результат выполнения программы не всегда точный... ![]() Здесь оригинальный пример и мой упрощенный. И вообщем, вот разобранный (и упрощенный) код: Начало программы (обязательно добовляемые библиотеки: DirectSound, SafeHandles и Threading)
Нажимаем на кнопочку и тем самым создаем новую форму с выбором устройства:
Код формы, где мы выбираем устройство захвата:
Создаём буффер захвата и поток, который сразу же и запускаем:
Постоянно получаем данные и отправляем их на обработку
Копируем short массив в double, получаем из него спектрограмму, а из нее частоту...
Черная магия ![]()
|
||||||||||||||
|
|||||||||||||||
tolan96 |
|
|||
Новичок Профиль Группа: Участник Сообщений: 27 Регистрация: 22.12.2009 Репутация: нет Всего: нет |
Еще вариант:
![]() Скачать с сайта mitov.com audio библиотеки и с их помощью создать анализатор частот. Для этого нужно на toolBar прикрепить AudioLab и AudioLabEssential (храняться в папке "bin" установленных библиотек), затем добавить на форму "spectrum" и "dsAudioIn", установив dsAudioIn'у в параметр OutputPin - spectrum. Затем, для получения частоты заходим в Events spectrum'а и создаем обработчик единственного события. И в параметре Args.Frequency храниться наша частота. Вот мой пример и генератор частот (сделанный, опять таки используя AudioLab ![]() П.С. Нужно поковыряться с параметрами, чтобы добиться более-менее нормального результата... ![]() |
|||
|
||||
![]() ![]() ![]() |
Прежде чем создать тему, посмотрите сюда: | |
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |