Jack2
1.9.10
|
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(0, 0, 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