Hann Window在一组音频样本上扭曲信号 - iOS粒度合成

时间:2014-05-05 15:32:01

标签: ios sampling windowing

我在iOS中制作粒状合成器,基本上循环非常短的微量样本,以创建新的不可能的声音。为此,我在Core Audio中设置了录制和播放功能,但播放和循环播放的内容是来自谷物缓冲区的短样本。

我的问题是,当我从记录中的任意点取样时,循环样本的起点和终点不一定是过零点。因此,每次样品再次开始时,这可能导致点击,这通常在粒状合成中。我试图通过使用hann函数窗口化示例来解决这个问题,但是当我测试它时,结果是一个扭曲的混乱。请注意,为了便于测试,我的谷物缓冲液长22050个样品(1/2秒)。

// Window over entirety of the grain
for (int i = 0; i < 22050; i++)
{
    // Hann window function, this is used as it zeros at beggining and end of window
    double window = 0.5 * (1.0 - cos((2.0 * M_PI * i) / (22050 -  1)));

    // Applying window
    windowedGrain[i] = grainBufferNew[i] * window;
}

我出错的任何想法? windowedGrain缓冲区是否包含比grain缓冲区更多的样本?我写过hann函数错了吗?或者我没有正确应用窗口?任何可以给出的建议将不胜感激。

干杯

更新:自从进一步测试了问题以来,设置window = 1会产生无失真但无窗口的声音。我也使用了一个简单的三角窗函数,但这也是扭曲的,见下文

SInt16 sampleSizeGrainBuffer = sizeof(grainBufferNew)/sizeof(SInt16);    

double window = 0.0;

double increment = 1.0/(sampleSizeGrainBuffer/2);

for (int i = 0; i < sampleSizeGrainBuffer; i++)
{
    // Simple triangular window function
    if (i<(sampleSizeGrainBuffer/2)) window += increment;
    else window -= increment;


    // Applying window
    windowedGrain[i] = grainBufferNew[i] * window;
}

更新:错误似乎是由于最终的乘法,因为grainBufferNew是一个SInt16,窗口是一个双倍。这两者需要在数学上相等才能使其正常工作。由于窗口函数不能是SInt,因此必须首先将缓冲区数据设为double。然后在这个总和之后它必须转换回SInt 16。

更新:我尝试将grainBuffer转换为double,但结果仍然失真,尽管结果看起来很好。

// Applying window
    windowedGrain[i] = (SInt16)(((double)grainBufferNew[i]) * window);

我还尝试将grainBuffer转换为double

// Applying window
    windowedGrain[i] = ((double)grainBufferNew[i]) * window;

我尝试将窗口转换为SInt16,但结果是静音,因为窗口函数始终等于零。

 // Applying window
    windowedGrain[i] = grainBufferNew[i] * ((SInt16)window);

然后我尝试使用

来区分两个整数的大小
windowedGrain[i] = grainBufferNew[i] * (window * sizeof(SInt16));

结果似乎结果似乎在终端窗口但输出失真

0 个答案:

没有答案