На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела "Программирование звука"
0) Данный раздел предназначен для обсуждения проблем, возникающих при программировании задач, связанных с записью, обработкой, воспроизведением звука. Перед созданием темы подумайте, не будет ли она уместнее в разделах Разработка и тестирование программ, Наши исходники, а особенно Разовые заказы и подработки
1) На Раздел распространяются все Правила форума.Огромная просьба с ними внимательно ознакомиться.
2) Запрещается давать бессмысленные ответы вроде: "Снеси Мастдай", "ХП рулит", "Поставь Линукс" и т.д.
3) Запрещается создавать темы, в которых Вы намереваетесь получить ссылку на кряки, серийники и т.п. Также запрещено любое обсуждение p2p (peer-to-peer) сетей (BitTorrent, eDonkey и т.д.).
4) Реклама всякого рода пресекается беспощадно.
5) Используйте тэг [CODE] для выделения кода программы (непременно с указанием языка программирования - выбрать из списка. В противном случае бессмысленно!). Уважайте тех, кто будет читать ваш код!
6) Если решение вашей проблемы найдено, то не забываем помечать тему специальной функцией "Вопрос решён". Вам всего лишь требуется при написании последнего ответа поставить одну единственную галочку прямо над формой ответа.
7) Если вы хотите получить совет для конкретной платформы/языка программирования, обязательно укажите их в вопросе

8) Если не прикрепляются/не скачиваются файлы, читаем Не прикрепляется / не скачивается файл. Любые обсуждения в данном разделе проблем с приложением файлов считаются оффтопиком! Со всеми вытекающими.

9) NEW! Уважаемые новички! Мы приветствуем Ваше желание научить всех посетителей раздела правильному программированию. Но огромная просьба, перед тем, как писать поучения в старых (последний ответ - "старее" месяца, а особенно, если вопрошавший не появляется на форуме уже не первый месяц, в чем можно убедиться в его профиле) темах, хорошо подумать, будет ли кому-нибудь, кроме Вас cамих, это интересно. Попытки накрутки количества тематических сообщений за счёт поднятия древних неактуальных тем ("некрофилия") будут наказываться по велению левой пятки модераторского состава (см. пп.12, 13 Правил)



Нарушение Правил может повлечь наказание со стороны модераторов.



