Transcription of a Short Piece for Keyboard Instrument


#21

I am also posting my current solution:

(The player must be revised, but the way to write a score will remain as it is. Honestly, I realised my method to write a score is more time-consuming than the method using Panola.)

(
fork{
	var bwv816_4, player;

	bwv816_4 = [
		[ // bar 0
			[ // voice 1, 2, 3: all voices have the same rhythms.
				[[83,74,55],65,4], //entry: [aChord, velocity, length.reciprocal]
				[[79,71,67],62,4]
			]
		],
		[ // bar 1
			[ // voice 1
				[74,62,4],
				[76,65,8], [78,64,8],
				[79,65,4],
				[76,62,4]
			],
			[ // voice 2
				[69,62,2],

				[71,65,4],
				[67,62,4]
			],
			[ // voice 3
				[66,62,4],
				[54,62,4],
				[52,65,4],
				[64,62,4]
			]
		],
		[ // bar 2
			[ // voice 1, 2
				[[71,66],62,2],

				[[76,67],65,4],
				[[72,69],62,4]
			],
			[ // voice 3
				[62,62,4],
				[50,62,4],
				[48,65,4],
				[60,62,4]
			]
		],
		[ // bar 3
			[ // voice 1 (occasionally 2)
				[[69,66],62,4],
				[71,64,8], [72,62,8],
				[74,64,8], [71,62,8],
				[72,64,8], [69,62,8]
			],
			[ // voice 3 (occasionally 2)
				[62,62,4],
				[57,62,4],
				[[54,69],65,4],
				[50,62,4]
			]
		],
		[ // bar 4
			[ // voice 1 (occasionally 2)
				[72,62,8], [71,62,8],
				[69,64,8], [67,62,8],
				[[83,74],65,4],
				[[79,71],62,4]
			],
			[ // voice 3 (occasionally 2)
				[[67,55],65,4],
				[50,62,4],
				[43,62,8], [50,62,8],
				[52,64,8], [54,62,8]

			]
		],
		[ // bar 5
			[ // voice 1, 1
				[[76,73],62,4],
				[[76,73],62,8], [[78,62],62,8],
				[[79,76],62,4],
				[[76,73],62,4]
			],
			[ // voice 3
				[55,62,8], [57,62,8],
				[55,64,8], [54,62,8],
				[52,62,8], [50,62,8],
				[52,64,8], [54,62,8]

			]
		],
		[ // bar 6
			[ // voice 1
				[73,62,4],
				[74,65,8], [76,64,8],
				[78,65,8], [74,62,8],
				[79,65,8], [76,62,8]
			],
			[ // voice 2
				[69,64,0.8]
			],
			[ // voice 3
				[55,65,8], [57,62,8],
				[59,65,8], [61,62,8],
				[62,62,4],
				[61,62,4],
			]
		],
		[ // bar 7
			[ // voice 1
				[78,65,8], [74,62,8],
				[81,65,4],
				[79,65,8], [78,62,8],
				[76,65,8], [78,62,8]
			],
			[ // voice 2
				[\reat,64,4],
				[74,64,2],
				[73,64,4],
			],
			[ // voice 3
				[62,65,4],
				[54,62,8], [55,62,8],
				[57,62,4],
				[45,62,4],
			]
		],
		[ // bar 8
			[ // voice 1, 2, 3: all voices have the same rhythms.
				[[74,50],65,2], //entry: [aChord, velocity, length.reciprocal]
			];
		]
	];

	player = {
		|music, synth, tempo=60, nthBar=0, vol=1|
		var timeFacror, entries, voiceItems, maxItemVoice, lastVoice;
		timeFacror = 60 / tempo * 4;
		entries = music[nthBar];
		voiceItems = entries.size.collect{
			|nth|
			entries[nth].size.collect{
				|ith|
				entries[nth][ith][2].reciprocal
			}
		};
		maxItemVoice = voiceItems.size.collect{
			|nth|
			var items, range;
			items = voiceItems[nth];
			range = (0..items.size - 2);
			(items.size == 1).if{ 0 }{ items[range].sum }
		};

		lastVoice = maxItemVoice.maxIndex;

		("Bar"+nthBar++"\nThe voice which will be played lastly:" + lastVoice).postln;

		{
			|vce|
			fork{

				(
					"\t\tVoice"+vce+"numItems:" + entries[vce].size +
					"\n\t\t\t\t\t\t  "++entries[vce]
				).postln;

				entries[vce].do{
					|entry,idxEntry|
					var aChord, entryPlayer, len, untilNext, rAmp, rRls;
					aChord = entry[0].asArray;
					entryPlayer = Array.newClear(10);
					len = entry[2];
					untilNext = len.reciprocal;
					rAmp = -0.1.rand;
					rRls = rrand(0.01, 0.03);
					aChord.size.do{
						|i|
						var aNote, amp;
						aNote = aChord[i];
						amp = entry[1]/127 * (2**(-3 - (i - 1.0.rand) + rAmp));
						(instrument: \default, midinote: aNote, amp: amp * vol, dur: untilNext, len:1).play;
						(
							[
								"voice:" + vce,
								"MIDI note:" + aNote,
								"rhythm:" + untilNext.asString.padRight(8, "0"),
								"dbFS:" + amp.ampdb.round(0.01).asString.padRight(6, "0")+"dB"
							]
						).postln;
						rrand(256, 384).reciprocal.wait;
					};

					( timeFacror * untilNext + (128.reciprocal.rand2) - rRls).wait;
					aChord.size.do{
						|i|
						entryPlayer[i].release
					};
					rRls.wait;

					if (
						(nthBar != (music.size - 1))
						&&
						vce == lastVoice
						&&
						(idxEntry == (entries[vce].size - 1))
					)
					{
						nthBar = nthBar+1;
						player.(music, synth, tempo, nthBar, vol);
					}
				}
			};
		}!entries.size;
	};

	// play music
	player.((bwv816_4!2).flatten(1), \default, 150, 0, 1)
}
)