java - Java中输出三角波形的公式问题

标签 java algebra waveform

我让我的波形文件创建器开始工作,并将其分为三个类,我还制作了一个正弦波生成器,它继承自一个名为波形的抽象类,我可以导出 8 和 16 位单声道或立体声正弦波。我正在尝试创建一个名为 TriangleWave Generator 的类来输出三角波音调,但我无法从 https://en.wikipedia.org/wiki/Triangle_wave# 获取代数,第一个公式,起作用。它只会输出规定的最高谐波,不会将它们与基波混合在一起

样本长度:长度(以秒为单位) 点:个体样本 放大器限制:可能的最高位置 谐波:用于制作波形的谐波数量 1 = 基波,2 = 第一泛音,3 = 第二泛音...... 频率:基频(中C = 261.63) 采样率 = 44100; (CD品质) triangle Samples数组:样本数据

这是我的代码

public class TriangleGenerator extends Waveform {
    
    // constants
    public static final int HARMONIC_COUNT = 16;

    // instance variabls
    int harmonics;
    int[] triangleSample;
    int addCount;

    // constructor
    public TriangleGenerator(double amplitude, double frequency, int bitRate, double duration, int harmonics) {
        super(amplitude, frequency, bitRate, duration);
        // sample data
        triangleSample = new int[sampleLength];
        calculateAmpLimit();
        this.harmonics = harmonics;
    }

    // one arg cunstructor
    public TriangleGenerator(double frequency) {
        this(AMPLITUDE, frequency, BIT_RATE, DURATION, HARMONIC_COUNT);
    }

    // no args constructor
    public TriangleGenerator() {
        this(AMPLITUDE, FREQUENCY, BIT_RATE, DURATION, HARMONIC_COUNT);
    }

    @Override
    public int[] generateWaveForm() {
        
        // generate the actual waveform
        for (int i = 0; i < sampleLength; i++) {
            point = (int)(ampLimit * ((8 / Math.pow(Math.PI, 2)) * sumnate(harmonics - 1, Math.pow(-1, addCount))
                    * Math.pow(harmonics, -2) * Math.sin(2 * Math.PI * frequency * harmonics * i / SAMPLE_RATE)));
            triangleSample[i] = point;
        }

        // return the sample data
        return triangleSample;
    }
    
    public double sumnate(int n, double adder) {
        double sum = 0;
        
        for (addCount = 0; addCount <= n; addCount++) {
            sum += adder;
        }
        
        return sum;
    }
}

最佳答案

triangle wave 的公式中:

模式编号n取决于谐波标签i:

这意味着它还必须对各个分量求和

这在当前的实现中不会发生。一种可能的实现是:

public int[] generateWaveForm() {
    for (int t = 0; t < sampleLength; t++) {
        triangleSample[t] = (int)(ampLimit * 8.0 / Math.pow(Math.PI, 2.0) * getDataPoint(t, N));
    }
    return triangleSample;
}

private double getDataPoint(int t, int N) {
    double sum = 0;
    for (int i = 0; i <= N - 1; i++) {
        sum += getHarmonicShare(t, i);
    }
    return sum;
}

private double getHarmonicShare(int t, int i) {
double n = 2.0 * i + 1.0;
    return Math.pow(-1.0, i) * Math.pow(n, -2.0) * Math.sin(2.0 * Math.PI * frequency * (t / SAMPLE_RATE) * n);
}

此处,tinN 对应于公式中的值。 频率表示频率。其余值对应于发布代码的参数。

曲线达到值sampleLength/SAMPLE_RATE。周期为1/频率,显示帧中有(sampleLength/SAMPLE_RATE) * 频率周期。

示例:

sampleLength:   500
ampLimit:       100.00
SAMPLE_RATE:  44100.00
frequency:      261.63

sampleLength / SAMPLE_RATE:               0.0113378685
1 / frequency:                            0.0038221916
(sampleLength / SAMPLE_RATE) * frequency: 2.9663265306

下面显示了使用 JFreeChart 的不同 N 的相应曲线:

enter image description here

关于java - Java中输出三角波形的公式问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59433916/

相关文章:

ios - 从两个 CGPoint 导出一条线

python - 找到所有可逆方阵

ios - 使用 AudioKit 在 UIView 中绘制样本文件的波形

audio - 如何使用OpenSL ES获得波形?

java - 如何向标准java类添加方法

java - 了解仅前向结果集

java - 有没有更简单的方法来更改 Eclipse 中的构建路径?

Java/Android - 获取套接字输出流会中断执行,并且不会启动任何异常

javascript - 如何使用 css 或 js 创建波形以显示音频文件何时播放

c++ - 是否有一种方法可以根据不同的变量重新计算和方程式?