{
   "description" : "Sometime you want to play a certain part of a sound file, but you must provide the Synthdef with the starting and ending buffer frame number. It's nice to be able to select it graphically. <Space> play the selected part (or till the end if no selection is made), <Enter> stop the playing. The position selected is posted on post window in the form [start, lenght, end]. The range slider allow zooming and scrolling.",
   "ancestor_list" : [],
   "author" : "grirgz",
   "name" : "Sound file position selector GUI",
   "is_private" : null,
   "id" : "1-4WY",
   "code" : "(\r\n\t~select_sample_position = { arg path;\r\n\t\tvar player;\r\n\t\tvar win, sf, sfview;\r\n\t\tvar post_position;\r\n\t\tvar vlayout;\r\n\t\tvar zoom_slider;\r\n\t\twin = Window.new(\"select sample position\", Rect(200, 300, 740, 100));\r\n\t\tsf = SoundFile.new;\r\n\t\tsfview = SoundFileView.new;\r\n\t\tvlayout = VLayout.new;\r\n\t\tzoom_slider = RangeSlider.new;\r\n\t\tzoom_slider.orientation = \\horizontal;\r\n\t\tzoom_slider.action  = { arg sli;\r\n\t\t\t[\\sliderLOW, sli.lo, \\sliderHI, sli.hi].postln;\r\n\t\t\tsfview.zoomToFrac(sli.hi - sli.lo);\r\n\t\t\tsfview.scrollTo(sli.lo);\r\n\r\n\t\t};\r\n\t\tvlayout.add(sfview);\r\n\t\tvlayout.add(zoom_slider);\r\n\t\twin.layout = vlayout;\r\n\t\tsf.openRead(path);\r\n\t\tsfview.soundfile = sf;\r\n\t\tsfview.read(0, sf.numFrames);\r\n\r\n\t\tsfview.elasticMode = true;\r\n\t\tsfview.timeCursorOn = true;\r\n\t\tsfview.timeCursorColor = Color.red;\r\n\t\tsfview.timeCursorPosition = 0;\r\n\t\tsfview.drawsWaveForm = true;\r\n\t\tsfview.gridOn = true;\r\n\t\tsfview.gridResolution = 1;\r\n\r\n\t\tpost_position = { \r\n\t\t\tvar cur;\r\n\t\t\tcur = sfview.selections[sfview.currentSelection];\r\n\t\t\t\"Current selection is now:\\nframes: %\\nseconds: %\\nnormalized: %\".format(\r\n\t\t\t\tcur++(cur[0]+cur[1]),\r\n\t\t\t\tcur++(cur[0]+cur[1]) / s.sampleRate,\r\n\t\t\t\tcur++(cur[0]+cur[1]) / sf.numFrames,\r\n\t\t\t).postln;\r\n\t\t};\r\n\r\n\t\tsfview.mouseUpAction = { arg a;\r\n\t\t\tpost_position.();\r\n\t\t};\r\n\r\n\t\tsfview.keyDownAction = { arg view, char, modifiers, u, k; \r\n\t\t\tvar cur;\r\n\t\t\tcur = view.selections[view.currentSelection];\r\n\t\t\t//[char, modifiers, u, k].debug(\"KEYBOARD INPUT\");\r\n\t\t\tif( u == 32 ) { // space\r\n\t\t\t\tif(player.notNil) {\r\n\t\t\t\t\tplayer.stop;\r\n\t\t\t\t\tplayer = nil;\r\n\t\t\t\t};\r\n\t\t\t\tplayer = sf.play(\r\n\t\t\t\t\t(\r\n\t\t\t\t\t\tfirstFrame: cur[0],\r\n\t\t\t\t\t\tlastFrame: if(cur[1] == 0) { nil } {cur[0]+cur[1]}\r\n\t\t\t\t\t)\r\n\r\n\t\t\t\t);\r\n\t\t\t\tpost_position.();\r\n\t\t\t};\r\n\t\t\tif( u == 13 ) { // Enter\r\n\t\t\t\tif(player.notNil) {\r\n\t\t\t\t\tplayer.stop;\r\n\t\t\t\t\tplayer = nil;\r\n\t\t\t\t};\r\n\t\t\t\tpost_position.();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\twin.view.keyDownAction = { arg view, char, modifiers, u, k; \r\n\t\t\t//[char, modifiers, u, k].debug(\"KEYBOARD INPUT\");\r\n\t\t\tif( u == 27 ) { // Esc\r\n\t\t\t\tif(player.notNil) {\r\n\t\t\t\t\tplayer.stop;\r\n\t\t\t\t\tplayer = nil;\r\n\t\t\t\t};\r\n\t\t\t\tview.close();\r\n\t\t\t};\r\n\t\t};\r\n\r\n\r\n\t\twin.front;\r\n\r\n\t};\r\n\r\n// example\r\n\t~select_sample_position.(Platform.resourceDir +/+ \"sounds/a11wlk01.wav\");\r\n)",
   "labels" : [
      "gui",
      "buffer",
      "utility",
      "dialog",
      "selection",
      "position",
      "frames"
   ]
}
