Mercurial > hg > ishara
diff audio/java/StreamSource.java @ 0:672052bd81f8
Initial partial import.
author | samer |
---|---|
date | Wed, 19 Dec 2012 22:38:28 +0000 |
parents | |
children | 63cefb01cbab |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/audio/java/StreamSource.java Wed Dec 19 22:38:28 2012 +0000 @@ -0,0 +1,103 @@ +/* + * StreamSource.java + * + * Copyright (c) 2012, Samer Abdallah, King's College London. + * All rights reserved. + * + * This software is provided AS iS and WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + */ + +package samer.audio.alt; +import javax.sound.sampled.*; +import java.io.*; + +public class StreamSource extends AudioSource +{ + InputStream in; + + public StreamSource(AudioInputStream ain) throws Exception { super(ain.getFormat()); in=ain; } + public StreamSource(AudioInputStream ain, AudioFormat target) throws Exception { + this(prepareStream(ain,target)); + } + + // AudioSource interface methods + public void dispose() { + print("Closing audio stream..."); + try { in.close(); } catch (IOException ex) {} + } + + public void start() {} + public void stop() {} + public int read(byte [] buf, int off, int len) throws Exception { + return in.read(buf,off,len); + } + + public static AudioInputStream prepareStream(AudioInputStream ain, AudioFormat target) throws Exception { + // convert to target format if required + print("Preparing audio stream..."); + print(" / audio format: "+ain.getFormat().toString()); + if (target==null) { + AudioFormat fin=ain.getFormat(); + ain=convertFormat(new AudioFormat( fin.getSampleRate(), 16, fin.getChannels(), true, false), ain); + } else { + ain=convertFormat(target, ain); + } + print(" \\ final format: "+ain.getFormat().toString()); + return ain; + } + + private static AudioInputStream convertVia(AudioFormat fout, AudioInputStream sin, AudioFormat fint) throws Exception + { + print(" | Trying recursive via "+fint.toString()); + AudioInputStream sint=AudioSystem.getAudioInputStream(fint,sin); + AudioFormat fres=sint.getFormat(); + if (!fres.equals(fint)) { + print(" | obtained "+fres.toString()); + } + return convertFormat(fout, sint); + } + + public static AudioInputStream convertFormat(AudioFormat fout, AudioInputStream sin) throws Exception + { + AudioFormat fin=sin.getFormat(); + + if (fin.equals(fout)) return sin; + if (fin.getEncoding()!=AudioFormat.Encoding.PCM_SIGNED) { + if (fin.getEncoding().getClass().getName().startsWith("javazoom.spi.")) { + // these are broken, must go via 16 bit decode with no channels change + print(" ! Detected noncompliant Javazoom decoder, going via 16 bit."); + return convertVia( fout, sin, new AudioFormat( + fin.getSampleRate(), 16, fin.getChannels(), true, fout.isBigEndian())); + } + + // first get into PCM encoding, then try recursive + try { + return convertVia( fout, sin, new AudioFormat( + fin.getSampleRate(), fout.getSampleSizeInBits(), + fin.getChannels(), true, fout.isBigEndian())); + } catch (IllegalArgumentException ex) { + print(" * Direct conversion failed"); + } + return convertVia( fout, sin, new AudioFormat( + fin.getSampleRate(), fin.getSampleSizeInBits(), + fin.getChannels(), true, fout.isBigEndian())); + } + + if ( !unify(fin.getChannels(),fout.getChannels()) + || !unify(fin.getSampleSizeInBits(),fout.getSampleSizeInBits())) { + // convert these before doing any sample rate conversion + return convertVia(fout, sin, new AudioFormat( + fin.getSampleRate(), fout.getSampleSizeInBits(), + fout.getChannels(), true, fout.isBigEndian())); + } + + // the only thing left is sample rate + return AudioSystem.getAudioInputStream(fout,sin); + } + + private static boolean unify(int x, int y) { return x==-1 || y==-1 || x==y; } + private static boolean unify(float x, float y) { return x==-1 || y==-1 || x==y; } +} +