/************************************************************************* * Compilation: javac PlayThatTune.java * Execution: java PlayThatTune < data.txt * Dependencies: StandardLib, found at http://introcs.cs.princeton.edu/java/stdlib/stdlib.jar * * % java PlayThatTune < testaudio.txt * * * Make sure amplitudes for each line add up to exactly 1 * Make sure lengths for each note on the same line are the same # * Data files format: * * note length amplitude note length amplitude... * 1 .5 .1 5 .5 .9 * * * *************************************************************************/ public class PlayThatTune { public static double[] sum(double[] a, double[] b, double awt, double bwt) { // superpose a and b, weighted. double[] c = new double[a.length]; assert (a.length == b.length); for (int i = 0; i < a.length; i++) c[i] = a[i]*awt + b[i]*bwt; return c; } public static double[] tone(double hz, double duration, double amplitude) { int N = (int) (StdAudio.SAMPLE_RATE * duration); double[] a = new double[N+1]; for (int i = 0; i <= N; i++) { a[i] = amplitude * Math.sin(2 * Math.PI * i * hz / StdAudio.SAMPLE_RATE); } return a; } public static double[] note(int p, double t, double amplitude) { //Play note p, with harmonics. double hz = 440.0 * Math.pow(2, p/12.0); double[] a = tone(hz, t, amplitude); double[] hi = tone(2*hz, t, amplitude); double[] lo = tone(hz/2, t, amplitude); double[] h = sum(hi, lo, .5, .5); return sum(a, h , .5, .5); } public static void playmore(int iter, double[] bj, String[] z) { //iterate with int iter backwards through z int pitch = Integer.parseInt(z[(iter*3)-3]); double duration = Double.parseDouble(z[(iter*3)-2]); double amplitude = Double.parseDouble(z[(iter*3)-1]); //Check amplitude value assert (amplitude < 1 && amplitude > 0); double[] a = note(pitch, duration, amplitude); System.out.println(a.length + " is a[]"); System.out.println(bj.length + " is bj[]"); iter -= 1; for (int i = a.length-1; i >= 0; i--) { //iterate over a[] backwards, adding a[i] to bj[i] //System.out.println("yes"+i); bj[i] = (bj[i] + a[i]); } if (iter == 0) { StdAudio.play(bj); } else { playmore(iter, bj, z); } } public static void play() { String[] z = StdIn.readLine().split(" "); int zphi = z.length; if (zphi == 1) return; if (zphi > 3) { System.out.println(zphi); double duration = Double.parseDouble(z[1]); int N = (int) (StdAudio.SAMPLE_RATE * duration); double[] bj = new double[N+1]; playmore((zphi)/3, bj, z); return; } for (int i = 0; i <= z.length-1; i++) { System.out.println(z[i]); } int pitch = Integer.parseInt(z[0]); double duration = Double.parseDouble(z[1]); double[] a = note(pitch, duration, 1); //System.out.println(a.length-1); StdAudio.play(a); } public static void main(String[] args) { //Read and play a tune with harmonics while (!StdIn.isEmpty()) { // Read and play a note with harmonics. play(); } } }