a question about onset: In my naive mind I thought it should be possible to find the last detectable onset of a given sample with:
sample :loop_amen, rate: -1, onset: 0
This does not seem to be true. The sample is of course played backwards but index 0 still gives the first onset of the sample played from the beginning in non-reversed manner. This is logical but not what I expected.
As with most programming languages, Sonic Piās arrays (which are really just Rubyās arrays) are 0 indexed. Therefore asking for something at index 0 is asking for the first item. To ask for the last item, you should ask for item -1 (this is thanks to the fact that Sonic Piās onset opt acts like a ring, so going back one index (from 0 to -1) is the same as jumping to the last item.
Without wanting to pretend to be as smart as this solution I somehow suspected that there must be an easy way like this Thanks!
Just to give some background: At Saturday I had the oportunity to present Sonic Pi at an IT fair for kids. I did mess around with Sonic Pi almost the whole day (which was fun and a very good exercise); during one of these sessions I recorded the āchord inversionā examples, because one question was about recording your Sonic Pi tune. Then I loaded this sample to further mess around with it.
The next day I was thinking about an easy way to trim the sample for further manipulation in a quick way and without any external application; this brought me to onset ā¦
Thanks for welcoming me back! Been doing many other musicking projects, mostly on iPad and in Bitwig Studio 3. Hadnāt touched SPi in quite a while when @samaaron sent that update about 3.2b8 for macOS.
Noticed some of the changes before reading the release notes. Rather neat!
The onset stuff is pretty motivating. Itās one of those neat little SPi tricks which are easy to use, learn, and teach. And they provide real value to musickers of all stripes!
The fact that onsets now behave more like samples is what needed to happen, IMHO. Now that we can slice them up, itās easier to imagine the type of sampling fun people like to do with sample-focused DAW plugins.
At any rate, going back to topicā¦
Has anyone found an elegant way to return that number of onsets value?
I feel like itād be pretty useful to have it directly in the ānotationā so you could randomly pick from all onsets.
If I already know the value, it can be fairly elegant/terseā¦
smp=:loop_safari;maxons=43
loop do
onsnum=rand(0..maxons)
smpdur=sample_duration(smp, onset: onsnum)
sample smp, onset: onsnum
puts onsnum, smpdur
sleep smpdur
end
Sounds groovy, a 10yo learner could understand the code fairly easily so she might add it to her own scripts, and itās fully transparent (unlike defs).
Maybe I should just use @robin.newmanās defs for now. Itās just that I get this nagging feeling that thereās a better way.
Now, thatās elegant!
Thanks a lot. Iāll update.
Maybe I donāt need to know the number, after all.
Still, my curiosity (hopefully cat-safe) keeps me wondering: isnāt there an obvious Ruby thing to do to reference the index value of the last item in a ring?
# Simple Sonic Pi script which randomly picks part of a looping sample to create a groovy rhythm.
# https://soundcloud.com/synthbreath/sonic-pi-random-safari-loop
# Thanks to Sam Aaron for that āpickā trick! http://in-thread.sonic-pi.net/t/find-the-last-onset-within-a-sample/1299/10?u=enkerli
# I still need to get the duration of that onset so Iām not yet able to fully use that trick.
# In the meantime, I did find a relatively simple way to get the number of onsets in a sampleā¦
smp=:loop_safari
maxons=0
l = lambda {|c|;maxons=c.length-1 ; c[0]}
sample smp, onset: l, finish: 0
loop do
ons=rand(0..maxons)
sample smp, onset: ons
sleep sample_duration(smp, onset: ons)
end
Still wish I could use the pick trick. Sooooo elegant! Itās just that I really need to know the duration of that onset. Setting them all to the same value really defeats the purpose, making it āquantizedā. The groovy thing about this random onset script is that these sections of the sample have different durations.
At first, I thought that, maybe, pick worked like tick and one could look to use the same value. Now, that would work so so well!
Of course, since these are rings, this also works:
smp=:loop_safari
loop do
ons=rand(0..1000)
sample smp, onset: ons
sleep sample_duration(smp, onset: ons)
end
Itās extremely unlikely that anyone would ever use a sample with more than 1001 onsets. If they did, itād probably cause performance issues. I just find this solution a bitā¦ kludgy. Maybe Iām thinking too much about teaching (which Iām not doing with SPi, at this point in time). It feels like something weād tell learners not to do. Better to find the actual value than think up an arbitrary number.
Ok, next step is to try this with imported loops. Got subscriptions to a few sample libraries so itās easy to find these.
# get a ring with all onsets
ring_of_onsets = sample_buffer(:loop_amen_full, 0).onset_slices
puts ring_of_onsets
# get the index of the last item of this ring
index_of_last_onset = sample_buffer(:loop_amen_full, 0).onset_slices.last[:index]
puts index_of_last_onset
Sure is!
Updated my simple code. And applied it to loops from sample libraries. It was interesting to find which loops worked best. There isnāt much thatās intuitive about it. The type of sound does matter. So does the relationships in duration between onsets. In a way, that recording is in decreasing order of preference.
smp=:loop_safari
maxons=sample_buffer(smp, 0).onset_slices.last[:index]
loop do
ons=rand(0..maxons)
sample smp, onset: ons
sleep sample_duration(smp, onset: ons)
end
Great! Glad that helpedā¦ but the actual credit for this little trick has to go to Pit, who - quite a while ago - showed it to me. Nice sounds, I mostly like the voice and guitar examples from 3ā14 on!
I mostly like the voice and guitar examples from 3ā14 on!
Ha! Should have known that putting them in decreasing order of preference could have the reverse effect.
Iāll experiment more with melodic and voice stuff. Come to think of it, conversational speech might work fairly well. Will search Freesound.org for such samples.
Something Iāve been thinking about as well is that onsets can help create a āpoor personās groove extractorā. My favourite DAW doesnāt support groove quantization. It might still be fun to trigger things in a groove, sending a MIDI event at each onset (without even needing to play the sample itself).
Not quite sure, what you aiming at. Is it about to create āhumanized variationsā? Do you care to elaborate?
I did some experiments with randomized slices (could also be onsets) to create fill-ins, which aim to sound as natural as possible; of course you can use pick on the collection of all slices a sample has been sliced into. Other times a ring with a choice of selected slices and .choose will do a better job. Examples are with the Amen break to not make it work with stock material from Sonic Pi, but its worthwhile to use all sorts of drums loops.
What I meant by āgroove extractorā was more about synching another instrument with the onsets of a groovy loop.
And experimenting with random onsets has been an ear-opening experience. As I said, it wasnāt really possible to guess which loops would work best. Applied the same idea to speech samples and it was rather effective in producing unexpected beats. The onsets donāt necessarily correspond to syllables and the speech is impossible to recognize as a specific language. Because thereās a lot of silence in speech, I ended up layering samples from different languages, playing a bit with pitch. Sounded a bit like a ānonsense conversationā.
Havenāt done much in SP but Samās notifications of beta releases make me think of some microprojects I might end up doing, with this unusual situation weāre in.