Markdown Based Show Notes (Proof of Concept)


#1

Saturday arvo experiment… thoughts?


Markdown for Notes
#2

For those wondering what the script behind that page looks like:

<html>
<head>
	<!-- Import the Cantabile Javscript API library -->
	<script src="/lib/cantabile-js.js"></script>

	<!-- Cantabile bundles a copy of vue -->
	<script src="/lib/vue.js"></script>

	<!-- and jQuery -->
	<script src="/lib/jquery.min.js"></script>

	<!-- and MarkdownDepp -->
	<script src="/lib/MarkdownDeep.js"></script>

	<!-- Styles -->
	<link href="/styles.css" type="text/css" rel="stylesheet" />

	<!-- Scale -->
	<meta name="viewport" content="initial-scale=1">
</head>
<body>

<div id="main">
<div class="content">

	<!-- This is the template for the displayed HTML -->
	<div class="header" id="header">
		<p>Song: <strong>{{name}}</strong> State:<strong>{{currentState}}</strong></p>
	</div>

	<hr />

	<div id="notesView"></div>

</div>
</div>

<script>

	// Create an instance of the Cantabile library and connect it
	var C = new Cantabile();
	C.connect();

	C.song.open();
	C.bindings.open();

	// Watch for CC 16 on the onscreen keyboard
	C.bindings.watch(
		"midiInputPort.Onscreen Keyboard",                      // The source binding point
		null,                                                   // No indicies needed
		{ kind: "Controller", controller: 16, channel: 0 },     // The event to watch for (CC 16 on channel 1)
		onScroll                                                  // The function to call when triggered
	);

	// This function will be called whenever CC 16 changes
	function onScroll(value)
	{
		console.log(value);
		var body = document.body;
		body.scrollTop = (value / 127) * (body.scrollHeight-body.clientHeight);
	}

	// watch for the current song changing...
	C.song.on('changed', () => {

		header.currentState = C.song.currentState;
		header.name = C.song.name;

		$("div#notesView").html("Loading...");

		$.ajax({
			url: "/files/" + C.song.name + ".md",
			headers: {
				'Cache-Control': 'no-cache, no-store, must-revalidate', 
				'Pragma': 'no-cache', 
				'Expires': '0'
			},
			success: function(data) {
				var mdd = new MarkdownDeep.Markdown();
				mdd.ExtraMode = true;
				mdd.UrlBaseLocation = "/files/";
				mdd.UrlRootLocation = "/files/";
				$("div#notesView").html(mdd.Transform(data));
			},
			error: function(xhr, textStatus, errorThrown)
			{
				$("div#notesView").html("");
			}
		});
	});


	// Connect data to the HTML template via Vue
	var header = new Vue({
		el: "#header",
		data: {
			currentState: C.song.currentState,
			name: C.song.name,
		},
	});

</script>
</body>
</html>

#3

I like the idea of more sophisticated formatting of notes, but I don’t like having notes in a separate window. Can it be made to live in the ‘Notes’ page within Cantabile - even if that means it has to be simplified?

Also, without being able to trigger scrolling events automatically from the timeline I would have to find time to scroll them myself, which is not what I want when my hands are full.


#4

Well, if scrolling is controllable via MIDI, then bindings can automatically scroll your notes whenever you step to the next state. Or, if you want to fully automate, you only need a media player with a MIDI file that controls scrolling by sending CC values.

Pretty nifty!

And having this networked to Cantabile would mean that I could actually have my show notes on a separate machine from Cantabile (big computer backstage, networked tablet on-stage).

So having both options - integrated with Cantabile as the show notes page AND networked in a separate browser window - would be spectacular!

Great stuff, @brad!

Cheers,

Torsten


#5

Trouble is I’m not always changing states within a piece.

I’ve tried the method of having a MIDI file controlling Live Prompter, but it was just too cumbersome. Until timeline has the ability to issue timed bindings I’m having to find ways to make sure my notes fit onto one screen!


#6

I like it!!! What I like best is have the notes window separate from Cantabile!


#7

Why do you need a MIDI file to control LivePrompter? I built LP so that a whole song can scroll precisely timed without any user intervention (only if the drummer is having a high-speed-day, I may have to skip forward once in a while).

The secret is in the {d_time:xxx} tags: sprinkle them into your song file at relevant points (Verse 1, Chorus 1, Verse 2, Chorus 2, Solo, Ending) to set the precise time when this part of the song needs to be in focus. Presto: your LivePrompter song will scroll in fully automatic mode once you press “play” during the pre-count.

You can even find a spreadsheet to calculate the d_time seconds on the LivePrompter website.

Let me know if you need any help getting this to run!

Cheers,

Torsten


#8

Thanks for the offer, Torsten, but I really don’t have time to sort this out now (gigs about to begin), and I definitely don’t wants notes in a separate window - the guys would lynch me for that!

I’m having to design these rigs to work for people with very little technical aptitude and if I find it a challenge they find it impossible! Only a solution integrated into Cantabile will really cut it, I’m afraid.


#9

Hey Guys

Thanks for the feedback. Just to clarify a few things…

This isn’t going to replace the current show notes any time soon. It was more an experiment to see if it would work. Unfortunately getting an integrated view into Cantabile probably isn’t going to happen any time soon - I’m fairly reluctant to embed web browser in Cantabile which it would require. I might add some better formatting for the buillt in notes but that’s a bigger job.

Aside from the network server functionality there’s nothing specific in Cantabile to support this - it’s all built using http, the JavaScript api, and client side script. It’s not even really using bindings - it’s just client side script using the bindings system to listen on a particular cc.

I should also say, this is really just an example - it could be extended in all sorts of ways:

  • buttons could be added for common actions, transport, next state/song etc…,
  • song and state selection grids
  • other file formats - PDFs, plain HTML, etc…
  • auto scrolling
  • different notes for different clients (ie band members)
  • embedded tags for hiding/showing sections or marking scroll positions.

What it does show however is what the network api is good for - building powerful custom extensions. Anyone with some basic scripting skills should be able to build pages like this.

And given the ingenious ways you guys have bent Cantabile to your will I’m expecting to see some fun stuff out of this. :wink:

This area is the next major thing on my list, but there’s a bunch of related feature requests which I’m hoping to tackle all at once (ie: a big chunk of work)

How useful would it be to have triggerable, animatable, bindable custom parameters. I’m think something where a song or rack could define parameters with a name, an A and B value, curve, a time period etc. bindings could trigger it to a or b and other bindings could react to it changing over time.

Brad


#10

The curve idea is interesting.

I would just like to be able to say “at 00:12:22 switch to State 4”. The integrated Notes would then show/hide relative to my backing track. This in turn reduces the need for scrolling and fancy formatting.

And with that I’ll bow out, because it isn’t what this thread is about! :wink:


#11

I wasn’t suggesting the animatable properties for scrolling show notes or as a time line trigger - that’s another area which I’ll be working on soon. It’s just I’ve seen this idea of using a media player to animate a cc a number of times now and it seems clunky.


#12

Since @The_Elf already hijacked the thread… :slight_smile:
Does anyone know of a program that will easily allow creating a midi file that contains program changes or control changes at a certain time? I tried it in Reaper and some other DAW, but they were so feature rich that I just gave up. Just a simple program that can perform program/control changes at a timestamp is all I would really need instead of the time line trigger.


#13

This can be quite easily done using the Event List in Sonar (rebranded Cakewalk by Bandlab, and now available for free). I create all my midi tracks in Sonar.

I love the easy way you can use the recording feature in Cantabile. Just yesterday I needed a little “cheat” for the intro of Children of the Sea where I play the acoustic guitar part on my keyboard. To play it well. I need both hands but am stilling fall one hand short for the modulation wheel on one note. So I just recorded that bit separately in Cantabile, then opened the midi file in Sonar to quickly edit it to perfection and save it, then loaded it into a mediaplayer to be triggered by a key on my keyboard. I can now play the intro fully and it sounds pretty much like a real guitar :wink:

I’m aware that I’m dragging this thread even further off-topic…


#14

Really great demo of what’s possible with Cantabile’s new API feature! One thought I had from this was to allow different people in a band to have different show notes - a singer could have lyrics, guitarist could have chord changes, etc. All networked onto different tablets.

I also like the way with a bit of scripting the web UI could incorporate buttons and other controls.

Great stuff @brad! Nice to see a tangible use case from the network API!

But having now seen the power of Markdown for show notes…I’m starting to think that would be a great enhancement for the existing show notes format :smiley:

Neil


RFC: Replacing Show Notes (kinda, maybe)