Вземете звуков спектър от микрофона
в общия предмет. Необходимо е да поставите в масива (0..511 от двойно) пропорционално стойността на нивото на звука на определена честота (40..18K). Като графичен еквалайзер за играчи, само че ще има повече високоговорители. Някой има ли работещ пример? Разрових се в куп примери "по FFT" - някои не се компилират, някои не разбирам как да вържа. Нещо като компоненти на MMTools - има еквалайзери, хващат "общия" звук. Просто трябва да забацам масива.
да, забравих, трябват ви без "извънградски" компоненти и библиотеки
Но трябва да учиш, ако искаш.
Вземете по-простия алгоритъм - alg. Herzel. Нека не е бързо, но по-лесно.
Използват се въображаеми числа, входни данни (числото им е степен на две, защото FFT): първо число, нула, второ число, нула. последно число, нула :) нулата е имагинерната част - ако входът е реални данни, например от звукова карта
ПРОЦЕДУРА four1(VAR данни: gldarray; nn,isign: цяло число); isign =1 напред, -1 назад FFT
изходните данни също са въображаеми числа, за тема на клон -
използвайте първата половина re1, im1, re2, im2, . re(n/2+1),im(n/2+1) желаната "сила на звука" = (re^2+im^2)^(1/2) е модулът на това въображаемо число.
След употреба добавете -
TYPE gldarray = ARRAY OF extended; // разширеният е по-готин :)
Процедурата се копира в кода, "sngl", който компилаторът не разбира, просто изтрийте.
Въведете - procedure TForm1.Button1Click(Sender: TObject); var dat:gldarray; i:integer; e:array[0..257-1] of double; //тук "обем" ще бъде начало setlength(dat,512*2+1); //функция four1 иска array[1. не е включен нулев елемент
за i:=1 до 512 направете begin dat[i*2-1]:=sin((2*pi/44100)*100*i); // тон 1000 Hz при честота на дискретизация 44100 за секунда dat[i*2]:=0; //данните са реални, въображаемичаст=0 край;
four1(dat,512,1); за i:=1 до 512*2 направете dat[i]:=1/512*dat[i]; //изисква се, ако е необходима обратна трансформация, за да съответства на оригинала
//само първата половина на FFT е информативна. имаме реални данни за i:=1 до 512 div 2+1 do e[i-1]:=sqrt(sqr(dat[i*2-1])+sqr(dat[i*2]));
tsa (05/19/06 12:28 PM) [4]благодаря ви. Пробвах и някаква функция Hartley(), ефектът е почти същият. между другото, с пауза в плейъра и пълна тишина, всички нива бързо подскачат и радостно подскачат :) Ще мисля как да ги убия.
засега се оказа такова нещо: http://an-files.narod.ru/_image/freq_mon.GIF (55kb) когато се появят високи честоти, всичко се покрива с "шум".
За да се намали феноменът на Гибс, входните данни трябва да бъдат обработени от една от прозоречните функции: Hening, Hann, Gauss, Papoulis, Lanczos и др.
>басът е усилен твърде много Не съм сигурен, че разбирам за какво се отнася това, но ако става въпрос за мощността на спектъра, тогава използвайте логаритмичната честотна скала, т.е. да речем, когато избирате честотни ленти, не ги правете с еднаква ширина, но с еднакво съотношение на горната и долната граница, например: 31..63 63..125 125..250 250..500 и т.н.
Е, да, логаритмичната скала трябва да се използва (или да се доведе до нея). от примери за bass.dll:
тип TFFTData = масив [0..512] от Single; TBandOut = масив [0..25-1] от дума;
procedure TBASSPlayer.TimerFFTTimer(Sender: TObject); const // Класифицирайте FFTData[x] по броя на необходимите ленти за визуализация на спектъра. // FreqCoef дефинира последния индексен номер на FFTData[x] за всяка лента. FreqCoef: масив[0..NumFFTBands - 1] от дума = ( 1, 2, 3, 6, // тесенинтервал за ниска честота. обхват 12, 18, 24, 30, 36, // нормален интервал за средна честота обхват 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 120, 132, 156, 180 ); // широк интервал за висока честота. диапазон
// Ако честотата на дискретизация е (стандартна) 44100Hz, тогава честотата на FFTData[x] // е 44100 / 512 * x, така че представителната (или максималната) честота на всяка // лента е както следва // BandOut[0] : 86.1Hz BandOut[1] : 172.3Hz BandOut[2] : 344.5Hz / / BandOut[3] : 516.8Hz BandOut[4] : 1033.6Hz BandOut[5] : 1550.4Hz // . . . (516,8Hz интервал до BandOut[20]) . . BandOut[20] : 9302.2Hz // BandOut[21] : 10336Hz BandOut[22] : 11370Hz BandOut[23] : 13437Hz // BandOut[24] : 15503Hz . . много висок честотен диапазон е изключен
Усилване = 0,15; // Фактор за усилване на високочестотните ленти Scale = 80; // Фактор за калибриране на изходния обхват на BandOut[x] // (приблизително от 0 до 24). var FFTData : TFFTData; NewBandOut : TBandOut; Начален индекс: цяло число; i, k : цяло число; tmpIntensity: двойно;
begin //тут трябва FFTData да запълни, удалил го. //Тут беше запълнен със самия Басъм.
for i := 0 to (NumFFTBands - 1) do begin if i = 0 then StartIndex := 1 else StartIndex := FreqCoef[i-1] + 1;
tmpIntensity := 0; за k := StartIndex към FreqCoef[i] направете ако FFTData[k] > tmpIntensity след това tmpIntensity := FFTData[k];
NewBandOut[i] := round(tmpIntensity * (1 + i * Boost) * Scale);
ако NewBandOut[i] > BandOut[i] then BandOut[i] := NewBandOut[i] else if BandOut[i] >= 2 then dec(BandOut[i], 2) else BandOut[i] := 0;
ако NewBandOut[i] > BandOut[i] след това BandOut[i] := NewBandOut[i]; край; край; тут от масива 25 столбикасъкращения (за граждански графичен еквалайзер), BandOut - "изход" и публично описан (или две "n"?). коригирайте множителя (Мащаб) и правоъгълниците отскачат по-равномерно :) въпреки че изневерих, не използвах данните от самото начало, иначе разликата в краищата не е с порядъци - повече. Накратко, изрязах го от центъра, нямам нужда от голяма точност, но там са по-равномерни :)
(като цяло се получи някакъв занаят, добре, добре, поне срещнах :))
>и след това в краищата разликата не е от порядъци относно ефектите на краищата - вижте [7]
Добър ден Мога ли да имам няколко въпроса по същата тема? Първият въпрос е какъв е честотният сигнал във всеки елемент от масива, когато се използва FFT (по-специално в Bass.dll)? По-горе (вижте публикация #9) се казва: // Ако честотата на дискретизация е (стандартна) 44100Hz, тогава честотата на FFTData[x] // е 44100 / 512 * x, така че представителната (или максимална) честота на всяка // лента е следната, BandOut[0] : 86,1Hz ……… Но в помощта за Bass.dll за BASS_C функция hannelGetData е написано следното: BASS_DATA_FFT512 (512 примерни FFT (връща 256 стойности с плаваща запетая)), т.е., както разбирам, чрез задаване на 512 проби получаваме 256 FFT стойности. Съответно средната честота на всеки диапазон ще бъде два пъти по-голяма? Или не е? И вторият въпрос - ако не греша - всеки елемент от масива съдържа ли амплитудата на сигнал с определена честота? (първият елемент от масива е нулевата честота, вторият елемент е например честотата от 86,1 Hz и т.н.) (изглежда така трябва да бъде логично, когато се използва трансформацията на Фурие)? Но как тогава да разберете амплитудата на сигнала, например с честота 40 Hz? Може би някой има интересни препратки към литературата за трансформациите на Фурие и по-специално за FFT?
MypaBeu (20.06.06 9:52) [14]в помощ на басасе казва, че минималната честота е 80Hz (и за двата еквалайзера)
А можеш ли да разбереш по-точно - къде го пише това в хелпа? И още нещо - все пак при извикване на BASS_ChannelGetData не се внедрява еквалайзер, а може да се каже спектрален анализатор.
MypaBeu (22.06.06 12:34) [16]
Еквалайзер чрез DFT: директен PF - регулатор на усилването - обратен PF
MypaBeu (6/22/06 12:34 pm) [16]хм, прочетох това в BASS_FXPARAMEQ: typedef struct float fCenter; float fBandwidth; float fGain; > BASS_FXPARAMEQ;
Members fCenter Централна честота, в херци, в диапазона от 80 до 16000. Тази стойност не може да надвишава една трета от честотата на канала. fBandwidth Ширина на честотната лента, в полутонове, в диапазона от 1 до 36. fGain Gain, в диапазона от -15 до 15.
подобно предложение (е, по-късно го видях в някакъв форум), че както за графичния, така и за аудио еквалайзера поне 80.