TransWikia.com

Разложение сигнала в ряд Фурье, C++

Stack Overflow на русском Asked on February 16, 2021

Друзья, мне нужно разложить входящий сигнал на несколько гармонических составляющих, после чего сдвинуть каждую из них по фазе на случайное число, а затем сложить всё обратно. У меня есть только структура для чтения заголовка .wav файла, но я не могу понять сам алгоритм преобразования Фурье
Может ли кто помочь?

struct WAVHEADER
{
    // WAV-формат начинается с RIFF-заголовка:

    // Содержит символы "RIFF" в ASCII кодировке
    char chunkId[4];

    //Это размер файла - 8, то есть,
    // исключены поля chunkId и chunkSize.
    unsigned long chunkSize;

    // Содержит символы "WAVE"
    char format[4];

    // Формат "WAVE" состоит из двух подцепочек: "fmt " и "data":
    // Подцепочка "fmt " описывает формат звуковых данных:

    // Содержит символы "fmt "
    char subchunk1Id[4];

    // Это оставшийся размер подцепочки, начиная с этой позиции.
    unsigned long subchunk1Size;

    // Для PCM = 1 (то есть, Линейное квантование).
    // Значения, отличающиеся от 1, обозначают некоторый формат сжатия.
    unsigned short audioFormat;

    // Количество каналов. Моно = 1, Стерео = 2 и т.д.
    unsigned short numChannels;

    // Частота дискретизации. 8000 Гц, 44100 Гц и т.д.
    unsigned long sampleRate;

    // sampleRate * numChannels * bitsPerSample/8
    unsigned long byteRate;

    // numChannels * bitsPerSample/8
    // Количество байт для одного сэмпла, включая все каналы.
    unsigned short blockAlign;

    // Так называемая "глубиная" или точность звучания. 8 бит, 16 бит и т.д.
    unsigned short bitsPerSample;

    // Подцепочка "data" содержит аудио-данные и их размер.

    // Содержит символы "data"
    char subchunk2Id[4];

    // numSamples * numChannels * bitsPerSample/8
    // Количество байт в области данных.
    unsigned long subchunk2Size;

    // Далее следуют непосредственно Wav данные.
};

Просто я пока даже не представляю, что мне делать с этим заголовком и как читать сам .wav-файл

One Answer

Фурье преобразование заключается в следующем:

сигнал, представленный в виде амплитудно-временной зависимости A(t), преобразовывается в амплитудно-частотную зависимость B(w), после чего осуществляется работа с сигналом (например, отрезаются данные в области высоких частот - mp3, jpeg и т.д.), после чего осуществляется обратное преобразование сигнала из амплитудно-частотной зависимости в амплитудно-временную зависимость

https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A4%D1%83%D1%80%D1%8C%D0%B5

Поскольку сам сигнал у нас дискретный, т.е. может быть представлен в виде совокупности точек [A(ti)] используется дискретное Фурье-преобразование

https://ru.wikipedia.org/wiki/%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A4%D1%83%D1%80%D1%8C%D0%B5

Простыми словами о преобразовании Фурье: https://ru.wikipedia.org/wiki/%D0%94%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5_%D0%A4%D1%83%D1%80%D1%8C%D0%B5

Для вашей задачи вам потребуется:

  1. получить ваш сигнал в виде массива амплитуд, где каждая точка Ai соответствует некоторому дискретному времени ti = t0 + n * dt

  2. преобразовать данный массив с помощью алгоритмов в больших кол-вах доступных в сети (просто взять готовый) в новый массив, где каждая точка Bi соответствует некоторой дискретной частоте wi = w0 + n * dw

  3. сместить все точки на некоторую фиксированную частоту delta_w вправо или влево

  4. провести обратное преобразование и получить новый массив амплитуд, где каждая точка соответствует некоторому дискретному времени

Для того, чтобы все это не занимало очень значительное время часто используют быстрое преобразование Фурье:

https://habr.com/ru/company/otus/blog/449996/#:~:text=%D0%91%D0%9F%D0%A4%20%E2%80%94%20%D1%8D%D1%82%D0%BE%20%D0%B1%D1%8B%D1%81%D1%82%D1%80%D1%8B%D0%B9%20%D0%B0%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC%20%D0%B4%D0%BB%D1%8F,%D0%B4%D0%B8%D1%81%D0%BA%D1%80%D0%B5%D1%82%D0%BD%D0%BE%D0%B5%20%D0%BF%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%20%D0%A4%D1%83%D1%80%D1%8C%D0%B5%20(%D0%94%D0%9F%D0%A4)%3A

(тут с готовым кодом - можете использовать)

Correct answer by Zhihar on February 16, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP