160eeb064f62a106069d2ce148fabd724f9df9780Bill Cox/* This file was written by Bill Cox in 2011, and is licensed under the Apache
260eeb064f62a106069d2ce148fabd724f9df9780Bill Cox   2.0 license. */
360eeb064f62a106069d2ce148fabd724f9df9780Bill Cox
42e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coxpackage sonic;
52e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
62e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport java.io.File;
72e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport java.io.IOException;
82e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
92e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.AudioFormat;
102e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.AudioInputStream;
112e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.AudioSystem;
122e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.DataLine;
132e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.LineUnavailableException;
142e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.SourceDataLine;
152e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coximport javax.sound.sampled.UnsupportedAudioFileException;
162e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
172e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Coxpublic class Main {
182e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
192e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    // Run sonic.
202e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    private static void runSonic(
212e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        AudioInputStream audioStream,
222e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        SourceDataLine line,
232e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float speed,
242e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float pitch,
252e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float rate,
262e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float volume,
272e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        boolean emulateChordPitch,
282e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int quality,
292e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int sampleRate,
302e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int numChannels) throws IOException
312e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    {
322e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        Sonic sonic = new Sonic(sampleRate, numChannels);
332e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int bufferSize = line.getBufferSize();
342e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        byte inBuffer[] = new byte[bufferSize];
352e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        byte outBuffer[] = new byte[bufferSize];
362e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int numRead, numWritten;
372e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
382e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        sonic.setSpeed(speed);
392e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        sonic.setPitch(pitch);
402e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        sonic.setRate(rate);
412e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        sonic.setVolume(volume);
422e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        sonic.setChordPitch(emulateChordPitch);
432e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        sonic.setQuality(quality);
442e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        do {
452e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            numRead = audioStream.read(inBuffer, 0, bufferSize);
462e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            if(numRead <= 0) {
472e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox                sonic.flushStream();
482e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            } else {
492e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox                sonic.writeBytesToStream(inBuffer, numRead);
502e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            }
512e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            do {
522e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox                numWritten = sonic.readBytesFromStream(outBuffer, bufferSize);
532e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox                if(numWritten > 0) {
542e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox                    line.write(outBuffer, 0, numWritten);
552e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox                }
562e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            } while(numWritten > 0);
572e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        } while(numRead > 0);
582e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    }
592e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
602e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    public static void main(
612e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    	String[] argv) throws UnsupportedAudioFileException, IOException, LineUnavailableException
622e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    {
632e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float speed = 2.0f;
642e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float pitch = 1.0f;
652e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float rate = 1.0f;
662e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        float volume = 1.0f;
672e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        boolean emulateChordPitch = false;
682e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int quality = 0;
692e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox
702e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        AudioInputStream stream = AudioSystem.getAudioInputStream(new File("talking.wav"));
712e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        AudioFormat format = stream.getFormat();
722e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int sampleRate = (int)format.getSampleRate();
732e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        int numChannels = format.getChannels();
742e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        SourceDataLine.Info info = new DataLine.Info(SourceDataLine.class, format,
752e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        	((int)stream.getFrameLength()*format.getFrameSize()));
762e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        SourceDataLine line = (SourceDataLine)AudioSystem.getLine(info);
772e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        line.open(stream.getFormat());
782e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        line.start();
792e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        runSonic(stream, line, speed, pitch, rate, volume, emulateChordPitch, quality,
802e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox            sampleRate, numChannels);
812e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        line.drain();
822e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox        line.stop();
832e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox    }
842e48c227bc3817ee76b92bdabcd3c3ff2b7e5b99Bill Cox}
85