(
//~~SYNTHDEF THAT PLAYS THE PIECE AND ACCEPTS CONTROL FROM THE GUI
SynthDef(\play, {
	arg buf = 0, env, playRate = 0, startPos = 0, startTrig = 0, curDur,
	goVol = #[1, 1, 1, 1, 1, 1], giVol = #[1, 1, 1, 1, 1, 1], pVol = #[1, 1, 1, 1, 1, 1], eVol = #[1, 1, 1, 1, 1, 1], aVol = #[1, 1, 1, 1, 1, 1],
	goMute = #[1, 1, 1, 1, 1, 1], giMute = #[1, 1, 1, 1, 1, 1], eMute = #[1, 1, 1, 1, 1, 1], pMute = #[1, 1, 1, 1, 1, 1], aMute = #[1, 1, 1, 1, 1, 1],
	goPan = #[0, 0, 0, 0, 0, 0], giPan = #[0, 0, 0, 0, 0, 0], ePan = #[0, 0, 0, 0, 0, 0], pPan = #[0, 0, 0, 0, 0, 0], aPan = #[0, 0, 0, 0, 0, 0],
	masterVolGroups = #[1, 1, 1, 1, 1], masterMuteGroups = #[1, 1, 1, 1, 1],
	allMasterVol = 1, allMasterMute = 1;
	var phasor, player;
	var guitarOTracks, guitarITracks, percussionTracks, ensembleTracks, accompTracks;
	var guitarOTracksPanned, guitarITracksPanned, percussionTracksPanned, ensembleTracksPanned, accompTracksPanned;
	var guitarOMaster, guitarIMaster, percussionMaster, ensembleMaster, accompMaster;
	var allMaster;
	var imp, delimp;

	player = PlayBuf.ar(26, buf, playRate, startTrig, startPos * BufFrames.kr(buf));
	phasor = Phasor.ar(startTrig,
		Select.kr(playRate, [0, BufRateScale.kr(buf)]),
		0, BufFrames.kr(buf), startPos * BufFrames.kr(buf));

	guitarOTracks = { |i| var string = 5 - i; player[string - 2] * goVol[i] * goMute[i] } ! 4;
	guitarITracks = { |i| var string = 5 - i; player[string + 4] * giVol[i] * giMute[i] } ! 6;
	percussionTracks = { |i| var string = 5 - i; player[string + 10] * pVol[i] * pMute[i] } ! 6;
	ensembleTracks = { |i| var string = 5 - i; player[string + 16] * eVol[i] * eMute[i] } ! 6;
	accompTracks = { |i| player[i + 22] * aVol[i] * aMute[i] } ! 4;

	guitarOTracksPanned = { |i| Pan2.ar(guitarOTracks[i], goPan[i]) } ! 4;
	guitarITracksPanned = { |i| Pan2.ar(guitarITracks[i], giPan[i]) } ! 6;
	percussionTracksPanned = { |i| Pan2.ar(percussionTracks[i], pPan[i]) } ! 6;
	ensembleTracksPanned = { |i| Pan2.ar(ensembleTracks[i], ePan[i]) } ! 6;
	accompTracksPanned = { |i| Pan2.ar(accompTracks[i], aPan[i]) } ! 4;

	guitarOMaster = Mix.new(guitarOTracksPanned) * masterVolGroups[0] * masterMuteGroups[0];
	guitarIMaster = Mix.new(guitarITracksPanned) * masterVolGroups[1] * masterMuteGroups[1];
	percussionMaster = Mix.new(percussionTracksPanned) * masterVolGroups[2] * masterMuteGroups[2];
	ensembleMaster = Mix.new(ensembleTracksPanned) * masterVolGroups[3] * masterMuteGroups[3];
	accompMaster = Mix.new(accompTracksPanned) * masterVolGroups[4] * masterMuteGroups[4];

	allMaster = Mix.new([guitarOMaster, guitarIMaster, percussionMaster, ensembleMaster, accompMaster]) * allMasterVol * allMasterMute;
	Out.ar(0, allMaster);

	curDur = ((A2K.kr(phasor) / BufFrames.kr(buf)) * BufDur.kr(buf) * 5).trunc;
	//Optional click - uncomment and send to an output not used to give the guitarist a click track.
	//Out.ar(2, 10 * BPF.ar(WhiteNoise.ar * EnvGen.kr(Env.perc(0.01, 0.1), curDur % 4 <= 0), 440 * ((curDur % 20 <= 0) + 1), 0.02));
	SendTrig.kr(Changed.kr(curDur), 0, curDur);
	imp = Impulse.kr(10);
	delimp = Delay1.kr(imp);
	SendReply.kr(imp,
		'/allMasterLevels',
		values: [Amplitude.kr(allMaster)]);
	SendReply.kr(imp,
		'/groupMasterLevels',
		values: [
			Amplitude.kr(guitarOMaster) ++ Amplitude.kr(guitarIMaster) ++
			Amplitude.kr(percussionMaster) ++ Amplitude.kr(ensembleMaster) ++ Amplitude.kr(accompMaster)]);
	SendReply.kr(imp,
		'/groupTrackLevels',
		values: [Amplitude.kr(guitarOTracks) ++ Amplitude.kr(guitarITracks) ++
			Amplitude.kr(percussionTracks) ++ Amplitude.kr(ensembleTracks) ++ Amplitude.kr(accompTracks)]);
}).add;
)