35 #define LOC QString("AOJack: ")
53 const char **matching_ports =
nullptr;
59 Error(
LOC + tr(
"Cannot start/connect to jack server "
60 "(to check supported rate/channels)"));
66 rate = jack_get_sample_rate(
m_client);
70 Error(
LOC + tr(
"Unable to retrieve jack server sample rate"));
74 settings->AddSupportedRate(rate);
82 if (!matching_ports || !matching_ports[0])
84 Error(
LOC + tr(
"No ports available to connect to"));
91 settings->AddSupportedChannels(i+1);
92 VBAUDIO(QString(
"Adding channels: %1").arg(i+1));
103 free(matching_ports);
118 const char **matching_ports =
nullptr;
124 Error(
LOC + tr(
"Requested more channels: (%1), than the maximum: %2")
129 VBAUDIO( QString(
"Opening JACK audio device: '%1'.")
140 Error(
LOC + tr(
"Cannot start/connect to jack server"));
146 if (!matching_ports || !matching_ports[0])
148 Error(
LOC + tr(
"No ports available to connect to"));
154 while (matching_ports[i])
159 Error(
LOC + tr(
"Not enough ports available to connect to"));
166 QString port_name = QString(
"out_%1").arg(i);
167 m_ports[i] = jack_port_register(
m_client, port_name.toLatin1().constData(),
168 JACK_DEFAULT_AUDIO_TYPE,
169 JackPortIsOutput, 0);
172 Error(
LOC + tr(
"Error while registering new jack port: %1").arg(i));
191 Error(
LOC + tr(
"Error. Unable to set process callback?!"));
193 Error(
LOC + tr(
"Error. Unable to set xrun callback?!"));
195 Error(
LOC + tr(
"Error. Unable to set graph order change callback?!"));
200 Error(
LOC + tr(
"Calling jack_activate failed"));
209 free(matching_ports);
216 free(matching_ports);
239 int frames_played = jack_frames_since_cycle_start (this->
m_client);
240 LOG(VB_AUDIO | VB_TIMESTAMP, LOG_INFO,
241 QString(
"Stats: frames_since_cycle_start:%1 fragment_size:%2")
261 std::array<float,JACK_CHANNELS_MAX> volumes {};
262 for (
int channel = 0; channel <
m_channels; channel++)
268 volumes[channel] = (float) (( channel_volumes[channel] *
269 channel_volumes[channel] ) /
273 volumes[channel] = 1.0 / 1.0;
278 for (
int frame = 0; frame < nframes; frame++)
280 bufs[0][frame] = aubuf[sample++] * volumes[0];
281 bufs[1][frame] = aubuf[sample++] * volumes[1];
286 for (
int frame = 0; frame < nframes; frame++)
290 bufs[0][frame] = aubuf[sample++] * volumes[0];
291 bufs[1][frame] = aubuf[sample++] * volumes[1];
292 bufs[4][frame] = aubuf[sample++] * volumes[4];
293 bufs[5][frame] = aubuf[sample++] * volumes[5];
294 bufs[2][frame] = aubuf[sample++] * volumes[2];
295 bufs[3][frame] = aubuf[sample++] * volumes[3];
300 for (
int frame = 0; frame < nframes; frame++)
305 bufs[0][frame] = aubuf[sample++] * volumes[0];
306 bufs[1][frame] = aubuf[sample++] * volumes[1];
307 bufs[4][frame] = aubuf[sample++] * volumes[4];
308 bufs[5][frame] = aubuf[sample++] * volumes[5];
309 bufs[2][frame] = aubuf[sample++] * volumes[2];
310 bufs[3][frame] = aubuf[sample++] * volumes[3];
311 bufs[6][frame] = aubuf[sample++] * volumes[6];
312 bufs[7][frame] = aubuf[sample++] * volumes[7];
317 for (
int frame = 0; frame < nframes; frame++)
321 for (
int channel = 0; channel <
m_channels; channel++)
323 bufs[channel][frame] = aubuf[sample++] * volumes[channel];
355 std::array<float*,JACK_CHANNELS_MAX> bufs {};
365 for (
int i = 0; i < t_jack_xruns; i++)
368 VBERROR(
"Discarded one audio fragment to compensate for xrun");
377 bufs[i] = (
float*)jack_port_get_buffer(
m_ports[i], nframes);
385 VBAUDIO(
"JackCallback: audio paused");
397 VBAUDIO(
"JackCallback: Play Event");
406 if (bytes_needed > bytes_read)
409 memset(
m_auBuf + bytes_read, 0, bytes_needed - bytes_read);
412 VBERROR(QString(
"Having to insert silence because GetAudioData "
413 "hasn't returned enough data. Wanted: %1 Got: %2")
414 .arg(bytes_needed).arg(bytes_read));
445 float delay = jack_get_xrun_delayed_usecs(
m_client);
449 int fragments = (int)ceilf( ((delay / 1000000.0F) *
m_sampleRate )
452 VBERROR(QString(
"Jack XRun Callback: %1 usecs delayed, xruns now %2")
474 jack_latency_range_t latency_range;
475 jack_nframes_t max_latency = 0;
479 jack_port_get_latency_range(
m_ports[i], JackPlaybackLatency, &latency_range );
480 jack_nframes_t port_latency = latency_range.max;
481 if (port_latency > max_latency)
482 max_latency = port_latency;
486 VBAUDIO(QString(
"JACK graph reordered. Maximum latency=%1")
500 controlLabel +=
"MixerVolume";
509 unsigned int vol = 0;
530 else if (channel == 1)
570 QString client_name = QString(
"mythtv_%1").arg(getpid());
571 auto open_options = (jack_options_t)(JackUseExactName | JackNoStartServer);
572 jack_status_t open_status = JackFailure;
574 jack_client_t *client = jack_client_open(client_name.toLatin1().constData(),
575 open_options, &open_status);
582 const char **matching_ports =
nullptr;
583 unsigned long port_flags=JackPortIsInput;
584 const char *port_name =
nullptr;
593 port_flags |= JackPortIsPhysical;
597 matching_ports = jack_get_ports(
m_client, port_name,
nullptr, port_flags);
598 return matching_ports;
609 if (jack_connect(
m_client, jack_port_name(
m_ports[i]), matching_ports[i]))
611 Error(
LOC + tr(
"Calling jack_connect failed on port: %1\n").arg(i));
623 int err = jack_client_close(*client);
625 Error(
LOC + tr(
"Error closing Jack output device. Error: %1")