Open Bohrbug opened 3 years ago
Hey @Bohrbug - could you let us know what we need to do to fix this?
For example - could you share some simple code (the simpler the better) that doesn't work as you expect and also let us know what the expected behaviour should be?
That way we can use the example to check to see if a fix is valid.
Hey @samaaron and @ethancrawford,
Swing By default, all steps in a pattern are equally spaced in time. At tempo of 120 BPM, a 16-step pattern will repeat every 2 seconds, making the steps one-eighth of a second apart. Altering the Swing parameter from its default value of 50% (the range is 20% to 80%) alters the timing odd- numbered steps (the off-beats); a lower swing value shortens the time between an odd beat and the previous even beat, a higher Swing value has the opposite effect.
Last drawing is swing 75%. A swing-feel is something that could be described as in between the timing of a triplet, and a dotted 8th. note with a 16th. Being able to move the quantization of every second note, allows you to tune in to that groove/feel. This was something Sam and I discussed, when he first made this function. It really worked when implemented. As an extra, you could even add an extra parameter, if you want this to be done on the second 16th note or the second 8th note. This is what Sam came up with when we discussed this 👍
`define :with_swing do |shift, pulse=2, key=:swing, &blk|
tick(key)
use_shift = (look(key) % pulse) != 0
if use_shift
time_shift shift do
blk.call
end
else
blk.call
end
end
live_loop :foo do
use_random_seed 30000657576587687645454
8.times do
with_swing rrand(0, 0.05), 2 do
cue :eggs
end
sample :elec_blip, on: (bools 1, 0, 1, 0).tick, rate: 2
sleep 0.125
end
end
live_loop :bar do
sync :eggs
sample :elec_blip, on: (bools 1, 0, 0, 1).tick
end
stop
live_loop :swing do
tick
dur = 0.125
shift = 0.01
shift_pat = (ring shift, 0, 0, 0)
pat = (bools 1, 0, 0, 1)
if pat.look
at shift_pat.look do
cue :foo
end
end
sleep dur
end
live_loop :bar do
sync :foo
sample :elec_beep
end
stop
live_loop :beat do
sync :clk
sample :elec_blip
end
live_loop :clksdflkjsdlfkjdslk do
use_bpm 60
# sleep [1.0/8 + 3.0/16, 1.0/16].ring.tick
shift = -0.04
# sleep [2.0/3 + shift,1.0/3 - shift].ring.tick
t = tick
puts look
if (look % 4) == 0
puts "hey"
cue :clk if (bools, 1, 0, 0,1)[t]
else
at shift do
cue :clk if (bools, 1, 0, 0,1)[t]
end
end
sleep 0.125
end
live_loop :foo, sync: :clk do
sample :sn_dolf, amp: 0.2, lpf: rrand(70, 130)
sleep 1r/6
end
live_loop :beat do
sync :clk
sample :elec_blip, rpitch: [-12, 0, 3, 12].choose, rate: 0.5
end
If you want extra info, please let me know, I would love to go to the bottom of this. Some extra awesomeness would be that the swing-function only would apply to rhythms that can be divided by 2, and would ignore rhythm values dividable by 3...
Hey @Bohrbug, A minimal example would be ideal 😅 so that we can make sense of it easily and it's clear exactly what the function in question is doing 🙂
Hi @Bohrbug - I can only repeat @ethancrawford here.
Whilst having some information about the general principles of swing is useful, it doesn't really help us understand where our current implementation isn't working. From my understanding nothing has changed with the with_swing
implementation since we discussed it and I implemented it. However, it might be that something else that it interacts with has changed which has resulted in different behaviour than you expect.
Is it just that you can "feel" that the swing isn't working? If so, that's going to be hard for us to replicate and fix! We really could do with a super simple example of what it should do and what it isn't. Perhaps slowing things down massively might help highlight the issues?
Also, are you observing this behviour on just MIDI sounds or calls to play
and sample
. It would be useful to know if the swing behaves differently with either external MIDI synths or triggering the internal SuperCollider synth.
Ok Thanks
On Mon, Dec 14, 2020, 8:05 AM Dago Sondervan notifications@github.com wrote:
For quiet a long time, swing_by doesn't seem to work anymore. Can't remember when it started. It might be when the Erlang timing implementation started, but that's just a very wild guess.
If you just check the examples, it is very clear this function doesn't produce swing timing adjustments as it should.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/sonic-pi-net/sonic-pi/issues/2589, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOF2UJJGYSHMOXBN63O26ETSUYESBANCNFSM4U2WZP7A .
Ok. I'll start first to let you see in Ableton what should be expected to see happening. I'll show you 3 pictures. After that I'll hook up Sonic Pi in sync with Ableton and will record the midi-output of Sonic Pi, first with and then without the swing. Then we can make a comparison.
This is the unaffected groove : THe C3's are the 4th note's (that should stay unchanged) the C3#'s are the 8th notes. Those are the one's where we should expect to see change :
Now we select a groove from the groove pool from Ableton. We will choose MPC 8th swing. And then the percentage. Let's take 54, and afterwards also 61.
once you have the groove selected, you can hear it. To see it in the clip, you should push the commit button. This is the result :
As you can see, all the see the C3's have remained in place, the C#3' have moved to the right. The are delayed in time. with always a equal amount. If we would increase the swing amount, those C#3 notes should move even further to the right in the grid. Lets do the same procedure and select MPC 8 swing 61 :
You could reproduce this easily in Ableton. Take a hihat or so as sound to make it clear what the swing-groove-adjustment does to the 'feel' of the rhythm. I'll be back with the Sonic Pi midi recordings.
I have used this code to test : `use_bpm 120
live_loop :clock do use_bpm 120 midi_start if tick == 0 midi_clock_beat sleep 1 end
live_loop :track1 do with_swing 0.1 do midi 60, channel: 1, port: "iac_driver_iac_bus_1", sustain: 0.3 end sleep 0.5 end`
And used different values for the swing function.
In sync with Ableton without swing it looks like this:
With 0.1 swing, it looks like this :
So it affects the first 4th (1) , that it should not. And it doesn't affect the first 8th note , which it should. Than at the second 4th note (1.2) it leaves the 4th alone (that's good), but doesn't again change the 8th note, which it should.
I hope this is a first start to make clear what is happening here. To be precise, the picture of the Ableton notes with the MPC 61 % swing should have a 1/16th grid, not a 1/16T (T for triplet) grid, and then it looks like this: And I used one bar in the Abelton internal examples, and two bars in the Sonic Pi midi recordings, but I hope you see it is the same thing... I had to do this with a previous beta version, because in v3.3.0-beta-4, the midi_clock_beat crashes. I'll open a new issue for that bug.
Thanks @Bohrbug - that's definitely very helpful!
@Bohrbug although the behaviour doesn't match what Ableton is doing, it does seem to match the documentation: "Runs block within a time_warp except for once every pulse consecutive runs (defaulting to 4)". I think if you change the parameters, it could do what you want. How does this look:
live_loop :track1 do
with_swing 0.1, pulse: 2, offset: 1 do
midi [:c3, :cs3].tick, channel: 1, port: "iac_driver_iac_bus_1", sustain: 0.3
end
sleep 0.5
end
Hi Emlyn,
Thanks for looking into this. Indeed, this does the trick.
I used the examples in the doc, but overlooked the options, that are not present in most examples. Also, as you mention, it is different from the approach in DAW's, but indeed, this does what should be expected.
Thanks you very much. Apologies that it was not a bug, but me overlooking the options.
Oh! That's quite alright, glad it does what you need in the end 😄
Great that a solution was found.
However, the original implementation of with_swing
was written after conversations with @Bohrbug - so I must have messed something up.
Dago, perhaps it makes sense to explore the defaults so that the behaviour you expect is what comes out of the box without any tweaking?
Also, @Bohrbug wrote:
I had to do this with a previous beta version, because in v3.3.0-beta-4, the midi_clock_beat crashes. I'll open a new issue for that bug.
Definitely do report this. It will be useful to know more about what causes the crash and also which was the last version that reliably worked. Also which platform you're working with :-)
@samaaron - just needs a few more details added to https://github.com/sonic-pi-net/sonic-pi/issues/2631 🙂
@samaaron Yes, would be happy to investigate. I will do some tweaking of the parameters, and I'll come back with some suggestions.
@samaaron After testing it for a while, i've noticed that swing values of 0.07 to 0.12 are doing what could be expect of swing. So I would suggest as default : with_swing 0.09, pulse: 2, offset: 1 It might be a good idea, if possible, to translate this to a more acceptable notation : with_swing 56 (%), as mentioned in my description of how this works in sequencers/daws , perhaps. It is totally workable how it is now however. Also I would like to add, that though different values don't lead to swing-feel, they are still very interesting to add a different groove to beats/melodies. So a broader idea of adjusting timing could be a with_groove function. So this 'faulty' behavior could be a win! For instance, if you want a groove to be 'laid-back", it would be sufficient to delay the 2 and 4th part of the beat a little. To be discussed further if you like.
Looking forward to hearing your thoughts on the above @samaaron 🙂
In the meantime @Bohrbug, as seen in the above notification I have separated out an issue for improving the with_swing
documentation - feel free to add descriptions there if you like of any examples you think might be useful 🙂
Hey @Bohrbug,
I'm now in a position to start looking at this again. Could you just confirm that the behaviour is still not quite right in v4?
For quiet a long time, swing_by doesn't seem to work anymore. Can't remember when it started. It might be when the Erlang timing implementation started, but that's just a very wild guess.
If you just check the examples, it is very clear this function doesn't produce swing timing adjustments as it should.