annotate 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
rev   line source
giuliomoro@181 1 /*
giuliomoro@181 2 * render.cpp
giuliomoro@181 3 *
giuliomoro@181 4 * Created on: Oct 24, 2014
giuliomoro@181 5 * Author: parallels
giuliomoro@181 6 */
giuliomoro@181 7
giuliomoro@181 8
giuliomoro@181 9 #include <BeagleRT.h>
giuliomoro@181 10 #include <Midi.h>
giuliomoro@181 11 #include <stdlib.h>
giuliomoro@181 12 #include <Utilities.h>
giuliomoro@181 13 #include <rtdk.h>
giuliomoro@181 14 #include <cmath>
giuliomoro@181 15
giuliomoro@181 16 // setup() is called once before the audio rendering starts.
giuliomoro@181 17 // Use it to perform any initialisation and allocation which is dependent
giuliomoro@181 18 // on the period size or sample rate.
giuliomoro@181 19 //
giuliomoro@181 20 // userData holds an opaque pointer to a data structure that was passed
giuliomoro@181 21 // in from the call to initAudio().
giuliomoro@181 22 //
giuliomoro@181 23 // Return true on success; returning false halts the program.
giuliomoro@181 24 Midi midi;
giuliomoro@181 25 bool setup(BeagleRTContext *context, void *userData)
giuliomoro@181 26 {
giuliomoro@181 27 midi.readFrom(0);
giuliomoro@181 28 if(context->analogFrames == 0) {
giuliomoro@181 29 rt_printf("Error: this example needs the matrix enabled\n");
giuliomoro@181 30 return false;
giuliomoro@181 31 }
giuliomoro@181 32 return true;
giuliomoro@181 33 }
giuliomoro@181 34
giuliomoro@181 35 // render() is called regularly at the highest priority by the audio engine.
giuliomoro@181 36 // Input and output are given from the audio hardware and the other
giuliomoro@181 37 // ADCs and DACs (if available). If only audio is available, numMatrixFrames
giuliomoro@181 38 // will be 0.
giuliomoro@181 39
giuliomoro@181 40 static midi_byte_t noteOnStatus =0x90; //on channel 1
giuliomoro@181 41
giuliomoro@181 42 enum {kVelocity, kNoteOn, kNoteNumber};
giuliomoro@181 43 void render(BeagleRTContext *context, void *userData)
giuliomoro@181 44 {
giuliomoro@181 45 static float f0;
giuliomoro@181 46 static float phaseIncrement = 0;
giuliomoro@181 47 int message;
giuliomoro@181 48 static bool noteOn = 0;
giuliomoro@181 49 static int velocity = 0;
giuliomoro@181 50 static int noteNumber = 0;
giuliomoro@181 51 static int waitingFor = kNoteOn;
giuliomoro@181 52 while ((message = midi.getInput()) >= 0){
giuliomoro@181 53 switch(waitingFor){
giuliomoro@181 54 case kNoteOn:
giuliomoro@181 55 if(message == noteOnStatus){
giuliomoro@181 56 noteOn = true;
giuliomoro@181 57 waitingFor = kNoteNumber;
giuliomoro@181 58 }
giuliomoro@181 59 break;
giuliomoro@181 60 case kNoteNumber:
giuliomoro@181 61 if((message & (1<<8)) == 0){
giuliomoro@181 62 noteNumber = message;
giuliomoro@181 63 waitingFor = kVelocity;
giuliomoro@181 64 f0 = powf(2, (noteNumber-69)/12.0f) * 440;
giuliomoro@181 65 phaseIncrement = 2 * M_PI * f0 / context->audioSampleRate;
giuliomoro@181 66 }
giuliomoro@181 67 break;
giuliomoro@181 68 case kVelocity:
giuliomoro@181 69 if((message & (1<<8)) == 0){
giuliomoro@181 70 velocity = message;
giuliomoro@181 71 waitingFor = kNoteOn;
giuliomoro@181 72 if(velocity == 0)
giuliomoro@181 73 noteOn = false;
giuliomoro@181 74 rt_printf("NoteOn: %d, NoteNumber: %d, velocity: %d\n", noteOn, noteNumber, velocity);
giuliomoro@181 75 }
giuliomoro@181 76 break;
giuliomoro@181 77 }
giuliomoro@181 78 }
giuliomoro@181 79 for(unsigned int n = 0; n < context->audioFrames; n++){
giuliomoro@181 80 if(noteOn == 1){
giuliomoro@181 81 static float phase = 0;
giuliomoro@181 82 phase += phaseIncrement;
giuliomoro@181 83 if(phase > 2 * M_PI)
giuliomoro@181 84 phase -= 2 * M_PI;
giuliomoro@181 85 float value = sinf(phase) * velocity/128.0f;
giuliomoro@181 86 audioWriteFrame(context, n, 0, value);
giuliomoro@181 87 audioWriteFrame(context, n, 1, value);
giuliomoro@181 88 } else {
giuliomoro@181 89 audioWriteFrame(context, n, 0, 0);
giuliomoro@181 90 audioWriteFrame(context, n, 1, 0);
giuliomoro@181 91 }
giuliomoro@181 92 }
giuliomoro@181 93 }
giuliomoro@181 94
giuliomoro@181 95 // cleanup() is called once at the end, after the audio has stopped.
giuliomoro@181 96 // Release any resources that were allocated in setup().
giuliomoro@181 97
giuliomoro@181 98 void cleanup(BeagleRTContext *context, void *userData)
giuliomoro@181 99 {
giuliomoro@181 100
giuliomoro@181 101 }