eyeversuseye
MouseButton.kr( lag: 0 )
would be the same as DigitalIn.kr
A replacement would be:
{ SinOsc.ar( DigitalIn.kr( 0 ).lag(2).range(440,740), 0, 0.1 ) }.play
eyeversuseye
MouseButton.kr( lag: 0 )
would be the same as DigitalIn.kr
A replacement would be:
{ SinOsc.ar( DigitalIn.kr( 0 ).lag(2).range(440,740), 0, 0.1 ) }.play
Absolutely, I understand that writing software that is open-sourced and non-paid is time consuming and doesn't put food on the table, so I really appreciate your help on this.
I'll give Changed.ar
a try with triggering.
An alternative way of asking this question, is how do we use DigitalIn to create a new synth and destroy the previous one - the machine i've built has a turnwheel that triggers a button with every rotation. I tried loading a buffer of 20 samples to trigger a new sample with every button press, but the walls i've hit are too tall for me to pass
I think you are already quite close, change the synthdef to:
SynthDef(\samplePlaying, {
arg atk=0, sus=0, rel=3, c1=1, c2=(-1),
firstbuf=0, rate=1, spos=0, freq=440, rq=1, bpfmix=0,
pan=0, amp=1, out=0;
var sig, env, sound, sample;
var trig;
var buffersAvailable=(0..19);
var bufseq;
trig = DigitalIn.kr( 0 );
bufseq = Dseq( buffersAvailable, inf );
sample = Demand.kr( trig, 0, bufseq ) + firstbuf; // firstbuf is the index of the first buffer
env = EnvGen.kr(Env([0,1,1,0], [atk, sus, rel], [c1,0,c2]), trig );
sig = PlayBuf.ar(1, sample, rate*BufRateScale.ir(sound), trig, startPos:spos);
sig = XFade2.ar(sig, BPF.ar(sig, freq, rq, 1/rq.sqrt), bpfmix*2-1);
sig = sig * amp;
sig = Pan2.ar(sig, pan, amp);
Out.ar(out, sig);
}).send(s);
Not tested, but should be something along those lines.
It assumes that you load the samples into 20 consequetive buffers and you can pass firstbuf as an argument to set the bufnum of the first buffer. The DigitalIn will trigger changing to a new buffer, and starting to play the buffer and retriggering the envelope.
nescivi Almost, but the error:
The preceding error dump is for ERROR: Primitive '_BasicAt' failed.
Index not an Integer
appears, as i can't seem to get this:
sample = Select.ar( ((0.4).linlin(0.01, 1, 0, 19).nearestInList(buffersAvailable)), buffersAvailable);
To be an integer, no matter what I've tried
eyeversuseye sorry, my post posted too fast... I fixed my example.
nescivi This is the one! All that is missing is how I control the buffers being played — Using a dictionary to load buffers from subfolders and assign them symbols like so:
b = Dictionary.new;
PathName(~path).entries.do {
arg subfolder;
b.add(
subfolder.folderName.asSymbol ->
Array.fill(
subfolder.entries.size,
{
arg i;
Buffer.read(s, subfolder.entries[i].fullPath);
}
)
);
};
Allows me to say b[\drum_kit][0].play;
With the code you've just changed, would I be right in thinking I can't simply prepend the sample name to the Demand.ar
Oh, but we don't have to use Demand
at all do we
(
// Buffers/Sound files loaded from dictionary
SynthDef(\samplePlaying, {
arg atk=0, sus=0, rel=3, c1=1, c2=(-1),
firstbuf=0, rate=1, spos=0, freq=440, rq=1, bpfmix=0,
pan=0, amp=1, out=0;
var sig, env, sound, sample;
var trig;
var buffersAvailable=(0..19).scramble;
var bufseq;
trig = DigitalIn.kr(0);
bufseq = Dseq( buffersAvailable, inf );
/////////////////////
sample = AnalogIn.ar(0).linlin(0.01, 1, 0, 19); // Pick the buffer, based on Analog sensor
/////////////////////
env = EnvGen.kr(Env([0,1,1,0], [atk, sus, rel], [c1,0,c2]), trig );
sig = PlayBuf.ar(1, sample, rate*BufRateScale.ir(sample), trig, startPos:spos);
sig = XFade2.ar(sig, BPF.ar(sig, freq, rq, 1/rq.sqrt), bpfmix*2-1);
sig = sig * amp;
sig = Pan2.ar(sig, pan, amp);
Out.ar(out, sig);
}).send(s);
);
eyeversuseye
the notations b[\drum_kit][0] works on the language side, not on the server side - that is also why you got the error messages for the buffer selection in your first version of the synthdef: you were trying to use the language representation of a buffer (an instance of Buffer) within the Synthdef. For things like that please check the "client-vs-server"-helpfile to get a better understanding of what happens in the language and what on the server.
You would pass on the index of your first drumkit buffer to the Synth like this:
a = Synth.new( \samplePlaying, [ \firstbuf, b[\drum_kit][0].bufnum ] );
eyeversuseye Ok, I thought you wanted to play a new sample at each button press from a sequence of buffers. I missed that you wanted to select the sample with that analog control.
Yes, then your solution works. And you can even leave out the bufseq=...
.
I would add the firstbuf to sample, as your first buffer is not necessarily always the one at bufnum 0:
sample = AnalogIn.ar(0).linlin(0.01, 1, 0, 19) + firstbuf;
nescivi interestingly, the analogIn can trigger the samples and cause a bunch of glitching - perhaps rounding would solve the issue?
eyeversuseye yes, just add a .round(1)
to it and it should be fine.
linlin
could also start at 0, so .linlin(0,1,0,19).round(1)
Hey everyone!
I developed your code trying to add one light as feedback for the synth. Could you verify what am I forgetting or doing wrong on this example?
....
s.waitForBoot({
SynthDef(\mic, {| inChan = 0,inPin, outPin|
var in, outLed, button;
in = SoundIn.ar(inChan);
in.poll;
button = DigitalIn.ar(inPin);
outLed = DigitalOut.ar(outPin, button); //Light Digital pin 1 - Button
Out.ar(0,in!2);
}).send(s);
s.sync;
~buttonMonitor = {
var d1 = DigitalIn.kr(1); // Digital pin 1 - Button
var d2 = DigitalIn.kr(2); // Digital pin 2 - Button
var d3 = DigitalIn.kr(3); // Digital pin 3 - Button
SendReply.kr(Changed.kr(d1+d2+d3), '/buttonMonitor', [ d1, d2, d3]);
}.play;
~button1 = 0;
~button2 = 0;
~button3 = 0;
// Listen to the buttons
OSCdef('listenToButtons', {
arg msg;
// Buttons
~button1 = msg[3].asInteger;
~button2 = msg[4].asInteger;
~button3 = msg[5].asInteger;
["Buttons: " ++ ~button1, ~button2, ~button3].postln;
}, '/buttonMonitor');
{
q = Synth(\mic, ['inPin', 0, 'outPin', 1]);
q.set(\t_trig, Pfunc({~button1}));
};
});
Hi all,
Excuse me diving back into this thread but I can't find a simple example of sending digital messages between the server and the client.
Does anyone an example they could share?
Many thanks
Simon
Ok this works for me....
/*
// obviously there are ways to shorten this code but it works for me and is
// a simple way to get buttons into the SuperCollider client environment.
// a SynthDef running on the server to read buttons.
// (As I understand they have to be read on the server)
// SendReply sends the button value 10 times a second from the server to the client
*/
SynthDef('button_button_reads', {
var button1 = DigitalIn.ar(1);
var button2 = DigitalIn.ar(2);
SendReply.kr(Impulse.kr(10), '/button1', button1.value);
SendReply.kr(Impulse.kr(10), '/button2', button2.value);
}).play;
// this code picks up the button values.
~button1 = OSCFunc({ arg msg; ~button1value = msg[3]}, '/button');
~button2 = OSCFunc({ arg msg; ~buttontvalue = msg[3]}, '/button');