2 Copyright (C) 2009 Grame.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 (at your option) any later version.
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "JackSystemDeps.h"
21 #include "JackMidiDriver.h"
23 #include "JackError.h"
24 #include "JackEngineControl.h"
26 #include "JackGraphManager.h"
27 #include "JackException.h"
33 JackMidiDriver::JackMidiDriver(const char* name
, const char* alias
, JackLockedEngine
* engine
, JackSynchro
* table
)
34 : JackDriver(name
, alias
, engine
, table
),
38 for (int i
= 0; i
< DRIVER_PORT_NUM
; i
++) {
39 fRingBuffer
[i
] = NULL
;
43 JackMidiDriver::~JackMidiDriver()
45 for (int i
= 0; i
< fCaptureChannels
; i
++) {
47 jack_ringbuffer_free(fRingBuffer
[i
]);
51 int JackMidiDriver::Open(bool capturing
,
56 const char* capture_driver_name
,
57 const char* playback_driver_name
,
58 jack_nframes_t capture_latency
,
59 jack_nframes_t playback_latency
)
61 fCaptureChannels
= inchannels
;
62 fPlaybackChannels
= outchannels
;
64 for (int i
= 0; i
< fCaptureChannels
; i
++) {
65 fRingBuffer
[i
] = jack_ringbuffer_create(sizeof(float) * BUFFER_SIZE_MAX
);
68 return JackDriver::Open(capturing
, playing
, inchannels
, outchannels
, monitor
, capture_driver_name
, playback_driver_name
, capture_latency
, playback_latency
);
71 int JackMidiDriver::Attach()
74 jack_port_id_t port_index
;
75 char name
[JACK_CLIENT_NAME_SIZE
+ JACK_PORT_NAME_SIZE
];
76 char alias
[JACK_CLIENT_NAME_SIZE
+ JACK_PORT_NAME_SIZE
];
77 unsigned long port_flags
= JackPortIsOutput
| JackPortIsPhysical
| JackPortIsTerminal
;
80 jack_log("JackMidiDriver::Attach fBufferSize = %ld fSampleRate = %ld", fEngineControl
->fBufferSize
, fEngineControl
->fSampleRate
);
82 for (i
= 0; i
< fCaptureChannels
; i
++) {
83 snprintf(alias
, sizeof(alias
) - 1, "%s:%s:out%d", fAliasName
, fCaptureDriverName
, i
+ 1);
84 snprintf(name
, sizeof(name
) - 1, "%s:capture_%d", fClientControl
.fName
, i
+ 1);
85 if ((port_index
= fGraphManager
->AllocatePort(fClientControl
.fRefNum
, name
, JACK_DEFAULT_MIDI_TYPE
, (JackPortFlags
)port_flags
, fEngineControl
->fBufferSize
)) == NO_PORT
) {
86 jack_error("driver: cannot register port for %s", name
);
89 port
= fGraphManager
->GetPort(port_index
);
90 port
->SetAlias(alias
);
91 fCapturePortList
[i
] = port_index
;
92 jack_log("JackMidiDriver::Attach fCapturePortList[i] port_index = %ld", port_index
);
95 port_flags
= JackPortIsInput
| JackPortIsPhysical
| JackPortIsTerminal
;
97 for (i
= 0; i
< fPlaybackChannels
; i
++) {
98 snprintf(alias
, sizeof(alias
) - 1, "%s:%s:in%d", fAliasName
, fPlaybackDriverName
, i
+ 1);
99 snprintf(name
, sizeof(name
) - 1, "%s:playback_%d", fClientControl
.fName
, i
+ 1);
100 if ((port_index
= fGraphManager
->AllocatePort(fClientControl
.fRefNum
, name
, JACK_DEFAULT_MIDI_TYPE
, (JackPortFlags
)port_flags
, fEngineControl
->fBufferSize
)) == NO_PORT
) {
101 jack_error("driver: cannot register port for %s", name
);
104 port
= fGraphManager
->GetPort(port_index
);
105 port
->SetAlias(alias
);
106 fPlaybackPortList
[i
] = port_index
;
107 jack_log("JackMidiDriver::Attach fPlaybackPortList[i] port_index = %ld", port_index
);
113 int JackMidiDriver::Detach()
116 jack_log("JackMidiDriver::Detach");
118 for (i
= 0; i
< fCaptureChannels
; i
++) {
119 fGraphManager
->ReleasePort(fClientControl
.fRefNum
, fCapturePortList
[i
]);
122 for (i
= 0; i
< fPlaybackChannels
; i
++) {
123 fGraphManager
->ReleasePort(fClientControl
.fRefNum
, fPlaybackPortList
[i
]);
129 int JackMidiDriver::Read()
134 int JackMidiDriver::Write()
139 int JackMidiDriver::ProcessNull()
144 int JackMidiDriver::Process()
146 // Read input buffers for the current cycle
148 jack_error("JackMidiDriver::Process: read error, skip cycle");
149 return 0; // Skip cycle, but continue processing...
152 fGraphManager
->ResumeRefNum(&fClientControl
, fSynchroTable
);
153 if (fEngineControl
->fSyncMode
) {
154 if (fGraphManager
->SuspendRefNum(&fClientControl
, fSynchroTable
, fEngineControl
->fTimeOutUsecs
) < 0) {
155 jack_error("JackFreewheelDriver::ProcessSync SuspendRefNum error");
160 // Write output buffers for the current cycle
162 jack_error("JackMidiDriver::Process: write error, skip cycle");
163 return 0; // Skip cycle, but continue processing...
169 JackMidiBuffer
* JackMidiDriver::GetInputBuffer(int port_index
)
171 assert(fCapturePortList
[port_index
]);
172 return (JackMidiBuffer
*)fGraphManager
->GetBuffer(fCapturePortList
[port_index
], fEngineControl
->fBufferSize
);
175 JackMidiBuffer
* JackMidiDriver::GetOutputBuffer(int port_index
)
177 assert(fPlaybackPortList
[port_index
]);
178 return (JackMidiBuffer
*)fGraphManager
->GetBuffer(fPlaybackPortList
[port_index
], fEngineControl
->fBufferSize
);
181 } // end of namespace