00001 #include <cstdio>
00002 #include <cstdlib>
00003 #include <fcntl.h>
00004 #include <sys/time.h>
00005 #include <unistd.h>
00006 #include <time.h>
00007 #include <cerrno>
00008 #include <cstring>
00009 #include <cmath>
00010
00011 #include <iostream>
00012
00013 using namespace std;
00014
00015 #include "mythcorecontext.h"
00016 #include "audiooutputjack.h"
00017 #include "mythmiscutil.h"
00018
00019 #define LOC QString("AOJack: ")
00020
00021 #define JERROR(str) Error(LOC + str)
00022
00023 AudioOutputJACK::AudioOutputJACK(const AudioSettings &settings) :
00024 AudioOutputBase(settings),
00025 client(NULL), stale_client(NULL),
00026 jack_latency(0), jack_underrun(false), jack_xruns(0), aubuf(NULL)
00027 {
00028 for (int i = 0; i < JACK_CHANNELS_MAX; i++)
00029 ports[i] = NULL;
00030 for (int i = 0; i < JACK_CHANNELS_MAX; i++)
00031 chan_volumes[i] = 100;
00032
00033
00034 InitSettings(settings);
00035 if (settings.init)
00036 Reconfigure(settings);
00037 }
00038
00039 AudioOutputSettings* AudioOutputJACK::GetOutputSettings(bool )
00040 {
00041 int rate = 0;
00042 int i = 0;
00043 const char **matching_ports = NULL;
00044 AudioOutputSettings *settings = new AudioOutputSettings();
00045
00046 client = _jack_client_open();
00047 if (!client)
00048 {
00049 JERROR("Cannot start/connect to jack server "
00050 "(to check supported rate/channels)");
00051 delete settings;
00052 return NULL;
00053 }
00054
00055 if (client)
00056 rate = jack_get_sample_rate(client);
00057
00058 if (!rate)
00059 {
00060 JERROR("Unable to retrieve jack server sample rate");
00061 goto err_out;
00062 }
00063 else
00064 settings->AddSupportedRate(rate);
00065
00066
00067 settings->AddSupportedFormat(FORMAT_FLT);
00068
00069
00070 matching_ports = _jack_get_ports();
00071
00072 if (!matching_ports || !matching_ports[0])
00073 {
00074 JERROR("No ports available to connect to");
00075 goto err_out;
00076 }
00077
00078 i = 1;
00079 while (matching_ports[i] && (i < JACK_CHANNELS_MAX))
00080 {
00081 settings->AddSupportedChannels(i+1);
00082 VBAUDIO(QString("Adding channels: %1").arg(i+1));
00083 i++;
00084 }
00085
00086
00087 free(matching_ports);
00088 _jack_client_close(&client);
00089 return settings;
00090
00091 err_out:
00092
00093 free(matching_ports);
00094 _jack_client_close(&client);
00095 delete settings;
00096 return NULL;
00097 }
00098
00099
00100 AudioOutputJACK::~AudioOutputJACK()
00101 {
00102
00103 KillAudio();
00104 }
00105
00106 bool AudioOutputJACK::OpenDevice()
00107 {
00108 const char **matching_ports = NULL;
00109 int i = 0;
00110
00111
00112 if (channels > JACK_CHANNELS_MAX)
00113 {
00114 JERROR(QString("Requested more channels: (%1), than the maximum: %2")
00115 .arg(channels).arg(JACK_CHANNELS_MAX));
00116 return false;
00117 }
00118
00119 VBAUDIO( QString("Opening JACK audio device: '%1'.")
00120 .arg(main_device));
00121
00122
00123 if (internal_vol)
00124 VolumeInit();
00125
00126
00127 client = _jack_client_open();
00128 if (!client)
00129 {
00130 JERROR("Cannot start/connect to jack server");
00131 goto err_out;
00132 }
00133
00134
00135 matching_ports = _jack_get_ports();
00136 if (!matching_ports || !matching_ports[0])
00137 {
00138 JERROR("No ports available to connect to");
00139 goto err_out;
00140 }
00141
00142
00143 i = 1;
00144 while (matching_ports[i])
00145 i++;
00146
00147 if (channels > i)
00148 {
00149 JERROR("Not enough ports available to connect to");
00150 goto err_out;
00151 }
00152
00153
00154 for (i = 0; i < channels; i++)
00155 {
00156 QString port_name = QString("out_%1").arg(i);
00157 ports[i] = jack_port_register(client, port_name.toAscii().constData(),
00158 JACK_DEFAULT_AUDIO_TYPE,
00159 JackPortIsOutput, 0);
00160 if (!ports[i])
00161 {
00162 JERROR(QString("Error while registering new jack port: %1").arg(i));
00163 goto err_out;
00164 }
00165 }
00166
00167
00168 samplerate = jack_get_sample_rate(client);
00169
00170
00171 fragment_size = jack_get_buffer_size(client) * output_bytes_per_frame;
00172
00173
00174 if (aubuf)
00175 delete[] aubuf;
00176 aubuf = new unsigned char[fragment_size];
00177
00178
00179
00180
00181
00182 if (jack_set_process_callback(client, _JackCallback, this))
00183 JERROR("Error. Unable to set process callback?!");
00184 if (jack_set_xrun_callback(client, _JackXRunCallback, this))
00185 JERROR("Error. Unable to set xrun callback?!");
00186 if (jack_set_graph_order_callback(client, _JackGraphOrderCallback, this))
00187 JERROR("Error. Unable to set graph order change callback?!");
00188
00189
00190 if (jack_activate(client))
00191 {
00192 JERROR("Calling jack_activate failed");
00193 goto err_out;
00194 }
00195
00196
00197 if (! _jack_connect_ports(matching_ports))
00198 goto err_out;
00199
00200
00201 free(matching_ports);
00202
00203
00204 return true;
00205
00206 err_out:
00207
00208 free(matching_ports);
00209 _jack_client_close(&client);
00210 return false;
00211 }
00212
00213 void AudioOutputJACK::CloseDevice()
00214 {
00215 _jack_client_close(&client);
00216 _jack_client_close(&stale_client);
00217 if (aubuf)
00218 {
00219 delete[] aubuf;
00220 aubuf = NULL;
00221 }
00222
00223 VBAUDIO("Jack: Stop Event");
00224 OutputEvent e(OutputEvent::Stopped);
00225 dispatch(e);
00226 }
00227
00228
00229 int AudioOutputJACK::GetBufferedOnSoundcard(void) const
00230 {
00231 int frames_played = jack_frames_since_cycle_start (this->client);
00232 LOG(VB_AUDIO | VB_TIMESTAMP, LOG_INFO,
00233 QString("Stats: frames_since_cycle_start:%1 fragment_size:%2")
00234 .arg(frames_played).arg(fragment_size));
00235 return (fragment_size * 2) - (frames_played * output_bytes_per_frame);
00236 }
00237
00238
00239
00240
00241
00242
00243 void AudioOutputJACK::DeinterleaveAudio(float *aubuf, float **bufs, int nframes,
00244 int* channel_volumes)
00245 {
00246
00247
00248 short sample = 0;
00249
00250
00251
00252
00253 float volumes[channels];
00254 for (int channel = 0; channel < channels; channel++)
00255 {
00256 if (internal_vol)
00257 {
00258
00259
00260 volumes[channel] = (float) (( channel_volumes[channel] *
00261 channel_volumes[channel] ) /
00262 10000.0);
00263 }
00264 else
00265 volumes[channel] = 1.0 / 1.0;
00266 }
00267
00268 if (channels == 2)
00269 {
00270 for (int frame = 0; frame < nframes; frame++)
00271 {
00272 bufs[0][frame] = aubuf[sample++] * volumes[0];
00273 bufs[1][frame] = aubuf[sample++] * volumes[1];
00274 }
00275 }
00276 else if (channels == 6)
00277 {
00278 for (int frame = 0; frame < nframes; frame++)
00279 {
00280
00281
00282 bufs[0][frame] = aubuf[sample++] * volumes[0];
00283 bufs[1][frame] = aubuf[sample++] * volumes[1];
00284 bufs[4][frame] = aubuf[sample++] * volumes[4];
00285 bufs[5][frame] = aubuf[sample++] * volumes[5];
00286 bufs[2][frame] = aubuf[sample++] * volumes[2];
00287 bufs[3][frame] = aubuf[sample++] * volumes[3];
00288 }
00289 }
00290 else if (channels == 8)
00291 {
00292 for (int frame = 0; frame < nframes; frame++)
00293 {
00294
00295
00296
00297 bufs[0][frame] = aubuf[sample++] * volumes[0];
00298 bufs[1][frame] = aubuf[sample++] * volumes[1];
00299 bufs[4][frame] = aubuf[sample++] * volumes[4];
00300 bufs[5][frame] = aubuf[sample++] * volumes[5];
00301 bufs[2][frame] = aubuf[sample++] * volumes[2];
00302 bufs[3][frame] = aubuf[sample++] * volumes[3];
00303 bufs[6][frame] = aubuf[sample++] * volumes[6];
00304 bufs[7][frame] = aubuf[sample++] * volumes[7];
00305 }
00306 }
00307 else
00308 {
00309 for (int frame = 0; frame < nframes; frame++)
00310 {
00311
00312
00313 for (int channel = 0; channel < channels; channel++)
00314 {
00315 bufs[channel][frame] = aubuf[sample++] * volumes[channel];
00316 }
00317 }
00318 }
00319
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 int AudioOutputJACK::_JackCallback(jack_nframes_t nframes, void *arg)
00331 {
00332 AudioOutputJACK *aoj = static_cast<AudioOutputJACK*>(arg);
00333 return aoj->JackCallback(nframes);
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 int AudioOutputJACK::JackCallback(jack_nframes_t nframes)
00346 {
00347 float *bufs[JACK_CHANNELS_MAX];
00348 int bytes_needed = nframes * output_bytes_per_frame;
00349 int bytes_read = 0;
00350 int i;
00351
00352
00353 _jack_client_close(&stale_client);
00354
00355
00356
00357 int t_jack_xruns = jack_xruns;
00358 for (i = 0; i < t_jack_xruns; i++)
00359 {
00360 bytes_read = GetAudioData(aubuf, fragment_size, true);
00361 VBERROR("Discarded one audio fragment to compensate for xrun");
00362 }
00363 jack_xruns -= t_jack_xruns;
00364
00365
00366 for (i = 0; i < channels; i++)
00367 bufs[i] = (float*)jack_port_get_buffer(ports[i], nframes);
00368
00369 if (pauseaudio || killaudio)
00370 {
00371 if (!actually_paused)
00372 {
00373 VBAUDIO("JackCallback: audio paused");
00374 OutputEvent e(OutputEvent::Paused);
00375 dispatch(e);
00376 was_paused = true;
00377 }
00378
00379 actually_paused = true;
00380 }
00381 else
00382 {
00383 if (was_paused)
00384 {
00385 VBAUDIO("JackCallback: Play Event");
00386 OutputEvent e(OutputEvent::Playing);
00387 dispatch(e);
00388 was_paused = false;
00389 }
00390 bytes_read = GetAudioData(aubuf, bytes_needed, false);
00391 }
00392
00393
00394 if (bytes_needed > bytes_read)
00395 {
00396
00397 memset(aubuf + bytes_read, 0, bytes_needed - bytes_read);
00398 if (!pauseaudio)
00399 VBERROR(QString("Having to insert silence because GetAudioData "
00400 "hasn't returned enough data. Wanted: %1 Got: %2")
00401 .arg(bytes_needed).arg(bytes_read));
00402 }
00403
00404 DeinterleaveAudio((float*)aubuf, bufs, nframes, chan_volumes);
00405
00406 if (!pauseaudio)
00407 {
00408
00409 Status();
00410 }
00411
00412 return 0;
00413 }
00414
00415
00416
00417
00418
00419
00420 int AudioOutputJACK::_JackXRunCallback(void *arg)
00421 {
00422 AudioOutputJACK *aoj = static_cast<AudioOutputJACK*>(arg);
00423 return aoj->JackXRunCallback();
00424 }
00425
00426
00427
00428
00429 int AudioOutputJACK::JackXRunCallback(void)
00430 {
00431 float delay = jack_get_xrun_delayed_usecs(client);
00432
00433
00434
00435 int fragments = (int)ceilf( ((delay / 1000000.0) * samplerate )
00436 / (float)(fragment_size / output_bytes_per_frame) );
00437 jack_xruns += fragments;
00438 VBERROR(QString("Jack XRun Callback: %1 usecs delayed, xruns now %2")
00439 .arg(delay).arg(jack_xruns) );
00440
00441 return 0;
00442 }
00443
00444
00445
00446
00447
00448 int AudioOutputJACK::_JackGraphOrderCallback(void *arg)
00449 {
00450 AudioOutputJACK *aoj = static_cast<AudioOutputJACK*>(arg);
00451 return aoj->JackGraphOrderCallback();
00452 }
00453
00454
00455
00456
00457
00458 int AudioOutputJACK::JackGraphOrderCallback(void)
00459 {
00460 int i;
00461 jack_nframes_t port_latency, max_latency = 0;
00462
00463 for (i = 0; i < channels; ++i)
00464 {
00465 port_latency = jack_port_get_total_latency( client, ports[i] );
00466 if (port_latency > max_latency)
00467 max_latency = port_latency;
00468 }
00469
00470 jack_latency = max_latency;
00471 VBAUDIO(QString("JACK graph reordered. Maximum latency=%1")
00472 .arg(jack_latency));
00473
00474 return 0;
00475 }
00476
00477
00478
00479 void AudioOutputJACK::VolumeInit(void)
00480 {
00481 int volume = 100;
00482 if (set_initial_vol)
00483 {
00484 QString controlLabel = gCoreContext->GetSetting("MixerControl", "PCM");
00485 controlLabel += "MixerVolume";
00486 volume = gCoreContext->GetNumSetting(controlLabel, 80);
00487 }
00488
00489 for (int i=0; i<JACK_CHANNELS_MAX; i++)
00490 chan_volumes[i] = volume;
00491 }
00492
00493 int AudioOutputJACK::GetVolumeChannel(int channel) const
00494 {
00495 unsigned int vol = 0;
00496
00497 if (!internal_vol)
00498 return 100;
00499
00500 if (channel < JACK_CHANNELS_MAX)
00501 vol = chan_volumes[channel];
00502
00503 return vol;
00504 }
00505
00506 void AudioOutputJACK::SetVolumeChannel(int channel, int volume)
00507 {
00508 if (internal_vol && (channel < JACK_CHANNELS_MAX))
00509 {
00510 chan_volumes[channel] = volume;
00511 if (channel == 0)
00512 {
00513
00514 chan_volumes[2] = volume;
00515 }
00516 else if (channel == 1)
00517 {
00518
00519 chan_volumes[3] = volume;
00520 }
00521
00522
00523 chan_volumes[4] = chan_volumes[5] =
00524 (chan_volumes[0] + chan_volumes[1]) / 2;
00525 }
00526 }
00527
00528
00529
00530
00531
00532
00533 bool AudioOutputJACK::StartOutputThread(void)
00534 {
00535 return true;
00536 }
00537
00538 void AudioOutputJACK::StopOutputThread(void)
00539 {
00540 }
00541
00542
00543 void AudioOutputJACK::WriteAudio(unsigned char *aubuf, int size)
00544 {
00545 (void)aubuf;
00546 (void)size;
00547 return;
00548 }
00549
00550
00551
00552
00553
00554 jack_client_t* AudioOutputJACK::_jack_client_open(void)
00555 {
00556 jack_client_t* client = NULL;
00557 QString client_name = QString("mythtv_%1").arg(getpid());
00558 jack_options_t open_options =
00559 (jack_options_t)(JackUseExactName | JackNoStartServer);
00560 jack_status_t open_status;
00561
00562 client = jack_client_open(client_name.toAscii().constData(),
00563 open_options, &open_status);
00564
00565 return client;
00566 }
00567
00568 const char** AudioOutputJACK::_jack_get_ports(void)
00569 {
00570 const char **matching_ports = NULL;
00571 unsigned long port_flags=JackPortIsInput;
00572 const char *port_name = NULL;
00573
00574
00575 if (!main_device.isEmpty())
00576 {
00577 port_name = main_device.toAscii().constData();
00578 }
00579 else
00580 {
00581 port_flags |= JackPortIsPhysical;
00582 }
00583
00584
00585 matching_ports = jack_get_ports(client, port_name, NULL, port_flags);
00586 return matching_ports;
00587 }
00588
00589
00590 bool AudioOutputJACK::_jack_connect_ports(const char** matching_ports)
00591 {
00592 int i=0;
00593
00594
00595 for (i = 0; i < channels; i++)
00596 {
00597 if (jack_connect(client, jack_port_name(ports[i]), matching_ports[i]))
00598 {
00599 JERROR(QString("Calling jack_connect failed on port: %1\n").arg(i));
00600 return false;
00601 }
00602 }
00603
00604 return true;
00605 }
00606
00607 void AudioOutputJACK::_jack_client_close(jack_client_t **client)
00608 {
00609 if (*client)
00610 {
00611 int err = jack_client_close(*client);
00612 if (err != 0)
00613 JERROR(QString("Error closing Jack output device. Error: %1")
00614 .arg(err));
00615 *client = NULL;
00616 }
00617 }
00618
00619