// title: Automatic looper by selecting a part of a sound file // author: prko // description: // originated from and . // code: ( w = Window("An Instant Sound File Player (Looper)", Rect(0,Window.screenBounds.height-180,Window.screenBounds.width-100,Window.screenBounds.height-180)).front; w.view.decorator = FlowLayout( w.view.bounds, 10@10, 20@5 ); q = Bus.control(s, 1); a = Button(w, Rect(20, 20, 340, 30)) .states_([ ["Load a Sound File into a Buffer", Color.white, Color.black] ]) .action_({ s.waitForBoot{ if(y!=nil, {y.free; y=nil}); b= Buffer.loadDialog(s, action:{ b.loadToFloatArray( action: { |a| { e.waveColors_(Color.green(1, 0.3)!b.numChannels); v.waveColors_(Color.green(1, 0.5)!b.numChannels); e.setData(a, channels: b.numChannels); v.setData(a, channels: b.numChannels); e.setSelection(0, [0,b.numFrames]); e.zoomAllOut; v.setSelection(0, [0,0]) }.defer }) } ); "is loading a sound file".postln } } ); m = [10, 10, 30, 30]; n = 100; e = SoundFileView(w, Rect(m[0], m[1], w.bounds.width-m[2], n)); e.timeCursorOn_(true); e.setSelectionColor(0, Color.gray(0.8, 0.2)); e.gridOn_(true); e.gridResolution_(60); e.mouseUpAction = {|view, char, modifiers, unicode, keycode, key| var posData, posLo, posHi; posData = [e.selections[0][0], (e.selections[0][0] + e.selections[0][1])] / e.numFrames; posData; v.zoomToFrac(posData[1] - posData[0]); v.scrollTo (posData[0]); v.scroll (posData[0]); }; v = SoundFileView(w, Rect(m[0], m[2], w.bounds.width-m[2], w.bounds.height-(m[3]*2)-n)); v.timeCursorOn_(true).setSelectionColor(0, Color.gray(0.8, 0.5)); v.gridOn_(true); v.gridResolution_(10); x = { |lo = 0, hi = 1| var phasor = Phasor.ar(0, BufRateScale.kr(b), lo * BufFrames.kr(b), hi *BufFrames.kr(b)); Out.kr(q.index,A2K.kr(phasor)); BufRd.ar(b.numChannels, b, phasor) }; v.mouseUpAction = {|view, char, modifiers, unicode, keycode, key| var posData, posLo, posHi; posData = [v.selections[0][0], (v.selections[0][0] + v.selections[0][1])] / v.numFrames; posData; v.selections[0][0]; v.selections[0][1]; if (y==nil, {y = x.play(args: [\lo, posData[0], \hi, posData[1]])}, {y.set(\lo, posData[0], \hi, posData[1]); }); }; w.onClose_({y.free; b=nil; c=nil; e=nil; y=nil; x=nil; v=nil; w=nil; AppClock.clear}); ( AppClock.sched(0.0, { q.get({arg val; {v.timeCursorPosition=val; e.timeCursorPosition=val}.defer;}); 0.05; }); ) )