| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > DirectX.DirectSound определение частоты. |
| Автор: tolan96 22.12.2009, 18:46 | ||
| С наступающим, товарищи. Я хочу полететь в космос, стать президентом и самая главная цель в жизни - узнать, как определить частоту и, соответственно, ноту полученного звукового сигнала, скажем с микрофона. Решил создать проект в C# с использованием DirectX.DirectSound. Разобрал пару примеров по DirectSound вложенных в DirectSDK и остановился на примере "CaptureSound". В нем данные из буфера считываются методом Read:
То есть мы получаем массив байт. И вот вопрос: "Как в этом массиве байт определить ноту?". P.S. Я не ветеран в программировании, так что хотелось бы объяснений поподробнее... |
| Автор: Ivankult 22.12.2009, 19:12 |
| С наступающим! Действительно пора новую ветку открывать:про звуко запись-чтение и обработку)) 5 тема за неделю! Итак. Во первых-определи сколькими байтами кодируется 1 миллисекунда записи. Затем дели всю запись на равные куски каждый из которых равен 1 мСек. Затем создай массив эталона(каждую ноту запиши раза 4-5, все эталоны по длине равны 1 мСек). Потом берешь один кусок записи и сравниваешь с эталонами. Считаешь процент совпадения с эталоном. у какой ноты средний процент выше-та и нота. Поколдуй с допустимым процентом совпадения. Должно работать. Отпишись потом, что получится. |
| Автор: tolan96 22.12.2009, 20:39 | ||||
| Хм...кажется представляю себе, как это должно выглядеть. Вопрос на счет определения размера одной миллисекунды. Имеем к примеру:
Так вот, размер одной миилисекунды это:
Правильно я понимаю? Поправьте, если не так...пожалуйста... |
| Автор: tolan96 22.12.2009, 20:56 |
| И еще. Идея с созданием семплов и сравнением с ними нашего семпла не подходит...так как должна отображаться полученная частота (как в гитарном тюнере), а не просто указываться, совпала ли нота или нет. К примеру я гитару подношу к микрофону, дергую струну и программа должна отобразить воспроизведенную частоту. Так собственно вопрос с самого начала стоял "Как узнать частоту получаемого звука?". P.S. Извините, если запутал. |
| Автор: Ivankult 23.12.2009, 06:28 |
| Ну, меня вы не запутали. Методом сравнения с семплом можно определить примерную частоту с некоторой точностью(чем больше семплов тем больше точность). А стандартных методов не знаю( |
| Автор: Heinzz 23.12.2009, 18:13 |
| Стандартных методов не знаю. Мое предложение - выдернуть небольшой кусок сигнала (частота ведь может "плавать"), аппроксимировать его сплайнами, разложить полученную функцию в ряд Фурье => члены ряда будут представлять собой гармоники, член с максимальным коэффициентом = основная частота. зы я в математике не силен, но мне кажется что этот путь возможен. Главное найти математические библиотеки для этого, если не найдете прикручивайте MatLab/MatCad. |
| Автор: tolan96 24.12.2009, 16:55 |
| Пришла в голову идея: В DirectSound у буфера воспроизведения есть такие параметры как: 1)Frequency (частота) 2)Volume (громкость) Так вот. Может сработать переброс данных из буфера записи в буфер воспроизведения, и в нём уже смотреть полученную частоту. Но, помнится, у меня была проблема с созданием буфера воспроизведения, все параметры ему ставил, а компилятор ругался : "Значение не попадает в заданный диапозон". Искал решение проблемы, но находил только людей, натыкавшихся на те же грабли, а тех, кто подсказал бы как эти грабли обойти - небыло... |
| Автор: tolan96 26.12.2009, 05:39 |
| Нннннет, не то...Эта Frequency то же самое, что и параметр у звукового формата (SamplesPerSecond). Чтож попробую кое что дугое... |
| Автор: tolan96 9.1.2010, 21:31 | ||||||||||||||
| Эх товарищи... Нашел один пример гитарного тюнера и разобрал его. Но только потом заметил, что результат выполнения программы не всегда точный... Здесь http://narod.ru/disk/16731477000/FftGuitarTuner_src.rar.html пример и мой http://narod.ru/disk/16731624000/singer.rar.html. И вообщем, вот разобранный (и упрощенный) код: Начало программы (обязательно добовляемые библиотеки: DirectSound, SafeHandles и Threading)
Нажимаем на кнопочку и тем самым создаем новую форму с выбором устройства:
Код формы, где мы выбираем устройство захвата:
Создаём буффер захвата и поток, который сразу же и запускаем:
Постоянно получаем данные и отправляем их на обработку
Копируем short массив в double, получаем из него спектрограмму, а из нее частоту...
Черная магия
|
| Автор: tolan96 12.1.2010, 13:59 |
| Еще вариант: Скачать с сайта http://www.mitov.com/html/audiolab.html audio http://www.video-process.com/AudioLab_NET_4_3_1.zip и с их помощью создать анализатор частот. Для этого нужно на toolBar прикрепить AudioLab и AudioLabEssential (храняться в папке "bin" установленных библиотек), затем добавить на форму "spectrum" и "dsAudioIn", установив dsAudioIn'у в параметр OutputPin - spectrum. Затем, для получения частоты заходим в Events spectrum'а и создаем обработчик единственного события. И в параметре Args.Frequency храниться наша частота. Вот мой http://narod.ru/disk/16823189000/Frequency_Identify.rar.html и http://narod.ru/disk/16823236000/ToneGenerator.rar.html частот (сделанный, опять таки используя AudioLab П.С. Нужно поковыряться с параметрами, чтобы добиться более-менее нормального результата... |