Warning : session_start(): open(/var/lib/php/sessions/sess_m5ntc7e3gv7a2khtdg7417o4oa, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
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 static x30_pkg.x30_util.DynamicObject;
import org.mp3transform.Bitstream;
import org.mp3transform.Decoder;
import org.mp3transform.Header;
import org.mp3transform.wav.*;
import it.sauronsoftware.jave.*;
import javazoom.jl.player.*;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.*;
import java.text.NumberFormat;
import javax.imageio.metadata.*;
import javax.imageio.stream.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import javax.swing.undo.UndoManager;
import java.awt.geom.*;
import java.awt.datatransfer.UnsupportedFlavorException;
class main {
static void audioRestorationDemo_v1() {
String text =
//"please tell me something nice";
"you can almost understand this now";
boolean sine = false;
double seconds = 1.0;
ContinuousOscillators_TestAudioRestoration test = new ContinuousOscillators_TestAudioRestoration();
test.showImage(true);
var co = test.co;
String waveName;
test.separateFrequencies(true);
test.separateRealAndImag(false);
test.cumulative(true);
co.renderUsingSine = false;
if (sine) {
test.setAudio(seconds, new SineSoundSource(440.0, test.inputSampleRate));
//if (true) ret;
waveName = "sine";
} else {
test.loadMP3(new GSay(text).audioFile());
waveName = text;
}
//test.co.setFrequencies(pianoFrequencies88());
test.co.setFrequencies(map(__20 -> toFrequency(__20), geometricIterator(55.0, test.inputSampleRate, 2.0)));
test.silence = 0.01;
//test.minFreq = 440;
//test.maxFreq = 440*4;
test.wavOut = javaxDataDir("Restored Audio/" + waveName + ".restored." + (test.co.renderUsingSine ? "sine" : "square") + ".wav");
test.run();
/*
double interval = co.sampleRate/880;
print(+interval);
int n = 3;
L period = map(x -> x/32767.0, asList(takeFirst(iceil(interval*n), test.resampled)));
L partSum = AutoCreateList(Average);
for i over period: {
var sample = period.get(i);
int part = ifloor(i/interval*4);
var sum = partSum.get(part);
sum.add(sample);
printVars(+i, +part, sample := formatDouble2(sample), sum := formatDouble2(sum!));
}
pnl(partSum);
for (int i = 0; i+3 < l(partSum); i += 4) {
double[] vals = new[2];
for phase to 2: {
double a = partSum.get(i+((4-phase)&3))!;
double b = partSum.get(i+((5-phase)&3))!;
double c = partSum.get(i+((6-phase)&3))!;
double d = partSum.get(i+((7-phase)&3))!;
printVars(+a, +b, +c, +d);
double hi = avg(a, b), lo = avg(c, d);
double val = hi-lo;
vals[phase] = val;
print("i=" + i + ", phase " + phase + ": " + formatDouble2(hi) + " - " + formatDouble2(lo) + " = " + formatDouble2(val));
}
print("c=" + renderComplexWithAngle(complex(vals)));
}
*/
// test linear interpolation
/*for (t : countIterator(0.0, 2.0, 0.1))
print(t + "=" + co.audio.sampleSum(0, 0, t));*/
}
static List map(Iterable l, Object f) { return map(f, l); }
static List map(Object f, Iterable l) {
List x = emptyList(l);
if (l != null) for (Object o : l)
{ ping(); x.add(callF(f, o)); }
return x;
}
static List map(Iterable l, F1 f) { return map(f, l); }
static List map(F1 f, Iterable l) {
List x = emptyList(l);
if (l != null) for (A o : l)
{ ping(); x.add(callF(f, o)); }
return x;
}
static List map(IF1 f, Iterable l) { return map(l, f); }
static List map(Iterable l, IF1 f) {
List x = emptyList(l);
if (l != null) for (A o : l)
{ ping(); x.add(f.get(o)); }
return x;
}
static List map(IF1 f, A[] l) { return map(l, f); }
static List map(A[] l, IF1 f) {
List x = emptyList(l);
if (l != null) for (A o : l)
{ ping(); x.add(f.get(o)); }
return x;
}
static List map(Object f, Object[] l) { return map(f, asList(l)); }
static List map(Object[] l, Object f) { return map(f, l); }
static List map(Object f, Map map) {
return map(map, f);
}
// map: func(key, value) -> list element
static List map(Map map, Object f) {
List x = new ArrayList();
if (map != null) for (Object _e : map.entrySet()) { ping();
Map.Entry e = (Map.Entry) _e;
x.add(callF(f, e.getKey(), e.getValue()));
}
return x;
}
static List map(Map map, IF2 f) {
return map(map, (Object) f);
}
// new magic alias for mapLL - does it conflict?
static List map(IF1 f, A data1, A... moreData) {
List x = emptyList(l(moreData)+1);
x.add(f.get(data1));
if (moreData != null) for (A o : moreData)
{ ping(); x.add(f.get(o)); }
return x;
}
static Frequency toFrequency(double freq) {
return new Frequency(freq);
}
static IterableIterator geometricIterator(double a, double b, double factor) {
assertTrue("factor > 1", factor > 0);
return new IterableIterator() {
double i = a;
public boolean hasNext() { return i < b; }
public Double next() { var j = i; i *= factor; return j; }
};
}
static File javaxDataDir_dir; // can be set to work on different base dir
static File javaxDataDir() {
return javaxDataDir_dir != null ? javaxDataDir_dir : new File(userHome(), "JavaX-Data");
}
static File javaxDataDir(String... subs) {
return newFile(javaxDataDir(), subs);
}
static ArrayList emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static ArrayList emptyList(int capacity) {
return new ArrayList(max(0, capacity));
}
// Try to match capacity
static ArrayList emptyList(Iterable l) {
return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList();
}
static ArrayList emptyList(Object[] l) {
return emptyList(l(l));
}
// get correct type at once
static ArrayList emptyList(Class c) {
return new ArrayList();
}
//sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// always returns true
static boolean ping() {
//ifdef useNewPing
newPing();
//endifdef
if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */);
//ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) { // don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized(ping_actions) {
if (!ping_actions.isEmpty()) {
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> callF_cache = newDangerousWeakHashMap();
static A callF(F0 f) {
return f == null ? null : f.get();
}
static B callF(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF(IF0 f) {
return f == null ? null : f.get();
}
static B callF(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF(VF1 f, A a) {
if (f != null) f.get(a);
}
static void callF(A a, IVF1 f) {
if (f != null) f.get(a);
}
static void callF(IVF1 f, A a) {
if (f != null) f.get(a);
}
static Object callF(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF(Object f, Object... args) {
if (f instanceof String)
return callMCWithVarArgs((String) f, args); // possible SLOWDOWN over callMC
return safeCallF(f, args);
}
static Object safeCallF(Object f, Object... args) {
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
}
if (f == null) return null;
Class c = f.getClass();
ArrayList methods;
synchronized(callF_cache) {
methods = callF_cache.get(c);
if (methods == null)
methods = callF_makeCache(c);
}
int n = l(methods);
if (n == 0) {
throw fail("No get method in " + getClassName(c));
}
if (n == 1) return invokeMethod(methods.get(0), f, args);
for (int i = 0; i < n; i++) {
Method m = methods.get(i);
if (call_checkArgs(m, args, false))
return invokeMethod(m, f, args);
}
throw fail("No matching get method in " + getClassName(c));
}
// used internally
static ArrayList callF_makeCache(Class c) {
ArrayList l = new ArrayList();
Class _c = c;
do {
for (Method m : _c.getDeclaredMethods())
if (m.getName().equals("get")) {
makeAccessible(m);
l.add(m);
}
if (!l.isEmpty()) break;
_c = _c.getSuperclass();
} while (_c != null);
callF_cache.put(c, l);
return l;
}
// unclear semantics as to whether return null on null
static ArrayList asList(A[] a) {
return a == null ? new ArrayList () : new ArrayList (Arrays.asList(a));
}
static ArrayList asList(int[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(long[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (long i : a) l.add(i);
return l;
}
static ArrayList asList(float[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (float i : a) l.add(i);
return l;
}
static ArrayList asList(double[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (double i : a) l.add(i);
return l;
}
static ArrayList asList(short[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (short i : a) l.add(i);
return l;
}
static ArrayList asList(Iterator it) {
ArrayList l = new ArrayList();
if (it != null)
while (it.hasNext())
l.add(it.next());
return l;
}
// disambiguation
static ArrayList asList(IterableIterator s) {
return asList((Iterator) s);
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static List asList(Pair p) {
return p == null ? null : ll(p.a, p.b);
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(Object o) {
return o == null ? 0
: o instanceof String ? l((String) o)
: o instanceof Map ? l((Map) o)
: o instanceof Collection ? l((Collection) o)
: o instanceof Object[] ? l((Object[]) o)
: o instanceof boolean[] ? l((boolean[]) o)
: o instanceof byte[] ? l((byte[]) o)
: o instanceof char[] ? l((char[]) o)
: o instanceof short[] ? l((short[]) o)
: o instanceof int[] ? l((int[]) o)
: o instanceof float[] ? l((float[]) o)
: o instanceof double[] ? l((double[]) o)
: o instanceof long[] ? l((long[]) o)
: (Integer) call(o, "size");
}
static int l(IntRange r) { return r == null ? 0 : r.length(); }
static double l(DoubleRange r) { return r == null ? 0 : r.length(); }
static int l(HalfLongs l) { return l == null ? 0 : l.size(); }
static void assertTrue(Object o) {
if (!(eq(o, true) /*|| isTrue(pcallF(o))*/))
throw fail(str(o));
}
static boolean assertTrue(String msg, boolean b) {
if (!b)
throw fail(msg);
return b;
}
static boolean assertTrue(boolean b) {
if (!b)
throw fail("oops");
return b;
}
static String _userHome;
static String userHome() {
if (_userHome == null)
return actualUserHome();
return _userHome;
}
static File userHome(String path) {
return new File(userDir(), path);
}
static File newFile(File base, String... names) {
for (String name : names) base = new File(base, name);
return base;
}
static File newFile(String name) {
return name == null ? null : new File(name);
}
static File newFile(String base, String... names) {
return newFile(newFile(base), names);
}
static int max(int a, int b) { return Math.max(a, b); }
static int max(int a, int b, int c) { return max(max(a, b), c); }
static long max(int a, long b) { return Math.max((long) a, b); }
static long max(long a, long b) { return Math.max(a, b); }
static double max(int a, double b) { return Math.max((double) a, b); }
static float max(float a, float b) { return Math.max(a, b); }
static double max(double a, double b) { return Math.max(a, b); }
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static float max(float[] c) {
if (c.length == 0) return Float.MAX_VALUE;
float x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static short max(short[] c) {
short x = -0x8000;
for (short d : c) if (d > x) x = d;
return x;
}
static int max(int[] c) {
int x = Integer.MIN_VALUE;
for (int d : c) if (d > x) x = d;
return x;
}
static Map newWeakHashMap() {
return _registerWeakMap(synchroMap(new WeakHashMap()));
}
static void newPing() {
var tl = newPing_actionTL();
Runnable action = tl == null ? null : tl.get();
{ if (action != null) action.run(); }
}
// 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 boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
if (o instanceof ThreadLocal) // TODO: remove this
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static void failIfUnlicensed() {
assertTrue("license off", licensed());
}
static Thread currentThread() {
return Thread.currentThread();
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
// a little kludge for stuff like eq(symbol, "$X")
static boolean eq(Symbol a, String b) {
return eq(str(a), 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(Object... objects) { throw new Fail(objects); }
static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static Map newDangerousWeakHashMap() {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()));
}
// initFunction: voidfunc(Map) - is called initially, and after clearing the map
static Map newDangerousWeakHashMap(Object initFunction) {
return _registerDangerousWeakMap(synchroMap(new WeakHashMap()), initFunction);
}
static Object callMCWithVarArgs(String method, Object... args) {
return call_withVarargs(mc(), method, args);
}
static String getClassName(Object o) {
return o == null ? "null" : o instanceof Class ? ((Class) o).getName() : o.getClass().getName();
}
static Object invokeMethod(Method m, Object o, Object... args) { try {
try {
return m.invoke(o, args);
} catch (InvocationTargetException e) {
throw rethrow(getExceptionCause(e));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(e.getMessage() + " - was calling: " + m + ", args: " + joinWithSpace(classNames(args)));
}
} catch (Exception __e) { throw rethrow(__e); } }
static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
print("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++) {
Object arg = args[i];
if (!(arg == null ? !types[i].isPrimitive()
: isInstanceX(types[i], arg))) {
if (debug)
print("Bad parameter " + i + ": " + arg + " vs " + types[i]);
return false;
}
}
return true;
}
static Field makeAccessible(Field f) {
try {
f.setAccessible(true);
} catch (Throwable e) {
// Note: The error reporting only works with Java VM option --illegal-access=deny
vmBus_send("makeAccessible_error", e, f);
}
return f;
}
static Method makeAccessible(Method m) {
try {
m.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, m);
}
return m;
}
static Constructor makeAccessible(Constructor c) {
try {
c.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, c);
}
return c;
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null) for (A x : a) l.add(x);
return l;
}
static int iteratorCount_int_close(Iterator i) { try {
int n = 0;
if (i != null) while (i.hasNext()) { i.next(); ++n; }
if (i instanceof AutoCloseable) ((AutoCloseable) i).close();
return n;
} catch (Exception __e) { throw rethrow(__e); } }
static Object call(Object o) {
return callF(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
//ret call_cached(o, method, args);
return call_withVarargs(o, method, args);
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return new String(c);
}
static String actualUserHome_value;
static String actualUserHome() {
if (actualUserHome_value == null) {
if (isAndroid())
actualUserHome_value = "/storage/emulated/0/";
else
actualUserHome_value = System.getProperty("user.home");
}
return actualUserHome_value;
}
static File actualUserHome(String sub) {
return newFile(new File(actualUserHome()), sub);
}
static File userDir() {
return new File(userHome());
}
static File userDir(String path) {
return new File(userHome(), path);
}
static List _registerWeakMap_preList;
static A _registerWeakMap(A map) {
if (javax() == null) {
// We're in class init
if (_registerWeakMap_preList == null) _registerWeakMap_preList = synchroList();
_registerWeakMap_preList.add(map);
return map;
}
try {
call(javax(), "_registerWeakMap", map);
} catch (Throwable e) {
printException(e);
print("Upgrade JavaX!!");
}
return map;
}
static void _onLoad_registerWeakMap() {
assertNotNull(javax());
if (_registerWeakMap_preList == null) return;
for (Object o : _registerWeakMap_preList)
_registerWeakMap(o);
_registerWeakMap_preList = null;
}
static Map synchroMap() {
return synchroHashMap();
}
static Map synchroMap(Map map) {
return Collections.synchronizedMap(map);
}
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL;
static x30_pkg.x30_util.BetterThreadLocal newPing_actionTL() {
if (newPing_actionTL == null)
newPing_actionTL = vm_generalMap_getOrCreate("newPing_actionTL",
() -> new x30_pkg.x30_util.BetterThreadLocal());
return newPing_actionTL;
}
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 Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (isAndroid()) return isHeadless_cache = true;
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 volatile boolean licensed_yes = true;
static boolean licensed() {
if (!licensed_yes) return false;
ping_okInCleanUp();
return true;
}
static void licensed_off() {
licensed_yes = false;
}
static RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static void _handleError(Error e) {
call(javax(), "_handleError", e);
}
static List _registerDangerousWeakMap_preList;
static A _registerDangerousWeakMap(A map) {
return _registerDangerousWeakMap(map, null);
}
static A _registerDangerousWeakMap(A map, Object init) {
callF(init, map);
if (init instanceof String) {
final String f = (String) init;
init = new VF1() { public void get(Map map) { try { callMC(f, map) ; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "callMC(f, map)"; }};
}
if (javax() == null) {
// We're in class init
if (_registerDangerousWeakMap_preList == null) _registerDangerousWeakMap_preList = synchroList();
_registerDangerousWeakMap_preList.add(pair(map, init));
return map;
}
call(javax(), "_registerDangerousWeakMap", map, init);
return map;
}
static void _onLoad_registerDangerousWeakMap() {
assertNotNull(javax());
if (_registerDangerousWeakMap_preList == null) return;
for (Pair p : _registerDangerousWeakMap_preList)
_registerDangerousWeakMap(p.a, p.b);
_registerDangerousWeakMap_preList = null;
}
static Object call_withVarargs(Object o, String method, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findStaticMethod(method, args);
if (me != null)
return invokeMethod(me, null, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
{ if (!(isStaticMethod(m))) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, null, newArgs);
}
throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(method, args);
if (me != null)
return invokeMethod(me, o, args);
// try varargs
List methods = cache.cache.get(method);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, o, newArgs);
}
throw fail("Method " + c.getName() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
}
} catch (Exception __e) { throw rethrow(__e); } }
static Class mc() {
return main.class;
}
static Throwable getExceptionCause(Throwable e) {
Throwable c = e.getCause();
return c != null ? c : e;
}
static String joinWithSpace(Iterable c) {
return join(" ", c);
}
static String joinWithSpace(String... c) {
return join(" ", c);
}
static List classNames(Collection l) {
return getClassNames(l);
}
static List classNames(Object[] l) {
return getClassNames(Arrays.asList(l));
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal print_byThread; // special handling by thread - prefers F1
static volatile Object print_allThreads;
static volatile Object print_preprocess;
static void print() {
print("");
}
static A print(String s, A o) {
print(combinePrintParameters(s, o));
return o;
}
// slightly overblown signature to return original object...
static A print(A o) {
ping_okInCleanUp();
if (print_silent) return o;
String s = o + "\n";
print_noNewLine(s);
return o;
}
static void print_noNewLine(String s) {
try {
Object f = getThreadLocal(print_byThread_dontCreate());
if (f == null) f = print_allThreads;
if (f != null)
// We do need the general callF machinery here as print_byThread is sometimes shared between modules
if (isFalse(
f instanceof F1 ? ((F1) f).get(s) :
callF(f, s))) return;
} catch (Throwable e) {
System.out.println(getStackTrace(e));
}
print_raw(s);
}
static void print_raw(String s) {
if (print_preprocess != null) s = (String) callF(print_preprocess, s);
s = fixNewLines(s);
Appendable loc = local_log;
Appendable buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
System.out.print(s);
vmBus_send("printed", mc(), s);
}
static void print_autoRotate() {
}
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
static void vmBus_send(String msg, Object... args) {
Object arg = vmBus_wrapArgs(args);
pcallFAll_minimalExceptionHandling(vm_busListeners_live(), msg, arg);
pcallFAll_minimalExceptionHandling(vm_busListenersByMessage_live().get(msg), msg, arg);
}
static void vmBus_send(String msg) {
vmBus_send(msg, (Object) null);
}
static AutoCloseable tempInterceptPrintIfNotIntercepted(F1 f) {
return print_byThread().get() == null ? tempInterceptPrint(f) : null;
}
static Class javax() {
return getJavaX();
}
static List synchroList() {
return synchroList(new ArrayList ());
}
static List synchroList(List l) {
return Collections.synchronizedList(l);
}
static A printException(A e) {
printStackTrace(e);
return e;
}
static A assertNotNull(A a) {
assertTrue(a != null);
return a;
}
static A assertNotNull(String msg, A a) {
assertTrue(msg, a != null);
return a;
}
static Map synchroHashMap() {
return synchronizedMap(new HashMap());
}
static A vm_generalMap_getOrCreate(Object key, F0 create) {
return vm_generalMap_getOrCreate(key, f0ToIF0(create));
}
static A vm_generalMap_getOrCreate(Object key, IF0 create) {
Map generalMap = vm_generalMap();
if (generalMap == null) return null; // must be x30 init
synchronized(generalMap) { // should switch to locks here
A a = (A) (vm_generalMap_get(key));
if (a == null)
vm_generalMap_put(key, a = create == null ? null : create.get());
return a;
}
}
static void ping_okInCleanUp() {
if (ping_pauseAll || ping_anyActions)
ping_impl(true);
}
static HashMap> callMC_cache = new HashMap();
static String callMC_key;
static Method callMC_value;
// varargs assignment fixer for a single string array argument
static Object callMC(String method, String[] arg) {
return callMC(method, new Object[] {arg});
}
static Object callMC(String method, Object... args) { try {
Method me;
if (callMC_cache == null) callMC_cache = new HashMap(); // initializer time workaround
synchronized(callMC_cache) {
me = method == callMC_key ? callMC_value : null;
}
if (me != null) try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
List m;
synchronized(callMC_cache) {
m = callMC_cache.get(method);
}
if (m == null) {
if (callMC_cache.isEmpty()) {
callMC_makeCache();
m = callMC_cache.get(method);
}
if (m == null) throw fail("Method named " + method + " not found in main");
}
int n = m.size();
if (n == 1) {
me = m.get(0);
synchronized(callMC_cache) {
callMC_key = method;
callMC_value = me;
}
try {
return invokeMethod(me, null, args);
} catch (IllegalArgumentException e) {
throw new RuntimeException("Can't call " + me + " with arguments " + classNames(args), e);
}
}
for (int i = 0; i < n; i++) {
me = m.get(i);
if (call_checkArgs(me, args, false))
return invokeMethod(me, null, args);
}
throw fail("No method called " + method + " with arguments (" + joinWithComma(getClasses(args)) + ") found in main");
} catch (Exception __e) { throw rethrow(__e); } }
static void callMC_makeCache() {
synchronized(callMC_cache) {
callMC_cache.clear();
Class _c = (Class) mc(), c = _c;
while (c != null) {
for (Method m : c.getDeclaredMethods())
if ((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0) {
makeAccessible(m);
multiMapPut(callMC_cache, m.getName(), m);
}
c = c.getSuperclass();
}
}
}
static Pair pair(A a, B b) {
return new Pair(a, b);
}
static Pair pair(A a) {
return new Pair(a, a);
}
static final Map callOpt_cache = newDangerousWeakHashMap();
static Object callOpt_cached(Object o, String methodName, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
// TODO: (super-rare) case where method exists static and non-static
// with different args
Method me = cache.findMethod(methodName, args);
if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null;
return invokeMethod(me, null, args);
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(methodName, args);
if (me == null) return null;
return invokeMethod(me, o, args);
}
} catch (Exception __e) { throw rethrow(__e); } }
// no longer synchronizes! (see #1102990)
static _MethodCache callOpt_getCache(Class c) {
_MethodCache cache = callOpt_cache.get(c);
if (cache == null)
callOpt_cache.put(c, cache = new _MethodCache(c));
return cache;
}
static boolean isStaticMethod(Method m) {
return methodIsStatic(m);
}
static Object[] massageArgsForVarArgsCall(Method m, Object[] args) {
Class>[] types = m.getParameterTypes();
int n = types.length-1, nArgs = args.length;
if (nArgs < n) return null;
for (int i = 0; i < n; i++)
if (!argumentCompatibleWithType(args[i], types[i]))
return null;
Class varArgType = types[n].getComponentType();
for (int i = n; i < nArgs; i++)
if (!argumentCompatibleWithType(args[i], varArgType))
return null;
Object[] newArgs = new Object[n+1];
arraycopy(args, 0, newArgs, 0, n);
Object[] varArgs = arrayOfType(varArgType, nArgs-n);
arraycopy(args, n, varArgs, 0, nArgs-n);
newArgs[n] = varArgs;
return newArgs;
}
static String joinWithComma(Collection c) {
return join(", ", c);
}
static String joinWithComma(Object... c) {
return join(", ", c);
}
static String joinWithComma(String... c) {
return join(", ", c);
}
static String joinWithComma(Pair p) {
return p == null ? "" : joinWithComma(str(p.a), str(p.b));
}
public static String join(String glue, Iterable strings) {
if (strings == null) return "";
if (strings instanceof Collection) {
if (((Collection) strings).size() == 1) return str(first((Collection) strings));
}
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
public static String join(String glue, String... strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(String glue, Object... strings) {
return join(glue, Arrays.asList(strings));
}
static String join(Iterable strings) {
return join("", strings);
}
static String join(Iterable strings, String glue) {
return join(glue, strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String join(String glue, Pair p) {
return p == null ? "" : str(p.a) + glue + str(p.b);
}
static List getClassNames(Collection l) {
List out = new ArrayList();
if (l != null) for (Object o : l)
out.add(o == null ? null : getClassName(o));
return out;
}
static String combinePrintParameters(String s, Object o) {
return (endsWithLetterOrDigit(s) ? s + ": " : s) + o;
}
// this syntax should be removed...
static Object getThreadLocal(Object o, String name) {
ThreadLocal t = (ThreadLocal) (getOpt(o, name));
return t != null ? t.get() : null;
}
static A getThreadLocal(ThreadLocal tl) {
return tl == null ? null : tl.get();
}
static A getThreadLocal(ThreadLocal tl, A defaultValue) {
return or(getThreadLocal(tl), defaultValue);
}
static ThreadLocal print_byThread_dontCreate() {
return print_byThread;
}
static boolean isFalse(Object o) {
return eq(false, o);
}
static String getStackTrace(Throwable throwable) {
lastException(throwable);
return getStackTrace_noRecord(throwable);
}
static String getStackTrace_noRecord(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return hideCredentials(writer.toString());
}
static String getStackTrace() {
return getStackTrace_noRecord(new Throwable());
}
static String getStackTrace(String msg) {
return getStackTrace_noRecord(new Throwable(msg));
}
static String fixNewLines(String s) {
int i = indexOf(s, '\r');
if (i < 0) return s;
int l = s.length();
StringBuilder out = new StringBuilder(l);
out.append(s, 0, i);
for (; i < l; i++) {
char c = s.charAt(i);
if (c != '\r')
out.append(c);
else {
out.append('\n');
if (i+1 < l && s.charAt(i+1) == '\n') ++i;
}
}
return out.toString();
}
static void print_append(Appendable buf, String s, int max) { try {
synchronized(buf) {
buf.append(s);
if (buf instanceof StringBuffer)
rotateStringBuffer(((StringBuffer) buf), max);
else if (buf instanceof StringBuilder)
rotateStringBuilder(((StringBuilder) buf), max);
}
} catch (Exception __e) { throw rethrow(__e); } }
static Object vmBus_wrapArgs(Object... args) {
return empty(args) ? null
: l(args) == 1 ? args[0]
: args;
}
static void pcallFAll_minimalExceptionHandling(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) { ping(); pcallF_minimalExceptionHandling(f, args); }
}
static void pcallFAll_minimalExceptionHandling(Iterator it, Object... args) {
while (it.hasNext()) { ping(); pcallF_minimalExceptionHandling(it.next(), args); }
}
static Set vm_busListeners_live_cache;
static Set vm_busListeners_live() { if (vm_busListeners_live_cache == null) vm_busListeners_live_cache = vm_busListeners_live_load(); return vm_busListeners_live_cache; }
static Set vm_busListeners_live_load() {
return vm_generalIdentityHashSet("busListeners");
}
static Map vm_busListenersByMessage_live_cache;
static Map vm_busListenersByMessage_live() { if (vm_busListenersByMessage_live_cache == null) vm_busListenersByMessage_live_cache = vm_busListenersByMessage_live_load(); return vm_busListenersByMessage_live_cache; }
static Map vm_busListenersByMessage_live_load() {
return vm_generalHashMap("busListenersByMessage");
}
static ThreadLocal print_byThread() {
synchronized(print_byThread_lock) {
if (print_byThread == null)
print_byThread = new ThreadLocal();
}
return print_byThread;
}
// f can return false to suppress regular printing
// call print_raw within f to actually print something
static AutoCloseable tempInterceptPrint(F1 f) {
return tempSetThreadLocal(print_byThread(), f);
}
static Class __javax;
static Class getJavaX() { try {
return __javax;
} catch (Exception __e) { throw rethrow(__e); } }
static A printStackTrace(A e) {
// we go to system.out now - system.err is nonsense
print(getStackTrace(e));
return e;
}
static void printStackTrace() {
printStackTrace(new Throwable());
}
static void printStackTrace(String msg) {
printStackTrace(new Throwable(msg));
}
static void printStackTrace(String msg, Throwable e) {
printStackTrace(new Throwable(msg, e));
}
static Map synchronizedMap() {
return synchroMap();
}
static Map synchronizedMap(Map map) {
return synchroMap(map);
}
static IF0 f0ToIF0(F0 f) {
return f == null ? null : () -> f.get();
}
static Map vm_generalMap_map;
static Map vm_generalMap() {
if (vm_generalMap_map == null)
vm_generalMap_map = (Map) get(javax(), "generalMap");
return vm_generalMap_map;
}
static Object vm_generalMap_get(Object key) {
return vm_generalMap().get(key);
}
static Object vm_generalMap_put(Object key, Object value) {
return mapPutOrRemove(vm_generalMap(), key, value);
}
static List getClasses(Object[] array) {
List l = emptyList(l(array));
for (Object o : array) l.add(_getClass(o));
return l;
}
static void multiMapPut(Map > map, A a, B b) {
List l = map.get(a);
if (l == null)
map.put(a, l = new ArrayList());
l.add(b);
}
static void multiMapPut(MultiMap mm, A key, B value) {
if (mm != null && key != null && value != null) mm.put(key, value);
}
static boolean methodIsStatic(Method m) {
return (m.getModifiers() & Modifier.STATIC) != 0;
}
static boolean argumentCompatibleWithType(Object arg, Class type) {
return arg == null ? !type.isPrimitive() : isInstanceX(type, arg);
}
static void arraycopy(Object[] a, Object[] b) {
if (a != null && b != null)
arraycopy(a, 0, b, 0, Math.min(a.length, b.length));
}
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int n) {
if (n != 0)
System.arraycopy(src, srcPos, dest, destPos, n);
}
static A[] arrayOfType(Class type, int n) {
return makeArray(type, n);
}
static A[] arrayOfType(int n, Class type) {
return arrayOfType(type, n);
}
static Object first(Object list) {
return first((Iterable) list);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static A first(IterableIterator i) {
return first((Iterator ) i);
}
static A first(Iterator i) {
return i == null || !i.hasNext() ? null : i.next();
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static Character first(CharSequence s) { return empty(s) ? null : s.charAt(0); }
static A first(Pair p) {
return p == null ? null : p.a;
}
static A first(T3 t) {
return t == null ? null : t.a;
}
static Byte first(byte[] l) {
return empty(l) ? null : l[0];
}
static A first(A[] l, IF1 pred) {
return firstThat(l, pred);
}
static A first(Iterable l, IF1 pred) {
return firstThat(l, pred);
}
static A first(IF1 pred, Iterable l) {
return firstThat(pred, l);
}
static boolean endsWithLetterOrDigit(String s) {
return s != null && s.length() > 0 && Character.isLetterOrDigit(s.charAt(s.length()-1));
}
static Object getOpt(Object o, String field) {
return getOpt_cached(o, field);
}
static Object getOpt(String field, Object o) {
return getOpt_cached(o, field);
}
static Object getOpt_raw(Object o, String field) { try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
// access of static fields is not yet optimized
static Object getOpt(Class c, String field) { try {
if (c == null) return null;
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
makeAccessible(f);
return f.get(null);
} catch (Exception __e) { throw rethrow(__e); } }
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static A or(A a, A b) {
return a != null ? a : b;
}
// PersistableThrowable doesn't hold GC-disturbing class references in backtrace
static volatile PersistableThrowable lastException_lastException;
static PersistableThrowable lastException() {
return lastException_lastException;
}
static void lastException(Throwable e) {
lastException_lastException = persistableThrowable(e);
}
static String hideCredentials(URL url) { return url == null ? null : hideCredentials(str(url)); }
static String hideCredentials(String url) {
try {
if (startsWithOneOf(url, "http://", "https://") && isAGIBlueDomain(hostNameFromURL(url))) return url;
} catch (Throwable e) {
print("HideCredentials", e);
}
return url.replaceAll("([&?])(_pass|key|cookie)=[^&\\s\"]*", "$1$2=");
}
static String hideCredentials(Object o) {
return hideCredentials(str(o));
}
static int indexOf(List l, A a, int startIndex) {
if (l == null) return -1;
int n = l(l);
for (int i = startIndex; i < n; i++)
if (eq(l.get(i), a))
return i;
return -1;
}
static int indexOf(List l, int startIndex, A a) {
return indexOf(l, a, startIndex);
}
static int indexOf(List l, A a) {
if (l == null) return -1;
return l.indexOf(a);
}
static int indexOf(String a, String b) {
return a == null || b == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, String b, int i) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, char b) {
return a == null ? -1 : a.indexOf(b);
}
static int indexOf(String a, int i, char b) {
return indexOf(a, b, i);
}
static int indexOf(String a, char b, int i) {
return a == null ? -1 : a.indexOf(b, i);
}
static int indexOf(String a, int i, String b) {
return a == null || b == null ? -1 : a.indexOf(b, i);
}
static int indexOf(A[] x, A a) {
int n = l(x);
for (int i = 0; i < n; i++)
if (eq(x[i], a))
return i;
return -1;
}
static void rotateStringBuffer(StringBuffer buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static void rotateStringBuilder(StringBuilder buf, int max) { try {
if (buf == null) return;
synchronized(buf) {
if (buf.length() <= max) return;
try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
buf.trimToSize();
}
} catch (Exception __e) { throw rethrow(__e); } }
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); }
static boolean empty(CharSequence s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(BitSet bs) { return bs == null || bs.isEmpty(); }
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
if (o instanceof byte[]) return empty((byte[]) o);
if (o == null) return true;
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) { return i == null || !i.hasNext(); }
static boolean empty(double[] a) { return a == null || a.length == 0; }
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static boolean empty(byte[] a) { return a == null || a.length == 0; }
static boolean empty(short[] a) { return a == null || a.length == 0; }
static boolean empty(MultiMap mm) { return mm == null || mm.isEmpty(); }
static boolean empty(File f) { return getFileSize(f) == 0; }
static boolean empty(IntRange r) { return r == null || r.empty(); }
static boolean empty(DoubleRange r) { return r == null || r.isEmpty(); }
static boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); }
static ArrayList cloneList(Iterable l) {
return l instanceof Collection ? cloneList((Collection) l) : asList(l);
}
static ArrayList cloneList(Collection l) {
if (l == null) return new ArrayList();
synchronized(collectionMutex(l)) {
return new ArrayList (l);
}
}
static Object pcallF_minimalExceptionHandling(Object f, Object... args) {
try {
return callFunction(f, args);
} catch (Throwable e) {
System.out.println(getStackTrace(e));
_storeException(e);
}
return null;
}
static Set vm_generalIdentityHashSet(Object name) {
synchronized(get(javax(), "generalMap")) {
Set set = (Set) (vm_generalMap_get(name));
if (set == null)
vm_generalMap_put(name, set = syncIdentityHashSet());
return set;
}
}
static Map vm_generalHashMap(Object name) {
synchronized(get(javax(), "generalMap")) {
Map m = (Map) (vm_generalMap_get(name));
if (m == null)
vm_generalMap_put(name, m = syncHashMap());
return m;
}
}
static AutoCloseable tempSetThreadLocal(final ThreadLocal tl, A a) {
if (tl == null) return null;
final A prev = setThreadLocal(tl, a);
return new AutoCloseable() { public String toString() { return "tl.set(prev);"; } public void close() throws Exception { tl.set(prev); }};
}
// get purpose 1: access a list/array/map (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static B get(Map map, A key) {
ret map != null ? map.get(key) : null;
}*/
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o == null) return null;
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
makeAccessible(f);
return f.get(o);
}
if (o instanceof DynamicObject)
return getOptDynOnly(((DynamicObject) o), field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
if (o == null) return null;
Field f = get_findField(o.getClass(), field);
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
makeAccessible(f);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
return get(o, field);
}
static boolean get(BitSet bs, int idx) {
return bs != null && bs.get(idx);
}
static B mapPutOrRemove(Map map, A key, B value) {
if (map != null && key != null)
if (value != null) return map.put(key, value);
else return map.remove(key);
return null;
}
static Class> _getClass(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static Class _getClass(Object o) {
return o == null ? null
: o instanceof Class ? (Class) o : o.getClass();
}
static Class _getClass(Object realm, String name) {
try {
return classLoaderForObject(realm).loadClass(classNameToVM(name));
} catch (ClassNotFoundException e) {
return null; // could optimize this
}
}
static A[] makeArray(Class type, int n) {
return (A[]) Array.newInstance(type, n);
}
static A firstThat(Iterable l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(A[] l, IF1 pred) {
for (A a : unnullForIteration(l))
if (pred.get(a))
return a;
return null;
}
static A firstThat(IF1 pred, Iterable l) {
return firstThat(l, pred);
}
static A firstThat(IF1 pred, A[] l) {
return firstThat(l, pred);
}
//static final Map> getOpt_cache = newDangerousWeakHashMap(f getOpt_special_init);
static class getOpt_Map extends WeakHashMap {
getOpt_Map() {
if (getOpt_special == null) getOpt_special = new HashMap();
clear();
}
public void clear() {
super.clear();
//print("getOpt clear");
put(Class.class, getOpt_special);
put(String.class, getOpt_special);
}
}
static final Map> getOpt_cache = _registerDangerousWeakMap(synchroMap(new getOpt_Map()));
//static final Map> getOpt_cache = _registerWeakMap(synchroMap(new getOpt_Map));
static HashMap getOpt_special; // just a marker
/*static void getOpt_special_init(Map map) {
map.put(Class.class, getOpt_special);
map.put(S.class, getOpt_special);
}*/
static Map getOpt_getFieldMap(Object o) {
Class c = _getClass(o);
HashMap map = getOpt_cache.get(c);
if (map == null)
map = getOpt_makeCache(c);
return map;
}
static Object getOpt_cached(Object o, String field) { try {
if (o == null) return null;
Map map = getOpt_getFieldMap(o);
if (map == getOpt_special) {
if (o instanceof Class)
return getOpt((Class) o, field);
/*if (o instanceof S)
ret getOpt(getBot((S) o), field);*/
if (o instanceof Map)
return ((Map) o).get(field);
}
Field f = map.get(field);
if (f != null) return f.get(o);
if (o instanceof DynamicObject)
return syncMapGet2(((DynamicObject) o).fieldValues, field);
return null;
} catch (Exception __e) { throw rethrow(__e); } }
// used internally - we are in synchronized block
static HashMap getOpt_makeCache(Class c) {
HashMap map;
if (isSubtypeOf(c, Map.class))
map = getOpt_special;
else {
map = new HashMap();
if (!reflection_classesNotToScan().contains(c.getName())) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields()) {
makeAccessible(f);
String name = f.getName();
if (!map.containsKey(name))
map.put(name, f);
}
_c = _c.getSuperclass();
} while (_c != null);
}
}
if (getOpt_cache != null) getOpt_cache.put(c, map);
return map;
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static PersistableThrowable persistableThrowable(Throwable e) {
return e == null ? null : new PersistableThrowable(e);
}
static boolean startsWithOneOf(String s, String... l) {
for (String x : l) if (startsWith(s, x)) return true; return false;
}
static boolean startsWithOneOf(String s, Matches m, String... l) {
for (String x : l) if (startsWith(s, x, m)) return true; return false;
}
static boolean isAGIBlueDomain(String domain) {
return domainIsUnder(domain, theAGIBlueDomain());
}
static String hostNameFromURL(String url) { try {
return new URL(url).getHost();
} catch (Exception __e) { throw rethrow(__e); } }
static String getType(Object o) {
return getClassName(o);
}
static long getFileSize(String path) {
return path == null ? 0 : new File(path).length();
}
static long getFileSize(File f) {
return f == null ? 0 : f.length();
}
static Object collectionMutex(List l) {
return l;
}
static Object collectionMutex(Object o) {
if (o instanceof List) return o;
String c = className(o);
if (eq(c, "java.util.TreeMap$KeySet"))
c = className(o = getOpt(o, "m"));
else if (eq(c, "java.util.HashMap$KeySet"))
c = className(o = get_raw(o, "this$0"));
if (eqOneOf(c, "java.util.TreeMap$AscendingSubMap", "java.util.TreeMap$DescendingSubMap"))
c = className(o = get_raw(o, "m"));
return o;
}
static Object callFunction(Object f, Object... args) {
return callF(f, args);
}
static Throwable _storeException_value;
static void _storeException(Throwable e) {
_storeException_value = e;
}
static Set syncIdentityHashSet() {
return (Set) synchronizedSet(identityHashSet());
}
static Map syncHashMap() {
return synchroHashMap();
}
static A setThreadLocal(ThreadLocal tl, A value) {
if (tl == null) return null;
A old = tl.get();
tl.set(value);
return old;
}
static Object getOptDynOnly(DynamicObject o, String field) {
if (o == null || o.fieldValues == null) return null;
return o.fieldValues.get(field);
}
static ClassLoader classLoaderForObject(Object o) {
if (o instanceof ClassLoader) return ((ClassLoader) o);
if (o == null) return null;
return _getClass(o).getClassLoader();
}
// Note: This is actually broken. Inner classes must stay with a $ separator
static String classNameToVM(String name) {
return name.replace(".", "$");
}
static String unnullForIteration(String s) {
return s == null ? "" : s;
}
static Collection unnullForIteration(Collection l) {
return l == null ? immutableEmptyList() : l;
}
static List unnullForIteration(List l) { return l == null ? immutableEmptyList() : l; }
static int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; }
static short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; }
static Map unnullForIteration(Map l) {
return l == null ? immutableEmptyMap() : l;
}
static Iterable unnullForIteration(Iterable i) {
return i == null ? immutableEmptyList() : i;
}
static A[] unnullForIteration(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnullForIteration(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnullForIteration(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnullForIteration(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnullForIteration(Pair p) {
return p != null ? p : new Pair(null, null);
}
static long unnullForIteration(Long l) { return l == null ? 0L : l; }
static void clear(Collection c) {
if (c != null) c.clear();
}
static void clear(Map map) {
if (map != null) map.clear();
}
static void put(Map map, A a, B b) {
if (map != null) map.put(a, b);
}
static void put(List l, int i, A a) {
if (l != null && i >= 0 && i < l(l)) l.set(i, a);
}
static B syncMapGet2(Map map, A a) {
if (map == null) return null;
synchronized(collectionMutex(map)) {
return map.get(a);
}
}
static B syncMapGet2(A a, Map map) {
return syncMapGet2(map, a);
}
static boolean isSubtypeOf(Class a, Class b) {
return b.isAssignableFrom(a); // << always hated that method, let's replace it!
}
static Set reflection_classesNotToScan_value = litset(
"jdk.internal.loader.URLClassPath"
);
static Set reflection_classesNotToScan() {
return reflection_classesNotToScan_value;
}
static boolean startsWith(String a, String b) {
return a != null && a.startsWith(unnull(b));
}
static boolean startsWith(String a, char c) {
return nemptyString(a) && a.charAt(0) == c;
}
static boolean startsWith(String a, String b, Matches m) {
if (!startsWith(a, b)) return false;
if (m != null) m.m = new String[] {substring(a, strL(b))};
return true;
}
static boolean startsWith(List a, List b) {
if (a == null || listL(b) > listL(a)) return false;
for (int i = 0; i < listL(b); i++)
if (neq(a.get(i), b.get(i)))
return false;
return true;
}
static boolean domainIsUnder(String domain, String mainDomain) {
return eqic(domain, mainDomain) || ewic(domain, "." + mainDomain);
}
static String theAGIBlueDomain() {
return "agi.blue";
}
static String className(Object o) {
return getClassName(o);
}
static boolean eqOneOf(Object o, Object... l) {
for (Object x : l) if (eq(o, x)) return true; return false;
}
static Set synchronizedSet() {
return synchroHashSet();
}
static Set synchronizedSet(Set set) {
return Collections.synchronizedSet(set);
}
static Set identityHashSet() {
return Collections.newSetFromMap(new IdentityHashMap());
}
static List immutableEmptyList() {
return Collections.emptyList();
}
static int[] emptyIntArray_a = new int[0];
static int[] emptyIntArray() { return emptyIntArray_a; }
static char[] emptyCharArray = new char[0];
static char[] emptyCharArray() { return emptyCharArray; }
static double[] emptyDoubleArray = new double[0];
static double[] emptyDoubleArray() { return emptyDoubleArray; }
static short[] emptyShortArray = new short[0];
static short[] emptyShortArray() { return emptyShortArray; }
static Map immutableEmptyMap() {
return Collections.emptyMap();
}
static Object[] emptyObjectArray_a = new Object[0];
static Object[] emptyObjectArray() { return emptyObjectArray_a; }
static Symbol emptySymbol_value;
static Symbol emptySymbol() {
if (emptySymbol_value == null) emptySymbol_value = symbol("");
return emptySymbol_value;
}
static HashSet litset(A... items) {
return lithashset(items);
}
static String unnull(String s) {
return s == null ? "" : s;
}
static Collection unnull(Collection l) {
return l == null ? emptyList() : l;
}
static List unnull(List l) { return l == null ? emptyList() : l; }
static int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; }
static Map unnull(Map l) {
return l == null ? emptyMap() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static A[] unnull(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnull(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnull(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnull(Pair p) {
return p != null ? p : new Pair(null, null);
}
static int unnull(Integer i) { return i == null ? 0 : i; }
static long unnull(Long l) { return l == null ? 0L : l; }
static double unnull(Double l) { return l == null ? 0.0 : l; }
static boolean nemptyString(String s) {
return s != null && s.length() > 0;
}
static String substring(String s, int x) {
return substring(s, x, strL(s));
}
static String substring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
int n = s.length();
if (y < x) y = x;
if (y > n) y = n;
if (x >= y) return "";
return s.substring(x, y);
}
static String substring(String s, IntRange r) {
return r == null ? null : substring(s, r.start, r.end);
}
// convenience method for quickly dropping a prefix
static String substring(String s, CharSequence l) {
return substring(s, lCharSequence(l));
}
static int strL(String s) {
return s == null ? 0 : s.length();
}
static int listL(Collection l) {
return l == null ? 0 : l.size();
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static boolean eqic(String a, String b) {
if ((a == null) != (b == null)) return false;
if (a == null) return true;
return a.equalsIgnoreCase(b);
}
static boolean eqic(Symbol a, Symbol b) {
return eq(a, b);
}
static boolean eqic(Symbol a, String b) {
return eqic(asString(a), b);
}
static boolean eqic(char a, char b) {
if (a == b) return true;
char u1 = Character.toUpperCase(a);
char u2 = Character.toUpperCase(b);
if (u1 == u2) return true;
return Character.toLowerCase(u1) == Character.toLowerCase(u2);
}
static boolean ewic(String a, String b) {
return endsWithIgnoreCase(a, b);
}
static boolean ewic(String a, String b, Matches m) {
return endsWithIgnoreCase(a, b, m);
}
// TODO: OurSyncCollections
static Set synchroHashSet() {
return Collections.synchronizedSet(new HashSet ());
}
static WeakHasherMap symbol_map = new WeakHasherMap(new Hasher() {
public int hashCode(Symbol symbol) { return symbol.text.hashCode(); }
public boolean equals(Symbol a, Symbol b) {
if (a == null) return b == null;
return b != null && eq(a.text, b.text);
}
});
static Symbol symbol(String s) {
if (s == null) return null;
synchronized(symbol_map) {
// TODO: avoid object creation by passing the string to findKey
Symbol symbol = new Symbol(s, true);
Symbol existingSymbol = symbol_map.findKey(symbol);
if (existingSymbol == null)
symbol_map.put(existingSymbol = symbol, true);
return existingSymbol;
}
}
static Symbol symbol(CharSequence s) {
if (s == null) return null;
if (s instanceof Symbol) return (Symbol) s;
if (s instanceof String) return symbol((String) s);
return symbol(str(s));
}
static Symbol symbol(Object o) {
return symbol((CharSequence) o);
}
static HashSet lithashset(A... items) {
HashSet set = new HashSet();
for (A a : items) set.add(a);
return set;
}
static Map emptyMap() {
return new HashMap();
}
static int lCharSequence(CharSequence s) {
return s == null ? 0 : s.length();
}
static String asString(Object o) {
return o == null ? null : o.toString();
}
static boolean endsWithIgnoreCase(String a, String b) {
int la = l(a), lb = l(b);
return la >= lb && regionMatchesIC(a, la-lb, b, 0, lb);
}
static boolean endsWithIgnoreCase(String a, String b, Matches m) {
if (!endsWithIgnoreCase(a, b)) return false;
if (m != null)
m.m = new String[] { substring(a, 0, l(a)-l(b)) };
return true;
}
static boolean regionMatchesIC(String a, int offsetA, String b, int offsetB, int len) {
return a != null && a.regionMatches(true, offsetA, b, offsetB, len);
}
// immutable, has strong refs
// Do not run in a synchronized block - it goes wrong in the presence
// of elaborate classloaders (like in Gazelle BEA)
// see #1102990 and #1102991
final static class _MethodCache {
final Class c;
final HashMap> cache = new HashMap();
_MethodCache(Class c) {
this.c = c; _init(); }
void _init() {
Class _c = c;
while (_c != null) {
for (Method m : _c.getDeclaredMethods())
if (!isAbstract(m) && !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
_c = _c.getSuperclass();
}
// add default methods - this might lead to a duplication
// because the overridden method is also added, but it's not
// a problem except for minimal performance loss.
for (Class intf : allInterfacesImplementedBy(c))
for (Method m : intf.getDeclaredMethods())
if (m.isDefault() && !reflection_isForbiddenMethod(m))
multiMapPut(cache, m.getName(), makeAccessible(m));
}
// Returns only matching methods
Method findMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
Method findStaticMethod(String method, Object[] args) { try {
List m = cache.get(method);
if (m == null) return null;
int n = m.size();
for (int i = 0; i < n; i++) {
Method me = m.get(i);
if (isStaticMethod(me) && call_checkArgs(me, args, false))
return me;
}
return null;
} catch (Exception __e) { throw rethrow(__e); } }
}
static abstract class VF1 implements IVF1 {
public abstract void get(A a);
}
static class Matches {
String[] m;
Matches() {}
Matches(String... m) {
this.m = m;}
String get(int i) { return i < m.length ? m[i] : null; }
String unq(int i) { return unquote(get(i)); }
String tlc(int i) { return unq(i).toLowerCase(); }
boolean bool(int i) { return "true".equals(unq(i)); }
String rest() { return m[m.length-1]; } // for matchStart
int psi(int i) { return Integer.parseInt(unq(i)); }
public String toString() { return "Matches(" + joinWithComma(quoteAll(asList(m))) + ")"; }
public int hashCode() { return _hashCode(toList(m)); }
public boolean equals(Object o) { return o instanceof Matches && arraysEqual(m, ((Matches) o).m); }
}
static class GSay {
String text;
Integer voiceNr;
String speaker; // optional, for some voices
GSay() {}
GSay(String text) {
this.text = text;}
File audioFile() {
return loadBinaryPageOnce(
appendParamsToURL("https://mouth.gazelle.rocks/beaHTML/16",
"page" , 0, "voiceNr", voiceNr, "speaker", speaker, "text", text));
}
}
// for the version with MasterSymbol (used WAY back in "Smart Bot"!) see #1010608
static class Symbol implements CharSequence {
String text;
Symbol() {}
Symbol(String text, boolean dummy) {
this.text = text;} // weird signature to prevent accidental calling
public int hashCode() { return _hashCode(text); }
public String toString() { return text; }
public boolean equals(Object o) {
return this == o;
}
// implementation of CharSequence methods
public int length() { return text.length(); }
public char charAt(int index) { return text.charAt(index); }
public CharSequence subSequence(int start, int end) {
return text.substring(start, end);
}
}
static abstract class F0 {
abstract A get();
}
static abstract class F1 {
abstract B get(A a);
}
// you still need to implement hasNext() and next()
static abstract class IterableIterator implements Iterator , Iterable {
public Iterator iterator() {
return this;
}
public void remove() {
unsupportedOperation();
}
}
static class ContinuousOscillators_TestAudioRestoration {
String audioURL = "https://mouth.gazelle.rocks/beaHTML/15/5502%2Frecognize+-+61351880347bd84b28c7f42d779cde94.mp3";
short[] inputSamples;
double inputSampleRate = 48000;
final ContinuousOscillators_TestAudioRestoration setSeparateFrequencies(boolean separateFrequencies){ return separateFrequencies(separateFrequencies); }
ContinuousOscillators_TestAudioRestoration separateFrequencies(boolean separateFrequencies) { this.separateFrequencies = separateFrequencies; return this; } final boolean getSeparateFrequencies(){ return separateFrequencies(); }
boolean separateFrequencies() { return separateFrequencies; } boolean separateFrequencies = false;
final ContinuousOscillators_TestAudioRestoration setCumulative(boolean cumulative){ return cumulative(cumulative); }
ContinuousOscillators_TestAudioRestoration cumulative(boolean cumulative) { this.cumulative = cumulative; return this; } final boolean getCumulative(){ return cumulative(); }
boolean cumulative() { return cumulative; } boolean cumulative = false;
final ContinuousOscillators_TestAudioRestoration setSeparateRealAndImag(boolean separateRealAndImag){ return separateRealAndImag(separateRealAndImag); }
ContinuousOscillators_TestAudioRestoration separateRealAndImag(boolean separateRealAndImag) { this.separateRealAndImag = separateRealAndImag; return this; } final boolean getSeparateRealAndImag(){ return separateRealAndImag(); }
boolean separateRealAndImag() { return separateRealAndImag; } boolean separateRealAndImag = false;
final ContinuousOscillators_TestAudioRestoration setPlayRestored(boolean playRestored){ return playRestored(playRestored); }
ContinuousOscillators_TestAudioRestoration playRestored(boolean playRestored) { this.playRestored = playRestored; return this; } final boolean getPlayRestored(){ return playRestored(); }
boolean playRestored() { return playRestored; } boolean playRestored = false;
final ContinuousOscillators_TestAudioRestoration setShowImage(boolean showImage){ return showImage(showImage); }
ContinuousOscillators_TestAudioRestoration showImage(boolean showImage) { this.showImage = showImage; return this; } final boolean getShowImage(){ return showImage(); }
boolean showImage() { return showImage; } boolean showImage = false;
boolean useInputSampleRate = true;
double silence = 0.2;
double minFreq = 0, maxFreq = 48000;
int useEveryNthOscillator = 1;
short[] resampled;
List audioOutput = new ArrayList();
File wavOut;
ContinuousOscillators co = new ContinuousOscillators();
void loadAudioURL() {
File mp3 = loadBinaryPageOnce(audioURL);
loadMP3(mp3);
}
void loadMP3(File mp3) {
printFileInfo("mp3", mp3);
File wav = mp3ToWAVUnlessExists(mp3, replaceExtension(mp3, ".mp3", ".wav"));
loadWAV(wav);
}
void loadWAV(File wav) {
//playWAV(wav);
printFileInfo("wav", wav);
wavOut = appendToBaseFileName(wav, ".restored");
WAVDecoder decoder = new WAVDecoder(wav); try {
print("sampleRate" , decoder.sampleRate);
int n = decoder.totalValues();
inputSamples = decodeWAVToMonoSamples(decoder, n);
inputSampleRate = decoder.sampleRate;
} finally { _close(decoder); }}
// assumes soundSource is using the default inputSampleRate
void setAudio(double seconds, VF1 soundSource) {
inputSamples = concatShortArrays(soundSourceToShortArrays(seconds, soundSource, 1));
print("inputSamples" , sfu(takeFirst(10, inputSamples)));
}
public void run() { try {
if (useInputSampleRate) co.sampleRate = inputSampleRate;
resampled = convertSampleRate_shortArray_simple(inputSampleRate, co.sampleRate, inputSamples);
print("samples" , l(resampled));
IQuerySound sound = shortSamplesToQuerySound(resampled);
//co.setAudio(new StaticAudioSample(ll(resampled), 1, co.sampleRate));
co.makeFullWindow(sound, intRange(0, l(resampled)));
print("windowBounds" , co.windowBounds());
co.startOscillators();
co.stepTo(co.windowBounds());
print("coverageByFreq" , co.coverageByFreq());
restoreAudio();
double[] audio = concatDoubleArrays(audioOutput);
double[] audioNorm = normalizeDoubles(audio, 32767);
if (wavOut != null) {
shortArrayToMonoWAVE(doubleToShortArray_iround(audioNorm), wavOut, co.sampleRate);
printFileInfo("wavOut", wavOut);
if (playRestored) playWAV(wavOut);
}
print("audioNorm" , sfu(takeFirst(10, audioNorm)));
double pixelsPerSecond = 100;
if (showImage)
dm_showPixelatedImage(co.imageForWindow(pixelsPerSecond));
} catch (Exception __e) { throw rethrow(__e); } }
void restoreAudio() {
List oscillators = new ArrayList();
//double ratio = 2; // octave
int nOscillators = l(co.oscillators);
var lOsc = asList(co.oscillators);
for (int i = 0; i < nOscillators; i++) {
if ((i % useEveryNthOscillator) == 0)
oscillators.add(lOsc.get(i));
}
oscillators = filter(oscillators, o -> between(o.frequency().get(), minFreq, maxFreq));
print("Using " + nFrequencies(oscillators) + ": " + map(oscillators, o -> formatDouble(o.frequency().get(), 1)));
if (separateFrequencies) {
wavOut = appendToBaseFileName(wavOut, ".separate");
double[] cum = null;
for (var o : oscillators) {
pnl(map(o.intensities, (k, v) ->
o.frequency() + " " + formatDouble(k, 1) + " = " + renderComplexWithAngle(div(v.first(), l(k)*32767))));
co.toAudio_shouldPrint = (i, n) -> i < 30 || i >= n-10;
for (var xx : separateRealAndImag ? ll(1, 2) : ll(0)) {
co.realOnly = (xx & 1) != 0;
co.imagOnly = (xx & 2) != 0;
double[] newAudio = co.toAudio(ifloor(co.windowBounds()), ll(o));
if (cumulative) cum = newAudio = doubleAdd(cum, newAudio);
audioOutput.add(newAudio);
audioOutput.add(repDouble(iround(co.sampleRate*silence), 0));
co.toAudio_shouldPrint = null;
co.realOnly = co.imagOnly = false;
}
}
}
audioOutput.add(co.toAudio(ifloor(co.windowBounds()), oscillators));
}
}
static interface IF0 {
A get();
}
static interface Hasher {
int hashCode(A a);
boolean equals(A a, A b);
}
static interface IF2 {
C get(A a, B b);
}
static interface IF1 {
B get(A a);
}
static class SineSoundSource extends VF1 {
double freq;
double sampleRate = 44100;
double step;
double phase;
SineSoundSource(double freq, double sampleRate) {
this.sampleRate = sampleRate;
this.freq = freq;
calcStep();
}
SineSoundSource(double freq) {
this.freq = freq;
calcStep();
}
void calcStep() {
step = pi()*2*freq/sampleRate;
}
public void get(double[] lr) {
fillDoubleArray(lr, Math.sin(phase)*32767);
phase += step;
}
}
/*
* @(#)WeakHashMap.java 1.5 98/09/30
*
* Copyright 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
// From https://github.com/mernst/plume-lib/blob/df0bfafc3c16848d88f4ea0ef3c8bf3367ae085e/java/src/plume/WeakHasherMap.java
static final class WeakHasherMap extends AbstractMap implements Map {
private Hasher hasher = null;
/*@Pure*/
private boolean keyEquals(Object k1, Object k2) {
return (hasher==null ? k1.equals(k2)
: hasher.equals(k1, k2));
}
/*@Pure*/
private int keyHashCode(Object k1) {
return (hasher==null ? k1.hashCode()
: hasher.hashCode(k1));
}
// The WeakKey class can't be static because it depends on the hasher.
// That in turn means that its methods can't be static.
// However, I need to be able to call the methods such as create() that
// were static in the original version of this code.
// This finesses that.
private /*@Nullable*/ WeakKey WeakKeyCreate(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private /*@Nullable*/ WeakKey WeakKeyCreate(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
// Cannot be a static class: uses keyHashCode() and keyEquals()
private final class WeakKey extends WeakReference {
private int hash; /* Hashcode of key, stored here since the key
may be tossed by the GC */
private WeakKey(K k) {
super(k);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k) {
if (k == null) return null;
else return new WeakKey(k);
}
private WeakKey(K k, ReferenceQueue super K> q) {
super(k, q);
hash = keyHashCode(k);
}
private /*@Nullable*/ WeakKey create(K k, ReferenceQueue super K> q) {
if (k == null) return null;
else return new WeakKey(k, q);
}
/* A WeakKey is equal to another WeakKey iff they both refer to objects
that are, in turn, equal according to their own equals methods */
/*@Pure*/
@Override
public boolean equals(/*@Nullable*/ Object o) {
if (o == null) return false; // never happens
if (this == o) return true;
// This test is illegal because WeakKey is a generic type,
// so use the getClass hack below instead.
// if (!(o instanceof WeakKey)) return false;
if (!(o.getClass().equals(WeakKey.class))) return false;
Object t = this.get();
@SuppressWarnings("unchecked")
Object u = ((WeakKey)o).get();
if ((t == null) || (u == null)) return false;
if (t == u) return true;
return keyEquals(t, u);
}
/*@Pure*/
@Override
public int hashCode() {
return hash;
}
}
/* Hash table mapping WeakKeys to values */
private HashMap hash;
/* Reference queue for cleared WeakKeys */
private ReferenceQueue super K> queue = new ReferenceQueue();
/* Remove all invalidated entries from the map, that is, remove all entries
whose keys have been discarded. This method should be invoked once by
each public mutator in this class. We don't invoke this method in
public accessors because that can lead to surprising
ConcurrentModificationExceptions. */
@SuppressWarnings("unchecked")
private void processQueue() {
WeakKey wk;
while ((wk = (WeakKey)queue.poll()) != null) { // unchecked cast
hash.remove(wk);
}
}
/* -- Constructors -- */
/**
* Constructs a new, empty WeakHashMap with the given
* initial capacity and the given load factor.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @param loadFactor the load factor of the WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero, or if the load factor is
* nonpositive
*/
public WeakHasherMap(int initialCapacity, float loadFactor) {
hash = new HashMap(initialCapacity, loadFactor);
}
/**
* Constructs a new, empty WeakHashMap with the given
* initial capacity and the default load factor, which is
* 0.75.
*
* @param initialCapacity the initial capacity of the
* WeakHashMap
*
* @throws IllegalArgumentException If the initial capacity is less than
* zero
*/
public WeakHasherMap(int initialCapacity) {
hash = new HashMap(initialCapacity);
}
/**
* Constructs a new, empty WeakHashMap with the default
* capacity and the default load factor, which is 0.75.
*/
public WeakHasherMap() {
hash = new HashMap();
}
/**
* Constructs a new, empty WeakHashMap with the default
* capacity and the default load factor, which is 0.75.
* The WeakHashMap uses the specified hasher for hashing
* keys and comparing them for equality.
* @param h the Hasher to use when hashing values for this map
*/
public WeakHasherMap(Hasher h) {
hash = new HashMap();
hasher = h;
}
/* -- Simple queries -- */
/**
* Returns the number of key-value mappings in this map.
* Note: In contrast to most implementations of the
* Map interface, the time required by this operation is
* linear in the size of the map.
*/
/*@Pure*/
@Override
public int size() {
return entrySet().size();
}
/**
* Returns true if this map contains no key-value mappings.
*/
/*@Pure*/
@Override
public boolean isEmpty() {
return entrySet().isEmpty();
}
/**
* Returns true if this map contains a mapping for the
* specified key.
*
* @param key the key whose presence in this map is to be tested
*/
/*@Pure*/
@Override
public boolean containsKey(Object key) {
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.containsKey(WeakKeyCreate(kkey));
}
/* -- Lookup and modification operations -- */
/**
* Returns the value to which this map maps the specified key.
* If this map does not contain a value for this key, then return
* null.
*
* @param key the key whose associated value, if any, is to be returned
*/
/*@Pure*/
@Override
public /*@Nullable*/ V get(Object key) { // type of argument is Object, not K
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.get(WeakKeyCreate(kkey));
}
/**
* Updates this map so that the given key maps to the given
* value. If the map previously contained a mapping for
* key then that mapping is replaced and the previous value is
* returned.
*
* @param key the key that is to be mapped to the given
* value
* @param value the value to which the given key is to be
* mapped
*
* @return the previous value to which this key was mapped, or
* null if if there was no mapping for the key
*/
@Override
public V put(K key, V value) {
processQueue();
return hash.put(WeakKeyCreate(key, queue), value);
}
/**
* Removes the mapping for the given key from this map, if
* present.
*
* @param key the key whose mapping is to be removed
*
* @return the value to which this key was mapped, or null if
* there was no mapping for the key
*/
@Override
public V remove(Object key) { // type of argument is Object, not K
processQueue();
@SuppressWarnings("unchecked")
K kkey = (K) key;
return hash.remove(WeakKeyCreate(kkey));
}
/**
* Removes all mappings from this map.
*/
@Override
public void clear() {
processQueue();
hash.clear();
}
/* -- Views -- */
/* Internal class for entries */
// This can't be static, again because of dependence on hasher.
@SuppressWarnings("TypeParameterShadowing")
private final class Entry implements Map.Entry {
private Map.Entry ent;
private K key; /* Strong reference to key, so that the GC
will leave it alone as long as this Entry
exists */
Entry(Map.Entry ent, K key) {
this.ent = ent;
this.key = key;
}
/*@Pure*/
@Override
public K getKey() {
return key;
}
/*@Pure*/
@Override
public V getValue() {
return ent.getValue();
}
@Override
public V setValue(V value) {
return ent.setValue(value);
}
/*@Pure*/
private boolean keyvalEquals(K o1, K o2) {
return (o1 == null) ? (o2 == null) : keyEquals(o1, o2);
}
/*@Pure*/
private boolean valEquals(V o1, V o2) {
return (o1 == null) ? (o2 == null) : o1.equals(o2);
}
/*@Pure*/
@SuppressWarnings("NonOverridingEquals")
public boolean equals(Map.Entry e /* Object o*/) {
// if (! (o instanceof Map.Entry)) return false;
// Map.Entry e = (Map.Entry)o;
return (keyvalEquals(key, e.getKey())
&& valEquals(getValue(), e.getValue()));
}
/*@Pure*/
@Override
public int hashCode() {
V v;
return (((key == null) ? 0 : keyHashCode(key))
^ (((v = getValue()) == null) ? 0 : v.hashCode()));
}
}
/* Internal class for entry sets */
private final class EntrySet extends AbstractSet> {
Set> hashEntrySet = hash.entrySet();
@Override
public Iterator> iterator() {
return new Iterator>() {
Iterator> hashIterator = hashEntrySet.iterator();
Map.Entry next = null;
@Override
public boolean hasNext() {
while (hashIterator.hasNext()) {
Map.Entry ent = hashIterator.next();
WeakKey wk = ent.getKey();
K k = null;
if ((wk != null) && ((k = wk.get()) == null)) {
/* Weak key has been cleared by GC */
continue;
}
next = new Entry(ent, k);
return true;
}
return false;
}
@Override
public Map.Entry next() {
if ((next == null) && !hasNext())
throw new NoSuchElementException();
Map.Entry e = next;
next = null;
return e;
}
@Override
public void remove() {
hashIterator.remove();
}
};
}
/*@Pure*/
@Override
public boolean isEmpty() {
return !(iterator().hasNext());
}
/*@Pure*/
@Override
public int size() {
int j = 0;
for (Iterator> i = iterator(); i.hasNext(); i.next()) j++;
return j;
}
@Override
public boolean remove(Object o) {
processQueue();
if (!(o instanceof Map.Entry,?>)) return false;
@SuppressWarnings("unchecked")
Map.Entry e = (Map.Entry)o; // unchecked cast
Object ev = e.getValue();
WeakKey wk = WeakKeyCreate(e.getKey());
Object hv = hash.get(wk);
if ((hv == null)
? ((ev == null) && hash.containsKey(wk)) : hv.equals(ev)) {
hash.remove(wk);
return true;
}
return false;
}
/*@Pure*/
@Override
public int hashCode() {
int h = 0;
for (Iterator> i = hashEntrySet.iterator(); i.hasNext(); ) {
Map.Entry ent = i.next();
WeakKey wk = ent.getKey();
Object v;
if (wk == null) continue;
h += (wk.hashCode()
^ (((v = ent.getValue()) == null) ? 0 : v.hashCode()));
}
return h;
}
}
private /*@Nullable*/ Set> entrySet = null;
/**
* Returns a Set view of the mappings in this map.
*/
/*@SideEffectFree*/
@Override
public Set> entrySet() {
if (entrySet == null) entrySet = new EntrySet();
return entrySet;
}
// find matching key
K findKey(Object key) {
processQueue();
K kkey = (K) key;
// TODO: use replacement for HashMap to avoid reflection
WeakKey wkey = WeakKeyCreate(kkey);
WeakKey found = hashMap_findKey(hash, wkey);
return found == null ? null : found.get();
}
}
static class PersistableThrowable extends DynamicObject {
String className;
String msg;
String stacktrace;
PersistableThrowable() {}
PersistableThrowable(Throwable e) {
if (e == null)
className = "Crazy Null Error";
else {
className = getClassName(e).replace('/', '.');
msg = e.getMessage();
stacktrace = getStackTrace_noRecord(e);
}
}
public String toString() {
return nempty(msg) ? className + ": " + msg : className;
}
}
static class Frequency implements Comparable , IFieldsToList{
double frequency;
Frequency() {}
public boolean equals(Object o) {
if (!(o instanceof Frequency)) return false;
Frequency __1 = (Frequency) o;
return frequency == __1.frequency;
}
public int hashCode() {
int h = 1933944124;
h = boostHashCombine(h, _hashCode(frequency));
return h;
}
public Object[] _fieldsToList() { return new Object[] {frequency}; }
final double getInterval(){ return interval(); }
double interval() { return interval; } double interval;
final double get(){ return frequency(); }
double frequency() { return frequency; }
Frequency(double frequency) {
this.frequency = frequency; interval = doubleRatio(1, frequency); }
public String toString() { return frequency + " Hz"; }
public int compareTo(Frequency f) {
return cmp(frequency, f.frequency);
}
}
static interface IVF1 {
void get(A a);
}
static class Fail extends RuntimeException implements IFieldsToList{
Object[] objects;
Fail() {}
Fail(Object... objects) {
this.objects = objects;}public Object[] _fieldsToList() { return new Object[] {objects}; }
Fail(Throwable cause, Object... objects) {
super(cause);
this.objects = objects;
}
public String toString() { return joinNemptiesWithColon("Fail", commaCombine(getCause(), objects)); }
}
static class Pair implements Comparable> {
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);
}
public String toString() {
return "<" + a + ", " + b + ">";
}
public int compareTo(Pair p) {
if (p == null) return 1;
int i = ((Comparable ) a).compareTo(p.a);
if (i != 0) return i;
return ((Comparable) b).compareTo(p.b);
}
}
static interface IFieldsToList {
Object[] _fieldsToList();
}
interface IQuerySound {
int channels();
double getSample(int channel, double time);
}
static class ContinuousOscillators {
boolean debug = false;
int channels = 1;
double sampleRate = 48000;
double currentSample;
IQuerySound sound;
IAudioSample audio;
SlidingWindow window;
boolean renderUsingSine = false; // or square wave
boolean realOnly, imagOnly; // for testing
double maxRelFreq = 0.25; // maximum oscillator frequency relative to sample rate
long haarFeaturesChecked;
class Oscillator extends HasKey {
Oscillator() {}
double currentPeriodStart;
// all recorded intensities
TreeMap> intensities = new TreeMap();
double interval; // length of period in samples
Oscillator(Frequency f) {
super(f);
interval = frequency().interval()*sampleRate;
}
Frequency frequency() { return key(); }
double interval() { return interval; }
void record_impl(DoubleRange r, Channels c) {
intensities.put(r, c);
}
void measure() {
DoubleRange p1 = doubleRangeWithLength(currentPeriodStart, interval);
AudioHaarFeature haar = new AudioHaarFeature(audio, p1);
record(this, p1, haar.getComplex());
haarFeaturesChecked += 2;
schuleNextOscillation();
}
void initial() {
completionsForSample.put(currentPeriodStart, this);
}
void schuleNextOscillation() {
completionsForSample.put(currentPeriodStart = phase360(), this);
}
double phase360() { return currentPeriodStart + interval(); }
} // end of Oscillator
TreeHasKeyMap oscillators;
TreeMultiMap completionsForSample = new TreeMultiMap();
ContinuousOscillators() {}
ContinuousOscillators(IAudioSample audio, double currentSample) {
this.currentSample = currentSample; setAudio(audio); }
ContinuousOscillators(IAudioSample audio) { setAudio(audio); } // start at time 0
void setFrequencies(Iterable frequencies) {
oscillators = new TreeHasKeyMap(map(f -> new Oscillator(f), filter(frequencies,
f -> between(f.get(), 1, sampleRate*maxRelFreq))));
}
void setAudio(IAudioSample audio) {
this.audio = audio;
window = optCast(SlidingWindow.class, audio);
}
int nFrequencies() { return oscillators.size(); }
void startOscillators() {
for (var o : oscillators) o.initial();
}
void stepTo(DoubleRange timeRange) {
while (true) { ping();
Double t = firstKey(completionsForSample);
if (t != null && t <= timeRange.end) {
var list = completionsForSample.getAndClear(t);
if (debug) printVars ("t", t, "list", list);
for (Oscillator o : list)
o.measure();
} else
break;
}
}
void record(Oscillator o, DoubleRange r, Channels c) {
if (o == null) return;
o.record_impl(r, c);
}
Frequency lowestFrequency() { return oscillators.firstKey(); }
Frequency highestFrequency() { return oscillators.lastKey(); }
int minWindowSize() {
return iceil(sampleRate*lowestFrequency().interval());
}
void makeSmallestWindow(IQuerySound sound) {
this.sound = sound;
setAudio(new SlidingWindow(channels, sampleRate, sound, 0, minWindowSize()));
}
void makeFullWindow(IQuerySound sound, IntRange r) {
this.sound = sound;
setAudio(new SlidingWindow(channels, sampleRate, sound,
r.start, r.length()));
}
double windowSize() { return window.length(); }
String stats() { return renderVars("audio", audio, "haarFeaturesChecked", haarFeaturesChecked); }
// how much horizontal area have we covered
List coverageByFreq() {
return mapReversed(oscillators, o -> totalLengthOfDoubleRanges(keys(o.intensities)));
}
DoubleRange windowBounds() { return window.bounds(); }
IIntegralImage imageColumn(DoubleRange timeRange) {
int n = nFrequencies();
double[] col = rawImageColumn(timeRange);
double[] col2 = normalizeDoubles(col, 255);
return bwIntegralImageFromFunction(1, n, (x, y) -> ifloor(col2[y]));
}
double[] rawImageColumn(DoubleRange timeRange) {
int n = nFrequencies();
var l = reversedList(oscillators);
double[] col = new double[n];
for (int y = 0; y < n; y++) {
TreeMap> l2 = l.get(y).intensities;
// find right period
DoubleRange period = l2.floorKey(timeRange);
if (period == null) continue;
double amplitude = l2.get(period).first().abs();
col[y] = amplitude;
}
return col;
}
MakesBufferedImage imageForWindow(double pixelsPerSecond) {
List images = new ArrayList();
double len = windowBounds().length()/sampleRate;
int pixels = iround(len*pixelsPerSecond);
for (int i = 0; i < pixels; i++) {
DoubleRange range = doubleRange(
i/pixelsPerSecond*sampleRate+windowBounds().start(),
(i+1)/pixelsPerSecond*sampleRate+windowBounds().start());
//print(+range);
images.add(imageColumn(range));
}
return mergeBWImagesHorizontally(map(__21 -> toBWImage(__21), images), "spacing" , 0);
}
double[] toAudio(IntRange sampleRange) { return toAudio(sampleRange, oscillators); }
double[] toAudio(IntRange sampleRange, Iterable oscillatorsToRender) {
double[] samples = new double[l(sampleRange)];
class PerFreq {
Oscillator o;
DoubleRange period;
Channels intensity;
PerFreq(Oscillator o) {
this.o = o;
setPeriod(o.intensities.floorKey(toDoubleRange(sampleRange)));
//printVars("PerFreq", f := o.frequency(), +sampleRange, +period, firstPeriod := firstKey(o.intensities));
}
void setPeriod(DoubleRange period) {
this.period = period;
intensity = period == null ? null : o.intensities.get(period);
}
void nextPeriod(double t) {
while (period != null && t >= period.end)
setPeriod(o.intensities.higherKey(period));
}
}
List perFreqs = map(oscillatorsToRender, o -> new PerFreq(o));
for (int i = 0; i < l(samples); i++) {
double t = sampleRange.start+i; // t is time in samples
double sum = 0;
for (var pf : perFreqs) {
pf.nextPeriod(t);
boolean shouldPrint = toAudio_shouldPrint(i, l(samples));
if (pf.intensity != null) {
Complex c = div(pf.intensity.first(), l(pf.period));
double t2 = t-pf.period.start;
double frac = t2/pf.o.interval;
//double phiRE = frac*pi()*2;
//double phiIM = phiRE+pi()/2;
if (shouldPrint)
printVars("f" , pf.o.frequency(), "i", i, "interval" , formatDouble1(pf.o.interval)/*, interval2 := l(pf.period)*/, "t", t, "t2", t2, "frac" , formatDouble2(frac),
"c" , renderComplexWithAngle(div(c, 32768)));
if (realOnly) c = complex(c.re());
else if (imagOnly) c = complex(0, c.im());
sum += renderFrequencySample(c, frac);
} else
if (shouldPrint)
printVars("f" , pf.o.frequency(), "i", i, "interval" , pf.o.interval, "t", t, "c" , 0);
}
samples[i] = sum;
}
return samples;
}
double renderFrequencySample(Complex c, double frac) {
return (renderUsingSine
? new RenderFrequencySample_Sine()
: new RenderFrequencySample_SquareWave()).get(c, frac);
}
transient IF2 toAudio_shouldPrint;
boolean toAudio_shouldPrint(int i, int n) { return toAudio_shouldPrint != null ? toAudio_shouldPrint.get(i, n) : toAudio_shouldPrint_base(i, n); }
final boolean toAudio_shouldPrint_fallback(IF2 _f, int i, int n) { return _f != null ? _f.get(i, n) : toAudio_shouldPrint_base(i, n); }
boolean toAudio_shouldPrint_base(int i, int n) { return false; }
}
// https://github.com/s4l4x/audio-analysis/blob/master/src/com/badlogic/audio/io/WaveDecoder.java
/**
* A simple class that can read in the PCM data from a
* Wav file, converting the data to signed 32-bit floats
* in the range [-1,1], merging stereo channels to a mono
* channel for processing. This only supports 16-bit signed
* stereo and mono Wav files with a sampling rate of 44100.
*
* @author mzechner
*
*/
static class WAVDecoder /*implements com.badlogic.audio.io.Decoder*/ implements AutoCloseable {
/** the input stream we read from **/
EndianDataInputStream in;
/** number of channels **/
int channels;
/** sample rate in Herz**/
float sampleRate;
boolean ignoreSampleRate = true;
boolean twentyFourBit = false;
// data length in bytes according to header
int specifiedDataLength;
int remainingDataBytes;
static int defaultBufferSize = 128*1024; //1024*1024
WAVDecoder(File wavFile) {
this(fileInputStream(wavFile));
}
WAVDecoder(InputStream stream) { try {
in = new EndianDataInputStream( new BufferedInputStream( stream, defaultBufferSize) );
if( !in.read4ByteString().equals( "RIFF" ) )
throw new IllegalArgumentException( "not a wav" );
in.readIntLittleEndian();
if( !in.read4ByteString().equals( "WAVE" ) )
throw new IllegalArgumentException( "expected WAVE tag" );
String s = in.read4ByteString();
if (eq(s, "bext")) { // skip extension block
in.skip(in.readIntLittleEndian());
s = in.read4ByteString();
}
if (!s.equals("fmt "))
throw new IllegalArgumentException( "expected fmt tag, got: " + s);
if( in.readIntLittleEndian() != 16 )
throw new IllegalArgumentException( "expected wave chunk size to be 16" );
int format;
if ((format = in.readShortLittleEndian()) != 1)
throw new IllegalArgumentException( "expected format to be 1, got: " + format);
channels = in.readShortLittleEndian();
//print("Channels: " + channels);
sampleRate = in.readIntLittleEndian();
if (sampleRate != 44100)
if (ignoreSampleRate) {
// print("Sample rate: " + sampleRate);
} else
throw fail("Not 44100 sampling rate: " + sampleRate);
in.readIntLittleEndian();
in.readShortLittleEndian();
int fmt = in.readShortLittleEndian();
if (fmt == 24) twentyFourBit = true;
else if (fmt != 16)
throw fail("Only 16/24-bit samples supported: " + fmt);
String tag;
while (!(tag = in.read4ByteString()).equals("data")) {
//print("Skipping tag " + tag);
//fail( "expected data tag, got: " + tag);
int len = in.readIntLittleEndian();
in.skip(len);
}
remainingDataBytes = specifiedDataLength = in.readIntLittleEndian();
} catch (Exception __e) { throw rethrow(__e); } }
/**
* Tries to read in samples.length samples, merging stereo to a mono
* channel by averaging and converting non float formats to float 32-bit.
* Returns the number of samples actually read. Guarantees that samples.length
* samples are read in if there was enough data in the stream.
*
* @param samples The samples array to write the samples to
* @return The number of samples actually read.
*/
public int readMonoSamples(short[] samples) { return readMonoSamples(samples, samples.length); }
public int readMonoSamples(short[] samples, int n) {
int readSamples = 0;
for (int i = 0; i < n && remainingDataBytes > 0; i++) {
double sample = 0;
try {
for (int j = 0; j < channels; j++)
sample += readSample();
sample /= channels;
samples[i] = (short) iround(max(-32768, min(32767, sample)));
readSamples++;
}
catch (Exception ex) { break; } // ouch
}
return readSamples;
}
public int readStereoSamples(short[] samples) { return readStereoSamples(samples, samples.length); }
public int readStereoSamples(short[] samples, int n) {
int readSamples = 0;
for (int i = 0; i < n && remainingDataBytes > 0; i += 2) {
double sample = 0;
try {
short left = readSample();
short right;
if (channels > 1)
right = readSample();
else
right = left;
samples[i] = left;
samples[i+1] = right;
readSamples += 2;
}
catch (Exception ex) { break; } // ouch
}
return readSamples;
}
short readSample() { try {
if (twentyFourBit) { --remainingDataBytes; in.read(); }
remainingDataBytes -= 2;
return in.readShortLittleEndian();
} catch (Exception __e) { throw rethrow(__e); } }
int bytesPerValue() { return twentyFourBit ? 3 : 2; }
int totalValues() { return specifiedDataLength/bytesPerValue(); }
// skips this number of samples (what is the terminology again
// for 1 value vs values)
public void skipSamples(long samples) { try {
long bytesToSkip = samples*channels*bytesPerValue();
remainingDataBytes -= bytesToSkip;
in.skip(bytesToSkip);
} catch (Exception __e) { throw rethrow(__e); } }
public void close() { try { in.close(); } catch (Exception __e) { throw rethrow(__e); } }
}
static class RenderFrequencySample_SquareWave implements RenderFrequencySample {
public double get(Complex c, double frac) {
double abs = c.abs();
if (abs == 0) return 0;
frac = frac_nonNeg(frac + c.fracAngle());
return abs * (frac < .5 ? 1 : -1);
}
public void subtractPeriodFrom(SubtractedAudio audio, DoubleRange period, Complex intensity) {
double goHigh = fracNonNeg(-intensity.fracAngle());
double abs = intensity.abs();
double goLow = fracNonNeg(goHigh+.5);
double t1 = period.start, t2 = period.end, n = l(period);
//if (switchPoint < switchPoint2)
audio.subtractPlateau(t1, t1+goHigh*n, abs);
audio.subtractPlateau( t1+goHigh*n, t2, -abs);
audio.subtractPlateau(t1, t1+goLow*n, -abs);
audio.subtractPlateau( t1+goLow*n, t2, abs);
}
}
// it's unclear whether the end is inclusive or exclusive
// (usually exclusive I guess)
static class IntRange {
int start, end;
IntRange() {}
IntRange(int start, int end) {
this.end = end;
this.start = start;}
IntRange(IntRange r) { start = r.start; end = r.end; }
public boolean equals(Object o) { return stdEq2(this, o); }
public int hashCode() { return stdHash2(this); }
final int length() { return end-start; }
final boolean empty() { return start >= end; }
final boolean isEmpty() { return start >= end; }
static String _fieldOrder = "start end";
public String toString() { return "[" + start + ";" + end + "]"; }
}
static class TreeMultiMap extends MultiMap {
TreeMultiMap() { super(true); }
}
abstract static class HasKey {
final A getKey(){ return key(); }
A key() { return key; } A key;
HasKey() {}
HasKey(A key) {
this.key = key;}
public String toString() { return "key " + key; }
}
static interface MakesBufferedImage extends WidthAndHeight {
BufferedImage getBufferedImage();
public default void drawAt(Graphics2D g, int x, int y) {
g.drawImage(getBufferedImage(), x, y, null);
}
}
static class Channels implements IFieldsToList{
A[] data;
Channels() {}
Channels(A[] data) {
this.data = data;}
public boolean equals(Object o) {
if (!(o instanceof Channels)) return false;
Channels __1 = (Channels) o;
return eq(data, __1.data);
}
public int hashCode() {
int h = 1497270256;
h = boostHashCombine(h, _hashCode(data));
return h;
}
public Object[] _fieldsToList() { return new Object[] {data}; }
Channels(int n) { data = newGenericArray(n); }
int channels() { return l(data); }
A get(int channel) { return data[channel]; }
void set(int channel, A a) { data[channel] = a; }
A first() { return main.first(data); }
A getSingleton() { assertEquals(1, channels()); return first(); }
public String toString() { return "Channels[" + joinWithComma(data) + "]"; }
}
static class Complex implements IFieldsToList{
static final String _fieldOrder = "re im";
double re;
double im;
Complex() {}
Complex(double re, double im) {
this.im = im;
this.re = re;}
public boolean equals(Object o) {
if (!(o instanceof Complex)) return false;
Complex __1 = (Complex) o;
return re == __1.re && im == __1.im;
}
public int hashCode() {
int h = -1679819632;
h = boostHashCombine(h, _hashCode(re));
h = boostHashCombine(h, _hashCode(im));
return h;
}
public Object[] _fieldsToList() { return new Object[] {re, im}; }
double abs() { return sqrt(re*re+im*im); }
double re() { return re; }
double im() { return im; }
final double angle(){ return phase(); }
double phase() { return Math.atan2(im, re); }
double fracAngle() { return fracNonNeg(angle()/twoPi()); } // angle as 0 to 1
public String toString() {
if (im != 0)
return re == 0 ? im + "i" : re + "+" + im + "i";
else
return str(re);
}
}
// We're a a bit confused about whether the time coordinates are double
// or int. (Probably int.)
static class SlidingWindow implements IAudioSample {
SlidingWindow() {}
// general params
double sampleRate = 48000;
int channels;
// length of window
int length; // in samples per channel
// start of window
int start;
// at which index in data array is our first value?
int boundaryIndex; // in data
// Here they are: the partial sums of the 16 bit audio samples
// in an array of 6-byte integers. Channels are stored interleaved.
HalfLongs data;
// query original sound (channel, time -> short-range)
IQuerySound sound;
public double sampleRate() { return sampleRate; }
public int channels() { return channels; }
public DoubleRange bounds() { return new DoubleRange(start, start+length); }
// Get an entry of the sum table - allow for out-of-bounds
// requests (those just default to silence).
long getEntry(int channel, int i) {
// do the first shift
i -= start;
if (i < 0) return 0;
i = min(i, length-1);
// do the second shift
i = (i+boundaryIndex) % length;
return data.get(i*channels+channel);
}
void setEntry(int channel, int i, long l) {
// do the shift
i = (i+boundaryIndex) % length;
data.set(i*channels+channel, l);
}
// constructor - perform integration of the raw audio data
SlidingWindow(int channels, double sampleRate, IQuerySound sound,
int start, int length) {
this.length = length;
this.start = start;
this.sound = sound;
this.sampleRate = sampleRate;
this.channels = channels;
grab();
}
short getSample_short(int channel, double relTime) {
return clampToShort(iround(sound.getSample(channel, start+relTime)));
}
void grab() {
assertTrue(length > 0);
if (l(data) != length*channels)
data = new HalfLongs(length*channels);
long[] sums = new long[channels];
for (int i = 0; i < length; i++)
for (int c = 0; c < channels; c++)
setEntry(c, i, sums[c] += getSample_short(c, i));
}
void moveTo(int newStart) {
shiftRight(newStart-start);
}
void moveToCenter(int t) {
moveTo(max(start, t-length/2));
}
void shiftRight() { shiftRight(1); }
void shiftRight(int n) {
if (n == 0) return;
assertTrue(n >= 0);
int oldEnd = ifloor(end());
start += n;
boundaryIndex = mod(boundaryIndex+n, length);
int overlap = max(0, oldEnd-ifloor(start));
if (overlap == 0)
grab();
else
for (int i = overlap; i < length; i++)
try {
for (int c = 0; c < channels; c++)
setEntry(c, i, getEntry(c, i-1) + getSample_short(c, i));
} catch (Throwable _e) {
printVars("i", i, "start", start, "n", n, "length", length);
throw rethrow(_e); }
}
}
final static class DoubleRange implements Comparable {
final double getStart(){ return start(); }
double start() { return start; } double start;
final double getEnd(){ return end(); }
double end() { return end; } double end;
DoubleRange() {}
DoubleRange(double start, double end) {
this.end = end;
this.start = start;}
public boolean equals(Object o) { return stdEq2(this, o); }
public int hashCode() { return stdHash2(this); }
double length() { return end-start; }
boolean isEmpty() { return start >= end; }
double center() { return (start+end)/2; }
static String _fieldOrder = "start end";
public String toString() { return "[" + start + ";" + end + "]"; }
@Override public int compareTo(DoubleRange r) {
int c = cmp(start, r.start);
if (c != 0) return c;
return cmp(end, r.end);
}
}
// It works like this: There is a general interface for accessing an "integrated" audio clip - IAudioSample.
interface IAudioSample {
int channels(); // 1 for mono, 2 for left+right, 3 for center+left+right... or whatever channel model you prefer
DoubleRange bounds(); // our bounding box in samples according to sampleRate
double sampleRate(); // in hertz
default double start() { return bounds().start(); }
default double end() { return bounds().end(); }
default double length() { return l(bounds()); }
// Query the integral.
// Result is in the range -32768*(end-start) to 32767*(end-start)...
// unless you applied too much gain (there is no clipping).
// channel is between 0 and channels()-1 from here on out
default double sampleSum(int channel, double start, double end) {
return readSumTable(channel, end-1) - readSumTable(channel, start-1);
}
default double readSumTable(int channel, double t) {
int tFloor = ifloor(t);
double val = readSumTable(channel, tFloor);
if (tFloor == t)
return val;
double next = readSumTable(channel, tFloor+1);
return blend(val, next, t-tFloor);
}
default double readSumTable(int channel, long position) {
throw unimplemented();
}
// Here the range is -1 to 1 just to spice things up
default double getPixel(int channel, double start, double end) {
return doubleRatio(sampleSum(channel, start, end), (end-start)*32768);
}
// RENDERING FUNCTIONS (visualize audio as BufferedImage)
// [also "acoustic" rendering]
// render audio as black-and-white (grayscale) stripes
// h = height per channel
default BufferedImage stripes() { return stripes(50); }
default BufferedImage stripes(int h) {
int w = iceil(length());
int channels = channels();
return imageFromFunction(w, h*channels, (x, y) -> {
int channel = y/h;
double value = sampleSum(channel, x, x+1);
// lose lower 8 bits and shift to 0 to 255
int digital = ifloor(value/256)+128;
return rgbIntFullAlpha(digital, digital, digital);
});
}
// render audio as graph
// h = height per channel
default BufferedImage graph() { return graph(100); }
default BufferedImage graph(int h) {
int w = iceil(length());
return mergeBufferedImagesVertically(
countIteratorToList(channels(), c ->
simpleGraph(w, h, x -> sampleSum(c, x, x+1), -32768, 32767)));
}
// render audio as stripes + graph (best way to look at it)
default BufferedImage render() { return render(100); }
default BufferedImage render(int h) {
return mergeBufferedImagesVertically(stripes(h/2), graph(h));
}
// in bounds
// all channels
default short[] toShortArray() {
DoubleRange r = bounds();
int i = ifloor(r.start()), j = ifloor(r.end());
int n = max(0, j-i);
var channels = channels();
short[] array = new short[n*channels];
int iArray = 0;
for (; i < j; i++)
for (int c = 0; c < channels; c++)
array[iArray++] = clampToShort(iround(sampleSum(c, i, i+1)));
return array;
}
// END OF RENDERING FUNCTIONS
// find maximum amplitude, going pixel-by-pixel
// (remember: This clip may already have been temporally
// scaled with speedUp(), so a "pixel" may represent the average
// of multiple audio samples.)
default double maxAmplitude() {
int n = iceil(length()), channels = channels();
double max = 0;
for (int i = 0; i < n; i++)
for (int c = 0; c < channels; c++)
max = max(max, abs(sampleSum(c, i, i+1)));
return min(32767, max);
}
// There are various non-destructive virtual transformations
// which you can do on the audio clip (gain, speed-up and time-shift).
// All transformations are affine in time and amplitude and thus
// preserve the "integral image" property.
default IAudioSample gain(double factor) {
return factor == 1 ? this : new AudioSampleOps.Gain(factor, this);
}
// gain to maximum volume possible without clipping
// (even though clipping isn't even a thing in integral audio wonderland,
// so we just define "clipping" as exceeding the 32767 value we are used to from real audio.)
default IAudioSample normalize() {
return gain(doubleRatio(32767, maxAmplitude()));
}
// resample with a factor
public default IAudioSample speedUp(double factor) {
return factor == 1 ? this : new AudioSampleOps.SpeedUp(factor, this);
}
// resample to a target frequency
public default IAudioSample sampleAt(double freq) {
return speedUp(sampleRate()/freq);
}
public default IAudioSample shift(double shift){ return timeShift(shift); }
public default IAudioSample timeShift(double shift) {
return shift == 0 ? this : new AudioSampleOps.TimeShift(shift, this);
}
// For debug-printing. Valued from 0 to 1 this time because why not. First channel only
default List firstPixels() { return firstPixels(20); }
default List firstPixels(int n) {
double[] pixels = new double[n];
for (int i = 0; i < n; i++)
pixels[i] = sampleSum(0, i, i+1)/32768;
return wrapDoubleArrayAsList(pixels);
}
} // end of IAudioSample
static class TreeHasKeyMap> extends HasKeyMap {
TreeHasKeyMap() { init(); }
TreeHasKeyMap(Iterable l) { init(); addAll(l); }
void init() { map = new TreeMap(); }
TreeMap map() { return (TreeMap) map; }
A lastKey() { return main.lastKey(map()); }
B higher(B a) { return a == null ? null : higherValue(map(), a.getKey()); }
}
// from com.badlogic.audio.io
static class EndianDataInputStream extends DataInputStream
{
EndianDataInputStream(InputStream in) { super(in); }
public String read4ByteString( ) { try {
byte[] bytes = new byte[4];
readFully(bytes);
return new String( bytes, "US-ASCII" );
} catch (Exception __e) { throw rethrow(__e); } }
public short readShortLittleEndian( ) { try {
int result = readUnsignedByte();
result |= readUnsignedByte() << 8;
return (short)result;
} catch (Exception __e) { throw rethrow(__e); } }
public int readIntLittleEndian( ) { try {
int result = readUnsignedByte();
result |= readUnsignedByte() << 8;
result |= readUnsignedByte() << 16;
result |= readUnsignedByte() << 24;
return result;
} catch (Exception __e) { throw rethrow(__e); } }
public int readInt24BitLittleEndian( ) { try {
int result = readUnsignedByte();
result |= readUnsignedByte() << 8;
result |= readUnsignedByte() << 16;
if( (result & ( 1 << 23 )) == 8388608 )
result |= 0xff000000;
return result;
} catch (Exception __e) { throw rethrow(__e); } }
public int readInt24Bit( ) { try {
int result = readUnsignedByte() << 16;
result |= readUnsignedByte() << 8;
result |= readUnsignedByte();
return result;
} catch (Exception __e) { throw rethrow(__e); } }
}
static class RenderFrequencySample_Sine implements RenderFrequencySample {
public double get(Complex c, double frac) {
double phi = frac*twoPi();
return c.re() * sin(phi) + c.im() * sin(phi+pi()/2);
}
public void subtractPeriodFrom(SubtractedAudio audio, DoubleRange period, Complex intensity) {
throw todo();
}
}
static class AudioHaarFeature implements IFieldsToList{
IAudioSample sample;
double start;
double end;
AudioHaarFeature() {}
AudioHaarFeature(IAudioSample sample, double start, double end) {
this.end = end;
this.start = start;
this.sample = sample;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + sample + ", " + start + ", " + end + ")"; }public Object[] _fieldsToList() { return new Object[] {sample, start, end}; }
double factor = 1;
boolean alternatePhase = false; // sample 90° phase shift?
AudioHaarFeature(IAudioSample sample, DoubleRange r) {
this.sample = sample;
start = r.start;
end = r.end;
}
double mid() { return (start+end)/2; }
double get(int channel) {
double value;
if (alternatePhase) {
double
quarter = start+(end-start)*.25,
threeQuarters = start+(end-start)*.75;
value =
sample.sampleSum(channel, start, end)
- sample.sampleSum(channel, quarter, threeQuarters)*2;
} else {
double mid = mid();
value = sample.sampleSum(channel, start, mid)
- sample.sampleSum(channel, mid, end);
}
return mul_optFor1(factor, value);
}
Channels get() {
return mapChannels(__43 -> get(__43), sample.channels());
}
Complex getComplex(int channel) {
alternatePhase = true;
double re = get(channel);
alternatePhase = false;
double im = get(channel);
return complex(re, im);
}
Channels getComplex() {
return mapChannels(__44 -> getComplex(__44), sample.channels());
}
}
static interface IIntegralImage extends MakesBufferedImage {
public int getWidth();
public int getHeight();
default public Pt getSize() { return pt(getWidth(), getHeight()); }
default public int defaultChannel() { return 0; }
default public int nChannels() { return 3; }
// get value for 1 channel
// normal range [0; pixelCount*256)
public double getIntegralValue(int x, int y, int channel);
default double getIntegralValue(double x, double y, int channel) {
return getIntegralValue(ifloor(x), ifloor(y), channel);
}
// gets value of the 3 channels
// normal range [0; pixelCount*256*3)
default double getIntegralValue(int x, int y) {
return getIntegralValue(x, y, 0)
+ getIntegralValue(x, y, 1)
+ getIntegralValue(x, y, 2);
}
default double rectSum(int x1, int y1, int x2, int y2, int channel) {
double bottomLeft = getIntegralValue(x1-1, y2-1, channel);
double bottomRight = getIntegralValue(x2-1, y2-1, channel);
double topLeft = getIntegralValue(x1-1, y1-1, channel);
double topRight = getIntegralValue(x2-1, y1-1, channel);
return bottomRight+topLeft-topRight-bottomLeft;
}
default double rectSum(double x1, double y1, double x2, double y2, int channel) {
return rectSum(iround(x1), iround(y1), iround(x2), iround(y2), channel);
}
default double rectSum(int x1, int y1, int x2, int y2) {
double bottomLeft = getIntegralValue(x1-1, y2-1);
double bottomRight = getIntegralValue(x2-1, y2-1);
double topLeft = getIntegralValue(x1-1, y1-1);
double topRight = getIntegralValue(x2-1, y1-1);
return bottomRight+topLeft-topRight-bottomLeft;
}
default double rectAverage(int x1, int y1, int x2, int y2, int channel) {
return doubleRatio(rectSum(x1, y1, x2, y2, channel), areaFromPoints(x1, y1, x2, y2));
}
default double rectAverage(Rect r, int channel) {
return doubleRatio(rectSum(r, channel), rectArea(r));
}
default double rectSum(Rect r) {
return rectSum(r.x, r.y, r.x2(), r.y2());
}
default double rectSum(Rect r, int channel) {
return rectSum(r.x, r.y, r.x2(), r.y2(), channel);
}
default double pixelSum(DoubleRect r) {
return rectSum(toRect_floor(r), defaultChannel());
}
default IIntegralImage clip(int x, int y, int w, int h) {
return new IIVirtualClip(this, x, y, w, h);
}
default double averageBrightness() {
int w = getWidth(), h = getHeight();
return doubleRatio(getIntegralValue(w-1, h-1), w*h*3*255.0);
}
// normal range: (0, 255)
default double getPixel(int x, int y, int channel) {
return rectSum(x, y, x+1, y+1, channel);
}
// returns RGB pixel without alpha
default int getPixel(int x, int y) {
int r = iround(rectSum(x, y, x+1, y+1, 0));
int g = iround(rectSum(x, y, x+1, y+1, 1));
int b = iround(rectSum(x, y, x+1, y+1, 2));
return rgbInt(r, g, b);
}
default BufferedImage getBufferedImage() {
int w = getWidth(), h = getHeight();
int[] pixels = new int[w*h];
int i = 0;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
pixels[i++] = getPixel(x, y) | fullAlphaMask();
return intArrayToBufferedImage(pixels, w, h);
}
// minimum and maximum brightness possible in image
// Better not to use because without this information
// you have a more general recognition algorithm.
//default DoubleRange colorRange(int channel) { ret doubleRange(0, 256); }
}
static class IIVirtualClip extends Meta implements IIntegralImage {
RegisteredReference < IIntegralImage > fullImage = new RegisteredReference<>(this);
int x1, y1, w, h;
IIVirtualClip() {}
IIVirtualClip(IIntegralImage fullImage, int x1, int y1, int w, int h) {
this.fullImage.set(fullImage);
this.h = h;
this.w = w;
this.y1 = y1;
this.x1 = x1;
}
public int getWidth() { return w; }
public int getHeight() { return h; }
public double getIntegralValue(int x, int y, int channel) {
return fullImage.get().getIntegralValue(x+x1, y+y1, channel);
}
public double getIntegralValue(int x, int y) {
return fullImage.get().getIntegralValue(x+x1, y+y1);
}
public BufferedImage getBufferedImage() {
return clipBufferedImage(fullImage.get().getBufferedImage(), x1, y1, w, h);
}
}
static class MultiMap {
Map > data = new HashMap >();
int fullSize;
MultiMap() {}
MultiMap(boolean useTreeMap) { if (useTreeMap) data = new TreeMap(); }
MultiMap(MultiMap map) { putAll(map); }
MultiMap(Map > data) {
this.data = data;}
void put(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
list.add(value);
++fullSize;
}}
void add(A key, B value) { put(key, value); }
void addAll(A key, Collection values) { putAll(key, values); }
void addAllIfNotThere(A key, Collection values) { synchronized(data) {
for (B value : values)
setPut(key, value);
}}
void setPut(A key, B value) { synchronized(data) {
if (!containsPair(key, value))
put(key, value);
}}
boolean containsPair(A key, B value) { synchronized(data) {
return get(key).contains(value);
}}
void putAll(Collection keys, B value) { synchronized(data) {
for (A key : unnullForIteration(keys))
put(key, value);
}}
void putAll(A key, Collection values) { synchronized(data) {
if (nempty(values)) getActual(key).addAll(values);
}}
void putAll(Iterable> pairs) { synchronized(data) {
for (Pair p : unnullForIteration(pairs))
put(p.a, p.b);
}}
void removeAll(A key, Collection values) { synchronized(data) {
for (B value : values)
remove(key, value);
}}
List get(A key) { synchronized(data) {
List list = data.get(key);
return list == null ? Collections. emptyList() : list;
}}
List getOpt(A key) { synchronized(data) {
return data.get(key);
}}
List getAndClear(A key) { synchronized(data) {
List l = cloneList(data.get(key));
remove(key);
return l;
}}
// returns actual mutable live list
// creates the list if not there
List getActual(A key) { synchronized(data) {
List list = data.get(key);
if (list == null)
data.put(key, list = _makeEmptyList());
return list;
}}
void clean(A key) { synchronized(data) {
List list = data.get(key);
if (list != null && list.isEmpty()) {
fullSize -= l(list);
data.remove(key);
}
}}
Set keySet() { synchronized(data) {
return data.keySet();
}}
Set keys() { synchronized(data) {
return data.keySet();
}}
void remove(A key) { synchronized(data) {
fullSize -= l(getOpt(key));
data.remove(key);
}}
void remove(A key, B value) { synchronized(data) {
List list = data.get(key);
if (list != null) {
if (list.remove(value))
fullSize--;
if (list.isEmpty())
data.remove(key);
}
}}
void clear() { synchronized(data) {
data.clear();
}}
boolean containsKey(A key) { synchronized(data) {
return data.containsKey(key);
}}
B getFirst(A key) { synchronized(data) {
List list = get(key);
return list.isEmpty() ? null : list.get(0);
}}
void addAll(MultiMap map) { putAll(map); }
void putAll(MultiMap map) { synchronized(data) {
for (A key : map.keySet())
putAll(key, map.get(key));
}}
void putAll(Map map) { synchronized(data) {
if (map != null) for (Map.Entry e : map.entrySet())
put(e.getKey(), e.getValue());
}}
final int keyCount(){ return keysSize(); }
int keysSize() { synchronized(data) { return l(data); }}
// full size - note: expensive operation
final int fullSize(){ return size(); }
int size() { synchronized(data) {
return fullSize;
}}
// expensive operation
List reverseGet(B b) { synchronized(data) {
List l = new ArrayList();
for (A key : data.keySet())
if (data.get(key).contains(b))
l.add(key);
return l;
}}
Map > asMap() { synchronized(data) {
return cloneMap(data);
}}
boolean isEmpty() { synchronized(data) { return data.isEmpty(); }}
// override in subclasses
List _makeEmptyList() {
return new ArrayList();
}
// returns live lists
Collection> allLists() {
synchronized(data) {
return new ArrayList(data.values());
}
}
Collection> values() { return allLists(); }
List allValues() {
return concatLists(data.values());
}
Object mutex() { return data; }
public String toString() { return "mm" + str(data); }
}
final static class Rect implements IFieldsToList{
static final String _fieldOrder = "x y w h";
int x;
int y;
int w;
int h;
Rect() {}
Rect(int x, int y, int w, int h) {
this.h = h;
this.w = w;
this.y = y;
this.x = x;}
public boolean equals(Object o) {
if (!(o instanceof Rect)) return false;
Rect __1 = (Rect) o;
return x == __1.x && y == __1.y && w == __1.w && h == __1.h;
}
public int hashCode() {
int h = 2543108;
h = boostHashCombine(h, _hashCode(x));
h = boostHashCombine(h, _hashCode(y));
h = boostHashCombine(h, _hashCode(w));
h = boostHashCombine(h, _hashCode(h));
return h;
}
public Object[] _fieldsToList() { return new Object[] {x, y, w, h}; }
Rect(Rectangle r) {
x = r.x;
y = r.y;
w = r.width;
h = r.height;
}
Rect(Pt p, int w, int h) {
this.h = h;
this.w = w; x = p.x; y = p.y; }
Rect(Rect r) { x = r.x; y = r.y; w = r.w; h = r.h; }
Rectangle getRectangle() {
return new Rectangle(x, y, w, h);
}
public String toString() {
return x + "," + y + " / " + w + "," + h;
}
int x1() { return x; }
int y1() { return y; }
int x2() { return x + w; }
int y2() { return y + h; }
boolean contains(Pt p) {
return contains(p.x, p.y);
}
boolean contains(int _x, int _y) {
return _x >= x && _y >= y && _x < x+w && _y < y+h;
}
boolean empty() { return w <= 0 || h <= 0; }
}
static class SubtractedAudio implements IAudioSample {
IAudioSample source;
int channels;
// for now same value in all channels
TreeMap subtractions = new TreeMap();
SubtractedAudio() {}
SubtractedAudio(IAudioSample source) {
this.source = source;}
void setSource(IAudioSample source) {
this.source = source;
channels = source.channels();
}
public double sampleRate() { return source.sampleRate(); }
public int channels() { return channels; }
public DoubleRange bounds_cache;
public DoubleRange bounds() { if (bounds_cache == null) bounds_cache = bounds_load(); return bounds_cache; }
public DoubleRange bounds_load() { return source.bounds(); }
void subtractPlateau(double start, double end, double intensity) {
if (start >= end) return;
_changeSumAt(start, intensity);
_changeSumAt(end, -intensity);
}
// We will probably add plateaus rather randomly throughout an area,
// so could optimize this doing something akin to LogNArray.
void _changeSumAt(double time, double intensity) {
double value = unnull(floorValue(subtractions, time)) + intensity;
// create, overwrite or delete
mapPutOrRemove(subtractions, time, nullIfZero(value));
Double next = subtractions.higherKey(time);
while (next != null) {
subtractions.put(next, subtractions.get(next) + intensity);
next = subtractions.higherKey(next);
}
}
public double readSumTable(int channel, double t) {
double diff = unnull(floorValue(subtractions, t));
return diff + source.readSumTable(channel, t);
}
}
static class Pt implements Comparable {
int x, y;
Pt() {}
Pt(Point p) {
x = p.x;
y = p.y;
}
Pt(int x, int y) {
this.y = y;
this.x = x;}
Point getPoint() {
return new Point(x, y);
}
public boolean equals(Object o) {
return o instanceof Pt && x == ((Pt) o).x && y == ((Pt) o).y;
}
public int hashCode() {
return boostHashCombine(x, y);
}
// compare in scan order
public int compareTo(Pt p) {
if (y != p.y) return cmp(y, p.y);
return cmp(x, p.x);
}
public String toString() {
return x + ", " + y;
}
}
static class AudioSampleOps {
// implementation of gain modifier
static class Gain implements IAudioSample , IFieldsToList{
double factor;
IAudioSample original;
Gain() {}
Gain(double factor, IAudioSample original) {
this.original = original;
this.factor = factor;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + factor + ", " + original + ")"; }public Object[] _fieldsToList() { return new Object[] {factor, original}; }
public double sampleRate() { return original.sampleRate(); }
public int channels() { return original.channels(); }
public DoubleRange bounds() { return original.bounds(); }
public double sampleSum(int channel, double start, double end) {
return original.sampleSum(channel, start, end)*factor;
}
// coalesce consecutive gains
public IAudioSample gain(double factor) {
return original.gain(this.factor*factor);
}
}
// Implementation of the time-shift modifier.
// moves the input samples to the left (cuts off beginning).
// Shift can be fractional - we're in integral image (audio) wonderland after all
// where a traditional pixel has no meaning.
static class TimeShift implements IAudioSample , IFieldsToList{
double shift;
IAudioSample original;
TimeShift() {}
TimeShift(double shift, IAudioSample original) {
this.original = original;
this.shift = shift;}
public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + shift + ", " + original + ")"; }public Object[] _fieldsToList() { return new Object[] {shift, original}; }
public double sampleRate() { return original.sampleRate(); }
public int channels() { return original.channels(); }
public DoubleRange bounds() { return shiftDoubleRange(original.bounds(), -shift); }
public double sampleSum(int channel, double start, double end) {
return original.sampleSum(channel, start+shift, end+shift);
}
// coalesce consecutive time-shifts
public IAudioSample timeShift(double shift) {
return original.timeShift(this.shift+shift);
}
}
// Implementation of the speed-up modifier which transforms every frequency f to f*factor.
// This is for convenience, you could also just call sampleSum() directly with larger intervals.
static class SpeedUp implements IAudioSample {
double factor, invFactor;
IAudioSample original;
SpeedUp(double factor, IAudioSample original) {
this.original = original;
this.factor = factor;
if (factor < 1) throw fail("Can't slow down. " + factor);
invFactor = 1/factor;
}
public double sampleRate() { return original.sampleRate()*invFactor; }
public int channels() { return original.channels(); }
public DoubleRange bounds() { return scaleDoubleRange(original.bounds(), invFactor); }
public double sampleSum(int channel, double start, double end) {
return original.sampleSum(channel, start*factor, end*factor)*invFactor;
}
// coalesce consecutive speed-ups
public IAudioSample speedUp(double factor) {
return original.speedUp(this.factor*factor);
}
}
}
static class HasKeyMap> /*extends AbstractMap */ implements Iterable {
Map map = new HashMap();
HasKeyMap() {}
//*(Map map) { putAll(this.map, map); }
HasKeyMap(Iterable l) { addAll(l); }
void addAll(Iterable l) {
for (var b : unnullForIteration(l)) if (b != null) map.put(b.key(), b);
}
public Iterator iterator() { return valueIterator(map); }
A firstKey() { return main.firstKey(map); }
public int size() { return map.size(); }
final Set keySet(){ return keys(); }
Set keys() { return map.keySet(); }
}
// an array of 6-byte integers
static class HalfLongs {
HalfLongs() {}
short[] data;
int length;
HalfLongs(int length) {
this.length = length;
data = new short[safeToInt(length*3L)];
}
public int size() { return length; }
public void set(int i, long val) {
data[i*3] = (short) val;
data[i*3+1] = (short) (val >> 16);
data[i*3+2] = (short) (val >> 32);
}
public long get(int i) {
return ushortToLong(data[i*3])
| (ushortToLong(data[i*3+1]) << 16)
| (data[i*3+2] << 32);
}
}
interface RenderFrequencySample {
public double get(Complex c, double frac);
void subtractPeriodFrom(SubtractedAudio audio, DoubleRange period, Complex intensity);
}
static interface WidthAndHeight {
int getWidth();
int getHeight();
}
static class DoubleRect {
double x, y, w, h;
DoubleRect() {}
DoubleRect(Rectangle r) {
x = r.x;
y = r.y;
w = r.width;
h = r.height;
}
DoubleRect(double x, double y, double w, double h) {
this.h = h;
this.w = w;
this.y = y;
this.x = x;}
// Huh. not implementing equals()/hashCode? Stefan is mysterious
boolean eq(Object o) {
if (!(o instanceof DoubleRect)) return false;
if (o == this) return true;
DoubleRect r = (DoubleRect) o;
return x == r.x && y == r.y && w == r.w && h == r.h;
}
public String toString() {
return x + "," + y + " / " + w + "," + h;
}
double x1() { return x; }
double y1() { return y; }
double x2() { return x + w; }
double y2() { return y + h; }
boolean contains(Pt p) {
return contains(p.x, p.y);
}
boolean contains(double _x, double _y) {
return _x >= x && _y >= y && _x < x+w && _y < y+h;
}
boolean empty() { return w <= 0 || h <= 0; }
}
// Meta - a "minimal" approach to adding meta-level to Java objects
static class Meta implements IMeta {
// We allocate one extra field for each Java object to make it
// reasoning-compatible. We couldn't go for 0 extra fields and
// there are no half fields in Java... so there you go.
// Also, if you don't use any meta data, you are probably not
// reasoning about anything. The point of reasoning in JavaX is
// to attach information to objects directly used in the program.
// Possible information contained in the meta field:
// Origin, destination, security level, sender, cost center,
// purpose, list of reifications, ...
// So here it is. THE FIELD YOU HAVE BEEN WAITING FOR
// We also have IMeta to retrofit foreign classes (rare but
// probably useful)
////////////
// "meta" //
////////////
// Generic meta value of any kind, but the typical case is it's a
// Map with extra field values for the object etc.
// "meta" is volatile to avoid synchronization; but you can also synchronize on
// _tempMetaMutex() which is usually the object itself. Collections
// and maps are exempt from using the collections's monitor as the meta
// mutex because their monitor tends to be held for long operations
// (e.g. cloneList). For those we use a substantially more complex
// algorithm using a weakMap. Probably overkill. I may reconsider.
volatile Object meta;
// The meta field is not transient, thus by default it will be
// persisted like anything else unless you customize your object
// to suppress or modulate this.
// ...and the interface methods
public void _setMeta(Object meta) { this.meta = meta; }
public Object _getMeta() { return meta; }
// MOST functions are implemented in IMeta (default implementations)
}
static class RegisteredReference implements IRef {
Meta owner; // all we require is a meta field
A value;
RegisteredReference() {
//if (!dynamicObjectIsLoading()) registerRef();
}
/*void registerRef {
vmBus_send registeringReference(this);
}*/
// Note that the single-argument constructor takes an owner, not a value
RegisteredReference(Meta owner) {
this(owner, null);
}
RegisteredReference(Meta owner, A value) {
this.value = value;
this.owner = owner;
index();
//registerRef();
}
// get owning object (source)
Meta owner() { return owner; }
// get target
public A get() { return value; }
public boolean has() { return value != null; }
public boolean set_trueIfChanged(A a) {
if (eq(a, value)) return false;
unindex();
value = a;
index();
return true;
}
public void set(A a) {
set_trueIfChanged(a);
}
void setIfEmpty(A a) {
if (!has()) set(a);
}
public void set(IRef ref) { set(ref == null ? null : ref.get()); }
public void clear() { set((A) null); }
// can override
boolean validRef() { return true; }
// TODO: sync all the indexing and unindexing!?
void index() {
if (!validRef()) return;
var br = lookupInterface(IHasBackRefs.class, get());
{ if (br != null) br._registerBackRef(this); }
}
void unindex() {
if (!validRef()) return;
var br = lookupInterface(IHasBackRefs.class, get());
{ if (br != null) br._unregisterBackRef(this); }
}
// not used yet
void change() {}
public String toString() {
return
str(value);
}
}
static interface IMeta {
// see class "Meta" for the bla bla
public void _setMeta(Object meta);
public Object _getMeta();
default public IAutoCloseableF0 _tempMetaMutex() {
return new IAutoCloseableF0() {
public Object get() { return IMeta.this; }
public void close() {}
};
}
// actually query another object
default public Object getMeta(Object obj, Object key){ return metaGet(obj, key); }
default public Object metaGet(Object obj, Object key) {
return main.metaGet(obj, key);
}
default public Object getMeta(Object key){ return metaGet(key); }
default public Object metaGet(Object key) {
if (key == null) return null;
Object meta = _getMeta();
if (meta instanceof Map) return ((Map) meta).get(key);
return null;
}
default public void metaSet(IMeta obj, Object key, Object value){ metaPut(obj, key, value); }
default public void metaPut(IMeta obj, Object key, Object value) {
main.metaSet(obj, key, value);
}
default public void metaSet(Object key, Object value){ metaPut(key, value); }
default public void metaPut(Object key, Object value) {
if (key == null) return;
Map map = convertObjectMetaToMap(this);
syncMapPutOrRemove(map, key, value);
}
}
static interface IHasBackRefs {
public void _registerBackRef(IRef ref);
public void _unregisterBackRef(IRef ref);
}
// could almost add IVar here - but void set() and bool set() are incompatible in some places
static interface IRef extends IF0 {
// called by the referencee to atomically replace itself
// Passing oldValue to avoid race conditions
public default void replaceValue(A oldValue, A newValue) {}
}
static interface IAutoCloseableF0 extends IF0 , AutoCloseable {}
static boolean isAbstract(Class c) {
return (c.getModifiers() & Modifier.ABSTRACT) != 0;
}
static boolean isAbstract(Method m) {
return (m.getModifiers() & Modifier.ABSTRACT) != 0;
}
static boolean reflection_isForbiddenMethod(Method m) {
return m.getDeclaringClass() == Object.class
&& eqOneOf(m.getName(), "finalize", "clone", "registerNatives");
}
static Set allInterfacesImplementedBy(Class c) {
if (c == null) return null;
HashSet set = new HashSet();
allInterfacesImplementedBy_find(c, set);
return set;
}
static void allInterfacesImplementedBy_find(Class c, Set set) {
if (c.isInterface() && !set.add(c)) return;
do {
for (Class intf : c.getInterfaces())
allInterfacesImplementedBy_find(intf, set);
} while ((c = c.getSuperclass()) != null);
}
static Method findMethod(Object o, String method, Object... args) {
return findMethod_cached(o, method, args);
}
static boolean findMethod_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static Method findStaticMethod(Class c, String method, Object... args) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (!m.getName().equals(method))
continue;
if ((m.getModifiers() & Modifier.STATIC) == 0 || !findStaticMethod_checkArgs(m, args))
continue;
return m;
}
c = c.getSuperclass();
}
return null;
}
static boolean findStaticMethod_checkArgs(Method m, Object[] args) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length)
return false;
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i])))
return false;
return true;
}
static String unquote(String s) {
if (s == null) return null;
if (startsWith(s, '[')) {
int i = 1;
while (i < s.length() && s.charAt(i) == '=') ++i;
if (i < s.length() && s.charAt(i) == '[') {
String m = s.substring(1, i);
if (s.endsWith("]" + m + "]"))
return s.substring(i+1, s.length()-i-1);
}
}
if (s.length() > 1) {
char c = s.charAt(0);
if (c == '\"' || c == '\'') {
int l = endsWith(s, c) ? s.length()-1 : s.length();
StringBuilder sb = new StringBuilder(l-1);
for (int i = 1; i < l; i++) {
char ch = s.charAt(i);
if (ch == '\\') {
char nextChar = (i == l - 1) ? '\\' : s.charAt(i + 1);
// Octal escape?
if (nextChar >= '0' && nextChar <= '7') {
String code = "" + nextChar;
i++;
if ((i < l - 1) && s.charAt(i + 1) >= '0'
&& s.charAt(i + 1) <= '7') {
code += s.charAt(i + 1);
i++;
if ((i < l - 1) && s.charAt(i + 1) >= '0'
&& s.charAt(i + 1) <= '7') {
code += s.charAt(i + 1);
i++;
}
}
sb.append((char) Integer.parseInt(code, 8));
continue;
}
switch (nextChar) {
case '\"': ch = '\"'; break;
case '\\': ch = '\\'; break;
case 'b': ch = '\b'; break;
case 'f': ch = '\f'; break;
case 'n': ch = '\n'; break;
case 'r': ch = '\r'; break;
case 't': ch = '\t'; break;
case '\'': ch = '\''; break;
// Hex Unicode: u????
case 'u':
if (i >= l - 5) {
ch = 'u';
break;
}
int code = Integer.parseInt(
"" + s.charAt(i + 2) + s.charAt(i + 3)
+ s.charAt(i + 4) + s.charAt(i + 5), 16);
sb.append(Character.toChars(code));
i += 5;
continue;
default:
ch = nextChar; // added by Stefan
}
i++;
}
sb.append(ch);
}
return sb.toString();
}
}
return s; // not quoted - return original
}
static List quoteAll(Collection l) {
List x = new ArrayList();
for (String s : l)
x.add(quote(s));
return x;
}
static int _hashCode(Object a) {
return a == null ? 0 : a.hashCode();
}
static ArrayList toList(A[] a) { return asList(a); }
static ArrayList toList(int[] a) { return asList(a); }
static ArrayList toList(Set s) { return asList(s); }
static ArrayList toList(Iterable s) { return asList(s); }
static boolean arraysEqual(Object[] a, Object[] b) {
if (a.length != b.length) return false;
for (int i = 0; i < a.length; i++)
if (neq(a[i], b[i])) return false;
return true;
}
static File loadBinaryPageOnce(String url) {
return loadBinaryPageToDefaultFileUnlessExists(url);
}
static String appendParamsToURL(String url, Map params) {
return appendQueryToURL(url, params);
}
static String appendParamsToURL(String url, Object... data) {
return appendQueryToURL(url, data);
}
static Iterator iterator(Iterable c) {
return c == null ? emptyIterator() : c.iterator();
}
static UnsupportedOperationException unsupportedOperation() {
throw new UnsupportedOperationException();
}
static String showImage_defaultIcon = "#1004230"; // "#1004227";
static ImageSurface showImage(String snippetIDOrURL, String title) {
return showImage(loadImage(snippetIDOrURL), title);
}
static ImageSurface showImage(String title, BufferedImage img) {
return showImage(img, title);
}
static ImageSurface showImage(final BufferedImage img, final String title) {
return (ImageSurface) swing(new F0() { public Object get() { try {
ImageSurface is = showImage(img);
getFrame(is).setTitle(title);
return is;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "ImageSurface is = showImage(img);\r\n getFrame(is).setTitle(title);\r\n ret..."; }});
}
static ImageSurface showImage(final BufferedImage img) {
return (ImageSurface) swing(new F0() { public Object get() { try {
ImageSurface is = new ImageSurface(img);
JFrame frame = showPackedFrame(new JScrollPane(is));
moveToTopRightCorner(frame);
frameIcon(frame, showImage_defaultIcon);
return is;
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "ImageSurface is = new ImageSurface(img);\r\n JFrame frame = showPackedFrame(..."; }});
}
static ImageSurface showImage(String imageID) {
return showImage(loadImage2(imageID));
}
static ImageSurface showImage(ImageSurface surface, BufferedImage img) {
return showImage(img, surface);
}
static ImageSurface showImage(ImageSurface surface, String title, BufferedImage img) {
return showImage(surface, img, title);
}
static ImageSurface showImage(ImageSurface surface, BufferedImage img, String title) {
return setFrameTitle(showImage(img, surface), title);
}
static ImageSurface showImage(BufferedImage img, ImageSurface surface) {
if (surface == null)
return showImage(img);
else {
surface.setImage(img);
return surface;
}
}
static ImageSurface showImage(String title, MakesBufferedImage img) {
return showImage(title, img.getBufferedImage());
}
static ImageSurface showImage(ImageSurface is, MakesBufferedImage img) {
return showImage(is, img.getBufferedImage());
}
static ImageSurface showImage(RGBImage img) {
return showImage(img.getBufferedImage());
}
static ImageSurface showImage(RGBImage img, String title) {
ImageSurface is = showImage(img.getBufferedImage());
getFrame(is).setTitle(title);
return is;
}
static ImageSurface showImage(ImageSurface surface, RGBImage img) {
return showImage(img, surface);
}
static ImageSurface showImage(RGBImage img, ImageSurface surface) {
if (surface == null)
return showImage(img);
else {
surface.setImage(img);
return surface;
}
}
static ImageSurface showImage(ImageSurface surface, String title, RGBImage img) {
return showImage(surface, img, title);
}
static ImageSurface showImage(ImageSurface surface, RGBImage img, String title) {
return setFrameTitle(showImage(img, surface), title);
}
static ImageSurface showImage(MakesBufferedImage img) {
return showImage(img.getBufferedImage());
}
static ImageSurface showImage() {
return showImage(currentImage());
}
static ImageSurface showImage(File f) {
return showImage(f2s(f), loadImage2(f)).setFile(f);
}
static File printFileInfo(File f) { return printFileInfo("", f); }
static File printFileInfo(String s, File f) {
print(s, renderFileInfo(f));
return f;
}
static File mp3ToWAVUnlessExists(File in) { return mp3ToWAVUnlessExists(in, replaceFileExtension(in, ".wav")); }
static File mp3ToWAVUnlessExists(File in,
File out) {
if (!out.exists()) try {
mp3ToWAV(in, out);
} catch (Throwable __0) { printStackTrace(__0);
mp3ToWAV_jave(in, out);
}
return out;
}
static File replaceExtension(File f, String extOld, String extNew) {
return newFile(replaceExtension(f2s(f), extOld, extNew));
}
static File replaceExtension(File f, String extNew) {
return replaceExtension(f, fileExtension(f), extNew);
}
static String replaceExtension(String s, String extOld, String extNew) {
s = dropSuffixIC(addPrefixOptIfNempty(".", extOld), s);
return s + addPrefixOptIfNempty(".", extNew);
}
static String replaceExtension(String name, String extNew) {
return replaceExtension(name, fileExtension(name), extNew);
}
static File appendToBaseFileName(File f, String s) {
return appendToFileNameBeforeExtension(f, s);
}
static short[] decodeWAVToMonoSamples(File wavFile) { try {
WAVDecoder decoder = new WAVDecoder(newFileInputStream(wavFile)); try {
return decodeWAVToMonoSamples(decoder, wavFile);
} finally { _close(decoder); }} catch (Exception __e) { throw rethrow(__e); } }
// weird signature
static short[] decodeWAVToMonoSamples(WAVDecoder decoder, File wavFile) {
return decodeWAVToMonoSamples(decoder);
}
static short[] decodeWAVToMonoSamples(WAVDecoder decoder) { return decodeWAVToMonoSamples(decoder, Integer.MAX_VALUE); }
static short[] decodeWAVToMonoSamples(WAVDecoder decoder, long maxSamples) { try {
List chunks = new ArrayList();
while (maxSamples > 0) { ping();
short[] buf = new short[(int) min(maxSamples, 4096)];
int n = decoder.readMonoSamples(buf);
if (n <= 0) break;
chunks.add(subArray(buf, 0, n));
maxSamples -= n;
}
return concatShortArrays(chunks);
} catch (Exception __e) { throw rethrow(__e); } }
static void _close(AutoCloseable c) {
if (c != null) try {
c.close();
} catch (Throwable e) {
// Some classes stupidly throw an exception on double-closing
if (c instanceof javax.imageio.stream.ImageOutputStream)
return;
else throw rethrow(e);
}
}
static short[] concatShortArrays(List arrays) {
int l = 0;
for (short[] a : unnull(arrays)) l += l(a);
short[] x = new short[l];
int i = 0;
for (short[] a : unnull(arrays)) if (a != null) {
System.arraycopy(a, 0, x, i, l(a));
i += l(a);
}
return x;
}
static List soundSourceToShortArrays(double maxSeconds, VF1 source) { return soundSourceToShortArrays(maxSeconds, source, 2); }
static List soundSourceToShortArrays(double maxSeconds, VF1 source, int channels) {
source = new CutOffSoundSource(maxSeconds, source);
double[] lr = new double[channels];
List out = new ArrayList();
short[] buf = new short[1024];
int i = 0;
while (licensed()) {
source.get(lr);
if (isNaN(lr[0])) break;
for (int c = 0; c < channels; c++)
buf[i++] = clipShort(lr[c]);
if (i >= l(buf)) {
out.add(buf);
buf = new short[l(buf)];
i = 0;
}
}
if (i > 0)
out.add(subShortArray(buf, 0, i));
return out;
}
static String sfu(Object o) { return structureForUser(o); }
static List takeFirst(List l, int n) {
return l(l) <= n ? l : newSubListOrSame(l, 0, n);
}
static List takeFirst(int n, List l) {
return takeFirst(l, n);
}
static String takeFirst(int n, String s) { return substring(s, 0, n); }
static String takeFirst(String s, int n) { return substring(s, 0, n); }
static CharSequence takeFirst(int n, CharSequence s) { return subCharSequence(s, 0, n); }
static List takeFirst(int n, Iterator it) {
if (it == null) return null;
List l = new ArrayList();
for (int _repeat_0 = 0; _repeat_0 < n; _repeat_0++) { if (it.hasNext()) l.add(it.next()); else break; }
return l;
}
static List takeFirst(int n, Iterable i) {
if (i == null) return null;
return i == null ? null : takeFirst(n, i.iterator());
}
static List takeFirst(int n, IterableIterator i) {
return takeFirst(n, (Iterator ) i);
}
static int[] takeFirst(int n, int[] a) { return takeFirstOfIntArray(n, a); }
static short[] takeFirst(int n, short[] a) { return takeFirstOfShortArray(n, a); }
static byte[] takeFirst(int n, byte[] a) { return takeFirstOfByteArray(n, a); }
static byte[] takeFirst(byte[] a, int n) { return takeFirstOfByteArray(n, a); }
static double[] takeFirst(int n, double[] a) { return takeFirstOfDoubleArray(n, a); }
static double[] takeFirst(double[] a, int n) { return takeFirstOfDoubleArray(n, a); }
static short[] convertSampleRate_shortArray_simple(short[] data, double oldSampleRate, double newSampleRate) {
double ratio = doubleRatio(newSampleRate, oldSampleRate);
if (ratio == 1) return data;
int l = l(data), l2 = iround(l(data)*ratio);
short[] data2 = new short[l2];
double j = 0, step = 1/ratio;
for (int i = 0; i < l2; i++) {
data2[i] = data[min(ifloor(j), l-1)];
j += step;
}
return data2;
}
static short[] convertSampleRate_shortArray_simple(double oldSampleRate, double newSampleRate, short[] data) {
return convertSampleRate_shortArray_simple(data, oldSampleRate, newSampleRate);
}
static IQuerySound shortSamplesToQuerySound(short[] samples) { return shortSamplesToQuerySound(1, samples); }
static IQuerySound shortSamplesToQuerySound(int channels, short[] samples) {
return new IQuerySound() {
public int channels() { return channels; }
// time is in samples
public double getSample(int channel, double time) {
int t = ifloor(time);
t /= channels;
return t < 0 || t >= l(samples) ? 0 : samples[t];
}
};
}
static IntRange intRange(int start, int end) {
return new IntRange(start, end);
}
static double[] concatDoubleArrays(List arrays) {
int l = 0;
for (double[] a : unnull(arrays)) l += l(a);
double[] x = new double[l];
int i = 0;
for (double[] a : unnull(arrays)) if (a != null) {
System.arraycopy(a, 0, x, i, l(a));
i += l(a);
}
return x;
}
static double[] concatDoubleArrays(double[]... arrays) {
return concatDoubleArrays(asList(arrays));
}
static double[] normalizeDoubles(double[] l) {
return normalizeDoubles(l, 1);
}
static double[] normalizeDoubles(double[] l, double targetMax) {
double factor = normalizationFactor(l, targetMax);
return doubleMul(l, factor);
}
static void shortArrayToMonoWAVE(short[] samples, File wavFile) { shortArrayToMonoWAVE(samples, wavFile, 44100); }
static void shortArrayToMonoWAVE(short[] samples, File wavFile, double sampleRate) {
multiShortArraysToMonoWAVE(ll(samples), wavFile, sampleRate);
}
static short[] doubleToShortArray_iround(double[] a, int start, int end) {
short[] b = new short[end-start];
for (int i = start; i < end; i++)
b[i-start] = clampToShort(iround(a[i]));
return b;
}
static short[] doubleToShortArray_iround(double[] a) {
return a == null ? null : doubleToShortArray_iround(a, 0, a.length);
}
static void playWAV(File f) {
playWAVAndWait(f);
}
static String dm_showPixelatedImage(MakesBufferedImage image) { return dm_showPixelatedImage(toBufferedImage(image)); }
static String dm_showPixelatedImage(BufferedImage image) {
String mod = dm_showImage(image);
dm_callOpt(mod, "pixelate");
return mod;
}
static String dm_showPixelatedImage(String title, MakesBufferedImage image) { return dm_showPixelatedImage(title, toBufferedImage(image)); }
static String dm_showPixelatedImage(String title, BufferedImage image) {
String mod = dm_showImage(title, image);
dm_callOpt(mod, "pixelate");
return mod;
}
static List filter(Iterable c, Object pred) {
if (pred instanceof F1) return filter(c, (F1 ) pred);
List x = new ArrayList();
if (c != null) for (Object o : c)
if (isTrue(callF(pred, o)))
x.add(o);
return x;
}
static List filter(Object pred, Iterable c) {
return filter(c, pred);
}
static List filter(Iterable c, F1 pred) {
List x = new ArrayList();
if (c != null) for (B o : c)
if (pred.get(o))
x.add(o);
return x;
}
static List filter(F1 pred, Iterable c) {
return filter(c, pred);
}
//ifclass IF1
static List filter(Iterable c, IF1 pred) {
List x = new ArrayList();
if (c != null) for (B o : c)
if (pred.get(o))
x.add(o);
return x;
}
static List filter(B[] c, IF1 pred) {
List x = new ArrayList();
if (c != null) for (B o : c)
if (pred.get(o))
x.add(o);
return x;
}
static List filter(IF1 pred, Iterable c) {
return filter(c, pred);
}
//endif
static boolean between(long x, long min, long max) {
return isBetween(x, min, max);
}
static boolean between(double x, double min, double max) {
return isBetween(x, min, max);
}
static String nFrequencies(long n) { return n2(n, "frequency", "frequencies"); }
static String nFrequencies(Collection l) { return nFrequencies(l(l)); }
static String nFrequencies(Map map) { return nFrequencies(l(map)); }
static String formatDouble(double d, int digits) {
String format = digits <= 0 ? "0" : "0." + rep(digits, '#');
return decimalFormatEnglish(format, d);
}
static String formatDouble(double d) {
return str(d);
}
static String formatDouble(DoubleRange r, int digits) {
return r == null ? "null" : "[" + formatDouble(r.start, digits)
+ ";" + formatDouble(r.end, digits) + "]";
}
static A pnl(A l) { return pnl("", l); }
static A pnl(String prefix, A l) {
printNumberedLines(prefix, l);
return l;
}
static A[] pnl(A[] l) { return pnl("", l); }
static A[] pnl(String prefix, A[] l) {
printNumberedLines(prefix, l);
return l;
}
static A pnl(A map) {
printNumberedLines(map);
return map;
}
static A pnl(String prefix, A map) {
printNumberedLines(prefix, map);
return map;
}
static String pnl(String s) {
printNumberedLines(lines(s));
return s;
}
static MultiMap pnl(MultiMap mm) {
pnl(mm == null ? null : mm.asMap());
return mm;
}
static String renderComplexWithAngle(Complex c) {
return c == null ? "null" : c.abs() + " at " + formatDouble(c.angle()*(180/pi()), 1) + "°";
}
static String div(Object contents, Object... params) {
return hfulltag("div", contents, params);
}
static String div() {
return div("");
}
static BigInteger div(BigInteger a, BigInteger b) {
return a.divide(b);
}
static BigInteger div(BigInteger a, int b) {
return a.divide(bigint(b));
}
static Complex div(Complex a, double b) {
return new Complex(a.re/b, a.im/b);
}
static double div(double a, double b) {
return a/b;
}
static int ifloor(double d) {
return (int) Math.floor(d);
}
static IntRange ifloor(DoubleRange r) {
return r == null ? null : intRange(ifloor(r.start), ifloor(r.end));
}
// add constant to each element
static double[] doubleAdd(double[] l, double a) {
if (a == 0) return l;
int n = l(l);
double[] x = new double[n];
for (int i = 0; i < n; i++)
x[i] = l[i]+a;
return x;
}
// add element-wise
static double[] doubleAdd(double[] a, double[] b) {
if (a == null) return b;
if (b == null) return a;
int n = l(a);
assertEquals(l(b), n);
double[] x = new double[n];
for (int i = 0; i < n; i++)
x[i] = a[i]+b[i];
return x;
}
static double[] repDouble(int n, double d) {
double[] a = new double[n];
for (int i = 0; i < n; i++) a[i] = d;
return a;
}
static int iround(double d) {
return (int) Math.round(d);
}
static int iround(Number n) {
return iround(toDouble(n));
}
static double pi() {
return Math.PI;
}
static void fillDoubleArray(double[] a, double value) {
Arrays.fill(a, value);
}
static Set> entrySet(Map map) {
return _entrySet(map);
}
static void remove(List l, int i) {
if (l != null && i >= 0 && i < l(l))
l.remove(i);
}
static void remove(Collection l, A a) {
if (l != null) l.remove(a);
}
static B remove(Map map, Object a) {
return map == null ? null : map.remove(a);
}
static void remove(BitSet bs, int i) {
bs.clear(i);
}
static Method hashMap_findKey_method;
static A hashMap_findKey(HashMap map, Object key) { try {
if (hashMap_findKey_method == null)
hashMap_findKey_method = findMethodNamed(HashMap.class, "getNode");
Map.Entry entry = (Map.Entry) hashMap_findKey_method.invoke(map, hashMap_internalHash(key), key);
// java.util.Map.Entry entry = (java.util.Map.Entry) call(hash, 'getNode, hashMap_internalHash(key), wkey);
return entry == null ? null : entry.getKey();
} catch (Exception __e) { throw rethrow(__e); } }
static boolean nempty(Collection c) {
return !empty(c);
}
static boolean nempty(CharSequence s) {
return !empty(s);
}
static boolean nempty(Object[] o) { return !empty(o); }
static boolean nempty(byte[] o) { return !empty(o); }
static boolean nempty(int[] o) { return !empty(o); }
static boolean nempty(BitSet bs) { return !empty(bs); }
static boolean nempty(Map m) {
return !empty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean nempty(Object o) { return !empty(o); }
static boolean nempty(IntRange r) { return !empty(r); }
static boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; }
static int boostHashCombine(int a, int b) {
return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
}
static double doubleRatio(double x, double y) {
return y == 0 ? 0 : x/y;
}
static int cmp(Number a, Number b) {
return a == null ? b == null ? 0 : -1 : cmp(a.doubleValue(), b.doubleValue());
}
static int cmp(double a, double b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(int a, int b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(long a, long b) {
return a < b ? -1 : a == b ? 0 : 1;
}
static int cmp(Object a, Object b) {
if (a == null) return b == null ? 0 : -1;
if (b == null) return 1;
return ((Comparable) a).compareTo(b);
}
static String joinNemptiesWithColon(String... strings) {
return joinNempties(": ", strings);
}
static String joinNemptiesWithColon(Collection strings) {
return joinNempties(": ", strings);
}
static String commaCombine(Object... l) {
return joinNemptiesWithComma(flattenCollectionsAndArrays(ll(l)));
}
static int hashCodeFor(Object a) {
return a == null ? 0 : a.hashCode();
}
static DoubleRange doubleRangeWithLength(double start, double len) {
return new DoubleRange(start, start+len);
}
static List record_list = synchroList();
static void record(Object o) {
record_list.add(o);
}
static A optCast(Class c, Object o) {
return isInstance(c, o) ? (A) o : null;
}
static A firstKey(Map map) {
return first(keys(map));
}
static A firstKey(MultiMap map) {
return map == null ? null : firstKey(map.data);
}
// Use like this: printVars(+x, +y);
// Or: printVars("bla", +x);
// Or: printVars bla(, +x);
static void printVars(Object... params) {
printVars_str(params);
}
static int iceil(double d) {
return (int) Math.ceil(d);
}
// Use like this: renderVars(+x, +y)
// Or like this: renderVars SomeID(+x, +y)
static String renderVars(Object... params) {
return renderVars_str(params);
}
static List mapReversed(Iterable l, IF1 f) {
return map(reversed(l), f);
}
static List mapReversed(IF1 f, Iterable l) {
return mapReversed(l, f);
}
static double totalLengthOfDoubleRanges(Iterable l) {
double sum = 0;
for (DoubleRange r : unnullForIteration(l)) sum += r.length();
return sum;
}
static Set keys(Map map) {
return map == null ? new HashSet() : map.keySet();
}
// convenience shortcut for keys_gen
static Set keys(Object map) {
return keys((Map) map);
}
static Set keys(MultiMap mm) {
return mm.keySet();
}
// f: (x, y) -> 0..255
// TODO: optimize!!
static BWIntegralImage bwIntegralImageFromFunction(int w, IF2_Int f) { return bwIntegralImageFromFunction(w, w, f); }
static BWIntegralImage bwIntegralImageFromFunction(int w, int h, IF2_Int f) {
byte[] pixels = new byte[w*h];
int i = 0;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
pixels[i++] = (byte) f.get(x, y);
return new BWIntegralImage(new BWImage(w, h, pixels));
}
static List reversedList(Iterable l) {
List x = cloneList(l);
Collections.reverse(x);
return x;
}
static DoubleRange doubleRange(double start, double end) {
return new DoubleRange(start, end);
}
static BWImage mergeBWImagesHorizontally(BWImage... images) {
return mergeBWImagesHorizontally(toList(images));
}
static BWImage mergeBWImagesHorizontally(List images, Object... __) {
if (empty(images)) return null;
int spacing = optPar("spacing", __, imageMergeSpacing());
float spaceColor = toFloat(optPar(__, "spaceColor", 0.9f));
int w = intSum(images, "width")+(l(images)-1)*spacing, h = intMax(images, "height");
BWImage out = new BWImage(w, h, spaceColor);
int x = 0;
for (int i = 0; i < l(images); i++) {
BWImage img = images.get(i);
int y = (h-img.h())/2;
copyBWImage(img, 0, 0, out, x, y);
x += img.w() + spacing;
}
return out;
}
static BWImage toBWImage(RGBImage img) {
return toBW(img);
}
static BWImage toBWImage(BufferedImage img) {
return img == null ? null : new BWImage(img);
}
static BWImage toBWImage(MakesBufferedImage img) {
if (img == null) return null;
if (img instanceof BWImage) return ((BWImage) img);
return new BWImage(toBufferedImage(img));
}
static DoubleRange toDoubleRange(IntRange r) {
return intToDoubleRange(r);
}
static String formatDouble1(double d) {
return formatDouble(d, 1);
}
static String formatDouble2(double d) {
return formatDouble(d, 2);
}
static Complex complex(double re, double im) {
return new Complex(re, im);
}
static Complex complex(double re) {
return new Complex(re, 0.0);
}
static Complex complex(double[] reIm) {
if (empty(reIm)) return null;
if (l(reIm) != 2) throw fail("Need 2 doubles to make complex number");
return complex(reIm[0], reIm[1]);
}
static FileInputStream fileInputStream(File path) { try {
return newFileInputStream(path);
} catch (Exception __e) { throw rethrow(__e); } }
static FileInputStream fileInputStream(String path) { try {
return newFileInputStream(path);
} catch (Exception __e) { throw rethrow(__e); } }
static int min(int a, int b) {
return Math.min(a, b);
}
static long min(long a, long b) {
return Math.min(a, b);
}
static float min(float a, float b) { return Math.min(a, b); }
static float min(float a, float b, float c) { return min(min(a, b), c); }
static double min(double a, double b) {
return Math.min(a, b);
}
static double min(double[] c) {
double x = Double.MAX_VALUE;
for (double d : c) x = Math.min(x, d);
return x;
}
static float min(float[] c) {
float x = Float.MAX_VALUE;
for (float d : c) x = Math.min(x, d);
return x;
}
static byte min(byte[] c) {
byte x = 127;
for (byte d : c) if (d < x) x = d;
return x;
}
static short min(short[] c) {
short x = 0x7FFF;
for (short d : c) if (d < x) x = d;
return x;
}
static int min(int[] c) {
int x = Integer.MAX_VALUE;
for (int d : c) if (d < x) x = d;
return x;
}
static double frac_nonNeg(double d) {
return mod(d, 1);
}
static double fracNonNeg(double d) {
return frac_nonNeg(d);
}
static boolean stdEq2(Object a, Object b) {
if (a == null) return b == null;
if (b == null) return false;
if (a.getClass() != b.getClass()) return false;
for (String field : allFields(a))
if (neq(getOpt(a, field), getOpt(b, field)))
return false;
return true;
}
static int stdHash2(Object a) {
if (a == null) return 0;
return stdHash(a, toStringArray(allFields(a)));
}
static A[] newGenericArray(int n) {
return (A[]) new Object[n];
}
static A assertEquals(Object x, A y) {
return assertEquals("", x, y);
}
static A assertEquals(String msg, Object x, A y) {
if (assertVerbose()) return assertEqualsVerbose(msg, x, y);
if (!(x == null ? y == null : x.equals(y)))
throw fail((msg != null ? msg + ": " : "") + y + " != " + x);
return y;
}
static double sqrt(double x) {
return Math.sqrt(x);
}
static double twoPi() {
return Math.PI*2;
}
static short clampToShort(int i) {
return (short) clamp(i, Short.MIN_VALUE, Short.MAX_VALUE);
}
// better modulo that gives positive numbers always
static int mod(int n, int m) {
return (n % m + m) % m;
}
static long mod(long n, long m) {
return (n % m + m) % m;
}
static BigInteger mod(BigInteger n, int m) {
return n.mod(bigint(m));
}
static double mod(double n, double m) {
return (n % m + m) % m;
}
static int blend(int x, int y, double yish) {
double xish = 1-yish;
return (int) (x*xish+y*yish);
}
static double blend(double x, double y, double yish) {
double xish = 1-yish;
return x*xish+y*yish;
}
static RuntimeException unimplemented() {
throw fail("TODO");
}
static RuntimeException unimplemented(String msg) {
throw fail("TODO: " + msg);
}
static int length(Object[] array) {
return array == null ? 0 : array.length;
}
static int length(List list) {
return list == null ? 0 : list.size();
}
static int length(String s) {
return s == null ? 0 : s.length();
}
static BufferedImage imageFromFunction(int w, IF2_Int f) { return imageFromFunction(w, w, f); }
static BufferedImage imageFromFunction(int w, int h, IF2_Int f) {
int[] pixels = new int[w*h];
int i = 0;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++)
pixels[i++] = f.get(x, y);
return intArrayToBufferedImage(pixels, w, h);
}
static int rgbIntFullAlpha(int r, int g, int b) {
return (clamp(r, 0, 255) << 16) | (clamp(g, 0, 255) << 8) | clamp(b, 0, 255) | fullAlphaMask();
}
static BufferedImage mergeBufferedImagesVertically(BufferedImage... images) {
return mergeBufferedImagesVertically(asList(images));
}
static BufferedImage mergeBufferedImagesVertically(Collection images, Object... __) {
if (l(images) == 1) return first(images);
return mergeImagesVertically(map(__45 -> toRGBImage(__45), images), __).getBufferedImage();
}
static List countIteratorToList(int b) { return countIteratorToList(0, b); }
static List