问题
I am trying to make a formula to output a triangle wave using logic instead of additive Synthesis since using additive Synthesis is more CPU intense.
More info can be found here, 'Problems with formula to output a triangle waveform in Java'
I have edited the code a bit since then. My problem is that the linear triangle wave generation formula is not precise. It has distortion and is too sharp for higher notes.
The method I am having trouble with is 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);
}
}
来源:https://stackoverflow.com/questions/61009312/problem-with-formula-to-output-a-triangle-waveform-using-linear-aliasing