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