Hi guys,
this is a follow up of my previous question.
I’m trying to create a sampler in SC to play back the Sonatina Symphonic Orchestra samples.
So I have to put all the sound files inside some sort of ordered list and then retrieve the correct one according to the midi note I want to play, possibly taking into account the playback ratio.
in order to do this I’ve starter loading the samples inside an array
~first_violins_piz_rr1 = SoundFile.collectIntoBuffers("/path/to/Sonatina Symphonic Orchestra/Samples/1st Violins/1st-violins-piz-rr1-*.wav", s);
Then I have created a new array where I’m storing buffers and some other related information like note name, corresponding midi number, etc…
Note: every element of the array is a dictionary so - I’ve thought - it would be easy to order it by one of its keys (see below).
~array = Array.newClear();
~first_violins_piz_rr1.do{
|item, index|
var d = Dictionary.new;
var string = PathName(item.path).fileNameWithoutExtension;
var output = string.findRegexp("[abcdefgABCDEFG]#?[0123456789]");
var noteNameAll = output[0][1];
var octNumber = noteNameAll.rotate(1)[0].asString.asInteger;
var noteName = noteNameAll[0].asString;
var isSharp = noteNameAll.contains("#"); // boolean
var midiNumber = (octNumber +1) * 12;
switch( noteName,
"c", { midiNumber = midiNumber+0; },
"d", { midiNumber = midiNumber+2; },
"e", { midiNumber = midiNumber+4; },
"f", { midiNumber = midiNumber+5; },
"g", { midiNumber = midiNumber+7; },
"a", { midiNumber = midiNumber+9; },
"b", { midiNumber = midiNumber+11; },
);
if(isSharp, {midiNumber = midiNumber + 1;});
[noteNameAll, noteName, isSharp, octNumber, midiNumber].postln;
d.add(\midi -> midiNumber.asInteger);
d.add(\note -> noteNameAll);
d.add(\buffer -> item);
~array = ~array.add(d);
}
Then I’ve sorted the array by the midi number
~array.sortBy(\midi);
I’ve defined the synth in order to play the samples back
SynthDef(\violins_pizz, {
|buf, rate=1.0, amp=1.0|
var sig = PlayBuf.ar(1, buf, BufRateScale.ir(buf)*rate, 1, doneAction:2);
sig = sig * amp;
Out.ar(0, sig!2);
}).add;
Now I’ve tried to create a Pbind to play the samples back but I’m not able to get the buffer from the specific element of the array.
I thought to use Pindex to get the specific Dictionary from the array according to a calculation on the midi note and then using the Pdict to get the value of the key \buffer
but I think I’m doing something wrong here…
Note: once I will be able to access the \buffer
key I will also be able to get the \midi
value from the Dictionary in order to calculate the ratio.
a = Pbind(
\instrument, \violins_pizz,
\midinote, Prand((54..95),inf),
\index, ((Pkey(\midinote) - (55-1))/3).floor,
\dictionary, Pindex(~array, Pkey(\index), inf),
\buf, Pdict(Pkey(\dictionary), \buffer, inf), // doesn't work
\ratio, ?,
\amp, 0.2,
\dur, 3
).play;
What I’m doing wrong in this Pbind?
Is there a way to retrieve a particular value from dictionaries inside patterns?
Is Pdict the pattern I should use? Is it meant to be used this way?
I’ve tried another way. Because I think Pdict is not the correct pattern to be used in this case (documentations seems to specify Pdict will only work if values inside it are patterns, which is not my case), I’ve tried to convert the dictionaries in arrays so to use Pindex two times:
So I’ve taken I step back and converted all the dictionary elements inside ~array
into lists, just after having ordered elements inside ~array
by the \midi
key ~array.sortBy(\midi);
:
~array.do{
|item, index|
[index, item.values].postln;
~array.put(index, item.values.asArray);
}
So I’ve tried using this Pbind, but it doesn’t work too
b = Pbind(
\instrument, \violins_pizz,
\index, Pseq([0, 1, 2, 3], inf),
\buf, Pindex(Pindex(~array, Pkey(\index), inf), 0, inf),
\amp, 0.2,
\dur, 3
).play;
What is the correct way to do what I want?
I wish I was able to explain myself…
Thank very much for your patience and support