好的,我成功的在这上面花费了3天
Hanako的音调变换算法(非专业,大佬轻喷)
我将一个采样叫做LFPCM,64位浮点数
#define LFPCM double
首先这里有一些采样:
我们希望将它的频率变为原来的p倍:
(很明显,时域变长了)
如果将时域压缩回原来的样子:
那么我们能否通过更改采样间隔来实现改变音高呢?
可以,但是怎么采样呢?
最简单的近似办法便是将两个采样用线连起来。
在两个采样的时间间隔很短时,可以近似的认为它们之间的采样是按直线排列的
那么
double offset = 0, k, b, x;
for (; offset < (double)tmp.size()-1; offset += power) {
x = offset - (double)((size_t)offset);
b = tmp[(size_t)offset];
k = tmp[(size_t)offset + 1] - b;
wave.push_back(k * x + b);
}
假设两个采样之间的间隔为1,新采样间隔为power
x是距离该区域左端(b)采样的长度(区域长度为旧采样间隔,1),
k是比例
源代码
void ConvertFreq(std::vector<LFPCM> &wave, double power) {
if (power < 0)return;
if (power == 0) {
for (size_t i = 0; i < wave.size(); i += 1)wave[i] = 0;
return;
}
std::vector<LFPCM> tmp(wave);
tmp.push_back(wave[0]);
wave.clear();
double offset = 0, k, b, x;
for (; offset < (double)tmp.size()-1; offset += power) {
x = offset - (double)((size_t)offset);
b = tmp[(size_t)offset];
k = tmp[(size_t)offset + 1] - b;
wave.push_back(k * x + b);
}
}