Convert for loop into a recursive function - java

this is a homework problem. I'm having trouble converting the following into a recursive function:
public class Integrate {
public static double integrate(int a, int b, int steps)
{
double sum=0;
double delta = 1.0 * (b - a)/steps;
double x = a;
double f = 0.5*x*x + 3*x + 5;
for (int i = 0; i< steps; i++)
{
x = x + delta;
double fr = 0.5*x*x + 3*x + 5;
double area = f * delta + 0.5*(fr - f)*delta;
sum += area;
f = fr;
}
return sum;
}
public static void main(String [] args)
{
int a, b, step;
a = Integer.parseInt(args[0]);
b = Integer.parseInt(args[1]);
step = Integer.parseInt(args[2]);
System.out.format("Integral is %f\n", integrate(a,b,step));
}
}
This is what I have so far but the output is not the same as the original code. I can't figure out what is wrong
public class Integrate {
public static double integrate(int a, int b, int steps) {
double sum=0;
int i=0;
sum = rintegrate(a, b, steps, i, sum);
return sum;
}
public static double rintegrate(int a, int b, int steps,
int i, double sum) {
double delta = 1.0 * (b - a)/steps;
double x = a;
double f = 0.5*x*x + 3*x + 5;
if (i<steps) {
x = x + delta;
double fr = 0.5*x*x + 3*x + 5;
double area = f * delta + 0.5*(fr - f)*delta;
sum += area;
f = fr;
i++;
rintegrate(a, b, steps, i, sum);
}
return sum;
}
public static void main(String[] args) {
int a, b, step;
a = Integer.parseInt(args[0]);
b = Integer.parseInt(args[1]);
step = Integer.parseInt(args[2]);
System.out.format("Integral is %f\n", integrate(a,b,step));
}
}

I'm not going to fully analyze the problem, but here are some observations that I have
if (i<steps) {
x = x + delta;
double fr = 0.5*x*x + 3*x + 5;
double area = f * delta + 0.5*(fr - f)*delta;
sum += area;
f = fr;
i++;
rintegrate(a, b, steps, i, sum);
}
return sum;
everything between sum += area; and return sum; is superfluous.
you're setting f to fr, but you never even use f after that. if you want f to be different next time, maybe you can pass it as a parameter to your recursive function
you're recursively calling rintegrate(...), but you're not doing anything with the value it returns. you might want to use that value.
You should think about recursion as using a smaller version of a problem to solve itself.
Here's some code for your problem assuming that you have a function: segment that just calculates the size of the first segment given a, and delta
rintegrate(a, b, steps)
{
if(steps <= 1)
{
delta = b-a;
return segment(a, delta)
}
else
{
delta = (b-a)/steps
return segment(a, delta) + rintegrate(a+delta, b, steps-1)
}
}

Working version
Just copy paste and you will get the same output as your original method.
public static void main(String[] args) {
int a = 1, b = 10, step = 1000;
double delta = 1.0 * (b - a) / step;
double sum = integrate(a, b, step, 0, 0, 0, delta);
double test = working(a, b, step);
System.out.println("Integral is " + sum);
System.out.println("Integral is " + test);
}
The working recursive version:
public static double integrate(double x, int b, int steps, int i,
double sum, double f, double delta) {
f = 0.5 * x * x + 3 * x + 5;
if (i < steps) {
x = x + delta;
double fr = 0.5 * x * x + 3 * x + 5;
double area = f * delta + 0.5 * (fr - f) * delta;
return integrate(x, b, steps, i + 1, sum + area, fr, delta);
}
return sum;
}
Your original iterative method;
public static double working(int a, int b, int steps) {
double sum = 0;
double delta = 1.0 * (b - a) / steps;
double x = a;
double f = 0.5 * x * x + 3 * x + 5;
for (int i = 0; i < steps; i++) {
x = x + delta;
double fr = 0.5 * x * x + 3 * x + 5;
double area = f * delta + 0.5 * (fr - f) * delta;
sum += area;
f = fr;
}
return sum;
}

This is what you want ;)
public class Integrate{
/**
* #param args
*/
public static void main(String[] args) {
int a, b, step;
a = Integer.parseInt(args[0]);
b = Integer.parseInt(args[1]);
step = Integer.parseInt(args[2]);
System.out.format("Integral is %f\n",
adaptiveSimpsons(a, b, step));
}
private static double f(double i) {
return (0.5 * i * i + 3 * i + 5);
}
static double adaptiveSimpsons(double a, double b, // interval [a,b]
int maxRecursionDepth) { // recursion cap
double c = (a + b) / 2, h = b - a;
double fa = f(a), fb = f(b), fc = f(c);
double S = (h / 6) * (fa + 4 * fc + fb);
return adaptiveSimpsonsAux(a, b, S, fa, fb, fc, maxRecursionDepth);
}
private static double adaptiveSimpsonsAux(double a, double b, double S, double fa,
double fb, double fc, int bottom) {
double c = (a + b) / 2, h = b - a;
double d = (a + c) / 2, e = (c + b) / 2;
double fd = f(d), fe = f(e);
double Sleft = (h / 12) * (fa + 4 * fd + fc);
double Sright = (h / 12) * (fc + 4 * fe + fb);
double S2 = Sleft + Sright;
if (bottom <= 0)
return S2 + (S2 - S) / 15;
return adaptiveSimpsonsAux(a, c, Sleft, fa, fc, fd, bottom - 1)
+ adaptiveSimpsonsAux(c, b, Sright, fc, fb, fe, bottom - 1);
}
}
Tested and Working
Translated C code given here

Related

how can I use a counter controlled iteration in the print/math section on this square root program

I was thinking about adding a while loop to the program that'll loop for maybe 10 times instead of writing 10 println statements. but I found it hard since the value of x is different every time in the math section. I wrote this code before, now I want to shorten it. It's a square root finder program that uses the Babylonian method to find the square root of an integer between [S > 20 || S < 400]
int S;
System.out.print("Enter an integer, S: ");
S = myInput.nextInt();
if (S < 0) {
System.out.println("This program can not take the square root of a negative number.");
}
else if (S < 20 || S > 400) {
System.out.println("This value is out of range.");
}
else {
double a = S / 2.0;
double b = S / a;
double c = a + b;
double d = 0.5 * c;
// for x2
double e = S / d;
double f = d + e;
double g = 0.5 * f;
// for x3
double h = S / g;
double i = g + h;
double j = 0.5 * i;
// for x4
double k = S / j;
double l = j + k;
double m = 0.5 * l;
// for x5
double n = S / m;
double o = m + n;
double p = 0.5 * o;
// for x6
double q = S / p;
double r = p + q;
double s = 0.5 * r;
// for x7
double t = S / s;
double u = s + t;
double v = 0.5 * u;
// for x8
double w = S / v;
double x = v + w;
double y = 0.5 * x;
// for x9
double z = S / y;
double aa = y + z;
double ab = 0.5 * aa;
System.out.printf("%nx0 = %8.4f ", a);
System.out.printf("%nx1 = %8.4f ", d);
System.out.printf("%nx2 = %8.4f ", g);
System.out.printf("%nx3 = %8.4f ", j);
System.out.printf("%nx4 = %8.4f ", m);
System.out.printf("%nx5 = %8.4f ", p);
System.out.printf("%nx6 = %8.4f ", s);
System.out.printf("%nx7 = %8.4f ", v);
System.out.printf("%nx8 = %8.4f ", y);
System.out.printf("%nx9 = %8.4f ", ab);
}
All you need to do is set d to 2.0 outside the loop. Then use d in place of 2.0 inside the loop. The loop index of i is also used to name the iterations (x0, x1, x2, ...) when printing.
double d = 2.0; // set d to 2.0 here
for (int i = 0; i < 10; i++) {
double a = S / d; // use d here, the modified value will be used again
double b = S / a;
double c = a + b;
d = 0.5 * c;
System.out.printf("x%d = %8.4f%n", i, a);
}
prints the following for the input value of 50
x0 = 25.0000
x1 = 3.7037
x2 = 5.8127
x3 = 6.9374
x4 = 7.0698
x5 = 7.0711
x6 = 7.0711
x7 = 7.0711
x8 = 7.0711
x9 = 7.0711
Here is an exercise. Compare the current computed value to the last. If they are equal (or their difference is small), then you can exit the loop since repeated iterations won't improve the accuracy very much.

Perlin noise glitch

I have an infinite map generator. It works well with positive coordinates.
Positive coordinates generation 1
But on negative coordinates I have this trash:
Negative coordinates broken generation
2
void generateChunk(int x0, int y0) {
Chunk chunk = new Chunk(x0, y0);
for(int yTile = 0; yTile < Chunk.CHUNK_SIZE; yTile++) {
for(int xTile = 0; xTile < Chunk.CHUNK_SIZE; xTile++) {
int pX = chunk.x0 + xTile;
int pY = chunk.y0 + yTile;
double perlinNoiseHeight = floorPerlinNoise.getHeight(pX, pY);;
if(perlinNoiseHeight > BEACH_AREA) {
chunk.setFloor(GrassTile.ID, xTile, yTile);
} else if(perlinNoiseHeight > 0) {
chunk.setFloor(SandTile.ID, xTile, yTile);
} else {
chunk.setFloor(WaterTile.ID, xTile, yTile);
}
}
}
saveChunk(chunk);
}
Perlin noise class:
package org.ixnomad.game.level.generation;
public class PerlinNoise {
private double persistence, frequency, amplitude;
private int octaves;
private long seed;
public PerlinNoise(double persistence, double frequency, double amplitude, int octaves, long seed) {
this.persistence = persistence;
this.amplitude = amplitude;
this.frequency = frequency;
this.octaves = octaves;
this.seed = seed;
}
public double getHeight(double x, double y) {
return amplitude * total(x, y) + 0.4;
}
private double total(double i, double j) {
double total = 0.0d;
double _ampl = 1;
double _freq = frequency;
for(int k = 0; k < octaves; k++) {
total += getValue(j * _freq + seed, i * _freq + seed) * _ampl;
_ampl *= persistence;
_freq *= 2;
}
return total;
}
private double getValue(double x, double y) {
int xInt = (int) x;
int yInt = (int) y;
double xFrac = x - xInt;
double yFrac = y - yInt;
double n01 = noise(xInt-1, yInt-1);
double n02 = noise(xInt+1, yInt-1);
double n03 = noise(xInt-1, yInt+1);
double n04 = noise(xInt+1, yInt+1);
double n05 = noise(xInt-1, yInt );
double n06 = noise(xInt+1, yInt );
double n07 = noise(xInt , yInt-1);
double n08 = noise(xInt , yInt+1);
double n09 = noise(xInt , yInt );
double n12 = noise(xInt+2, yInt-1);
double n14 = noise(xInt+2, yInt+1);
double n16 = noise(xInt+2, yInt );
double n23 = noise(xInt-1, yInt+2);
double n24 = noise(xInt+1, yInt+2);
double n28 = noise(xInt , yInt+2);
double n34 = noise(xInt+2, yInt+2);
double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);
double v1 = interpolate(x0y0, x1y0, xFrac);
double v2 = interpolate(x0y1, x1y1, xFrac);
return interpolate(v1, v2, yFrac);
}
private double interpolate(double x, double y, double frac) {
double negFrac = 1.0 - frac;
double negFraqSqr = negFrac * negFrac;
double fac1 = 3.0 * negFraqSqr - 2.0 * negFraqSqr * negFrac;
double fracSqr = frac * frac;
double fac2 = 3.0 * fracSqr - 2.0 * fracSqr * frac;
return x * fac1 + y * fac2;
}
private double noise(int x, int y) {
int n = x + y * 57;
n = (n << 13) ^ n;
int t = (n * (n * n * 15713 + 789221) + 1376312589) & 0x7fffffff;
return 1.0d - (double) (t * 0.931322574615478515625e-9);
}
}
I have tried to solve this problem for a whole day, but I don't know, what I'm doing wrong. I thought that the problem is in bit shift (private double noise(double x, double y)), but the problem doesn't depend on it.
I tried to use this Perlin's algoryth: https://mrl.nyu.edu/~perlin/noise/
But effect is the same.
Good morning, I probably have solved the problem :D Jush should sleep and reload brains)
Just use the max value the integer can bring and move generate coordinates to half :D
int maxint = 0x07fffffff;
double perlinNoiseHeight = floorPerlinNoise.getHeight(pX + (maxint >> 1), pY + (maxint >> 1));
That is a simple solution, but it works)
Negative coordinates

Returning an Double/Integer from a Method in Java?

