!7 import static x30_pkg.x30_util.VF1; sclass AudioOutput > DynPrintLog { int bufSize = 40960; float gain = 1; transient playAudioFromSampleMakingFunction_AudioLoop loop; transient L> sources = synchroList(); transient SimpleLiveValue numSources = new(Int, 0); visualize { ret centerAndSouth(super.visualize(), vstackWithSpacing( withLabel("Volume (0-200%):", liveSliderZeroToOne(gain/2, voidfunc(float f) { setField(gain := f*2) })), jrightalignedline(withLabel("Sound sources:", jLiveValueLabel(numSources))) )); } start { ownTimer(loop = playAudioFromSampleMakingFunction(bufSize, voidfunc(double[] pair) { audio_makeSampleFromSources(sources, pair, gain) })); } void setNumSources { numSources.set(l(sources)); } // API void addSource(VF1 source) { sources.add(source); setNumSources(); } void removeSource(VF1 source) { sources.remove(source); setNumSources(); } }