23 #include "JackEngineControl.h"
24 #include "JackWinMMEDriver.h"
28 JackWinMMEDriver::JackWinMMEDriver(
const char *name,
const char *alias,
29 JackLockedEngine *engine,
31 JackMidiDriver(name, alias, engine, table)
38 JackWinMMEDriver::~JackWinMMEDriver()
42 JackWinMMEDriver::Attach()
44 jack_nframes_t buffer_size = fEngineControl->fBufferSize;
46 jack_nframes_t latency = buffer_size;
50 latency_range.
max = latency +
51 ((jack_nframes_t) std::ceil((period / 1000.0) *
52 fEngineControl->fSampleRate));
53 latency_range.
min = latency;
55 jack_info(
"JackWinMMEDriver::Attach - fCaptureChannels %d", fCaptureChannels);
56 jack_info(
"JackWinMMEDriver::Attach - fPlaybackChannels %d", fPlaybackChannels);
59 for (
int i = 0; i < fCaptureChannels; i++) {
60 JackWinMMEInputPort *input_port = input_ports[i];
61 name = input_port->GetName();
62 if (fEngine->PortRegister(fClientControl.fRefNum, name,
63 JACK_DEFAULT_MIDI_TYPE,
64 CaptureDriverFlags, buffer_size, &index) < 0) {
65 jack_error(
"JackWinMMEDriver::Attach - cannot register input port "
66 "with name '%s'.", name);
70 port = fGraphManager->GetPort(index);
71 port->SetAlias(input_port->GetAlias());
72 port->SetLatencyRange(JackCaptureLatency, &latency_range);
73 fCapturePortList[i] = index;
76 if (! fEngineControl->fSyncMode) {
77 latency += buffer_size;
78 latency_range.
max = latency;
79 latency_range.
min = latency;
83 for (
int i = 0; i < fPlaybackChannels; i++) {
84 JackWinMMEOutputPort *output_port = output_ports[i];
85 name = output_port->GetName();
86 if (fEngine->PortRegister(fClientControl.fRefNum, name,
87 JACK_DEFAULT_MIDI_TYPE,
88 PlaybackDriverFlags, buffer_size, &index) < 0) {
89 jack_error(
"JackWinMMEDriver::Attach - cannot register output "
90 "port with name '%s'.", name);
94 port = fGraphManager->GetPort(index);
95 port->SetAlias(output_port->GetAlias());
96 port->SetLatencyRange(JackPlaybackLatency, &latency_range);
97 fPlaybackPortList[i] = index;
104 JackWinMMEDriver::Close()
107 int result = JackMidiDriver::Close();
110 for (
int i = 0; i < fCaptureChannels; i++) {
111 delete input_ports[i];
113 delete[] input_ports;
117 for (
int i = 0; i < fPlaybackChannels; i++) {
118 delete output_ports[i];
120 delete[] output_ports;
124 if (timeEndPeriod(period) != TIMERR_NOERROR) {
125 jack_error(
"JackWinMMEDriver::Close - failed to unset timer "
134 JackWinMMEDriver::Open(
bool capturing,
bool playing,
int in_channels,
135 int out_channels,
bool monitor,
136 const char* capture_driver_name,
137 const char* playback_driver_name,
138 jack_nframes_t capture_latency,
139 jack_nframes_t playback_latency)
141 const char *client_name = fClientControl.fName;
143 int output_count = 0;
144 int num_potential_inputs = midiInGetNumDevs();
145 int num_potential_outputs = midiOutGetNumDevs();
147 jack_info(
"JackWinMMEDriver::Open - num_potential_inputs %d", num_potential_inputs);
148 jack_info(
"JackWinMMEDriver::Open - num_potential_outputs %d", num_potential_outputs);
152 if (timeGetDevCaps(&caps,
sizeof(TIMECAPS)) != TIMERR_NOERROR) {
153 jack_error(
"JackWinMMEDriver::Open - could not get timer device "
154 "capabilities. Continuing anyway ...");
156 period = caps.wPeriodMin;
157 if (timeBeginPeriod(period) != TIMERR_NOERROR) {
158 jack_error(
"JackWinMMEDriver::Open - could not set minimum timer "
159 "resolution. Continuing anyway ...");
163 jack_info(
"JackWinMMEDriver::Open - multimedia timer resolution "
164 "set to %d milliseconds.", period);
169 if (num_potential_inputs) {
171 input_ports =
new JackWinMMEInputPort *[num_potential_inputs];
172 }
catch (std::exception e) {
173 jack_error(
"JackWinMMEDriver::Open - while creating input port "
174 "array: %s", e.what());
175 goto unset_timer_resolution;
177 for (
int i = 0; i < num_potential_inputs; i++) {
179 input_ports[input_count] =
180 new JackWinMMEInputPort(fAliasName, client_name,
181 capture_driver_name, i);
182 }
catch (std::exception e) {
183 jack_error(
"JackWinMMEDriver::Open - while creating input "
184 "port: %s", e.what());
190 if (num_potential_outputs) {
192 output_ports =
new JackWinMMEOutputPort *[num_potential_outputs];
193 }
catch (std::exception e) {
194 jack_error(
"JackWinMMEDriver::Open - while creating output port "
195 "array: %s", e.what());
196 goto destroy_input_ports;
198 for (
int i = 0; i < num_potential_outputs; i++) {
200 output_ports[output_count] =
201 new JackWinMMEOutputPort(fAliasName, client_name,
202 playback_driver_name, i);
203 }
catch (std::exception e) {
204 jack_error(
"JackWinMMEDriver::Open - while creating output "
205 "port: %s", e.what());
212 jack_info(
"JackWinMMEDriver::Open - input_count %d", input_count);
213 jack_info(
"JackWinMMEDriver::Open - output_count %d", output_count);
215 if (! (input_count || output_count)) {
216 jack_error(
"JackWinMMEDriver::Open - no WinMME inputs or outputs "
218 }
else if (! JackMidiDriver::Open(capturing, playing, input_count,
219 output_count, monitor,
221 playback_driver_name, capture_latency,
227 for (
int i = 0; i < output_count; i++) {
228 delete output_ports[i];
230 delete[] output_ports;
235 for (
int i = 0; i < input_count; i++) {
236 delete input_ports[i];
238 delete[] input_ports;
241 unset_timer_resolution:
243 if (timeEndPeriod(period) != TIMERR_NOERROR) {
244 jack_error(
"JackWinMMEDriver::Open - failed to unset timer "
252 JackWinMMEDriver::Read()
254 jack_nframes_t buffer_size = fEngineControl->fBufferSize;
255 for (
int i = 0; i < fCaptureChannels; i++) {
256 input_ports[i]->ProcessJack(GetInputBuffer(i), buffer_size);
263 JackWinMMEDriver::Write()
265 jack_nframes_t buffer_size = fEngineControl->fBufferSize;
266 for (
int i = 0; i < fPlaybackChannels; i++) {
267 output_ports[i]->ProcessJack(GetOutputBuffer(i), buffer_size);
274 JackWinMMEDriver::Start()
276 jack_info(
"JackWinMMEDriver::Start - Starting driver.");
278 JackMidiDriver::Start();
281 int output_count = 0;
283 jack_info(
"JackWinMMEDriver::Start - Enabling input ports.");
285 for (; input_count < fCaptureChannels; input_count++) {
286 if (input_ports[input_count]->Start() < 0) {
287 jack_error(
"JackWinMMEDriver::Start - Failed to enable input "
289 goto stop_input_ports;
293 jack_info(
"JackWinMMEDriver::Start - Enabling output ports.");
295 for (; output_count < fPlaybackChannels; output_count++) {
296 if (output_ports[output_count]->Start() < 0) {
297 jack_error(
"JackWinMMEDriver::Start - Failed to enable output "
299 goto stop_output_ports;
303 jack_info(
"JackWinMMEDriver::Start - Driver started.");
308 for (
int i = 0; i < output_count; i++) {
309 if (output_ports[i]->Stop() < 0) {
310 jack_error(
"JackWinMMEDriver::Start - Failed to disable output "
315 for (
int i = 0; i < input_count; i++) {
316 if (input_ports[i]->Stop() < 0) {
317 jack_error(
"JackWinMMEDriver::Start - Failed to disable input "
326 JackWinMMEDriver::Stop()
330 JackMidiDriver::Stop();
332 jack_info(
"JackWinMMEDriver::Stop - disabling input ports.");
334 for (
int i = 0; i < fCaptureChannels; i++) {
335 if (input_ports[i]->Stop() < 0) {
336 jack_error(
"JackWinMMEDriver::Stop - Failed to disable input "
342 jack_info(
"JackWinMMEDriver::Stop - disabling output ports.");
344 for (
int i = 0; i < fPlaybackChannels; i++) {
345 if (output_ports[i]->Stop() < 0) {
346 jack_error(
"JackWinMMEDriver::Stop - Failed to disable output "
367 return jack_driver_descriptor_construct(
"winmme", JackDriverSlave,
"WinMME API based MIDI backend", NULL);
415 if (driver->Open(1, 1, 0, 0,
false,
"in",
"out", 0, 0) == 0) {
422 jack_info(
"JackWinMMEDriver already allocated, cannot be loaded twice");