I am trying to make code that takes a set of numbers in, runs them through the quadratic formula and returns the answer that is then printed.
P.S. I'm new to java, doing this to learn.
Scanner firstCoeff = new Scanner(System.in);
int ax = firstCoeff.nextInt();
firstCoeff.close();
Scanner secCoeff = new Scanner(System.in);
int bx = secCoeff.nextInt();
secCoeff.close();
Scanner finConstant = new Scanner(System.in);
int c = finConstant.nextInt();
Quadratic_Formula work = new Quadratic_Formula();
work.posquadForm(ax, bx, c);
work.negquadForm(ax, bx, c);
System.out.println("Your answer is" + work.posquadForm() +"or" + work.negquadForm() +".");
Here is the formula class:
public class Quadratic_Formula {
public double posquadForm(int ax, int bx, int c) {
int b;
b = (bx);
int a;
a = (ax);
double posanswer;
posanswer = ((-b) - Math.sqrt((b^2) + ((-4) * a * c)) / (2 * a));
return posanswer;
}
public double negquadForm(int ax, int bx, int c) {
int b;
b = (bx);
int a;
a = (ax);
double neganswer;
neganswer = ((-b) + Math.sqrt((b^2) + ((-4) * a * c)) / (2 * a));
return neganswer;
}
Change to
Quadratic_Formula work = new Quadratic_Formula();
double posAnswer = work.posquadForm(ax, bx, c);
double negAnswer = work.negquadForm(ax, bx, c);
System.out.println("Your answer is" +posAnswer +"or" + negAnswer +".");
Your functions posquadForm & negquadForm have already computed the answers, you just need to store them in variables and print them out?
Your method is declared as such:
public double posquadForm(int ax, int bx, int c) {
So just pass in those variables...
int valueForAx = 2;
int valueForBx = 3;
int valueForC = 4;
System.out.println("Your answer is " + work.posquadForm(valueForAx, valueForBx, valueForC));
Side note, instead of:
int b;
b = (bx);
int a;
a = (ax);
you just use:
int b = bx;
int a = ax;
And the opposite of Alex K's answer is to not take any parameters, just deal with ax, bx and c as globals (assuming the quad formula class is an inner class).
public double posquadForm() {
double posanswer;
posanswer = ((-bx) - Math.sqrt((bx^2) + ((-4) * ax * c)) / (2 * ax));
return posanswer;
}

Result of Quaternion Multiplication not yielding expected Rotation of local coordinate system

I'm getting unexpected results when multiplying two quaternions and applying the resulting rotation to my local right-handed coordinate system. (X pointing forward, Y to the right and Z downward).
(See my Java SCCE below)
So I am trying to first apply a Z rotation by 90 degrees (yaw) and then a rotation of 90 degrees around the local X axis (roll).
I am trying to accomplish this by multiplying two quaternions representing these two rotations, creating a rotation Matrix from the result and applying it to the 3 unit vectors of my coordinate system but the results I am getting do not make sense. (i.e. they do not represent the coordinate system you should get from these two rotations.)
I have tried changing the quaternion multiplication order which did not help (see code lines that were commented out in the main method of the SCCE).
I have also tried creating the quaternion for the second rotation from global Y to simulate that it was created from the resulting local coordinate system after the first rotation.
For reference I am also calculating the result by applying the two individual rotation matrices (which works as expected).
What am I doing wrong?
import java.text.DecimalFormat;
import java.text.NumberFormat;
public class Quaternion {
public static final double NORMALIZATION_LOWER_TOLERANCE = 1 - 1e-4;
public static final double NORMALIZATION_UPPER_TOLERANCE = 1 + 1e-4;
private double w = 1.0;
private double x = 0.0;
private double y = 0.0;
private double z = 0.0;
public static void main(String[] args) {
Vector3D xVect = new Vector3D(1,0,0);
Vector3D yVect = new Vector3D(0,1,0);
Vector3D zVect = new Vector3D(0,0,1);
System.out.println("Initial Local Coordinate System: X:"+xVect+" / Y:"+yVect+ " / Z:"+zVect);
Quaternion rotZ = new Quaternion(Math.PI/2, zVect); // Yaw +90 deg
Quaternion rotY = new Quaternion(Math.PI/2, yVect); // Yaw +90 deg
Quaternion rotX = new Quaternion(Math.PI/2, xVect); // Then roll +90 deg
Matrix rotationMatrixZ = new Matrix(rotZ);
Vector3D localX = xVect.rotate(rotationMatrixZ);
Vector3D localY = yVect.rotate(rotationMatrixZ);
Vector3D localZ = zVect.rotate(rotationMatrixZ);
System.out.println("New Local Coordinate System after Yaw: X:"+localX+" / Y:"+localY+ " / Z:"+localZ); // Gives expected result
Quaternion localRotX = new Quaternion(Math.PI/2, localX);
Matrix localRotXMatrix = new Matrix(localRotX);
Vector3D rotatedX = localX.rotate(localRotXMatrix);
Vector3D rotatedY = localY.rotate(localRotXMatrix);
Vector3D rotatedZ = localZ.rotate(localRotXMatrix);
System.out.println("New Local Coordinate System two local rotations: X:"+rotatedX+" / Y:"+rotatedY+ " / Z:"+rotatedZ); // Gives expected result
Quaternion rotZX = rotZ.multiply(rotX);
// Quaternion rotZX = rotX.multiply(rotZ); // Tried both orders
// Quaternion rotZX = rotZ.multiply(rotY); // rotY is in fact the local rotX
// Quaternion rotZX = rotZ.multiply(rotY); // rotY is in fact the local rotX, tried both orders
rotZX.normalizeIfNeeded();
Matrix rotationXMatrixZX = new Matrix(rotZX);
rotatedX = xVect.rotate(rotationXMatrixZX);
rotatedY = localY.rotate(rotationXMatrixZX);
rotatedZ = localZ.rotate(rotationXMatrixZX);
System.out.println("New Local Coordinate System Quaternion Multiplication: X:"+rotatedX+" / Y:"+rotatedY+ " / Z:"+rotatedZ); // Expect same as above
}
public Quaternion() {
}
public Quaternion(double w, double x, double y, double z) {
this.w = w;
this.x = x;
this.y = y;
this.z = z;
}
public Quaternion(double angle, Vector3D vector){
double halfAngle = angle / 2;
double sin = Math.sin(halfAngle);
this.w = Math.cos(halfAngle);
this.x = vector.getX()*sin;
this.y = vector.getY()*sin;
this.z = vector.getZ()*sin;
}
public boolean normalizeIfNeeded() {
double sum = w * w + x * x + y * y + z * z;
if (NORMALIZATION_LOWER_TOLERANCE < sum && sum < NORMALIZATION_UPPER_TOLERANCE) {
return false;
}
double magnitude = Math.sqrt(sum);
w /= magnitude;
x /= magnitude;
y /= magnitude;
z /= magnitude;
return true;
}
public Quaternion multiply(Quaternion q2) {
Quaternion result = new Quaternion();
result.w = w * q2.w - x * q2.x - y * q2.y - z * q2.z;
result.x = w * q2.x + x * q2.w + y * q2.z - z * q2.y;
result.y = w * q2.y - x * q2.z + y * q2.w + z * q2.x;
result.z = w * q2.z + x * q2.y - y * q2.x + z * q2.w;
return result;
}
public Quaternion conjugate() {
return new Quaternion(w, -x, -y, -z);
}
public double getW() {
return w;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
#Override
public String toString() {
return "Quaternion [w=" + w + ", x=" + x + ", y=" + y + ", z=" + z + "]";
}
static class Vector3D {
double x=0;
double y=0;
double z=0;
public Vector3D(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public Vector3D rotate(Matrix rotationMatrix){
return rotationMatrix.multiply(this);
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
#Override
public String toString() {
NumberFormat df = DecimalFormat.getNumberInstance();
return "[x=" + df.format(x) + ", y=" + df.format(y) + ", z=" + df.format(z) + "]";
}
}
static class Matrix {
private double[][] values;
public Matrix(int rowCount, int colCount) {
values = new double[rowCount][colCount];
}
public Matrix(Quaternion quaternionForRotationMatrix) {
this(3,3);
double w = quaternionForRotationMatrix.getW();
double x = quaternionForRotationMatrix.getX();
double y = quaternionForRotationMatrix.getY();
double z = quaternionForRotationMatrix.getZ();
double ww = w*w;
double wx = w*x;
double xx = x*x;
double xy = x*y;
double xz = x*z;
double wy = w*y;
double yy = y*y;
double yz = y*z;
double wz = w*z;
double zz = z*z;
values[0][0] = ww + xx - yy - zz;
values[0][1] = 2 * xy - 2 * wz;
values[0][2] = 2 * xz + 2 * wy;
values[1][0] = 2 * xy + 2 * wz;
values[1][1] = ww - xx + yy - zz;
values[1][2] = 2 * yz + 2 * wx;
values[2][0] = 2 * xz - 2 * wy;
values[2][1] = 2 * yz - 2 * wx;
values[2][2] = ww - xx - yy + zz;
}
public Vector3D multiply(Vector3D vector){
double [][] vect = new double [3][1];
vect[0][0] = vector.getX();
vect[1][0] = vector.getY();
vect[2][0] = vector.getZ();
double [][] result = multiplyMatrices(values, vect);
return new Vector3D(result[0][0], result[1][0], result[2][0]);
}
private double[][] multiplyMatrices(double[][] m1, double[][] m2) {
double[][] result = null;
if (m1[0].length == m2.length) {
int rowCount1 = m1.length;
int colCount1 = m1[0].length;
int rowCount2 = m2[0].length;
result = new double[rowCount1][rowCount2];
for (int i = 0; i < rowCount1; i++) {
for (int j = 0; j < rowCount2; j++) {
result[i][j] = 0;
for (int k = 0; k < colCount1; k++) {
result[i][j] += m1[i][k] * m2[k][j];
}
}
}
} else {
int rowCount = m1.length;
int colCount = m1[0].length;
result = new double[rowCount][colCount];
for (int i = 0; i < m1.length; i++) {
for (int j = 0; j < m1[0].length; j++) {
result[i][j] = 0;
}
}
}
return result;
}
#Override
public String toString() {
StringBuffer sb = new StringBuffer("Matrix = ");
for(int row = 0 ; row<values.length; row++){
sb.append ("[ ");
for(int col = 0 ; col<values[0].length; col++){
sb.append(Double.toString(values[row][col]));
if(col<values.length-1){
sb.append(" | ");
}
}
sb.append("] ");
}
return sb.toString();
}
}
}
Nevermind. Found it. I had an error in the formulas to build the rotation matrix. It now works as expected.
I am making a mental note to use formulas from Wikipedia in the future and not some random other site.
The respective part should be
values[0][0] = ww + xx - yy - zz;
values[0][1] = 2 * xy - 2 * wz;
values[0][2] = 2 * xz + 2 * wy;
values[1][0] = 2 * xy + 2 * wz;
values[1][1] = ww - xx + yy - zz;
values[1][2] = 2 * yz - 2 * wx; //CORRECTED SIGN
values[2][0] = 2 * xz - 2 * wy;
values[2][1] = 2 * yz + 2 * wx; //CORRECTED SIGN
values[2][2] = ww - xx - yy + zz;
At the end of the main method I was also using the wrong vectors for y and z:
Matrix rotationXMatrixZX = new Matrix(rotZX);
rotatedX = xVect.rotate(rotationXMatrixZX);
rotatedY = yVect.rotate(rotationXMatrixZX); // Corrected used y-vector
rotatedZ = zVect.rotate(rotationXMatrixZX); // Corrected used z-vector

How do I 'translate' a Java enum-type to JRuby code?

How would I go about to translate this Java code to i.e. JRuby:
enum Note {
REST, A4, A4$, B4, C4, C4$, D4, D4$, E4, F4, F4$, G4, G4$, A5;
public static final int SAMPLE_RATE = 16 * 1024; // ~16KHz
public static final int SECONDS = 2;
private byte[] sin = new byte[SECONDS * SAMPLE_RATE];
Note() {
int n = this.ordinal();
if (n > 0) {
double exp = ((double) n - 1) / 12d;
double f = 440d * Math.pow(2d, exp);
for (int i = 0; i < sin.length; i++) {
double period = (double)SAMPLE_RATE / f;
double angle = 2.0 * Math.PI * i / period;
sin[i] = (byte)(Math.sin(angle) * 127f);
}
}
}
public byte[] data() {
return sin;
}
}

Categories