Mercurial > hg > beaglert
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 } |