На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА 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: некрофилия
  
> Проблема со спектром , Симметричный спектр
    У меня возникла следующая трабла:
    Решил поработать со звуком, но когда юзаю БПФ, то спектр у меня получается симетричный :(. Не могу понять с чем это связано.
    Что я делаю не так?


    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 Кбайт, скачиваний: 501)
        Вообще-то так и должно быть.
          Цитата 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 -
                    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 -
                              Цитата
                              Ты 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 @
                                Схему-то всё равно придётся клепать для пьезодатчика. Не к микрофонному же усилителю звуковушки его подключать.

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

                                Мона канеша на сом порт подцепить, но не факт, что это будет лучше.
                                  Потому что его нужно согласовывать с микрофонным входом. Если напрямую подключить, гудеть будет очень сильно(если вообще будет работать): все наводки 50 Гц будут ваши. Кроме того, не уверен, что усиления хватит. Так мне кажется. На глазок.
                                    Пьезодатчик с микрофонным входом - это, конечно, круто.
                                    По идее, можно было бы одключить к линейному - амплитуда сигнала как раз подходящая. Но если не хватит входного сопротивления, нужно будет добавить повторитель на полевике.
                                    В ринципе, можно попытаться подключить и к микрофонному, зашунтировав резистором на несколько ком, но это будет ФВЧ.

                                    Кстати, из описания вообще непонятно, зачем нужен Фурье, когда, судя по всему, достаточно амплитудного детектора.
                                    Сообщение отредактировано: andriano -
                                      Цитата andriano @
                                      Кстати, из описания вообще непонятно, зачем нужен Фурье, когда, судя по всему, достаточно амплитудного детектора.

                                      Поковырявшись с теорией я решил сделать следующее:

                                      Я беру сигнал и раскладываю по Фурье и прогоняю первый цикл преса. Смотрю в каких диапазонах частот идут всплески. Выделяю эти диапазоны +- 500герц и для этих диапазонов (1 кГц) высчитываю СКЗ (среднеквадратичное значение). Кидаю эти значения на график. В итоге получаю график на котором будет видно относительные величины всплесков. Этот график должен мне показывать правильно ли я меняю настройки преса(всплески будут либо увеличиваться либо уменьшаться).
                                        Не боишься, что у тебя будут пики на собственных частотах пьезодатчика, а не на максимумах спектра звука, создаваемого прессом?

                                        И, кстати, основываясь на каких критериях, ты будешь оценивать равильность настройки?
                                          У меня появился еще вопросик ответ на который я пока не нашел:
                                          Как управлять чувствительностью микрофона?
                                            Встречный вопрос: какого именно микрофона?
                                            ДЛя конденсаторного - изменять приложенное напряжение. Для динамического - никак.
                                              Цитата andriano @
                                              Встречный вопрос: какого именно микрофона?
                                              ДЛя конденсаторного - изменять приложенное напряжение. Для динамического - никак.

                                              С пьезоелементом разобрался. На прямую подключил его на вход звуковой карты и все чудно работает. Минус - он не слышит низкие частоты(до 2кГц), но это его свойство. Плюс - хорошо слышит высокие частоты.
                                              Кто-нить знает почему встроеные звуковухи не слышут частоты выше 6,5 кГц?(на 3 компах тестил) Поставил звуковуху Креатив и проблема отпала(22кГц слышит отлично, выше не тестил)
                                                Цитата BFenix @
                                                С пьезоелементом разобрался. На прямую подключил его на вход звуковой карты и все чудно работает. Минус - он не слышит низкие частоты(до 2кГц), но это его свойство. Плюс - хорошо слышит высокие частоты.
                                                Кто-нить знает почему встроеные звуковухи не слышут частоты выше 6,5 кГц?(на 3 компах тестил) Поставил звуковуху Креатив и проблема отпала(22кГц слышит отлично, выше не тестил)

                                                1. Скорее, свойство пьезоэлемента - это высокое выходное сопротивление, зависящее от частоты. Впервом приближении пьезоэлемент - это конденсатор. Так что отсутствие нижних частот - это не свойство пьезоэлемента, а, скорее, свойство низкоомного входного каскада, который совместно с пьезоэлементом работает как ФВЧ.
                                                2. Мне лично кажется странным, как они вообще могут писать звук. Встроенная звуковуха поддерживает режим записи чисто номинально, - как правило, для чего-нибудь типа IP-телефонии, т.е. там, где диапазон частот ограничен 3.5 кГц, а величина нелинейных искажений несущественна. Так что для записи можно использовать ТОЛЬКО отдельную звуковую карту. Кстати, вполне вероятно, что из-за экономии (АЦП - существенно более ресурсоемкий процесс чем ЦАП) звук пишется только на 11 кГц, а все остальное программно интерполируется.
                                                  Микрофоном ниразу не мерял вибрацию, а датчиками вибрации работал.

                                                  Удары лучше фиксировать по виброускорению, всплеск идёт на высоких частотах. Мы используем акселерометры, т.е. они сразу меряют ускорение. Насколько я понимаю, микрофон измеряет виброперемещение. После одинарного интегрирования на виброскорости удары хуже видны. После второго интегрирования и получения виброперемещения удар вообще еле заметен.

                                                  Можно попробовать дважды продифференцировать сигнал с микрофона, чтобы получить ускорение.

                                                  Если интересно, могу показать разницу в спектрах.
                                                    Цитата Kekek @
                                                    Если интересно, могу показать разницу в спектрах.

                                                    Не просто интересно, а необходимо!
                                                    ЗЫ Заранее сенк!
                                                      Скинь пожалуйста в форум то что получилось в итоге :) интересно ведь чем дело кончилось. Спасибо!
                                                        Цитата vmihaylov @
                                                        Скинь пожалуйста в форум то что получилось в итоге :) интересно ведь чем дело кончилось. Спасибо!

                                                        Все еще в процесе! Када приведу все к норм состоянию, то выложу!
                                                          Это лёгкий удар шариковой ручкой по датчику вибрации.

                                                          Ускорение
                                                          Скорость
                                                          Перемещение

                                                          Датчик держал в руках, на тринадцати герцах дрожание рук от удара шариковой ручкой по датчику.
                                                          Сообщение отредактировано: Kekek -
                                                            BFenix можете прислать исходник кода на почту, пожалуйста. просто копируя код с первой страницы, выдает ошибку, жалуется почему-то на массив a :)
                                                              Пришлось на некоторое время забыть про этот проект, но ща буду браться заново:
                                                              вот то что есть на данный момент:
                                                              ехе + исходник
                                                                Люди плиз дайте ссілку на компонент Rz то что в проге юзается
                                                                Плиз оч надо
                                                                Ищу не могу найти :wall:
                                                                  Цитата Kekek @
                                                                  Микрофоном ниразу не мерял вибрацию, а датчиками вибрации работал.

                                                                  Удары лучше фиксировать по виброускорению, всплеск идёт на высоких частотах. Мы используем акселерометры, т.е. они сразу меряют ускорение. Насколько я понимаю, микрофон измеряет виброперемещение. После одинарного интегрирования на виброскорости удары хуже видны. После второго интегрирования и получения виброперемещения удар вообще еле заметен.

                                                                  Можно попробовать дважды продифференцировать сигнал с микрофона, чтобы получить ускорение.

                                                                  Если интересно, могу показать разницу в спектрах.

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


                                                                    Рейтинг@Mail.ru
                                                                    [ Script execution time: 0,3427 ]   [ 15 queries used ]   [ Generated: 4.07.25, 21:14 GMT ]