朋友们,我需要将输入信号分解成几个谐波分量,然后将它们中的每一个同相移动一个随机数,然后将所有内容加回去。我只有一个结构来读取 .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 文件本身。
傅里叶变换如下:
将呈现为幅度-时间相关性 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
对于您的任务,您将需要:
将您的信号作为幅度数组获取,其中每个点 Ai 对应于一些离散时间
ti = t0 + n * dt使用网络上大量可用的算法(只需一个现成的)将该数组转换为一个新数组,其中每个点 Bi 对应于某个离散频率
wi = w0 + n * dwdelta_w将所有点向右或向左移动某个固定频率进行逆变换并得到一个新的幅度数组,其中每个点对应于一些离散时间
为了使所有这些不花费非常多的时间,通常使用快速傅里叶变换:
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
(这里有现成的代码 - 你可以使用它)