diff projects/basic_midi/render.cpp @ 224:97faaf985164 mergingClockSync

Added callback for Midi channel messages
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 08 Mar 2016 15:49:42 +0000
parents b128e3ea84ff
children af1e662400fc
line wrap: on
line diff
--- a/projects/basic_midi/render.cpp	Mon Feb 22 11:28:21 2016 +0000
+++ b/projects/basic_midi/render.cpp	Tue Mar 08 15:49:42 2016 +0000
@@ -12,6 +12,22 @@
 #include <rtdk.h>
 #include <cmath>
 
+float gFreq;
+float gPhaseIncrement = 0;
+bool gIsNoteOn = 0;
+int gVelocity = 0;
+float gSamplingPeriod = 0;
+
+void midiMessageCallback(MidiChannelMessage message){
+	message.prettyPrint();
+	if(message.getType() == kmmNoteOn){
+		gFreq = powf(2, (message.getDataByte(0)-69)/12.0f) * 440;
+		gVelocity = message.getDataByte(1);
+		gPhaseIncrement = 2 * M_PI * gFreq * gSamplingPeriod;
+		gIsNoteOn = gVelocity > 0;
+		rt_printf("v0:%f, ph: %6.5f, gVelocity: %d\n", gFreq, gPhaseIncrement, gVelocity);
+	}
+}
 // setup() is called once before the audio rendering starts.
 // Use it to perform any initialisation and allocation which is dependent
 // on the period size or sample rate.
@@ -25,11 +41,13 @@
 {
 	midi.readFrom(0);
 	midi.writeTo(0);
-//	midi.enableParser(true);
+	midi.enableParser(true);
+	midi.setParserCallback(midiMessageCallback);
 	if(context->analogFrames == 0) {
 		rt_printf("Error: this example needs the matrix enabled\n");
 		return false;
 	}
+	gSamplingPeriod = 1/context->audioSampleRate;
 	return true;
 }
 
@@ -38,21 +56,18 @@
 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
 // will be 0.
 
-static midi_byte_t noteOnStatus = 0x90; //on channel 1
 
 enum {kVelocity, kNoteOn, kNoteNumber};
 void render(BeagleRTContext *context, void *userData)
 {
-	static float f0;
-	static float phaseIncrement = 0;
-	static bool noteOn = 0;
-	static int velocity = 0;
+// one way of getting the midi data is to parse them yourself
+//	(you should set midi.enableParser(false) above):
+/*
+	static midi_byte_t noteOnStatus = 0x90; //on channel 1
 	static int noteNumber = 0;
 	static int waitingFor = kNoteOn;
 	static int playingNote = -1;
-/*
 	int message;
-	// one way of getting the midi data is to parse them yourself (you should set midi.enableParser(false) above):
 	while ((message = midi.getInput()) >= 0){
 		rt_printf("%d\n", message);
 		switch(waitingFor){
@@ -92,6 +107,7 @@
 		}
 	}
 */
+	/*
 	int num;
 	//alternatively, you can use the built-in parser (only processes channel messages at the moment).
 	while((num = midi.getParser()->numAvailableMessages()) > 0){
@@ -103,28 +119,31 @@
 			velocity = message.getDataByte(1);
 			phaseIncrement = 2 * M_PI * f0 / context->audioSampleRate;
 			noteOn = velocity > 0;
-			rt_printf("v0:%f, ph: %6.5f, velocity: %d\n", f0, phaseIncrement, velocity);
+			rt_printf("v0:%f, ph: %6.5f, velocity: %d\n", f0, phaseIncrement, gVelocity);
 		}
 	}
-
+	 */
+	// the following block toggles the LED on an Owl pedal
+	// and asks the pedal to return the status of the LED
+	// using MIDI control changes
 	for(unsigned int n = 0; n < context->analogFrames; n++){
 		static int count = 0;
 		static bool state = 0;
 		analogWriteFrameOnce(context, n, 1, state);
 		if(count % 40000 == 0){
 			state = !state;
-			midi_byte_t bytes[6] = {176, 30, state*127, 176, 67, 30}; // toggle the OWL led and ask for the led status
+			midi_byte_t bytes[6] = {176, 30, (char)(state*127), 176, 67, 30}; // toggle the OWL led and ask for the led status
 			midi.writeOutput(bytes, 6);
 		}
 		count++;
 	}
 	for(unsigned int n = 0; n < context->audioFrames; n++){
-		if(noteOn == 1){
+		if(gIsNoteOn == 1){
 			static float phase = 0;
-			phase += phaseIncrement;
+			phase += gPhaseIncrement;
 			if(phase > 2 * M_PI)
 				phase -= 2 * M_PI;
-			float value = sinf(phase) * velocity/128.0f;
+			float value = sinf(phase) * gVelocity/128.0f;
 			audioWriteFrame(context, n, 0, value);
 			audioWriteFrame(context, n, 1, value);
 		} else {