Проблема с формулой для вывода формы треугольника с использованием линейного алиасинга - PullRequest
0 голосов
/ 03 апреля 2020

Я пытаюсь создать формулу для вывода треугольной волны, используя logi c вместо аддитивного синтеза, поскольку использование аддитивного синтеза более интенсивно использует процессор.

Более подробную информацию можно найти здесь, ' Проблемы с формулой для вывода формы треугольника в Java '

С тех пор я немного отредактировал код. Моя проблема в том, что формула генерации линейной треугольной волны не является точной. Он искажен и слишком резок для высоких нот.

Метод, с которым у меня возникли проблемы: liniarTriangle()

public class TriangleGenerator extends AdditiveWaveform {

    // constants
    public static final int HARMONIC_COUNT = 16;

    // instance variables
    int[] triangleSample;

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

    // one arg constructor
    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() {
        if (harmonics == 0) {
            liniarTriangle();
        } else {
            additiveTriangle();
        }
        return triangleSample;
    }

    public void liniarTriangle() {

        // method variables
        double halfWaveLength = (double)SAMPLE_RATE / 
                frequency / (double)2;
        double ratio = 2 / halfWaveLength;
        double finePoint = 0;
        boolean risingEdge = true;

        // set first sample
        point = 0;
        triangleSample[0] = point;

        // loop
        for (exportIndex = 1; exportIndex < sampleLength; exportIndex++) {
            if (risingEdge) {
                if (finePoint + ratio < 1)
                    finePoint += ratio;
                else if (finePoint + ratio > 1) {
                    finePoint = finePoint - (ratio - (finePoint + ratio - 1));
                    risingEdge = false;
                } else if (finePoint + ratio == 1) {
                    finePoint = 1;
                    risingEdge = false;
                }
            } else {
                if (finePoint - ratio > -1)
                    finePoint -= ratio;
                else if (finePoint - ratio < -1) {
                    finePoint =
                        finePoint + (ratio - (Math.abs(finePoint) + ratio - 1));
                    risingEdge = true;
                } else if (finePoint - ratio == -1) {
                    finePoint = -1;
                    risingEdge = true;
                }
            }
            point = (int)(finePoint * ampLimit);
            triangleSample[exportIndex] = point;
        }
    }

    public void additiveTriangle() {
        for (exportIndex = 0; exportIndex < sampleLength; exportIndex++) {
            point = (int) (ampLimit * (8.0 / Math.pow(Math.PI, 2.0) 
                    * getDataPoint(exportIndex, harmonics)));
            triangleSample[exportIndex] = point;
        }
    }

    private double getDataPoint(int t, int N) {
        double sum = 0;
        for (int i = 0; i <= N; 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 / sampleRate * n);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...