supercollider / learn

Official SuperCollider tutorial
78 stars 24 forks source link

Bar and beat #9

Open prko opened 5 years ago

prko commented 5 years ago

Hello, thank you for writing the tutorial series. I think the following melody section is excellent. https://github.com/supercollider/learn/blob/master/src/beginner/src/ch02-01-melody.md

However, the array of melody does not contain bar and beat. I know introducing these might be more complex. I would like to know if the concepts of bar and beat will be introduced later or not?

cianoc commented 5 years ago

Thank you, that's good to hear.

I do plan to add more stuff to this later in the tutorial, but I'm curious as to what you mean by bar and beat. Something I do plan to add is a bit on how you can write parameters that are dependent upon the beat, or bar. But I'm guessing that you're looking for something a little bit different.

If you want to clarify what you're looking for (and the scsynth.org forum might be a better place), that would help me a lot. Thanks :)

prko commented 5 years ago

To show what I mean, here are two examples:

I think the method of example 2 is not so good as example 1. Example 1 must be rewritten with patterns.

You need the following sample: https://freewavesamples.com/alesis-fusion-nylon-string-guitar-c4

I am not sure if it is good to post these examples in the scsynth.org because they are too long. If you think I should post all two examples or one of them in the scsynth.org, I will post it or them there. I think the example 1 should also be rewritten with the piece "twinkle, twinkle, little star".

~twinkle_b= [ [ // bar 9, 13 [79,48,4]!2, [ // voice 2 [64,48,4],[55,48,4] ] ], [ // bar 10, 14 [77,48,4]!2, [ [62,48,4],[55,48,4] ] ], [ // bar 11, 15 [76,64,4].dup(2), [ [60,48,4],[55,48,4] ] ], [ // bar 12, 16 [ [74,48,2] ], [ [59,48,4],[55,48,4] ] ] ];

~twinkle=~twinkle_a++(~twinkle_b!2).flatten(1)++~twinkle_a; )

/ bus /

( SynthDef(\reverb, { arg oCh, iCh, rs=100, rt=2.5, mul=0.5; var sig= GVerb.ar(In.ar(iCh), rs, rt, mul:mul); Out.ar(oCh, sig) } ).add )

~gtrC4m= Buffer.readChannel(s, "Alesis-Fusion-Nylon-String-Guitar-C4.wav".resolveRelative, channels:0);

( SynthDef(\gtrM, { arg len=1, oCh=0, pit=60, vSpd=3.5, vDepth=0.3, mul=1; var env, atk=0.01, rls=0.05, rate, fm, am, sig; env=Env([0,1,1,0],[atk,len-atk-rls,rls]).kr(doneAction:2); fm= SinOsc.kr(vSpd,1.5pi).range(1, 2(vDepth/12)); rate= 2(pit-60/12) BufRateScale.kr(~gtrC4m.bufnum) fm; am= SinOsc.kr(vSpd, 0.5pi).range(0.5.sqrt, 1); sig= PlayBuf.ar(~gtrC4m.numChannels, ~gtrC4m.bufnum, rate); sig= sig am env * mul; Out.ar(oCh, sig) } ).add )

( ~gtrM={ arg score, voice=0, temp=2, offset=0, leg=1; fork{ score.do{ arg barItms, barIdx; barItms[voice].do{ arg item, idx; var wait, len, notes, mul, phr; if (idx==0 && voice==0) {barIdx.postln}; phr= if ((barIdx/2).asInteger.even==3) {idx} {barItms.size-idx} - barItms.size; wait= 2(phr/20) temp item[2].reciprocal; len= wait leg; notes= item[0].asArray; mul= exprand(22.5.neg, 21.neg) (item[1]/127).sqrt; [voice, idx, item].postln; notes.size.do{ arg i; var deTune, phrMul; deTune= rrand( -0.02, 0.02); phrMul= 2(phr/3); Synth.before( ~reverb, \gtrM, [ oCh:~bus_reverb, pit:notes[i]+deTune+offset, len:len, mul:mul*(2*(1/(i+1)).neg).sqrt phrMul, vSpd:2, vDepth:0.2 ] ); (rrand(1/256, 1/128)).wait }; ( wait + rrand(-1/256, 1/256) ).wait } } } } )

~bus_reverb= Bus.audio(s, 1);

~reverb= Synth(\reverb, [iCh:~bus_reverb, oCh:0]);

( ~gtrM.(score:~twinkle, voice:0, leg:1); ~gtrM.(score:~twinkle, voice:1, leg:0.4) )

~reverb.set(\rs, 10, \rt,1.15, \mul,2)

cianoc commented 5 years ago

I probably won't do this, no, though I may augment the melodic stuff a little (for example showing how you can specify the notes and duration together using nested arrays). I will also show a way to use environments so that you can use note names, rather than numbers (e.g. \cs4 for C sharp 4) - though that will probably go into the cookbook. I'm also going to talk about importing midi files, and using those with patterns.

If you want to discuss this further though, the SCcode forum is the place to do it. Other people may have views, and I would like to discuss this more generally. I think it's a shame that there isn't an easy way to do melodies in SuperCollider, though this looks pretty promising: https://github.com/shimpe/panola

You don't get the bar lines, but there may be other ways to achieve that (e.g. using the current time in a pbind).

prko commented 5 years ago

Thank you for your precious opinion!

In February, 2018, I posted it in the mailing list, but nobody gave me any feedback: https://www.listarc.bham.ac.uk/lists/sc-users/msg59085.html

I am a bit confused with the term SCcode forum. Do you mean scsynth.org, sccode.org or the mailing list?

I probably make code simpler with Pbind, then should post it. What do you think about it?

I do not use bar lines as an element of arrays. However, I can easily accentuate the first note or chord of each bar with altering velocity or altering duration in Example 1 because the playback firstly detects the size of the array of a bar then plays each element then go to next bar if the all notes in the current bar are played. In Example 1, I also make a rubato, accelerando, ritardando, crescendo and decrescendo within a bar. By using a global variable, I can do such things for some bars in Example 1.

I am not sure if pitch name is good because pitch names are diverse according to lands: In Germany, they use the Helmholtz-system; in the US, they use American Standard Pitch Notation (ASPN); In France, the octave number is lower than ASPN. Yamaha follows the French system, and Rolland follows the American system. Most software programmes provide an option to choose middle C as C3 or C4. Thus, I think that fixing middle C as C4 would be not good.

Anyway, Panola is cool! Is it your Quarks?

cianoc commented 5 years ago

Sorry I meant scsynth.org

There is a way to detect which beat of a bar you're in from within a pattern, and I plan to show how you can use that to create more realistic playback (it's a trick I use quite a bit). You can also do rubato/crescendo etc using patterns relatively easily - perhaps I should also show how to do that so it relates to bars/beats as well.

As far as notation goes - this is for an example, so the user can change it if they want. However, it is far easier to support ASPN in SuperCollider, than any of the others:

\C0;   \\ No problems
\C-1; \\ Not going to work.

Panola isn't mine - but I plan to use it.

prko commented 5 years ago

I expect to read your method in the tutorial! I understand now ASPN is simpler in SC, but the system of the pitch names should be explained in the tutorial.

Twinkle ... is too simple, and the Korean song is good enough to discuss on notation method, but it is not well-known. I will search for another short and well-known example for the post in scsynth.org.

Thank you a lot!

prko commented 5 years ago

Is the first part of the following piece interesting enough for a transcription example? https://www.youtube.com/watch?v=ffZnrJpQmZY the number of voice is fixed but mixed with rests. There is a note exceeds a bar.

cianoc commented 5 years ago

Ha, I remember learning that piece for piano.

Yes, that's pretty good. Multiple voices, a tied note, rests, repeats. Post it on the forum and see what people make of it.