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
00010 #include <iostream>
00011 #include <qdatetime.h>
00012
00013 using namespace std;
00014
00015 #include "mythcontext.h"
00016 #include "audiooutputjack.h"
00017 #include "util.h"
00018
00019 extern "C"
00020 {
00021 #include "bio2jack.h"
00022 }
00023
00024 AudioOutputJACK::AudioOutputJACK(
00025 QString laudio_main_device, QString laudio_passthru_device,
00026 int laudio_bits, int laudio_channels,
00027 int laudio_samplerate, AudioOutputSource lsource,
00028 bool lset_initial_vol, bool laudio_passthru) :
00029 AudioOutputBase(laudio_main_device, laudio_passthru_device,
00030 laudio_bits, laudio_channels,
00031 laudio_samplerate, lsource,
00032 lset_initial_vol, laudio_passthru),
00033 audioid(-1)
00034 {
00035
00036 JACK_Init();
00037
00038
00039 Reconfigure(laudio_bits, laudio_channels,
00040 laudio_samplerate, laudio_passthru);
00041 }
00042
00043 AudioOutputJACK::~AudioOutputJACK()
00044 {
00045
00046 KillAudio();
00047 }
00048
00049 bool AudioOutputJACK::OpenDevice()
00050 {
00051 MythTimer timer;
00052 timer.start();
00053
00054 unsigned long jack_port_flags=JackPortIsPhysical;
00055 unsigned int jack_port_name_count=0;
00056 const char *jack_port_name=NULL;
00057
00058 VERBOSE(VB_GENERAL, QString("Opening JACK audio device '%1'.")
00059 .arg(audio_main_device));
00060
00061 if (!audio_main_device.isEmpty()) {
00062 jack_port_flags = 0;
00063 jack_port_name_count = 1;
00064 jack_port_name = audio_main_device.ascii();
00065 }
00066
00067 int err = -1;
00068 audioid = -1;
00069 while (timer.elapsed() < 2000 && audioid == -1)
00070 {
00071 err = JACK_OpenEx(&audioid, 16, (unsigned long *) &audio_samplerate,
00072 audio_channels, audio_channels, &jack_port_name,
00073 jack_port_name_count, jack_port_flags);
00074 if (err == 1) {
00075 Error(QString("Error connecting to jackd:%1. Is it running?")
00076 .arg(audio_main_device));
00077 return false;
00078 } else if (err == 2) {
00079
00080 VERBOSE(VB_AUDIO, QString("Failed to open device at"
00081 " requested samplerate. Retrying"));
00082 err = JACK_OpenEx(&audioid, 16, (unsigned long *) &audio_samplerate,
00083 audio_channels, audio_channels, &jack_port_name,
00084 jack_port_name_count, jack_port_flags);
00085 } else if (err == ERR_PORT_NOT_FOUND) {
00086 VERBOSE(VB_IMPORTANT, QString("Error opening audio device (%1), "
00087 " Port not found.").arg(audio_main_device));
00088 perror(audio_main_device.ascii());
00089 }
00090
00091 if (err != 0)
00092 {
00093 VERBOSE(VB_IMPORTANT, QString("Error opening audio device (%1), the"
00094 " error num was: %2").arg(audio_main_device).arg(err));
00095 perror(audio_main_device.ascii());
00096 }
00097 if (audioid < 0)
00098 usleep(50);
00099 }
00100
00101 if (audioid == -1)
00102 {
00103 Error(QString("Error opening audio device (%1), the error num was: %2")
00104 .arg(audio_main_device).arg(err));
00105 return false;
00106 }
00107
00108 fragment_size = JACK_GetJackBufferedBytes(audioid);
00109
00110
00111 JACK_SetMaxBufferedBytes(audioid, 4 * fragment_size);
00112
00113 VERBOSE(VB_AUDIO, QString("Audio fragment size: %1")
00114 .arg(fragment_size));
00115
00116 audio_buffer_unused = JACK_GetBytesFreeSpace(audioid);
00117 JACK_SetPosition(audioid, BYTES, 0);
00118
00119
00120 if (internal_vol)
00121 VolumeInit();
00122
00123
00124 return true;
00125 }
00126
00127 void AudioOutputJACK::CloseDevice()
00128 {
00129 int err = -1;
00130 if (audioid != -1)
00131 {
00132 err = JACK_Close(audioid);
00133 if (err != 0)
00134 Error(QString("Error closing Jack output device"));
00135 }
00136
00137 audioid = -1;
00138 }
00139
00140 void AudioOutputJACK::WriteAudio(unsigned char *aubuf, int size)
00141 {
00142 if (audioid < 0)
00143 return;
00144
00145 unsigned char *tmpbuf;
00146 int written = 0, lw = 0;
00147
00148 tmpbuf = aubuf;
00149
00150 while ((written < size) &&
00151 ((lw = JACK_Write(audioid, tmpbuf, size - written)) > 0))
00152 {
00153 written += lw;
00154 tmpbuf += lw;
00155 }
00156 }
00157
00158
00159 inline int AudioOutputJACK::getBufferedOnSoundcard(void)
00160 {
00161 return JACK_GetBytesStored(audioid) + fragment_size * 2;
00162 }
00163
00164 inline int AudioOutputJACK::getSpaceOnSoundcard(void)
00165 {
00166 int space = 0;
00167
00168 space = JACK_GetBytesFreeSpace(audioid);
00169
00170 if (space < 0)
00171 {
00172 VERBOSE(VB_IMPORTANT, "Jack returned negative number for Free Space...");
00173 }
00174
00175 return space;
00176 }
00177
00178 void AudioOutputJACK::VolumeInit(void)
00179 {
00180 int volume = 100;
00181 if (set_initial_vol)
00182 volume = gContext->GetNumSetting("MasterMixerVolume", 80);
00183
00184 JACK_SetAllVolume(audioid, volume);
00185 }
00186
00187 int AudioOutputJACK::GetVolumeChannel(int channel)
00188 {
00189 unsigned int vol = 0;
00190
00191 if (!internal_vol)
00192 return 100;
00193
00194 JACK_GetVolumeForChannel(audioid, channel, &vol);
00195 return vol;
00196 }
00197
00198 void AudioOutputJACK::SetVolumeChannel(int channel, int volume)
00199 {
00200 if (internal_vol)
00201 JACK_SetVolumeForChannel(audioid, channel, volume);
00202 }
00203