diff projects/basic_midi/render.cpp @ 181:391ad036557d

Basic Midi input implementation
author Giulio Moro <giuliomoro@yahoo.it>
date Fri, 15 Jan 2016 21:50:46 +0000
parents
children 9108a0a34cb8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/projects/basic_midi/render.cpp	Fri Jan 15 21:50:46 2016 +0000
@@ -0,0 +1,101 @@
+/*
+ * render.cpp
+ *
+ *  Created on: Oct 24, 2014
+ *      Author: parallels
+ */
+
+
+#include <BeagleRT.h>
+#include <Midi.h>
+#include <stdlib.h>
+#include <Utilities.h>
+#include <rtdk.h>
+#include <cmath>
+
+// 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.
+//
+// userData holds an opaque pointer to a data structure that was passed
+// in from the call to initAudio().
+//
+// Return true on success; returning false halts the program.
+Midi midi;
+bool setup(BeagleRTContext *context, void *userData)
+{
+	midi.readFrom(0);
+	if(context->analogFrames == 0) {
+		rt_printf("Error: this example needs the matrix enabled\n");
+		return false;
+	}
+	return true;
+}
+
+// render() is called regularly at the highest priority by the audio engine.
+// Input and output are given from the audio hardware and the other
+// 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;
+	int message;
+	static bool noteOn = 0;
+	static int velocity = 0;
+	static int noteNumber = 0;
+	static int waitingFor = kNoteOn;
+	while ((message = midi.getInput()) >= 0){
+		switch(waitingFor){
+		case kNoteOn:
+			if(message == noteOnStatus){
+				noteOn = true;
+				waitingFor = kNoteNumber;
+			}
+			break;
+		case kNoteNumber:
+			if((message & (1<<8)) == 0){
+				noteNumber = message;
+				waitingFor = kVelocity;
+				f0 = powf(2, (noteNumber-69)/12.0f) * 440;
+				phaseIncrement = 2 * M_PI * f0 / context->audioSampleRate;
+			}
+			break;
+		case kVelocity:
+			if((message & (1<<8)) == 0){
+				velocity = message;
+				waitingFor = kNoteOn;
+				if(velocity == 0)
+					noteOn = false;
+				rt_printf("NoteOn: %d, NoteNumber: %d, velocity: %d\n", noteOn, noteNumber, velocity);
+			}
+			break;
+		}
+	}
+	for(unsigned int n = 0; n < context->audioFrames; n++){
+		if(noteOn == 1){
+			static float phase = 0;
+			phase += phaseIncrement;
+			if(phase > 2 * M_PI)
+				phase -= 2 * M_PI;
+			float value = sinf(phase) * velocity/128.0f;
+			audioWriteFrame(context, n, 0, value);
+			audioWriteFrame(context, n, 1, value);
+		} else {
+			audioWriteFrame(context, n, 0, 0);
+			audioWriteFrame(context, n, 1, 0);
+		}
+	}
+}
+
+// cleanup() is called once at the end, after the audio has stopped.
+// Release any resources that were allocated in setup().
+
+void cleanup(BeagleRTContext *context, void *userData)
+{
+
+}