Created
July 5, 2024 17:37
-
-
Save schollz/35accc76234ff22961ed45a7ad38c418 to your computer and use it in GitHub Desktop.
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
// var f = FoldersOfSound.new(Server.default); | |
// var server2 = Server.new(name, "192.168.0.24:57110", options, clientID) | |
// var f2 = FolderOfSound.new(server2); | |
// ( | |
// s.waitForBoot({ | |
// ~bikes=FoldersOfSound.new(s); | |
// ~birds=FoldersOfSound.new(s); | |
// }); | |
// ) | |
// ( | |
// ~birds.playFolder(...) | |
// ~birds.remove(1); | |
// ) | |
// ( | |
// ~bikes.playFolder(...); | |
// ~bikes.setFadeIn(5.0); | |
// ) | |
// (Routine { | |
// inf.do{ | |
// 10.wait; | |
// ~bikes.remove(1); | |
// 30.wait; | |
// ~birds.setFadeIn(4); | |
// }; | |
// }.play;) | |
FoldersOfSound { | |
var server; | |
var bufs; | |
var buses; | |
var syns; | |
var synlist; | |
var oscs; | |
var playi; | |
var fadein; | |
var fadeout; | |
var panRange; | |
var ampRange; | |
var randomSelection; | |
*new { | |
arg argServer; | |
^super.new.init(argServer); | |
} | |
playFolder { | |
arg folder, num; | |
var files = PathName.new(folder); | |
var audioFiles = []; | |
files.filesDo({arg file; | |
if (file.fullPath.endsWith(".ogg"),{ | |
audioFiles=audioFiles.add(file.fullPath); | |
}); | |
if (file.fullPath.endsWith(".wav"),{ | |
audioFiles=audioFiles.add(file.fullPath); | |
}); | |
if (file.fullPath.endsWith(".flac"),{ | |
audioFiles=audioFiles.add(file.fullPath); | |
}); | |
// if you have SuperCollider 3.13+ you can use mp3 files | |
// if (file.fullPath.endsWith(".mp3"),{ | |
// audioFiles=audioFiles.add(file.fullPath); | |
// }); | |
}); | |
("[playFolder] loaded"+audioFiles.size+"files from"+folder).postln; | |
if (randomSelection>0,{ | |
("[playFolder] playing random").postln; | |
// random selection | |
audioFiles.scramble.do({ arg v,i; | |
if (i<num,{ | |
[i,v].postln; | |
this.play(v); | |
}); | |
}) | |
},{ | |
("[playFolder] playing ordered").postln; | |
num.do({ | |
if (playi>=audioFiles.size,{ | |
playi=0; | |
}); | |
this.play(audioFiles[playi]); | |
playi = playi+1; | |
}); | |
}); | |
} | |
remove { | |
arg num; | |
num.do({ arg i; | |
if (synlist.size>0,{ | |
this.stop(synlist[0]); | |
}); | |
}); | |
} | |
stop { | |
arg fname; | |
if (syns.at(fname).notNil,{ | |
var remove=1.neg; | |
if (syns.at(fname).isRunning,{ | |
("stopping"+fname).postln; | |
syns.at(fname).set(\gate,0); | |
}); | |
syns.put(fname,nil); | |
synlist.do({arg v,i; | |
if (v.asString==fname.asString,{ | |
remove=i; | |
}); | |
}); | |
if (remove>1.neg,{ | |
("dequeued"+fname).postln; | |
synlist.removeAt(remove); | |
}); | |
}); | |
} | |
play { | |
arg fname; | |
// the maximum number sounds is 10 | |
// you could change to >10 | |
if (synlist.size<10,{ | |
["[play] playing ",fname].postln; | |
if (bufs.at(fname).isNil,{ | |
bufs.put(fname,Buffer.read(server,fname,0,-1,action:{ | |
"loooping audio file".postln; | |
syns.put(fname,Synth.before(syns.at("fx"),"looper"++bufs.at(fname).numChannels,[\ampRange,ampRange,\panRange,panRange,\fadein,fadein,\fadeout,fadeout,\buf,bufs.at(fname),\busReverb,buses.at("busReverb"),\busNoCompress,buses.at("busNoCompress"),\busCompress,buses.at("busCompress")]).onFree({ | |
})); | |
NodeWatcher.register(syns.at(fname)); | |
})); | |
},{ | |
// only allow one sample of one kind to play at once | |
this.stop(fname); | |
syns.put(fname,Synth.before(syns.at("fx"),"looper"++bufs.at(fname).numChannels,[\ampRange,ampRange,\panRange,panRange,\fadein,fadein,\fadeout,fadeout,\buf,bufs.at(fname),\busReverb,buses.at("busReverb"),\busNoCompress,buses.at("busNoCompress"),\busCompress,buses.at("busCompress")]).onFree({ | |
})); | |
NodeWatcher.register(syns.at(fname)); | |
}); | |
synlist=synlist.add(fname); | |
}); | |
} | |
sound_delta { | |
arg folder, num; | |
if (num>0,{ | |
this.playFolder(folder,num); | |
}); | |
if (num<0,{ | |
this.remove(num); | |
}); | |
} | |
setAmpRange { | |
arg ampRange; | |
syns.keysValuesDo({ arg k, syn; | |
if (syn.isRunning,{ | |
syn.set(\ampRange,ampRange); | |
}); | |
}); | |
} | |
setPanRange { | |
arg panRange; | |
syns.keysValuesDo({ arg k, syn; | |
if (syn.isRunning,{ | |
syn.set(\panRange,panRange); | |
}); | |
}); | |
} | |
setOrdered { | |
arg ordered; | |
randomSelection = ordered; | |
} | |
setFadeIn { | |
arg argFadeIn; | |
fadein=argFadeIn; | |
} | |
setFadeOut { | |
arg argFadeOut; | |
fadeout = argFadeOut; | |
syns.keysValuesDo({ arg k, syn; | |
if (syn.isRunning,{ | |
syn.set(\fadeout,fadeout); | |
}); | |
}); | |
} | |
setp { | |
arg parm, value; | |
syns.keysValuesDo({ arg k, syn; | |
if (syn.isRunning,{ | |
syn.set(parm.asString,value); | |
}); | |
}); | |
} | |
// ~bikes.getNumber.postln; | |
// ~bikes.getNumber | |
// if (~bikes.getNumber>3,{ | |
// ~bikes.remove(1); | |
// }, { // if false }); | |
getNumber { | |
^synlist.size; | |
} | |
init { | |
arg argServer; | |
server=argServer; | |
playi = 0; | |
// default parameters for creating a synth | |
randomSelection = 1; | |
fadein=5.0; | |
fadeout=5.0; | |
ampRange=9.neg; | |
panRange=0.25; | |
// a simple SynthDef | |
// SynthDef("sine",{ | |
// Out.ar(0,SinOsc.ar(440,0,0.1)); | |
// }).add; | |
// Synth("sine") | |
// basic players | |
SynthDef("fx",{ | |
arg busReverb,busCompress,busNoCompress; | |
var snd; | |
var sndReverb=In.ar(busReverb,2); | |
var sndCompress=In.ar(busCompress,2); | |
var sndNoCompress=In.ar(busNoCompress,2); | |
sndCompress=Compander.ar(sndCompress,sndCompress,0.05,slopeAbove:0.1,relaxTime:0.01); | |
sndNoCompress=Compander.ar(sndNoCompress,sndNoCompress,1,slopeAbove:0.1,relaxTime:0.01); | |
// change between Freverb2 or maybe Greyhole ? | |
sndReverb=FreeVerb2.ar(sndReverb[0],sndReverb[1],1.0,0.7); | |
// sndReverb = Greyhole.ar() | |
snd=sndCompress+sndNoCompress+sndReverb; | |
// if you have clipping you can prevent it with some wavefolders | |
// snd = snd / 10; // reduce the sound level | |
// snd = snd * -10.dbamp; // reduce by 10 db | |
// snd = Clip.ar(snd,-1,1); // clipping | |
// snd = snd.dist; // distortion | |
// snd = snd.tanh; // tanh wavefolder | |
// snd = Fold.ar(snd); // folding | |
Out.ar(0,snd*Line.ar(0,1,3)); | |
}).add; | |
SynthDef("looper1",{ | |
arg buf,busReverb,busCompress,busNoCompress,gate=1,rateMult=1.0,db=0.0,timescalein=0.05,fadein=5,fadeout=5,panRange=0.25,ampRange=9.neg; | |
var sndl,sndr; | |
var timescale = 1.0 / timescalein; | |
var snd=PlayBuf.ar(1,buf,rate:rateMult*BufRateScale.kr(buf),loop:1,trigger:Impulse.kr(0),startPos:BufFrames.ir(buf)*Rand(0,1)); | |
//var lr=(0.8*LFNoise2.kr(1/timescale))+(0.1*LFNoise2.kr(10/timescale)); | |
// try changing LFNoise2 to SinOsc or LFTri or LFSaw or LFPulse | |
// lr stands for left right | |
var lr = SinOsc.kr(1); // oscillating 1/second | |
// fb stands from front back | |
var fb=LFNoise2.kr(1/timescale)+(0.1*LFNoise2.kr(10/timescale)); | |
var amp=(db+LinLin.kr(LFNoise2.kr(1/timescale)+(0.1*LFNoise2.kr(10/timescale)),1.1.neg,1.1,ampRange,0)).dbamp; | |
var pan=lr*panRange; | |
lr = Clip.kr(lr,-1,1); | |
fb = Clip.kr(fb,-1,1); | |
amp = Clip.kr(amp,-64,12); | |
pan = Clip.kr(pan,-1,1); | |
snd=HPF.ar(snd,LinLin.kr(fb,-1,1,20,1000)); | |
sndl=snd; | |
sndr=snd; | |
// "Play point" to increase filtering change "100" to between 0 and 100 | |
sndl=LPF.ar(sndl,LinLin.kr(lr,-1,1,135,100).midicps); | |
sndr=LPF.ar(sndr,LinLin.kr(lr,-1,1,100,135).midicps); | |
// try increasing the delay from 0.03 to something higher | |
sndl=SelectX.ar(((lr>0.1)*lr.abs),[sndl,DelayN.ar(sndl,0.03,Rand(0.0,0.03))]); | |
sndr=SelectX.ar(((lr<0.1.neg)*lr.abs),[sndr,DelayN.ar(sndr,0.03,Rand(0.0,0.03))]); | |
snd=Balance2.ar(sndl,sndr,pan,amp)*Line.kr(0,1,1); | |
// doneAction:2 means free the synth when the envelope is done | |
amp = amp * EnvGen.ar(Env.adsr(fadein,1,1,fadeout,curve:[4,4]),gate,doneAction:2); | |
snd=snd*amp; | |
// if you anticipate having 10+ sounds you can scale the amplitude so the | |
// mix doesn't overload | |
// snd = snd / 10; // where 10 is the number of sounds you anticipate having | |
// SendReply.kr(Impulse.kr(10),"/position",[buf,lr,fb,amp]); | |
// first send sound to compression bus | |
Out.ar(busCompress,(fb+1)/2*snd); | |
// then send sound to bus that doesn't do compression | |
Out.ar(busNoCompress,(1-((fb+1)/2))*snd); | |
// then send sound to reverb bus | |
// increase reverb by increasing 0.1 to 1? | |
Out.ar(busReverb,LinExp.kr(fb,1,-1,0.01,0.1)*snd); | |
}).add; | |
SynthDef("looper2",{ | |
arg buf,busReverb,busCompress,busNoCompress,gate=1,rateMult=1.0,db=0.0,timescalein=0.05,fadein=5,fadeout=5,panRange=0.25,ampRange=9.neg; | |
var sndl,sndr; | |
var timescale = 1.0 / timescalein; | |
var snd=PlayBuf.ar(2,buf,rate:rateMult*BufRateScale.kr(buf),loop:1,trigger:Impulse.kr(0),startPos:BufFrames.ir(buf)*Rand(0,1)); | |
var lr=(0.8*LFNoise2.kr(1/timescale))+(0.1*LFNoise2.kr(10/timescale)); | |
var fb=LFNoise2.kr(1/timescale)+(0.1*LFNoise2.kr(10/timescale)); | |
var amp=(db+LinLin.kr(LFNoise2.kr(1/timescale)+(0.1*LFNoise2.kr(10/timescale)),1.1.neg,1.1,ampRange,0)).dbamp; | |
var pan=lr*panRange; | |
lr = Clip.kr(lr,-1,1); | |
fb = Clip.kr(fb,-1,1); | |
amp = Clip.kr(amp,-64,12); | |
pan = Clip.kr(pan,-1,1); | |
snd=HPF.ar(snd,LinLin.kr(fb,-1,1,20,1000)); | |
sndl=snd[0]; | |
sndr=snd[1]; | |
sndl=LPF.ar(sndl,LinLin.kr(lr,-1,1,135,100).midicps); | |
sndr=LPF.ar(sndr,LinLin.kr(lr,-1,1,100,135).midicps); | |
sndl=SelectX.ar(((lr>0.1)*lr.abs),[sndl,DelayN.ar(sndl,0.03,Rand(0.0,0.03))]); | |
sndr=SelectX.ar(((lr<0.1.neg)*lr.abs),[sndr,DelayN.ar(sndr,0.03,Rand(0.0,0.03))]); | |
snd=Balance2.ar(sndl,sndr,pan,amp)*Line.kr(0,1,1); | |
amp = amp * EnvGen.ar(Env.adsr(fadein,1,1,fadeout,curve:[4,4]),gate,doneAction:2); | |
snd=snd*amp; | |
// SendReply.kr(Impulse.kr(10),"/position",[buf,lr,fb,amp]); | |
Out.ar(busCompress,(fb+1)/2*snd); | |
Out.ar(busNoCompress,(1-((fb+1)/2))*snd); | |
Out.ar(busReverb,LinExp.kr(fb,1,-1,0.01,0.1)*snd); | |
}).add; | |
// initialize variables | |
syns = Dictionary.new(); | |
buses = Dictionary.new(); | |
bufs = Dictionary.new(); | |
oscs = Dictionary.new(); | |
synlist = Array.new(); | |
server.sync; | |
// oscs.put("position",OSCFunc({ |msg| | |
// var oscRoute=msg[0]; | |
// var synNum=msg[1]; | |
// var dunno=msg[2]; | |
// var bufNum=msg[3].asInteger; | |
// var lr=msg[4]; | |
// var fb=msg[5]; | |
// var amp=msg[6]; | |
// NetAddr("127.0.0.1", 10111).sendMsg("lr",bufNum,lr); | |
// NetAddr("127.0.0.1", 10111).sendMsg("fb",bufNum,fb); | |
// NetAddr("127.0.0.1", 10111).sendMsg("amp",bufNum,amp); | |
// }, '/position')); | |
// define buses | |
buses.put("busCompress",Bus.audio(server,2)); | |
buses.put("busNoCompress",Bus.audio(server,2)); | |
buses.put("busReverb",Bus.audio(server,2)); | |
server.sync; | |
// define fx | |
syns.put("fx",Synth.tail(server,"fx",[\busReverb,buses.at("busReverb"),\busNoCompress,buses.at("busNoCompress"),\busCompress,buses.at("busCompress")])); | |
server.sync; | |
"done loading.".postln; | |
} | |
free { | |
bufs.keysValuesDo({ arg k, val; | |
val.free; | |
}); | |
oscs.keysValuesDo({ arg k, val; | |
val.free; | |
}); | |
syns.keysValuesDo({ arg k, val; | |
val.free; | |
}); | |
buses.keysValuesDo({ arg k, val; | |
buses.free; | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment