I am trying to play 2 sounds (e.g. 220 Hz and 440 Hz) simultaneously in Java.
I was able to play one sound using StdAudio . Later I made it non-static and deleted some methods that are not relevant to me.
I do not know how to play 2 sounds at the same time. I tried to do this using a thread, but they are not always in sync.
Below is my modified version of StdAudio, and here is an example of how I tried to use streams.
program.java
public class program { public static void main(String[] args) { Thread t1 = new Thread(new soundThread(220)); t1.start(); Thread t2 = new Thread(new soundThread(440)); t2.start(); t1.notify(); t2.notify(); } }
soundThread.java
public class soundThread implements Runnable { private int fq; public soundThread(int fq) { this.fq = fq; } public void run() { StdAudio s = new StdAudio(); double[] note = s.note(fq, 2, 1); try { this.wait(); } catch (Exception e) { } s.play(note); s.close(); } }
Stdaudio.java
import javax.sound.sampled.*; public final class StdAudio { public final int SAMPLE_RATE = 44100; private final int BYTES_PER_SAMPLE = 2;
Thanks in advance, Shay Ben Moshe
EDIT: The solution wrote this method:
public double[] multipleNotes(double[] hzs, double duration, double amplitude) { amplitude = amplitude / hzs.length; int N = (int) (SAMPLE_RATE * duration); double[] a = new double[N + 1]; for (int i = 0; i <= N; i++) { a[i] = 0; for (int j = 0; j < hzs.length; j++) a[i] += amplitude * Math.sin(2 * Math.PI * i * hzs[j] / SAMPLE_RATE); } return a; }
EDIT2: An even better solution for me (O (1) memory):
public void multiplePlay(double[] hzs, double duration, double amplitude) { amplitude = amplitude / hzs.length; int N = (int) (SAMPLE_RATE * duration); double sum; for (int i = 0; i <= N; i++) { sum = 0; for (int j = 0; j < hzs.length; j++) sum += amplitude * Math.sin(2 * Math.PI * i * hzs[j] / SAMPLE_RATE); this.play(sum); } }