Marsyas  0.5.0-beta1
/Users/jleben/code/marsyas/src/marsyas/marsystems/MidiInput.cpp
Go to the documentation of this file.
00001 /*
00002  ** Copyright (C) 1998-2006 George Tzanetakis <gtzan@cs.uvic.ca>
00003  **
00004  ** This program is free software; you can redistribute it and/or modify
00005  ** it under the terms of the GNU General Public License as published by
00006  ** the Free Software Foundation; either version 2 of the License, or
00007  ** (at your option) any later version.
00008  **
00009  ** This program is distributed in the hope that it will be useful,
00010  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  ** GNU General Public License for more details.
00013  **
00014  ** You should have received a copy of the GNU General Public License
00015  ** along with this program; if not, write to the Free Software
00016  ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 
00020 #include "MidiInput.h"
00021 #include "../common_source.h"
00022 
00023 #ifdef MARSYAS_MIDIIO
00024 #include "RtMidi.h"
00025 #endif
00026 
00027 #include <cstddef>
00028 
00029 using std::ostringstream;
00030 using std::size_t;
00031 using namespace Marsyas;
00032 
00033 MidiInput::MidiInput(mrs_string name):MarSystem("MidiInput",name)
00034 {
00035   initMidi = false;
00036 #ifdef MARSYAS_MIDIIO
00037   midiin = NULL;
00038 #endif
00039   addControls();
00040 }
00041 
00042 MidiInput::MidiInput(const MidiInput& a): MarSystem(a)
00043 {
00044   ctrl_byte1_ = getctrl("mrs_natural/byte1");
00045   ctrl_byte2_ = getctrl("mrs_natural/byte2");
00046   ctrl_byte3_ = getctrl("mrs_natural/byte3");
00047 }
00048 
00049 MidiInput::~MidiInput()
00050 {
00051 #ifdef MARSYAS_MIDIIO
00052   delete midiin;
00053 #endif
00054 }
00055 
00056 MarSystem* MidiInput::clone() const
00057 {
00058   return new MidiInput(*this);
00059 }
00060 
00061 void MidiInput::addControls()
00062 {
00063   addctrl("mrs_natural/port", 0);
00064   addctrl("mrs_bool/virtualPort", false);
00065   addctrl("mrs_bool/initmidi", false);
00066   setctrlState("mrs_bool/initmidi", true);
00067   addctrl("mrs_natural/byte1", 0, ctrl_byte1_);
00068   addctrl("mrs_natural/byte2", 0, ctrl_byte2_);
00069   addctrl("mrs_natural/byte3", 0, ctrl_byte3_);
00070 }
00071 
00072 void MidiInput::myUpdate(MarControlPtr sender)
00073 {
00074   MRSDIAG("MidiInput.cpp - MidiInput:myUpdate");
00075   MarSystem::myUpdate(sender);
00076 
00077 #ifdef MARSYAS_MIDIIO
00078   midiin = NULL;
00079 
00080   initMidi= getctrl("mrs_bool/initmidi")->to<mrs_bool>();
00081   initMidi = !initMidi;
00082 
00083   virtualPort = getctrl("mrs_bool/virtualPort")->to<mrs_bool>();
00084 
00085   if (!initMidi) {
00086     try {
00087       midiin = new RtMidiIn();
00088     }
00089     catch (RtError &error) {
00090       error.printMessage();
00091       return;
00092     }
00093     midiin->setCallback(&MidiInput::mycallback, this);
00094     midiin->ignoreTypes(false, false, false);
00095     setctrl("mrs_bool/initmidi", false);
00096 
00097     if (virtualPort)
00098     {
00099       try {
00100         midiin->openVirtualPort("MarsyasInput");
00101       }
00102       catch (RtError &error)
00103       {
00104         error.printMessage();
00105         return;
00106       }
00107     }
00108     else
00109     {
00110       try {
00111         midiin->openPort(getctrl("mrs_natural/port")->to<mrs_natural>());
00112       }
00113       catch (RtError &error)
00114       {
00115         error.printMessage();
00116         return;
00117       }
00118     }
00119   }
00120 
00121 #endif
00122 }
00123 
00124 void MidiInput::mycallback(double deltatime, std::vector< unsigned char > * message, void *userData)
00125 {
00126   // FIXME Unused parameter
00127   (void) deltatime;
00128   std::size_t nBytes = 0;
00129   nBytes = message->size();
00130 
00131   MidiInput* mythis = (MidiInput*) userData;
00132   std::vector<int> v(3);
00133 
00134   if (nBytes > 0)
00135   {
00136     if (nBytes > 2)
00137     {
00138       v[0] = message->at(0);
00139       v[1] = message->at(1);
00140       v[2] = message->at(2);
00141       mythis->msgQueue.push(v);
00142     }
00143   }
00144 }
00145 
00146 void MidiInput::myProcess(realvec& in, realvec& out)
00147 {
00148   mrs_natural t,o;
00149   std::vector<int> *v;
00150   // just pass data through
00151   for (o=0; o < inObservations_; o++)
00152   {
00153     for (t = 0; t < inSamples_; t++)
00154     {
00155       out(o,t) =  in(o,t);
00156     }
00157   }
00158   if (!msgQueue.empty()) {
00159     v = new std::vector<int>(msgQueue.front());
00160     msgQueue.pop();
00161     ctrl_byte1_->setValue((mrs_natural)v->at(0), NOUPDATE);
00162     ctrl_byte2_->setValue((mrs_natural)v->at(1), NOUPDATE);
00163     ctrl_byte3_->setValue((mrs_natural)v->at(2), NOUPDATE);
00164     delete v;
00165   }
00166 }