Jack2 1.9.8

JackMidiDriver.cpp

00001 /*
00002 Copyright (C) 2009 Grame.
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 This program is distributed in the hope that it will be useful,
00008 but WITHOUT ANY WARRANTY; without even the implied warranty of
00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010 (at your option) any later version.
00011 
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., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 
00018 */
00019 
00020 #include "JackSystemDeps.h"
00021 #include "JackMidiDriver.h"
00022 #include "JackTime.h"
00023 #include "JackError.h"
00024 #include "JackEngineControl.h"
00025 #include "JackPort.h"
00026 #include "JackGraphManager.h"
00027 #include "JackException.h"
00028 #include <assert.h>
00029 
00030 using namespace std;
00031 
00032 namespace Jack
00033 {
00034 
00035 JackMidiDriver::JackMidiDriver(const char* name, const char* alias, JackLockedEngine* engine, JackSynchro* table)
00036         : JackDriver(name, alias, engine, table)
00037 {}
00038 
00039 JackMidiDriver::~JackMidiDriver()
00040 {}
00041 
00042 int JackMidiDriver::Open(bool capturing,
00043                         bool playing,
00044                         int inchannels,
00045                         int outchannels,
00046                         bool monitor,
00047                         const char* capture_driver_name,
00048                         const char* playback_driver_name,
00049                         jack_nframes_t capture_latency,
00050                         jack_nframes_t playback_latency)
00051 {
00052     fCaptureChannels = inchannels;
00053     fPlaybackChannels = outchannels;
00054     return JackDriver::Open(capturing, playing, inchannels, outchannels, monitor, capture_driver_name, playback_driver_name, capture_latency, playback_latency);
00055 }
00056 
00057 int JackMidiDriver::Attach()
00058 {
00059     JackPort* port;
00060     jack_port_id_t port_index;
00061     char name[REAL_JACK_PORT_NAME_SIZE];
00062     char alias[REAL_JACK_PORT_NAME_SIZE];
00063     int i;
00064 
00065     jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl->fBufferSize, fEngineControl->fSampleRate);
00066 
00067     for (i = 0; i < fCaptureChannels; i++) {
00068         snprintf(alias, sizeof(alias), "%s:%s:out%d", fAliasName, fCaptureDriverName, i + 1);
00069         snprintf(name, sizeof(name), "%s:capture_%d", fClientControl.fName, i + 1);
00070         if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, CaptureDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
00071             jack_error("driver: cannot register port for %s", name);
00072             return -1;
00073         }
00074         port = fGraphManager->GetPort(port_index);
00075         port->SetAlias(alias);
00076         fCapturePortList[i] = port_index;
00077         jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index);
00078     }
00079 
00080     for (i = 0; i < fPlaybackChannels; i++) {
00081         snprintf(alias, sizeof(alias), "%s:%s:in%d", fAliasName, fPlaybackDriverName, i + 1);
00082         snprintf(name, sizeof(name), "%s:playback_%d", fClientControl.fName, i + 1);
00083         if (fEngine->PortRegister(fClientControl.fRefNum, name, JACK_DEFAULT_MIDI_TYPE, PlaybackDriverFlags, fEngineControl->fBufferSize, &port_index) < 0) {
00084             jack_error("driver: cannot register port for %s", name);
00085             return -1;
00086         }
00087         port = fGraphManager->GetPort(port_index);
00088         port->SetAlias(alias);
00089         fPlaybackPortList[i] = port_index;
00090         jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index);
00091     }
00092 
00093     UpdateLatencies();
00094     return 0;
00095 }
00096 
00097 int JackMidiDriver::Detach()
00098 {
00099     int i;
00100     jack_log("JackMidiDriver::Detach");
00101 
00102     for (i = 0; i < fCaptureChannels; i++) {
00103         fEngine->PortUnRegister(fClientControl.fRefNum, fCapturePortList[i]);
00104     }
00105 
00106     for (i = 0; i < fPlaybackChannels; i++) {
00107         fEngine->PortUnRegister(fClientControl.fRefNum, fPlaybackPortList[i]);
00108     }
00109 
00110     return 0;
00111 }
00112 
00113 void JackMidiDriver::UpdateLatencies()
00114 {
00115     jack_latency_range_t range;
00116 
00117     for (int i = 0; i < fCaptureChannels; i++) {
00118         range.max = range.min = fEngineControl->fBufferSize;
00119         fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range);
00120     }
00121 
00122     for (int i = 0; i < fPlaybackChannels; i++) {
00123         if (! fEngineControl->fSyncMode) {
00124             range.max = range.min = fEngineControl->fBufferSize * 2;
00125         }
00126         fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range);
00127     }
00128 }
00129 
00130 int JackMidiDriver::SetBufferSize(jack_nframes_t buffer_size)
00131 {
00132     UpdateLatencies();
00133     return 0;
00134 }
00135 
00136 int JackMidiDriver::ProcessReadSync()
00137 {
00138     int res = 0;
00139 
00140     // Read input buffers for the current cycle
00141     if (Read() < 0) {
00142         jack_error("JackMidiDriver::ProcessReadSync: read error");
00143         res = -1;
00144     }
00145 
00146     if (ResumeRefNum() < 0) {
00147         jack_error("JackMidiDriver::ProcessReadSync: ResumeRefNum error");
00148         res = -1;
00149     }
00150 
00151     return res;
00152 }
00153 
00154 int JackMidiDriver::ProcessWriteSync()
00155 {
00156     int res = 0;
00157 
00158     if (SuspendRefNum() < 0) {
00159         jack_error("JackMidiDriver::ProcessWriteSync: SuspendRefNum error");
00160         res = -1;
00161     }
00162 
00163     // Write output buffers from the current cycle
00164     if (Write() < 0) {
00165         jack_error("JackMidiDriver::ProcessWriteSync: write error");
00166         res = -1;
00167     }
00168 
00169     return res;
00170 }
00171 
00172 int JackMidiDriver::ProcessReadAsync()
00173 {
00174     int res = 0;
00175 
00176     // Read input buffers for the current cycle
00177     if (Read() < 0) {
00178         jack_error("JackMidiDriver::ProcessReadAsync: read error");
00179         res = -1;
00180     }
00181 
00182     // Write output buffers from the previous cycle
00183     if (Write() < 0) {
00184         jack_error("JackMidiDriver::ProcessReadAsync: write error");
00185         res = -1;
00186     }
00187 
00188     if (ResumeRefNum() < 0) {
00189         jack_error("JackMidiDriver::ProcessReadAsync: ResumeRefNum error");
00190         res = -1;
00191     }
00192 
00193     return res;
00194 }
00195 
00196 int JackMidiDriver::ProcessWriteAsync()
00197 {
00198     return 0;
00199 }
00200 
00201 JackMidiBuffer* JackMidiDriver::GetInputBuffer(int port_index)
00202 {
00203     assert(fCapturePortList[port_index]);
00204     return (JackMidiBuffer*)fGraphManager->GetBuffer(fCapturePortList[port_index], fEngineControl->fBufferSize);
00205 }
00206 
00207 JackMidiBuffer* JackMidiDriver::GetOutputBuffer(int port_index)
00208 {
00209     assert(fPlaybackPortList[port_index]);
00210     return (JackMidiBuffer*)fGraphManager->GetBuffer(fPlaybackPortList[port_index], fEngineControl->fBufferSize);
00211 }
00212 
00213 } // end of namespace