user posted imageFAQ Раздела user posted imageПоиск в Разделе user posted imageMSDN Library Online | Ваше мнение о модераторах: user posted imageBarazuk user posted imageRikkie
Закрыто Rikkie 21-01-2010: некрофилия

Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Проблема со спектром, Симметричный спектр
    У меня возникла следующая трабла:
    Решил поработать со звуком, но когда юзаю БПФ, то спектр у меня получается симетричный :(. Не могу понять с чем это связано.
    Что я делаю не так?


    ExpandedWrap disabled
      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.


    Добавлено
    Сигнал беру с микрофона!
    Сообщение отредактировано: BFenix -
      Вот екзешник:
      Прикреплённый файлПрикреплённый файлProject1.rar (307.54 Кбайт, скачиваний: 406)
        Вообще-то так и должно быть.
          Цитата andriano @
          Вообще-то так и должно быть.

          Тада у меня вопрос. Неужто БПФ возвращает спектр в таком виде: 5г, 10г, 15г, ... 10кг, 15кг, 15кг, 10кг, ...15г, 10г, 5г??? (числа проставил условно)
          З.Ы. Изначально у меня все выходило норм(в моем понимании нормально), но потом я начал экспериментировать с размером буфера, количеством каналов, частотой... и стало так как есть сейчас. Вернуть как было у меня не получается :(
            Цитата
            Тада у меня вопрос. Неужто БПФ возвращает спектр в таком виде: 5г, 10г, 15г, ... 10кг, 15кг, 15кг, 10кг, ...15г, 10г, 5г??? (числа проставил условно)

            Такое у него, у БПФ, свойство.
            Сообщение отредактировано: Prince -
            Человек человека понять не может.
              Комплексный БПФ он и есть симметричный. Отруби ненужную часть арифметически и получишь то что нужно. И еще, чей то на спектре нулевая частота разлезлась по краям спектра (т.е. симметрия наоборот, собственно математически они так и выглядят), но думаю и это организовать можно, перенеся выборку N/2...2*N-1 после БПФ в начало графика, а 0...N/2-1 за ней.
                Цитата ХЭМ @
                Комплексный БПФ он и есть симметричный. Отруби ненужную часть арифметически и получишь то что нужно. И еще, чей то на спектре нулевая частота разлезлась по краям спектра (т.е. симметрия наоборот, собственно математически они так и выглядят), но думаю и это организовать можно, перенеся выборку N/2...2*N-1 после БПФ в начало графика, а 0...N/2-1 за ней.

                Как я понял то выборка 0..N/2 - это и есть мой искомый спектр. Я просто игнорирую вторую часть масива который вернул FFT.

                З.Ы. Если все верно, то что нам даст если мы перенесем выборку N/2...2*N-1 после БПФ в начало графика, а 0...N/2-1 будет за ней?
                  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 Подробнее читай про реальное преобразование фурье. На этом сайте в алгоритмах.

                  Или же загнать сразу два сигнала в один массив и использовать одино преобразования для двух сигналов.
                  Сообщение отредактировано: Pavia -
                  Правильный обед должен состоять из 5 блюд приготовленных из 33 ингредиентов.
                    BFenix,
                    точнее: -15000,-14995,-14990,...-10б-5,0,5,10,15,...14990,14995,15000, т.к. ширины всех полос одинаковы.
                    И желательно не отбрасывать "лшние" отсчеты, а посчитать модуль.
                      Цитата andriano @
                      BFenix,
                      точнее: -15000,-14995,-14990,...-10б-5,0,5,10,15,...14990,14995,15000, т.к. ширины всех полос одинаковы.
                      И желательно не отбрасывать "лшние" отсчеты, а посчитать модуль.

                      У меня задача состоит вот в чем: мне надо слушать работу преса(большой прес который давит ДСП). Прес не правильно настроен и потому останавливается с ударом. Я должен услышать этот удар и сказать, что удар точно был(возможно сравнение с предыдущими ударами по силе).

                      Как я понимаю, то мне надо смотреть спектр и фиксировать всплески.
                      После первого цикла я зафиксирую частоту на которой всплеск при ударе и дальше буду смотреть только некий диапазон спектра.
                      Сигнал буду брать не с микрофона, а с пьезоэлемента.


                      З.Ы. Подскажите моя задумка правильная или я чтото упустил?
                        Цитата
                        Мы получим частоты в виде
                        -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, т.к. ширины всех полос одинаковы.
                        И желательно не отбрасывать "лшние" отсчеты, а посчитать модуль.

                        У меня задача состоит вот в чем: мне надо слушать работу преса(большой прес который давит ДСП). Прес не правильно настроен и потому останавливается с ударом. Я должен услышать этот удар и сказать, что удар точно был(возможно сравнение с предыдущими ударами по силе).

                        Как я понимаю, то мне надо смотреть спектр и фиксировать всплески.
                        После первого цикла я зафиксирую частоту на которой всплеск при ударе и дальше буду смотреть только некий диапазон спектра.
                        Сигнал буду брать не с микрофона, а с пьезоэлемента.


                        З.Ы. Подскажите моя задумка правильная или я чтото упустил?

                        Имхо, конечно. Насчёт пьезо. Для него схему придётся собирать. И калибровать как-то нужно. А крепить как.... Может, поискать готовый датчик?
                        И вот ещё, может быть эта страничка будет вам интересна.
                        Сообщение отредактировано: Prince -
                        Человек человека понять не может.
                          Цитата Prince @
                          Цитата

                          Вроде частоты после БПФ(комплексного)получаются в виде:
                          0,1,2,3,...N/2-1, -N/2,-N/2-1,...-3,-2,-1.
                          Или я совсем неправ?

                          Именно так частоты и идут.

                          Сенк статья оч полезная.

                          -Added
                          Цитата Prince @
                          Имхо, конечно. Насчёт пьезо. Для него схему придётся собирать. И калибровать как-то нужно. А крепить как.... Может, поискать готовый датчик?

                          Ну прикрепить - это не большая трабла, особо заморачиваться с калибровкой не нужно(мне точные численые значения не нужны, мне нужно видеть сам факт - будет всплеск или нет).
                            Prince
                            Ты 0 забыл посчитать. И читай внимательнее это уже после перестановки. Хотя это моя вина, в том что не уточнил что это ответ на вопрос о перестановки.

                            BFenix
                            Цитата BFenix @
                            Подскажите моя задумка правильная или я чтото упустил?

                            Нужен вибро датчик.

                            Теории для БПФ есть, найти легко. А вот для вайвлетов надо искать и не факт что есть в данной облости.
                            Но помойму удары лучши какраз на вайвлетах изучать. Почему? Интуция.
                            Сообщение отредактировано: Pavia -
                            Правильный обед должен состоять из 5 блюд приготовленных из 33 ингредиентов.
                              Цитата
                              Ты 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 элементов.


                              Цитата
                              с калибровкой не нужно(мне точные численые значения не нужны, мне нужно видеть сам факт - будет всплеск или нет).

                              Схему-то всё равно придётся клепать для пьезодатчика. Не к микрофонному же усилителю звуковушки его подключать.
                              Сообщение отредактировано: Prince -
                              Человек человека понять не может.
                                Цитата Prince @
                                Схему-то всё равно придётся клепать для пьезодатчика. Не к микрофонному же усилителю звуковушки его подключать.

                                а почему не к микрофонному?

                                Мона канеша на сом порт подцепить, но не факт, что это будет лучше.
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все
                                Закрыто Rikkie 21-01-2010: некрофилия



                                Рейтинг@Mail.ru
                                [ Script Execution time: 0,1634 ]   [ 14 queries used ]   [ Generated: 16.12.19, 11:06 GMT ]