import java.io.*; import javax.sound.sampled.*; import java.net.URL; import javax.sound.*; public class Sound { /** * The sample rate - 44,100 Hz for CD quality audio. */ public static int channels = 2; public static final int SAMPLE_RATE = 44100; private static final int BYTES_PER_SAMPLE = 4; // 16-bit audio private static final int BITS_PER_SAMPLE = 16; // 16-bit audio private static final double MAX_16_BIT = Short.MAX_VALUE; // 32,767 private static final int SAMPLE_BUFFER_SIZE = 4096; static SourceDataLine[] line = new SourceDataLine[channels]; // to play the sound private static byte[][] buffer = new byte[2][]; // our internal buffer private static int i = 0; // number of samples currently in internal buffer private static int i2 = 0; public static Mixer mainmix; // static initializer public Sound() { init(); } // open up an audio stram static void init() { try { Mixer.Info[] mixerinfo = AudioSystem.getMixerInfo(); mainmix = AudioSystem.getMixer(mixerinfo[0]); Line.Info lineinf[] = mainmix.getSourceLineInfo(); // 44,100 samples per second, 16-bit audio, mono, signed PCM, little Endian AudioFormat format = new AudioFormat((float) SAMPLE_RATE, BITS_PER_SAMPLE, 2, true, false); DataLine.Info info = new DataLine.Info(SourceDataLine.class, format); line[0] = (SourceDataLine) mainmix.getLine(info); line[1] = (SourceDataLine) mainmix.getLine(info); //line[2] = (SourceDataLine) mainmix.getLine(info); Control[] linectrl = line[0].getControls(); Control[] linectrl1 = line[1].getControls(); //line = (SourceDataLine) AudioSystem.getLine(info); line[0].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE); line[1].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE); // line[2].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE); //line[1].open(format, SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE); // the internal buffer is a fraction of the actual buffer size, this choice is arbitrary // it gets diveded because we can't expect the buffered data to line up exactly with when // the sound card decides to push out its samples. buffer[0] = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE]; buffer[1] = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE]; //buffer[2] = new byte[SAMPLE_BUFFER_SIZE * BYTES_PER_SAMPLE]; } catch (Exception e) { System.out.println(e.getMessage()); System.exit(1); } // no sound gets made before this call line[0].flush(); line[0].start(); line[1].flush(); line[1].start(); } /** * Close standard audio. */ public final void close() { line[0].drain(); line[0].stop(); line[1].drain(); line[1].stop(); } public final void play(double in) { // clip if outside [-1, +1] if (in < -1.0) in = -1.0; if (in > +1.0) in = +1.0; // convert to bytes short s = (short) (MAX_16_BIT * in); buffer[0][i++] = (byte) s; buffer[0][i++] = (byte) (s >> 8); // little Endian buffer[0][i++] = (byte) s; buffer[0][i++] = (byte) (s >> 8); // little Endian // send to sound card if buffer is full if (i >= buffer.length) { line[0].write(buffer[0], 0, 4); i = 0; } } public void play(double[] input) { for (int i = 0; i < input.length; i++) { play(input[i]); } } public final void play(double in, double an) { // clip if outside [-1, +1] if (in < -1.0) in = -1.0; if (in > +1.0) in = +1.0; // convert to bytes short s = (short) (MAX_16_BIT * in); buffer[1][i++] = (byte) s; buffer[1][i++] = (byte) (s >> 8); // little Endian buffer[1][i++] = (byte) s; buffer[1][i++] = (byte) (s >> 8); // little Endian // clip if outside [-1, +1] if (an < -1.0) an = -1.0; if (an > +1.0) an = +1.0; // convert to bytes short a = (short) (MAX_16_BIT * an); buffer[0][i2++] = (byte) a; buffer[0][i2++] = (byte) (a >> 8); // little Endian buffer[0][i2++] = (byte) a; buffer[0][i2++] = (byte) (a >> 8); // little Endian // send to sound card if buffer is full if (i >= buffer.length) { line[1].write(buffer[1], 0, 4); line[0].write(buffer[0], 0, 4); i2 = 0; i = 0; } } public void play(double[] input,double[] input1) { for (int i = 0; i < input.length; i++) { play(input[i],input1[i]); } } }