
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.52] |
![]() |
|
Сообщ.
#1
,
|
|
|
У меня возникла следующая трабла:
Решил поработать со звуком, но когда юзаю БПФ, то спектр у меня получается симетричный ![]() Что я делаю не так? ![]() ![]() unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, MMSystem, TeeProcs, TeEngine, Chart, Series, ap, fft; const freq=44100; BufSize=2048; Xgraph=512; Ygraph=100; type TData16 = array [0..BufSize-1] of smallint; PData16 = ^TData16; TPointArr = array [0..BufSize-1] of TPoint; PPointArr = ^TPointArr; TForm1 = class(TForm) Button1: TButton; Button2: TButton; PaintBox1: TPaintBox; Chart1: TChart; Chart2: TChart; Series2: TBarSeries; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public procedure OnWaveIn(var Msg: TMessage); message MM_WIM_DATA; end; var Form1: TForm1; series1, series2 : tlineSeries; coef: array of integer; a,b: TReal1DArray; implementation {$R *.DFM} var WaveIn: hWaveIn; hBuf: THandle; BufHead: TWaveHdr; p: PPointArr; stop: boolean = false; comp:complex; function modul(const comp:complex):double; begin result:=sqrt(sqr(comp.x)+sqr(comp.y)); end; procedure TForm1.Button1Click(Sender: TObject); var header: TWaveFormatEx; BufLen: word; buf: pointer; begin with header do begin wFormatTag := WAVE_FORMAT_PCM; nChannels := 2; { количество каналов } nSamplesPerSec := freq; { частота } wBitsPerSample := 16; { 8 / 16 бит } nBlockAlign := nChannels * (wBitsPerSample div 8); nAvgBytesPerSec := nSamplesPerSec * nBlockAlign; cbSize := 0; end; WaveInOpen(Addr(WaveIn), WAVE_MAPPER, addr(header), Form1.Handle, 0, CALLBACK_WINDOW); BufLen := header.nBlockAlign * BufSize; hBuf := GlobalAlloc(GMEM_MOVEABLE and GMEM_SHARE, BufLen); Buf := GlobalLock(hBuf); with BufHead do begin lpData := Buf; dwBufferLength := BufLen; dwFlags := WHDR_BEGINLOOP; end; WaveInPrepareHeader(WaveIn, Addr(BufHead), sizeof(BufHead)); WaveInAddBuffer(WaveIn, addr(BufHead), sizeof(BufHead)); GetMem(p, BufSize * sizeof(TPoint)); stop := true; WaveInStart(WaveIn); end; procedure TForm1.Button2Click(Sender: TObject); begin if stop = false then Exit; stop := false; while not stop do Application.ProcessMessages; stop := false; WaveInReset(WaveIn); WaveInUnPrepareHeader(WaveIn, addr(BufHead), sizeof(BufHead)); WaveInClose(WaveIn); GlobalUnlock(hBuf); GlobalFree(hBuf); FreeMem(p, BufSize * sizeof(TPoint)); end; procedure TForm1.OnWaveIn; var i,j: integer; data16: PData16; XScale, YScale: single; begin XScale := Xgraph / BufSize; data16 := PData16(PWaveHdr(Msg.lParam)^.lpData); YScale := Ygraph / (1 shl 16); series1.Clear; for i := 0 to BufSize-1 do begin p^[i] := Point(round(i * XScale), round(Ygraph / 2 - data16^[i] * YScale)); series1.AddXY(round(i * XScale), round(Ygraph / 2 - data16^[i] * YScale)); a[2*i]:=round(Ygraph / 2 - data16^[i] * YScale); a[2*i+1]:=0; end; FastFourierTransform(a, BufSize, false); series2.clear; for j :=1 to BufSize-1 do begin // comp.X:= a[2*j]; // comp.Y:=a[2*j+1]; b[j]:=sqrt(a[2*j]*a[2*j]+a[2*j+1]*a[2*j+1]); series2.AddXY(coef[j],b[j]); end; with PaintBox1.Canvas do begin Brush.Color := clWhite; FillRect(ClipRect); Polyline(Slice(p^, BufSize)); end; if stop then WaveInAddBuffer(WaveIn, PWaveHdr(Msg.lParam), SizeOf(TWaveHdr)) else stop := true; end; procedure TForm1.FormDestroy(Sender: TObject); begin Button2.Click; Finalize(a); Finalize(b); Finalize(coef); end; procedure TForm1.FormCreate(Sender: TObject); var i: integer; XScale: single; begin series1 := tlineSeries.Create(nil); series1.ParentChart := Chart1; series1.Clear; setlength(a,2*BufSize); setlength(b,BufSize); setlength(coef,BufSize); XScale := Xgraph / BufSize; for I := 0 to BufSize-1 do coef[i]:=round(i * XScale); Button1.Caption := 'Start'; Button2.Caption := 'Stop'; end; end. Добавлено Сигнал беру с микрофона! |
Сообщ.
#2
,
|
|
|
Вот екзешник:
Прикреплённый файл ![]() |
Сообщ.
#3
,
|
|
|
Вообще-то так и должно быть.
|
Сообщ.
#4
,
|
|
|
Цитата andriano @ Вообще-то так и должно быть. Тада у меня вопрос. Неужто БПФ возвращает спектр в таком виде: 5г, 10г, 15г, ... 10кг, 15кг, 15кг, 10кг, ...15г, 10г, 5г??? (числа проставил условно) З.Ы. Изначально у меня все выходило норм(в моем понимании нормально), но потом я начал экспериментировать с размером буфера, количеством каналов, частотой... и стало так как есть сейчас. Вернуть как было у меня не получается ![]() |
Сообщ.
#5
,
|
|
|
Цитата Тада у меня вопрос. Неужто БПФ возвращает спектр в таком виде: 5г, 10г, 15г, ... 10кг, 15кг, 15кг, 10кг, ...15г, 10г, 5г??? (числа проставил условно) Такое у него, у БПФ, свойство. |
Сообщ.
#6
,
|
|
|
Комплексный БПФ он и есть симметричный. Отруби ненужную часть арифметически и получишь то что нужно. И еще, чей то на спектре нулевая частота разлезлась по краям спектра (т.е. симметрия наоборот, собственно математически они так и выглядят), но думаю и это организовать можно, перенеся выборку N/2...2*N-1 после БПФ в начало графика, а 0...N/2-1 за ней.
|
Сообщ.
#7
,
|
|
|
Цитата ХЭМ @ Комплексный БПФ он и есть симметричный. Отруби ненужную часть арифметически и получишь то что нужно. И еще, чей то на спектре нулевая частота разлезлась по краям спектра (т.е. симметрия наоборот, собственно математически они так и выглядят), но думаю и это организовать можно, перенеся выборку N/2...2*N-1 после БПФ в начало графика, а 0...N/2-1 за ней. Как я понял то выборка 0..N/2 - это и есть мой искомый спектр. Я просто игнорирую вторую часть масива который вернул FFT. З.Ы. Если все верно, то что нам даст если мы перенесем выборку N/2...2*N-1 после БПФ в начало графика, а 0...N/2-1 будет за ней? |
Сообщ.
#8
,
|
|
|
BFenix
Мы получим частоты в виде -N/2-1,...,-3,-2,-1,0,1,2,3,..., N/2-1 Отрицательная чатота тоже чатсота. Если взять цекличискую частоту то знак просто определяет направленияе вращения по частовой стрелки или против. Просто если переставить то так лучши смотриться. 0 Начало отсчета находиться по середине. Аналогично если перед прообразованием домножить на (-1)^i i- номер отсчета, то получим аналогичную перестановку. Свойства дублирования чатот можно использовать для двух вещей. Первое это убрать мнимые части внутрь массива, сэкономить место. И тем самым еще и ускорить. Тогда имея массив отсчетов их действительные части мы можем сразу получить упаковонное представление преобразования в этом же массиве. В виде Re0, Re(N/2-), Re1,Im1, Re2,Im2 Подробнее читай про реальное преобразование фурье. На этом сайте в алгоритмах. Или же загнать сразу два сигнала в один массив и использовать одино преобразования для двух сигналов. |
Сообщ.
#9
,
|
|
|
BFenix,
точнее: -15000,-14995,-14990,...-10б-5,0,5,10,15,...14990,14995,15000, т.к. ширины всех полос одинаковы. И желательно не отбрасывать "лшние" отсчеты, а посчитать модуль. |
Сообщ.
#10
,
|
|
|
Цитата andriano @ BFenix, точнее: -15000,-14995,-14990,...-10б-5,0,5,10,15,...14990,14995,15000, т.к. ширины всех полос одинаковы. И желательно не отбрасывать "лшние" отсчеты, а посчитать модуль. У меня задача состоит вот в чем: мне надо слушать работу преса(большой прес который давит ДСП). Прес не правильно настроен и потому останавливается с ударом. Я должен услышать этот удар и сказать, что удар точно был(возможно сравнение с предыдущими ударами по силе). Как я понимаю, то мне надо смотреть спектр и фиксировать всплески. После первого цикла я зафиксирую частоту на которой всплеск при ударе и дальше буду смотреть только некий диапазон спектра. Сигнал буду брать не с микрофона, а с пьезоэлемента. З.Ы. Подскажите моя задумка правильная или я чтото упустил? |
Сообщ.
#11
,
|
|
|
Цитата Мы получим частоты в виде -N/2-1,...,-3,-2,-1,0,1,2,3,..., N/2-1 Получается всего N-1 значений вместо N. Вроде частоты после БПФ(комплексного)получаются в виде: 0,1,2,3,...N/2-1, -N/2,-N/2-1,...-3,-2,-1. Или я совсем неправ? -Added Цитата BFenix @ Цитата andriano @ BFenix, точнее: -15000,-14995,-14990,...-10б-5,0,5,10,15,...14990,14995,15000, т.к. ширины всех полос одинаковы. И желательно не отбрасывать "лшние" отсчеты, а посчитать модуль. У меня задача состоит вот в чем: мне надо слушать работу преса(большой прес который давит ДСП). Прес не правильно настроен и потому останавливается с ударом. Я должен услышать этот удар и сказать, что удар точно был(возможно сравнение с предыдущими ударами по силе). Как я понимаю, то мне надо смотреть спектр и фиксировать всплески. После первого цикла я зафиксирую частоту на которой всплеск при ударе и дальше буду смотреть только некий диапазон спектра. Сигнал буду брать не с микрофона, а с пьезоэлемента. З.Ы. Подскажите моя задумка правильная или я чтото упустил? Имхо, конечно. Насчёт пьезо. Для него схему придётся собирать. И калибровать как-то нужно. А крепить как.... Может, поискать готовый датчик? И вот ещё, может быть эта страничка будет вам интересна. |
Сообщ.
#12
,
|
|
|
Цитата Prince @ Цитата Вроде частоты после БПФ(комплексного)получаются в виде: 0,1,2,3,...N/2-1, -N/2,-N/2-1,...-3,-2,-1. Или я совсем неправ? Именно так частоты и идут. Сенк статья оч полезная. -Added Цитата Prince @ Имхо, конечно. Насчёт пьезо. Для него схему придётся собирать. И калибровать как-то нужно. А крепить как.... Может, поискать готовый датчик? Ну прикрепить - это не большая трабла, особо заморачиваться с калибровкой не нужно(мне точные численые значения не нужны, мне нужно видеть сам факт - будет всплеск или нет). |
Сообщ.
#13
,
|
|
|
Prince
Ты 0 забыл посчитать. И читай внимательнее это уже после перестановки. Хотя это моя вина, в том что не уточнил что это ответ на вопрос о перестановки. BFenix Цитата BFenix @ Подскажите моя задумка правильная или я чтото упустил? Нужен вибро датчик. Теории для БПФ есть, найти легко. А вот для вайвлетов надо искать и не факт что есть в данной облости. Но помойму удары лучши какраз на вайвлетах изучать. Почему? Интуция. |
Сообщ.
#14
,
|
|
|
Цитата Ты 0 забыл посчитать. Ну давай вместе посчитаем(для твоего варианта):-N/2-1,...,-3,-2,-1,0,1,2,3,..., N/2-1. Есть две последовательности: -1...-N/2-1 и 1...N/2-1 , которые дают нам N-2 элементов. И плюс ещё 0. Итого: N-1 элементов. Цитата с калибровкой не нужно(мне точные численые значения не нужны, мне нужно видеть сам факт - будет всплеск или нет). Схему-то всё равно придётся клепать для пьезодатчика. Не к микрофонному же усилителю звуковушки его подключать. |
Сообщ.
#15
,
|
|
|
Цитата Prince @ Схему-то всё равно придётся клепать для пьезодатчика. Не к микрофонному же усилителю звуковушки его подключать. а почему не к микрофонному? Мона канеша на сом порт подцепить, но не факт, что это будет лучше. |
Сообщ.
#16
,
|
|
|
Потому что его нужно согласовывать с микрофонным входом. Если напрямую подключить, гудеть будет очень сильно(если вообще будет работать): все наводки 50 Гц будут ваши. Кроме того, не уверен, что усиления хватит. Так мне кажется. На глазок.
|
Сообщ.
#17
,
|
|
|
Пьезодатчик с микрофонным входом - это, конечно, круто.
По идее, можно было бы одключить к линейному - амплитуда сигнала как раз подходящая. Но если не хватит входного сопротивления, нужно будет добавить повторитель на полевике. В ринципе, можно попытаться подключить и к микрофонному, зашунтировав резистором на несколько ком, но это будет ФВЧ. Кстати, из описания вообще непонятно, зачем нужен Фурье, когда, судя по всему, достаточно амплитудного детектора. |
Сообщ.
#18
,
|
|
|
Цитата andriano @ Кстати, из описания вообще непонятно, зачем нужен Фурье, когда, судя по всему, достаточно амплитудного детектора. Поковырявшись с теорией я решил сделать следующее: Я беру сигнал и раскладываю по Фурье и прогоняю первый цикл преса. Смотрю в каких диапазонах частот идут всплески. Выделяю эти диапазоны +- 500герц и для этих диапазонов (1 кГц) высчитываю СКЗ (среднеквадратичное значение). Кидаю эти значения на график. В итоге получаю график на котором будет видно относительные величины всплесков. Этот график должен мне показывать правильно ли я меняю настройки преса(всплески будут либо увеличиваться либо уменьшаться). |
Сообщ.
#19
,
|
|
|
Не боишься, что у тебя будут пики на собственных частотах пьезодатчика, а не на максимумах спектра звука, создаваемого прессом?
И, кстати, основываясь на каких критериях, ты будешь оценивать равильность настройки? |
Сообщ.
#20
,
|
|
|
У меня появился еще вопросик ответ на который я пока не нашел:
Как управлять чувствительностью микрофона? |
Сообщ.
#21
,
|
|
|
Встречный вопрос: какого именно микрофона?
ДЛя конденсаторного - изменять приложенное напряжение. Для динамического - никак. |
Сообщ.
#22
,
|
|
|
Цитата andriano @ Встречный вопрос: какого именно микрофона? ДЛя конденсаторного - изменять приложенное напряжение. Для динамического - никак. С пьезоелементом разобрался. На прямую подключил его на вход звуковой карты и все чудно работает. Минус - он не слышит низкие частоты(до 2кГц), но это его свойство. Плюс - хорошо слышит высокие частоты. Кто-нить знает почему встроеные звуковухи не слышут частоты выше 6,5 кГц?(на 3 компах тестил) Поставил звуковуху Креатив и проблема отпала(22кГц слышит отлично, выше не тестил) |
Сообщ.
#23
,
|
|
|
Цитата BFenix @ С пьезоелементом разобрался. На прямую подключил его на вход звуковой карты и все чудно работает. Минус - он не слышит низкие частоты(до 2кГц), но это его свойство. Плюс - хорошо слышит высокие частоты. Кто-нить знает почему встроеные звуковухи не слышут частоты выше 6,5 кГц?(на 3 компах тестил) Поставил звуковуху Креатив и проблема отпала(22кГц слышит отлично, выше не тестил) 1. Скорее, свойство пьезоэлемента - это высокое выходное сопротивление, зависящее от частоты. Впервом приближении пьезоэлемент - это конденсатор. Так что отсутствие нижних частот - это не свойство пьезоэлемента, а, скорее, свойство низкоомного входного каскада, который совместно с пьезоэлементом работает как ФВЧ. 2. Мне лично кажется странным, как они вообще могут писать звук. Встроенная звуковуха поддерживает режим записи чисто номинально, - как правило, для чего-нибудь типа IP-телефонии, т.е. там, где диапазон частот ограничен 3.5 кГц, а величина нелинейных искажений несущественна. Так что для записи можно использовать ТОЛЬКО отдельную звуковую карту. Кстати, вполне вероятно, что из-за экономии (АЦП - существенно более ресурсоемкий процесс чем ЦАП) звук пишется только на 11 кГц, а все остальное программно интерполируется. |
Сообщ.
#24
,
|
|
|
Микрофоном ниразу не мерял вибрацию, а датчиками вибрации работал.
Удары лучше фиксировать по виброускорению, всплеск идёт на высоких частотах. Мы используем акселерометры, т.е. они сразу меряют ускорение. Насколько я понимаю, микрофон измеряет виброперемещение. После одинарного интегрирования на виброскорости удары хуже видны. После второго интегрирования и получения виброперемещения удар вообще еле заметен. Можно попробовать дважды продифференцировать сигнал с микрофона, чтобы получить ускорение. Если интересно, могу показать разницу в спектрах. |
Сообщ.
#25
,
|
|
|
Цитата Kekek @ Если интересно, могу показать разницу в спектрах. Не просто интересно, а необходимо! ЗЫ Заранее сенк! |
Сообщ.
#26
,
|
|
|
Скинь пожалуйста в форум то что получилось в итоге
![]() |
Сообщ.
#27
,
|
|
|
Цитата vmihaylov @ Скинь пожалуйста в форум то что получилось в итоге ![]() Все еще в процесе! Када приведу все к норм состоянию, то выложу! |
Сообщ.
#28
,
|
|
|
Это лёгкий удар шариковой ручкой по датчику вибрации.
Ускорение Скорость Перемещение Датчик держал в руках, на тринадцати герцах дрожание рук от удара шариковой ручкой по датчику. |
Сообщ.
#29
,
|
|
|
BFenix можете прислать исходник кода на почту, пожалуйста. просто копируя код с первой страницы, выдает ошибку, жалуется почему-то на массив a
![]() |
Сообщ.
#30
,
|
|
|
Пришлось на некоторое время забыть про этот проект, но ща буду браться заново:
вот то что есть на данный момент: ехе + исходник |
Сообщ.
#31
,
|
|
|
Люди плиз дайте ссілку на компонент Rz то что в проге юзается
Плиз оч надо Ищу не могу найти ![]() |
Сообщ.
#32
,
|
|
|
Цитата Kekek @ Микрофоном ниразу не мерял вибрацию, а датчиками вибрации работал. Удары лучше фиксировать по виброускорению, всплеск идёт на высоких частотах. Мы используем акселерометры, т.е. они сразу меряют ускорение. Насколько я понимаю, микрофон измеряет виброперемещение. После одинарного интегрирования на виброскорости удары хуже видны. После второго интегрирования и получения виброперемещения удар вообще еле заметен. Можно попробовать дважды продифференцировать сигнал с микрофона, чтобы получить ускорение. Если интересно, могу показать разницу в спектрах. Ерунду я написал. Микрофон пишет тоже виброускорение. Вывел записанный с датчика вибрации сигнал виброускорения на звуковую плату. Звук очень похожим получается. |
Сообщ.
#33
,
|
|
|
блин ссылка на исходник не работает,перезалейте пожалуйста.
|