Страница: 1 |
Вопрос: Высота звука | Добавлено: 04.01.06 14:55 |
Автор вопроса: ![]() |
Каким образом определить высоту звука (в герцах) с входящего источника звука? vb 6 |
Ответы | Всего ответов: 7 |
Номер ответа: 1 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: 345743490 Вопросов: 42 Ответов: 385 |
Web-сайт: Профиль | Цитата | #1 | Добавлено: 06.01.06 00:12 |
Считай автокоррелляционную функцию и ищи ее пересечение с нулем. |
Номер ответа: 2 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: 345743490 Вопросов: 42 Ответов: 385 |
Web-сайт: Профиль | Цитата | #2 | Добавлено: 06.01.06 00:29 |
Пересечение с нулем кажется даст четверть-период.
Как считать автокоррелляционную функцию? вот как. Есть массив значений через определенные промежутки времени. Автокоррелляционная функция от аргумента n*(время между элементами) есть сумма произведений Data(i)*Data(i+n) Можно и вычислять спектральную функцию и искать ее максимум. |
Номер ответа: 3 Автор ответа: ![]() ![]() ![]() ![]() ICQ: 195555443 Вопросов: 1 Ответов: 3 |
Профиль | Цитата | #3 | Добавлено: 06.01.06 13:59 |
Если не тяжело, скажите где можно найти код и т.д. |
Номер ответа: 4 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: 345743490 Вопросов: 42 Ответов: 385 |
Web-сайт: Профиль | Цитата | #4 | Добавлено: 09.01.06 15:26 |
Тяжело.
Для начала, как записаны звуковые данные и куда. А затем код легко нарисовать. Вот только метод автокоррелляционной функции будет медленным. Особенно для длинного звукового фрагмента. Буду считать, что звуковой фрагмент записан в массив integer'ов с частотой дискретизации 44100Hz. Подожди, напишу. |
Номер ответа: 5 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: 345743490 Вопросов: 42 Ответов: 385 |
Web-сайт: Профиль | Цитата | #5 | Добавлено: 09.01.06 17:39 |
Вот.
Пробовал прибавлять шумы - немного (совсем чуть-чуть) влияет на точность результата. Пробовал складывать две синусоиды - вроде работает. Лучше видит ту, что большей амплитуды. Когда амплитуды были равны, результат был неверен. Жутко медленно для маленьких частот (типа 50Hz). Для больших частот (сравнимых с частотой дискретизации, 6KHz например) скорость значительно больше. Код в форму. Option Explicit
Const DiscrFreq As Double = 44100 'частота дискретизации Dim dt As Double 'период дискретизации Dim Sound() As Integer 'Сигнал Private Sub Form_Load() MakeSound Sound, SndFreq:=50, SndLength:=0.5 MsgBox CStr(DetectFreq(Sound, MinFreq:=20)) End Sub 'Генерит сигнал для исследования Public Sub MakeSound(ByRef Snd() As Integer, _ ByVal SndFreq As Double, _ ByVal SndLength As Double) Dim DtxOmega As Double Dim n As Long 'number of samples Dim dt As Double Dim i As Long dt = 1 / DiscrFreq DtxOmega = (2 * Pi * SndFreq) * (dt) n = SndLength / dt ReDim Snd(0 To n - 1) For i = 0 To n - 1 Snd(i) = Sin(i * DtxOmega) Next i End Sub Public Function Pi() As Double Pi = Atn(1) * 4 End Function 'Определяет частоту. Хреновато, медленновато, но дело делает. Выравнивание сигнала на ноль обязательно (но нигде не реализовано). Public Function DetectFreq(ByRef Snd() As Integer, _ MinFreq As Double) As Double Dim i As Long Dim AC As Double, PrevAC As Double Dim MaxI As Long Dim dt As Double Dim ZeroCrossingI As Double Dim QuarterPeriod As Double dt = 1 / DiscrFreq MaxI = (1 / MinFreq) / dt AC = AutoCorr(Snd, i, MaxI) Do Until i > MaxI PrevAC = AC i = i + 1 AC = AutoCorr(Snd, i, MaxI) If AC < 0 Then Exit Do Loop If i > MaxI Then Err.Raise 123, " ![]() End If ZeroCrossingI = PrevAC / (PrevAC - AC) + i - 1# QuarterPeriod = ZeroCrossingI * dt DetectFreq = 1# / (4# * QuarterPeriod) End Function 'Считает автокоррелляционную функцию. Public Function AutoCorr(ByRef Data() As Integer, _ ByVal Offset As Long, _ ByVal MaxOffset As Long) Dim i As Long Dim Accu As Double If Offset > MaxOffset Then Err.Raise 12321, "AutoCorr", "The offset value should be less or equal MaxOffset!" End If For i = MaxOffset To UBound(Data) Accu = Accu + Data(i) * Data(i - Offset) Next i AutoCorr = Accu End Function Можно для коротких звуков использовать целочисленную арифметику. Можно также оптимизировать поиск первого пересечения нуля. Можно считать автокоррелляционную функцию с меньшей точностью, делая шаги по несколько выборок. Ничего из этого я не делал. Если не нравится, могу заняться разложением в спектр. Но там возни побольше. |
Номер ответа: 6 Автор ответа: ![]() ![]() ![]() ![]() ICQ: 195555443 Вопросов: 1 Ответов: 3 |
Профиль | Цитата | #6 | Добавлено: 09.01.06 19:19 |
Спасибо огромное |
Номер ответа: 7 Автор ответа: ![]() ![]() ![]() ![]() ICQ: 195555443 Вопросов: 1 Ответов: 3 |
Профиль | Цитата | #7 | Добавлено: 09.01.06 19:19 |
Спасибо огромное |
Страница: 1 |
|