// TODO: copy buffers less (have multiple listeners keep buffers without copying) sclass AudioInputDispatcher { new Flag stopFlag; short[] convertedBuf; L> audioListeners; SimpleLiveValue lvVolume; bool cloneDataOnce; bool verbose; O currentListener; // who is holding up audio processing *(int bufSize) { convertedBuf = new short[bufSize/2]; } void handleData(byte[] data) { handleData(data, l(data)); } void handleData(byte[] data, int n) { if (verbose) printWithMilliseconds("Handling audio data (" + nBytes(n) + ", first: " + first(data) + ")"); pcall { bytesToShorts_littleEndian(data, convertedBuf, n); short[] convertedData = subShortArray(convertedBuf, 0, n/2); if (lvVolume != null) { float vol = shortSamplesToPercentVolume(convertedData); if (verbose) { printStruct(subShortArray(convertedData, 0, 5)); //print("Volume: " + vol); } lvSet(lvVolume, vol); } if (cloneDataOnce) convertedData = cloneShortArray(convertedData); for i over audioListeners: { // synchro-safe, garbage-free iteration VF1 l = syncGet(audioListeners, i); continue if l == null; try { currentListener = l; pcallF(l, convertedData); } finally { currentListener = null; } } } if (verbose) printWithMilliseconds("Done handling audio data"); } }