import java.util.*; import java.util.zip.*; import java.util.List; import java.util.regex.*; import java.util.concurrent.*; import java.util.concurrent.atomic.*; import java.util.concurrent.locks.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import javax.swing.table.*; import java.io.*; import java.net.*; import java.lang.reflect.*; import java.lang.ref.*; import java.lang.management.*; import java.security.*; import java.security.spec.*; import java.awt.*; import java.awt.event.*; import java.awt.image.*; import javax.imageio.*; import java.math.*; import javax.sound.sampled.*; class main { // Original source: AudioLoop from jsresources.org static int DEFAULT_INTERNAL_BUFSIZ = 40960, DEFAULT_EXTERNAL_BUFSIZ = 40960; static String mixerName; public static void main(final String[] args) throws Exception { new AudioLoop(javaSound_cdQuality(), DEFAULT_INTERNAL_BUFSIZ, DEFAULT_EXTERNAL_BUFSIZ, mixerName).start(); } static class AudioLoop extends Thread { TargetDataLine in; SourceDataLine out; Flag stopFlag = new Flag(); int externalBufferSize; AudioLoop(AudioFormat format, int internalBufferSize, int externalBufferSize, String mixerName) { this.externalBufferSize = externalBufferSize; Pair p = javaSound_bothLines(mixerName, format, internalBufferSize); in = p.a; out = p.b; } public void start() { in.start(); out.start(); super.start(); } void stopRecording() { in.stop(); out.close(); stopFlag.raise(); } // "stop()" was taken public void run() { javaSound_streamFromLineToLine(in, out, externalBufferSize, stopFlag); } } static void javaSound_streamFromLineToLine(TargetDataLine in, SourceDataLine out, int bufferSize, Flag stopFlag) { byte[] buf = new byte[bufferSize]; while (licensed() && !stopFlag.isUp()) out.write(buf, 0, in.read(buf, 0, bufferSize)); } static Map _registerThread_threads = Collections.synchronizedMap(new WeakHashMap()); static Thread _registerThread(Thread t) { _registerThread_threads.put(t, true); return t; } static void _registerThread() { _registerThread(Thread.currentThread()); } static AudioFormat javaSound_cdQuality() { return new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100f, 16, 2, 4, 44100f, false); } static Pair javaSound_bothLines(String mixerName, AudioFormat format, int internalBufferSize) { try { Mixer mixer = mixerName == null ? null : AudioSystem.getMixer(javaSound_getMixerInfo(mixerName)); DataLine.Info targetInfo = new DataLine.Info(TargetDataLine.class, format, internalBufferSize); DataLine.Info sourceInfo = new DataLine.Info(SourceDataLine.class, format, internalBufferSize); TargetDataLine in; SourceDataLine out; if (mixer != null) { in = (TargetDataLine) mixer.getLine(targetInfo); out = (SourceDataLine) mixer.getLine(sourceInfo); } else { in = (TargetDataLine) AudioSystem.getLine(targetInfo); out = (SourceDataLine) AudioSystem.getLine(sourceInfo); } in.open(format, internalBufferSize); out.open(format, internalBufferSize); return pair(in, out); } catch (Exception __e) { throw rethrow(__e); } } static volatile boolean licensed_yes = true; static boolean licensed() { ping(); return licensed_yes; } static void licensed_off() { licensed_yes = false; } static Mixer.Info javaSound_getMixerInfo(String strMixerName) { Mixer.Info[] aInfos = AudioSystem.getMixerInfo(); for (int i = 0; i < aInfos.length; i++) if (aInfos[i].getName().equals(strMixerName)) return aInfos[i]; return null; } static Pair pair(A a, B b) { return new Pair(a, b); } static volatile boolean ping_pauseAll; static int ping_sleep = 100; // poll pauseAll flag every 100 static volatile boolean ping_anyActions; static Map ping_actions = synchroMap(new WeakHashMap()); // always returns true static boolean ping() { if (ping_pauseAll || ping_anyActions) ping_impl(); return true; } // returns true when it slept static boolean ping_impl() { try { if (ping_pauseAll && !isAWTThread()) { do Thread.sleep(ping_sleep); while (ping_pauseAll); return true; } if (ping_anyActions) { Object action; synchronized(mc()) { action = ping_actions.get(currentThread()); if (action instanceof Runnable) ping_actions.remove(currentThread()); if (ping_actions.isEmpty()) ping_anyActions = false; } if (action instanceof Runnable) ((Runnable) action).run(); else if (eq(action, "cancelled")) throw fail("Thread cancelled."); } return false; } catch (Exception __e) { throw rethrow(__e); } } static Map synchroMap() { return synchroHashMap(); } static Map synchroMap(Map map) { return Collections.synchronizedMap(map); } static Thread currentThread() { return Thread.currentThread(); } static boolean eq(Object a, Object b) { return a == null ? b == null : a == b || a.equals(b); } static RuntimeException fail() { throw new RuntimeException("fail"); } static RuntimeException fail(Throwable e) { throw asRuntimeException(e); } static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); } static RuntimeException fail(String msg) { throw new RuntimeException(unnull(msg)); } static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); } static Object mc() { return getMainClass(); } // TODO: test if android complains about this static boolean isAWTThread() { if (isAndroid()) return false; if (isHeadless()) return false; return isAWTThread_awt(); } static boolean isAWTThread_awt() { return SwingUtilities.isEventDispatchThread(); } static Class getMainClass() { return main.class; } static Class getMainClass(Object o) { try { return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main"); } catch (Exception __e) { throw rethrow(__e); } } static Boolean isHeadless_cache; static boolean isHeadless() { if (isHeadless_cache != null) return isHeadless_cache; if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true; // Also check if AWT actually works. // If DISPLAY variable is set but no X server up, this will notice. try { SwingUtilities.isEventDispatchThread(); return isHeadless_cache = false; } catch (Throwable e) { return isHeadless_cache = true; } } static String unnull(String s) { return s == null ? "" : s; } static List unnull(List l) { return l == null ? emptyList() : l; } static Iterable unnull(Iterable i) { return i == null ? emptyList() : i; } static Object[] unnull(Object[] a) { return a == null ? new Object[0] : a; } static BitSet unnull(BitSet b) { return b == null ? new BitSet() : b; } static RuntimeException asRuntimeException(Throwable t) { return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t); } static Map synchroHashMap() { return Collections.synchronizedMap(new HashMap()); } static int isAndroid_flag; static boolean isAndroid() { if (isAndroid_flag == 0) isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1; return isAndroid_flag > 0; } static List emptyList() { return new ArrayList(); //ret Collections.emptyList(); } /** this class is fully thread-safe */ static class Flag { private boolean up; /** returns true if flag was down before */ public synchronized boolean raise() { if (!up) { up = true; notifyAll(); return true; } else return false; } public synchronized void waitUntilUp() { while (!up) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void waitUntilUp(long timeout) { if (!up) { try { wait(timeout); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized boolean isUp() { return up; } public String toString() { return isUp() ? "up" : "down"; } // currently does a semi-active wait with latency = 50 ms public void waitForThisOr(Flag otherFlag) { try { while (!isUp() && !otherFlag.isUp()) Thread.sleep(50); } catch (Exception __e) { throw rethrow(__e); } } } static class Pair { A a; B b; Pair() {} Pair(A a, B b) { this.b = b; this.a = a;} public int hashCode() { return hashCodeFor(a) + 2*hashCodeFor(b); } public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Pair)) return false; Pair t = (Pair) o; return eq(a, t.a) && eq(b, t.b); } } static RuntimeException rethrow(Throwable e) { throw asRuntimeException(e); } static boolean equals(Object a, Object b) { return a == null ? b == null : a.equals(b); } static int hashCodeFor(Object a) { return a == null ? 0 : a.hashCode(); } }