1

我正在我的 Java 程序中创建音调。所以有许多振荡器模块可以产生我需要的样本,这样我就可以一次播放多个音调。这些样本被添加并播放。如果我选择一个低幅度,例如 100,一切正常(在 Audacity 中对其进行标准化):

窦

但如果我选择更高的幅度,在本例中为 Short.MAX_VALUE,则创建的音调看起来和听起来都很奇怪:

窦2

示例在此处创建(来源:http ://www.wolinlabs.com/blog/java.sine.wave.html ):

    short value;
    if (type == TYPE_SINE)
    {
        cycleIncrease = frequency / parent.getSamplingRate();
        value = (short) (amplitude * Math.sin(2 * Math.PI * cyclePosition));
        cyclePosition += cycleIncrease;
        if (cyclePosition > 1)
            cyclePosition -= 1; 
        return value;
    }

对于锯齿波,我有同样的问题:

    else if (type == TYPE_SAW)
    {
        cycleIncrease = frequency / parent.getSamplingRate();
        double doubleValue = cyclePosition - Math.floor(cyclePosition);
        cyclePosition += cycleIncrease;
        value = (short) (amplitude * doubleValue);
        if (cyclePosition > 1)
            cyclePosition -= 1; 
        return value;
    }

amplitude具有我上面提到的值,所以在这两种情况下100Short.MAX_VALUE

样本以这种方式求和,其中sum是输出样本,value是计算样本(如果没有播放音调,则为 0):

    int n = 0;
    int sum = 0;

    for (Wire inputWire:inputWires)
    {
        short value = inputWire.getNextSample();
        if (value != 0)
        {
            n += 1;
        }
        sum += value;
        x++;
    }

    if (n != 0)
        sum = sum / n;

如果只播放一种音调,我还确保一个振荡器只有一个样本,所以sum = value.

但是我不明白为什么使用相同的代码为不同的幅度创建不同的音调,那么为什么会发生这种情况呢?

我还有第二个问题:如果我结束播放低幅度的正弦音,我会听到短促的噪音,如下所示:

噪音

这是从哪里来的,我该如何解决?

谢谢您的帮助!

4

2 回答 2

1

验证sampleSizeInBits您的AudioFormatcomports 是否与您选择的amplitude. 如果不是,您可能会在乘以 时看到“环绕”效果amplitude。作为参考,此示例将样本大小缩放为 8 位,表示范围内的有符号字节值-128..127

AudioFormat af = new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true);
…
sin[i] = (byte)(Math.sin(angle) * 127f);
于 2015-09-13T11:36:32.273 回答
1

问题一:

看起来好像您可能正在包装波形:

if (cyclePosition > 1)
    cyclePosition -= 1; // You are reducing the amplitude by half? (goes from 1 to -1)

这是应该发生一些剪辑的地方:

// For example...
if (cyclePosition > 1)
    cyclePosition = 1
if (cyclePosition < -1)
    cyclePosition = -1

音频可能听起来很糟糕,但是当幅度太大时通常会发生这种情况。

也许尝试缩放幅度以始终将其拟合在范围内:

scale = 1 / highestAmplitude;
foreach (point in wavePoints)
{
    point *= scale;
}
// or something similar

问题2:

确保正弦波以 0 幅度结束

于 2015-09-13T11:32:23.823 回答