Last active
December 31, 2015 16:19
-
-
Save iani/8013195 to your computer and use it in GitHub Desktop.
SuperCollider class: Watches the wav files in a chosen directory. If any files are added, they are read into buffers. If any files are removed, their buffers are freed. When any buffer is read or freed, a changed notification is issued. One can make any object do any action when receiving that notification by using the addNotifier method (see ex…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // IZ Dec 17, 2013 (11:31 PM) | |
| /* | |
| (Save this file as WatchSamplesInDir.sc and put it inside SuperCollider Extensions folder. | |
| Then recompile. ) | |
| Watches the wav files in a chosen directory. | |
| If any files are added, they are read into buffers. | |
| If any files are removed, their buffers are freed. | |
| When any buffer is read or freed, a changed notification is issued. | |
| Here is how to add an action to do when receiving the notification: | |
| //: | |
| \anyObject.addNotifier(WatchSamplesInDir, \buffers, { | |
| // As an example, | |
| // play the first sample, when new samples are loaded: | |
| { WatchSamplesInDir.buffers.first.play; }.defer(1); | |
| }) | |
| //: | |
| */ | |
| WatchSamplesInDir { | |
| classvar default; | |
| classvar <loadedPaths; | |
| classvar <buffers; | |
| classvar <>soundFileExtension = "aiff"; | |
| var <>path2watch; | |
| var <loop; | |
| var <>pollingRate = 5; | |
| *start { this.default.start; } | |
| *stop { this.default.stop; } | |
| *default { | |
| if (default.isNil) { default = this.new }; | |
| ^default; | |
| } | |
| *initClass { | |
| StartUp.add({ ServerBoot.add({ this.serverBooted }, Server.default) }); | |
| } | |
| *new { | path2watch | | |
| if (loadedPaths.isNil) { | |
| loadedPaths = Set(); | |
| }; | |
| ^super.new.init(path2watch); | |
| } | |
| *serverBooted { | |
| var buf, bufnum, numFrames; | |
| if (buffers.size > 0) { | |
| buf = buffers.first; | |
| bufnum = buf.bufnum; | |
| numFrames = buf.numFrames; | |
| buf.updateInfo({ | b | | |
| { | |
| postf("Server booted?????. Checking actual buffer here: \n %\n", b); | |
| if (b.numFrames != numFrames) { | |
| buffers = nil; | |
| loadedPaths = Set(); | |
| "server booted, buffers emptied, checking to reload if running.".postln; | |
| }{ | |
| "Buffer ok. Continuing without reload.".postln; | |
| }; | |
| }.defer(0.5); | |
| }); | |
| }; | |
| } | |
| init { | argPath2Watch | | |
| path2watch = argPath2Watch; | |
| } | |
| start { | |
| if (path2watch.notNil) { ^this.startLoop }; | |
| path2watch = this.loadDefaultPath2Watch; | |
| if (path2watch.notNil) { ^this.startLoop }; | |
| Dialog.openPanel({ | path | | |
| path2watch = PathName(path).pathOnly +/+ "*." ++ soundFileExtension; | |
| path2watch.writeArchive(this.defaultPathSavePath); | |
| this.startLoop; | |
| }) | |
| } | |
| startLoop { | |
| if (loop.notNil) { loop.stop }; | |
| loop = { | |
| loop { | |
| this.poll; | |
| pollingRate.wait; | |
| } | |
| }.fork; | |
| } | |
| poll { | |
| var paths2add, paths2remove, pathsNowInFolder, buffer; | |
| pathsNowInFolder = Set() addAll: path2watch.pathMatch; | |
| // paths now in folder which are not currently loaded: | |
| paths2add = pathsNowInFolder difference: loadedPaths; | |
| // paths currently loaded which are not any more in folder: | |
| paths2remove = loadedPaths difference: pathsNowInFolder; | |
| loadedPaths = pathsNowInFolder; | |
| // first load new buffers | |
| paths2add do: { | p | | |
| postf("adding: %\n", p); | |
| buffers = buffers add: Buffer.read(Server.default, p); | |
| }; | |
| // then free the buffers | |
| paths2remove do: { | p | | |
| buffer = buffers detect: { | b | b.path == p }; | |
| if (buffer.notNil) { | |
| postf("removing: %\n", p); | |
| buffer.free; | |
| buffers remove: buffer; | |
| }; | |
| }; | |
| // if any buffers were loaded or removed, notify: | |
| if (0 < (paths2add.size + paths2remove.size)) { | |
| this.class.changed(\buffers, this); | |
| } | |
| } | |
| loadDefaultPath2Watch { | |
| var path; | |
| path = this.defaultPathSavePath; | |
| if (File.exists(path)) { | |
| ^path.load; | |
| }{ | |
| ^nil; | |
| } | |
| } | |
| defaultPathSavePath { | |
| ^Platform.userAppSupportDir ++ "/WatchSamplesInDirPath.scd"; | |
| } | |
| stop { | |
| loop.stop; | |
| loop = nil; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment