Mercurial > hg > beaglert
view 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 source
/* * 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) { }