Страница: 1 |
Страница: 1 |
Вопрос: Звук
Добавлено: 02.01.07 15:06
Автор вопроса: RNB-X
Есть проблема и как по мне довольно сложная. Имеется массив чисел, характерезующий синусоидальных звуковой сигнал (постоянной частоты). А теперь вопрос: как определить частоту этого сигнала? Желательно с примерами(лучше на VB). Зарание благодарен!!!
Ответы
Всего ответов: 13
Номер ответа: 1
Автор ответа:
Djon
Вопросов: 61
Ответов: 471
Web-сайт:
Профиль | | #1
Добавлено: 02.01.07 15:11
А что у тебя получилось? Напиши код
Номер ответа: 2
Автор ответа:
Серёга
ICQ: 262809473
Вопросов: 17
Ответов: 561
Web-сайт:
Профиль | | #2
Добавлено: 02.01.07 15:40
Ты бы хоть кусочек массива показал, а то фиг его знает как он там характеризует ))
Номер ответа: 3
Автор ответа:
RNB-X
Вопросов: 17
Ответов: 29
Профиль | | #3
Добавлено: 02.01.07 15:43
У меня ничего не получилось. Я пытался ныделять полупериод, находя в массиве точку 128 потом следующую за ней 128. Далее смотрел растояние между ними и пытался на основании этого растояния вывести зависимость. Однако проблема в том что эти "растояния" непостоянны и есть погрешность +-10. И вобще алгоритм крайне нестабильно работает. Поэтому мне кажется что он неверный! Может кто-то поможет???
Номер ответа: 4
Автор ответа:
RNB-X
Вопросов: 17
Ответов: 29
Профиль | | #4
Добавлено: 02.01.07 15:44
массив такой: числа от 0 до 255. если нарисовать график по этим числам(я пробовал) получается красивенькая синусоида нулём которой является точка 128.
Номер ответа: 5
Автор ответа:
Серёга
ICQ: 262809473
Вопросов: 17
Ответов: 561
Web-сайт:
Профиль | | #5
Добавлено: 02.01.07 16:12
ИМХО эти 2 утверждения немного несостыковываются - ведь если частота постоянная, то и период колебаний должен быть постоянным? Или как ...???
Номер ответа: 6
Автор ответа:
Djon
Вопросов: 61
Ответов: 471
Web-сайт:
Профиль | | #6
Добавлено: 02.01.07 16:15
погрешность, по моему, получается из-за того что массив начинается с 0, а индексация массива с 1.
Номер ответа: 7
Автор ответа:
RNB-X
Вопросов: 17
Ответов: 29
Профиль | | #7
Добавлено: 02.01.07 16:27
Да, но я ведь и говорю что погрешность сигнал постоянный, вот только вычеслить точно не выходит и это не из-за индексации.. Пожайлуста предложите какой-то алгоритм. Если кто-то сможет обьяснить мне суть алгоритмя быстрого преобразования Фурье(желательно на примере VB) буду благодарен. А то я не понимаю его в упор.
Номер ответа: 8
Автор ответа:
Djon
Вопросов: 61
Ответов: 471
Web-сайт:
Профиль | | #8
Добавлено: 02.01.07 16:48
http://slovari.yandex.ru/art.xml?art=bse/00085/67000.htm&encpage=bse&mrkp=http%3A//hghltd.yandex.com/yandbtm%3Furl%3Dhttp%253A//encycl.yandex.ru/texts/bse/00085/67000.htm%26text%3D%25EF%25F0%25E5%25EE%25E1%25F0%25E0%25E7%25EE%25E2%25E0%25ED%25E8%25E5%2B%25D4%25F3%25F0%25FC%25E5%26reqtext%3D%2528%25EF%25F0%25E5%25EE%25E1%25F0%25E0%25E7%25EE%25E2%25E0%25ED%25E8%25E5%253A%253A87151%2B%2526%2526%2B%25D4%25F3%25F0%25FC%25E5%253A%253A1926118%2529//6%26%26isu%3D2
Номер ответа: 9
Автор ответа:
RNB-X
Вопросов: 17
Ответов: 29
Профиль | | #9
Добавлено: 02.01.07 21:32
мда, "хорошее" обьяснение. Чесно говоря понятней от него не стало.
Номер ответа: 10
Автор ответа:
Djon
Вопросов: 61
Ответов: 471
Web-сайт:
Профиль | | #10
Добавлено: 02.01.07 22:02
Там есть формула, что еще нужно, перелажить на VB это не трудно, даже легко.
Номер ответа: 11
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #11
Добавлено: 02.01.07 22:55
Я, вроде, уже постил пример работы с FFT.
//
// Complex forward and inverse FFT routines
// Written by Alexey Lukin
//
#include <cmath>
using namespace std;
#define Round(x) ((int)(x+0.5))
#define M_PI 3.14159265358979323
typedef double RealData;
typedef struct C {
RealData Re;
RealData Im;
} Cmplx;
// Complex FFT
// Input: N complex points in time domain
// Output: N complex points in frequency domain
void FFTC(Cmplx *X, int FFTSize)
{
int N, M, i, j, L, LE, LE2, ip, k, s;
Cmplx t,z;
RealData UR, UI, SR, SI, TR, TI;
N = FFTSize;
M = Round(log((double)N)/log((double)2));
// Bit-reverse
i = 0;
for (s=0;s<N-1;s++) {
if (s<i) {
t = *(X+i); *(X+i) = *(X+s); *(X+s) = t;
}
k = N >> 1;
while (i&k) k >>= 1;
i += k;
k <<= 1;
while (k<N) {
i -= k;
k <<= 1;
}
}
// First pass
for (i=0;i<N;i+=2) {
t = *(X+i);
X[i].Re = t.Re + X[i+1].Re;
X[i].Im = t.Im + X[i+1].Im;
X[i+1].Re = t.Re - X[i+1].Re;
X[i+1].Im = t.Im - X[i+1].Im;
}
// Second pass
for (i=0;i<N;i+=4) {
t = X[i];
X[i].Re = t.Re + X[i+2].Re;
X[i].Im = t.Im + X[i+2].Im;
X[i+2].Re = t.Re - X[i+2].Re;
X[i+2].Im = t.Im - X[i+2].Im;
t = X[i+1];
z = X[i+3];
X[i+1].Re = t.Re + z.Im;
X[i+1].Im = t.Im - z.Re;
X[i+3].Re = t.Re - z.Im;
X[i+3].Im = t.Im + z.Re;
}
// Remaining passes
for (L=3;L<=M;L++) {
LE = 1 << L;
LE2 = LE >> 1;
UR = 1; UI = 0;
SR = cos(M_PI/LE2);
SI = -sin(M_PI/LE2);
for (j=0;j<LE2;j++) {
for (i=j;i<N;i+=LE) {
ip = i + LE2;
TR = X[ip].Re*UR - X[ip].Im*UI;
TI = X[ip].Re*UI + X[ip].Im*UR;
X[ip].Re = X[i].Re - TR;
X[ip].Im = X[i].Im - TI;
X[i].Re = X[i].Re + TR;
X[i].Im = X[i].Im + TI;
}
TR = UR;
UR = TR*SR - UI*SI;
UI = TR*SI + UI*SR;
}
}
}
// Inverse complex FFT
// Input: N complex points in frequency domain
// Output: N complex points in time domain
void IFFTC(Cmplx *X, int FFTSize)
{
int i;
RealData DivFFTSize = 1.0 / FFTSize;
// Change the sign of ImX
for (i=0;i<FFTSize;i++) X[i].Im = -X[i].Im;
// Calculate N-point complex FFT
FFTC(X,FFTSize);
// Adjust the result data
for (i=0;i<FFTSize;i++) {
X[i].Re *= DivFFTSize;
X[i].Im = -X[i].Im * DivFFTSize;
}
}
Cmplx getCmplx(double ampl, double phi){
Cmplx res;
res.Re = ampl * cos(phi);
res.Im = ampl * sin(phi);
return res;
}
double cmplxabs(Cmplx c){
return sqrt(c.Re*c.Re + c.Im*c.Im);
}
#define SAMPLERATE 1024
int main(){
Cmplx data[SAMPLERATE];
double phi, ampl;
for(int i = 0; i < SAMPLERATE; i++){
phi = (double)i / SAMPLERATE * 2 * M_PI;
// 3 составляющие: 16Гц, инт. 1, 8Гц, инт. 2, 128Гц, инт. 0.4
ampl = sin(phi * 16 - M_PI / 3.0) + sin(phi * 8) * 2 + sin(phi * 500) * 0.4;
data[i] = getCmplx(ampl, phi);
}
FFTC(data, SAMPLERATE);
for(int i = SAMPLERATE / 2; i < SAMPLERATE; i++){
if(cmplxabs(data[i] > 1e-6){
printf("%4d Hz: ampl = %lf; phase = %lf\n",
SAMPLERATE - i + 1,
sqrt(data[i].Im * data[i].Im + data[i].Re * data[i].Re) * 2 / SAMPLERATE,
atan(data[i].Im / data[i].Re));
}
}
return 0;
}
Вкратце, FFT (Быстрое Преобразование Фурье) преобразует массив комплексных чисел длиной 2^N в массив 2^(N-1). Амплитуда сигнала это модуль, а его фаза - аргумент комплексного числа. На вход ты передаешь комплексные числа с аргументом от 0 (начало последовательности отсчетов) до 2*Pi (ее конец), и соответствующей этому отсчету амплитудой. На выходе получаешь массив комплексных чисел, где номер элемента соответствует частоте, аргумент содержащегося числа фазе, а модуль - амплитуде.
Номер ответа: 12
Автор ответа:
RNB-X
Вопросов: 17
Ответов: 29
Профиль | | #12
Добавлено: 03.01.07 17:24
а как использование этого алгоритма поможет мне определить частоту???
Номер ответа: 13
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #13
Добавлено: 05.01.07 14:29
Самым непосредственным образом. Максимум амплитуды из всех частот и соответствует основной частоте звука.