static playAudioFromSampleMakingFunction_AudioLoop playAudioFromSampleMakingFunction(int bufSize, VF1 sampleMaker) { playAudioFromSampleMakingFunction_AudioLoop loop = new(bufSize, sampleMaker); loop.start(); ret loop; } static playAudioFromSampleMakingFunction_AudioLoop playAudioFromSampleMakingFunction_dontStart(int bufSize, VF1 sampleMaker) { ret playAudioFromSampleMakingFunction_AudioLoop(bufSize, sampleMaker); } sclass playAudioFromSampleMakingFunction_AudioLoop extends Thread implements AutoCloseable { SourceDataLine out; new Flag stopFlag; byte[] buf; VF1 sampleMaker; AudioFormat quality = javaSound_cdQuality(); long samplesPlayed; *(int bufSize, VF1 *sampleMaker) { out = javaSound_outputLine(quality, bufSize); buf = new byte[bufSize]; } public void start { out.start°; super.start°; } void stopPlaying { // "stop()" was taken if (stopFlag.isUp()) ret; stopFlag.raise°; out.close°; print("Audio output loop stopped."); } public void close { stopPlaying(); } public void run° { print("Audio output loop started. Buffer size=" + l(buf) + " (" + iround(l(buf)/44100.0/4*1000) + " ms)"); double[] pair = new double[2]; while (licensed() && !stopFlag.isUp()) { for (int i = 0; i < l(buf); i += 4) { sampleMaker.get(pair); short l = clipShort(pair[0]); short r = clipShort(pair[1]); buf[i] = (byte) l; buf[i+1] = (byte) (l >> 8); buf[i+2] = (byte) r; buf[i+3] = (byte) (r >> 8); } //print("Writing " + l(buf) + " bytes"); int n = out.write(buf, 0, l(buf)); samplesPlayed += n; if (n != l(buf)) ret with print("huh: " + n + " of " + l(buf)); } } }