MythTV  master
audiooutput.cpp
Go to the documentation of this file.
1 #include <cstdio>
2 #include <cstdlib>
3 
4 using namespace std;
5 
6 // Qt utils: to parse audio list
7 #include <QFile>
8 #include <QDateTime>
9 #include <QDir>
10 
11 #include "mythconfig.h"
12 #include "audiooutput.h"
13 #include "mythmiscutil.h"
14 #include "compat.h"
15 
16 #include "audiooutputnull.h"
17 #ifdef _WIN32
18 #include "audiooutputdx.h"
19 #include "audiooutputwin.h"
20 #endif
21 #ifdef USING_OSS
22 #include "audiooutputoss.h"
23 #endif
24 #ifdef USING_ALSA
25 #include "audiooutputalsa.h"
26 #endif
27 #if CONFIG_DARWIN
28 #include "audiooutputca.h"
29 #endif
30 #ifdef USING_JACK
31 #include "audiooutputjack.h"
32 #endif
33 #ifdef USING_PULSEOUTPUT
34 #include "audiooutputpulse.h"
35 #endif
36 #ifdef USING_PULSE
37 #include "audiopulsehandler.h"
38 #endif
39 #ifdef Q_OS_ANDROID
40 #include "audiooutputopensles.h"
41 #include "audiooutputaudiotrack.h"
42 #endif
43 
44 extern "C" {
45 #include "libavcodec/avcodec.h" // to get codec id
46 }
47 #include "audioconvert.h"
48 
49 #define LOC QString("AO: ")
50 
52 {
53 #ifdef USING_PULSE
55 #endif
56 }
57 
59  const QString &main_device, const QString &passthru_device,
60  AudioFormat format, int channels, AVCodecID codec, int samplerate,
61  AudioOutputSource source, bool set_initial_vol, bool passthru,
62  int upmixer_startup, AudioOutputSettings *custom)
63 {
64  AudioSettings settings(
65  main_device, passthru_device, format, channels, codec, samplerate,
66  source, set_initial_vol, passthru, upmixer_startup, custom);
67 
68  return OpenAudio(settings);
69 }
70 
72  const QString &main_device, const QString &passthru_device,
73  bool willsuspendpa)
74 {
75  AudioSettings settings(main_device, passthru_device);
76 
77  return OpenAudio(settings, willsuspendpa);
78 }
79 
81  bool willsuspendpa)
82 {
83  QString &main_device = settings.m_mainDevice;
84  AudioOutput *ret = nullptr;
85 
86  // Don't suspend Pulse if unnecessary. This can save 100mS
87  if (settings.m_format == FORMAT_NONE || settings.m_channels <= 0)
88  willsuspendpa = false;
89 
90 #ifdef USING_PULSE
91  bool pulsestatus = false;
92 #else
93  {
94  static bool warned = false;
95  if (!warned && IsPulseAudioRunning())
96  {
97  warned = true;
98  LOG(VB_GENERAL, LOG_WARNING,
99  "WARNING: ***Pulse Audio is running***");
100  }
101  }
102 #endif
103 
104  settings.FixPassThrough();
105 
106  if (main_device.startsWith("PulseAudio:"))
107  {
108 #ifdef USING_PULSEOUTPUT
109  return new AudioOutputPulseAudio(settings);
110 #else
111  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to PulseAudio "
112  "but PulseAudio support is not compiled in!");
113  return nullptr;
114 #endif
115  }
116  if (main_device.startsWith("NULL"))
117  {
118  return new AudioOutputNULL(settings);
119  }
120 
121 #ifdef USING_PULSE
122  if (willsuspendpa)
123  {
124  bool ispulse = false;
125 #ifdef USING_ALSA
126  // Check if using ALSA, that the device doesn't contain the word
127  // "pulse" in its hint
128  if (main_device.startsWith("ALSA:"))
129  {
130  QString device_name = main_device;
131 
132  device_name.remove(0, 5);
133  QMap<QString, QString> *alsadevs =
135  if (!alsadevs->empty() && alsadevs->contains(device_name))
136  {
137  if (alsadevs->value(device_name).contains("pulse",
138  Qt::CaseInsensitive))
139  {
140  ispulse = true;
141  }
142  }
143  delete alsadevs;
144  }
145 #endif
146  if (main_device.contains("pulse", Qt::CaseInsensitive))
147  {
148  ispulse = true;
149  }
150  if (!ispulse)
151  {
153  }
154  }
155 #else // USING_PULSE
156  // Quiet warning error when not compiling with pulseaudio
157  Q_UNUSED(willsuspendpa);
158 #endif
159 
160  if (main_device.startsWith("ALSA:"))
161  {
162 #ifdef USING_ALSA
163  settings.TrimDeviceType();
164  ret = new AudioOutputALSA(settings);
165 #else
166  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to an ALSA device "
167  "but ALSA support is not compiled in!");
168 #endif
169  }
170  else if (main_device.startsWith("JACK:"))
171  {
172 #ifdef USING_JACK
173  settings.TrimDeviceType();
174  ret = new AudioOutputJACK(settings);
175 #else
176  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to a JACK device "
177  "but JACK support is not compiled in!");
178 #endif
179  }
180  else if (main_device.startsWith("DirectX:"))
181  {
182 #ifdef _WIN32
183  ret = new AudioOutputDX(settings);
184 #else
185  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to DirectX device "
186  "but DirectX support is not compiled in!");
187 #endif
188  }
189  else if (main_device.startsWith("Windows:"))
190  {
191 #ifdef _WIN32
192  ret = new AudioOutputWin(settings);
193 #else
194  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to a Windows "
195  "device but Windows support is not compiled "
196  "in!");
197 #endif
198  }
199  else if (main_device.startsWith("OpenSLES:"))
200  {
201 #ifdef Q_OS_ANDROID
202  ret = new AudioOutputOpenSLES(settings);
203 #else
204  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to a OpenSLES "
205  "device but Android support is not compiled "
206  "in!");
207 #endif
208  }
209  else if (main_device.startsWith("AudioTrack:"))
210  {
211 #ifdef Q_OS_ANDROID
212  ret = new AudioOutputAudioTrack(settings);
213 #else
214  LOG(VB_GENERAL, LOG_ERR, "Audio output device is set to AudioTrack "
215  "device but Android support is not compiled "
216  "in!");
217 #endif
218  }
219 #if defined(USING_OSS)
220  else
221  ret = new AudioOutputOSS(settings);
222 #elif CONFIG_DARWIN
223  else
224  ret = new AudioOutputCA(settings);
225 #endif
226 
227  if (!ret)
228  {
229  LOG(VB_GENERAL, LOG_CRIT, "No useable audio output driver found.");
230  LOG(VB_GENERAL, LOG_ERR, "Don't disable OSS support unless you're "
231  "not running on Linux.");
232 #ifdef USING_PULSE
233  if (pulsestatus)
235 #endif
236  return nullptr;
237  }
238 #ifdef USING_PULSE
239  ret->m_pulseWasSuspended = pulsestatus;
240 #endif
241  return ret;
242 }
243 
245 {
246 #ifdef USING_PULSE
247  if (m_pulseWasSuspended)
249 #endif
250  av_frame_free(&m_frame);
251 }
252 
253 void AudioOutput::SetStretchFactor(float /*factor*/)
254 {
255 }
256 
258 {
259  return new AudioOutputSettings;
260 }
261 
263 {
264  return new AudioOutputSettings;
265 }
266 
267 bool AudioOutput::CanPassthrough(int /*samplerate*/,
268  int /*channels*/,
269  AVCodecID /*codec*/,
270  int /*profile*/) const
271 {
272  return false;
273 }
274 
275 // TODO: get rid of this if possible... need to see what uses GetError() and
276 // GetWarning() and why. These would give more useful logs as macros
277 void AudioOutput::Error(const QString &msg)
278 {
279  m_lastError = msg;
280  LOG(VB_GENERAL, LOG_ERR, "AudioOutput Error: " + m_lastError);
281 }
282 
283 void AudioOutput::SilentError(const QString &msg)
284 {
285  m_lastError = msg;
286 }
287 
288 void AudioOutput::Warn(const QString &msg)
289 {
290  m_lastWarn = msg;
291  LOG(VB_GENERAL, LOG_WARNING, "AudioOutput Warning: " + m_lastWarn);
292 }
293 
295 {
296  m_lastError.clear();
297 }
298 
300 {
301  m_lastWarn.clear();
302 }
303 
305  QString &name, QString &desc, bool willsuspendpa)
306 {
307  AudioOutputSettings aosettings(true);
308 
309  AudioOutput *ao = OpenAudio(name, QString(), willsuspendpa);
310  if (ao)
311  {
312  aosettings = *(ao->GetOutputSettingsCleaned());
313  delete ao;
314  }
315  if (aosettings.IsInvalid())
316  {
317  if (!willsuspendpa)
318  return nullptr;
319  QString msg = tr("Invalid or unuseable audio device");
320  return new AudioOutput::AudioDeviceConfig(name, msg);
321  }
322 
323  QString capabilities = desc;
324  int max_channels = aosettings.BestSupportedChannelsELD();
325  if (aosettings.hasELD())
326  {
327  if (aosettings.getELD().isValid())
328  {
329  capabilities += tr(" (%1 connected to %2)")
330  .arg(aosettings.getELD().product_name().simplified())
331  .arg(aosettings.getELD().connection_name());
332  }
333  else
334  {
335  capabilities += tr(" (No connection detected)");
336  }
337  }
338 
339  QString speakers;
340  switch (max_channels)
341  {
342  case 6:
343  speakers = "5.1";
344  break;
345  case 8:
346  speakers = "7.1";
347  break;
348  default:
349  speakers = "2.0";
350  break;
351  }
352 
353  capabilities += tr("\nDevice supports up to %1")
354  .arg(speakers);
355  if (aosettings.canPassthrough() >= 0)
356  {
357  if (aosettings.hasELD() && aosettings.getELD().isValid())
358  {
359  // We have an ELD, show actual reported capabilities
360  capabilities += " (" + aosettings.getELD().codecs_desc() + ")";
361  }
362  else
363  {
364  // build capabilities string, in a similar fashion as reported
365  // by ELD
366  int mask = 0;
367  mask |=
368  (static_cast<int>(aosettings.canLPCM()) << 0) |
369  (static_cast<int>(aosettings.canAC3()) << 1) |
370  (static_cast<int>(aosettings.canDTS()) << 2);
371  // cppcheck-suppress variableScope
372  static const std::array<const std::string,3> s_typeNames { "LPCM", "AC3", "DTS" };
373 
374  if (mask != 0)
375  {
376  capabilities += QObject::tr(" (guessing: ");
377  bool found_one = false;
378  for (unsigned int i = 0; i < 3; i++)
379  {
380  if ((mask & (1 << i)) != 0)
381  {
382  if (found_one)
383  capabilities += ", ";
384  capabilities += QString::fromStdString(s_typeNames[i]);
385  found_one = true;
386  }
387  }
388  capabilities += QString(")");
389  }
390  }
391  }
392  LOG(VB_AUDIO, LOG_INFO, QString("Found %1 (%2)")
393  .arg(name).arg(capabilities));
394  auto *adc = new AudioOutput::AudioDeviceConfig(name, capabilities);
395  adc->m_settings = aosettings;
396  return adc;
397 }
398 
399 #ifdef USING_OSS
400 static void fillSelectionsFromDir(const QDir &dir,
401  AudioOutput::ADCVect *list)
402 {
403  QFileInfoList entries = dir.entryInfoList();
404  for (const auto& fi : qAsConst(entries))
405  {
406  QString name = fi.absoluteFilePath();
407  QString desc = AudioOutput::tr("OSS device");
410  if (!adc)
411  continue;
412  list->append(*adc);
413  delete adc;
414  }
415 }
416 #endif
417 
419 {
420  auto *list = new ADCVect;
421 
422 #ifdef USING_PULSE
424 #endif
425 
426 #ifdef USING_ALSA
427  QMap<QString, QString> *alsadevs = AudioOutputALSA::GetDevices("pcm");
428 
429  if (!alsadevs->empty())
430  {
431  for (auto i = alsadevs->cbegin(); i != alsadevs->cend(); ++i)
432  {
433  const QString& key = i.key();
434  QString desc = i.value();
435  QString devname = QString("ALSA:%1").arg(key);
436 
437  auto *adc = GetAudioDeviceConfig(devname, desc);
438  if (!adc)
439  continue;
440  list->append(*adc);
441  delete adc;
442  }
443  }
444  delete alsadevs;
445 #endif
446 #ifdef USING_OSS
447  {
448  QDir dev("/dev", "dsp*", QDir::Name, QDir::System);
449  fillSelectionsFromDir(dev, list);
450  dev.setNameFilters(QStringList("adsp*"));
451  fillSelectionsFromDir(dev, list);
452 
453  dev.setPath("/dev/sound");
454  if (dev.exists())
455  {
456  dev.setNameFilters(QStringList("dsp*"));
457  fillSelectionsFromDir(dev, list);
458  dev.setNameFilters(QStringList("adsp*"));
459  fillSelectionsFromDir(dev, list);
460  }
461  }
462 #endif
463 #ifdef USING_JACK
464  {
465  QString name = "JACK:";
466  QString desc = tr("Use JACK default sound server.");
467  auto *adc = GetAudioDeviceConfig(name, desc);
468  if (adc)
469  {
470  list->append(*adc);
471  delete adc;
472  }
473  }
474 #endif
475 #if CONFIG_DARWIN
476 
477  {
478  QMap<QString, QString> *devs = AudioOutputCA::GetDevices(nullptr);
479  if (!devs->empty())
480  {
481  for (QMap<QString, QString>::const_iterator i = devs->begin();
482  i != devs->end(); ++i)
483  {
484  QString key = i.key();
485  QString desc = i.value();
486  QString devname = QString("CoreAudio:%1").arg(key);
487 
488  auto adc = GetAudioDeviceConfig(devname, desc);
489  if (!adc)
490  continue;
491  list->append(*adc);
492  delete adc;
493  }
494  }
495  delete devs;
496  QString name = "CoreAudio:Default Output Device";
497  QString desc = tr("CoreAudio default output");
498  auto adc = GetAudioDeviceConfig(name, desc);
499  if (adc)
500  {
501  list->append(*adc);
502  delete adc;
503  }
504  }
505 #endif
506 #ifdef _WIN32
507  {
508  QString name = "Windows:";
509  QString desc = "Windows default output";
510  auto adc = GetAudioDeviceConfig(name, desc);
511  if (adc)
512  {
513  list->append(*adc);
514  delete adc;
515  }
516 
517  QMap<int, QString> *dxdevs = AudioOutputDX::GetDXDevices();
518 
519  if (!dxdevs->empty())
520  {
521  for (QMap<int, QString>::const_iterator i = dxdevs->begin();
522  i != dxdevs->end(); ++i)
523  {
524  QString devdesc = i.value();
525  QString devname = QString("DirectX:%1").arg(devdesc);
526 
527  adc = GetAudioDeviceConfig(devname, devdesc);
528  if (!adc)
529  continue;
530  list->append(*adc);
531  delete adc;
532  }
533  }
534  delete dxdevs;
535  }
536 #endif
537 
538 #ifdef USING_PULSE
539  if (pasuspended)
541 #endif
542 
543 #ifdef USING_PULSEOUTPUT
544  {
545  QString name = "PulseAudio:default";
546  QString desc = tr("PulseAudio default sound server.");
547  auto *adc = GetAudioDeviceConfig(name, desc);
548  if (adc)
549  {
550  list->append(*adc);
551  delete adc;
552  }
553  }
554 #endif
555 
556 #ifdef ANDROID
557  {
558  QString name = "OpenSLES:";
559  QString desc = tr("OpenSLES default output. Stereo support only.");
560  auto adc = GetAudioDeviceConfig(name, desc);
561  if (adc)
562  {
563  list->append(*adc);
564  delete adc;
565  }
566  }
567  {
568  QString name = "AudioTrack:";
569  QString desc = tr("Android AudioTrack output. Supports surround sound.");
570  auto adc = GetAudioDeviceConfig(name, desc);
571  if (adc)
572  {
573  list->append(*adc);
574  delete adc;
575  }
576  }
577 #endif
578 
579  QString name = "NULL";
580  QString desc = "NULL device";
581  auto *adc = GetAudioDeviceConfig(name, desc);
582  if (adc)
583  {
584  list->append(*adc);
585  delete adc;
586  }
587  return list;
588 }
589 
597 int AudioOutput::DecodeAudio(AVCodecContext *ctx,
598  uint8_t *buffer, int &data_size,
599  const AVPacket *pkt)
600 {
601  bool got_frame = false;
602 
603  data_size = 0;
604  if (!m_frame)
605  {
606  if (!(m_frame = av_frame_alloc()))
607  {
608  return AVERROR(ENOMEM);
609  }
610  }
611  else
612  {
613  av_frame_unref(m_frame);
614  }
615 
616 // SUGGESTION
617 // Now that avcodec_decode_audio4 is deprecated and replaced
618 // by 2 calls (receive frame and send packet), this could be optimized
619 // into separate routines or separate threads.
620 // Also now that it always consumes a whole buffer some code
621 // in the caller may be able to be optimized.
622  int ret = avcodec_receive_frame(ctx,m_frame);
623  if (ret == 0)
624  got_frame = true;
625  if (ret == AVERROR(EAGAIN))
626  ret = 0;
627  if (ret == 0)
628  ret = avcodec_send_packet(ctx, pkt);
629  if (ret == AVERROR(EAGAIN))
630  ret = 0;
631  else if (ret < 0)
632  {
633  std::string error;
634  LOG(VB_AUDIO, LOG_ERR, LOC +
635  QString("audio decode error: %1 (%2)")
637  .arg(got_frame));
638  return ret;
639  }
640  else
641  ret = pkt->size;
642 
643  if (!got_frame)
644  {
645  LOG(VB_AUDIO, LOG_DEBUG, LOC +
646  QString("audio decode, no frame decoded (%1)").arg(ret));
647  return ret;
648  }
649 
650  auto format = (AVSampleFormat)m_frame->format;
651  AudioFormat fmt =
652  AudioOutputSettings::AVSampleFormatToFormat(format, ctx->bits_per_raw_sample);
653 
654  data_size = m_frame->nb_samples * m_frame->channels * av_get_bytes_per_sample(format);
655 
656  // May need to convert audio to S16
657  AudioConvert converter(fmt, CanProcess(fmt) ? fmt : FORMAT_S16);
658  uint8_t* src = nullptr;
659 
660  if (av_sample_fmt_is_planar(format))
661  {
662  src = buffer;
663  converter.InterleaveSamples(m_frame->channels,
664  src,
665  (const uint8_t **)m_frame->extended_data,
666  data_size);
667  }
668  else
669  {
670  // data is already compacted...
671  src = m_frame->extended_data[0];
672  }
673 
674  uint8_t* transit = buffer;
675 
676  if (!CanProcess(fmt) &&
677  av_get_bytes_per_sample(ctx->sample_fmt) < AudioOutputSettings::SampleSize(converter.Out()))
678  {
679  // this conversion can't be done in place
680  transit = (uint8_t*)av_malloc(data_size * av_get_bytes_per_sample(ctx->sample_fmt)
681  / AudioOutputSettings::SampleSize(converter.Out()));
682  if (!transit)
683  {
684  LOG(VB_AUDIO, LOG_ERR, LOC +
685  QString("audio decode, out of memory"));
686  data_size = 0;
687  return ret;
688  }
689  }
690  if (!CanProcess(fmt) || src != transit)
691  {
692  data_size = converter.Process(transit, src, data_size, true);
693  }
694  if (transit != buffer)
695  {
696  av_free(transit);
697  }
698  return ret;
699 }
FORMAT_NONE
@ FORMAT_NONE
Definition: audiooutputsettings.h:26
audiooutputwin.h
AudioOutputSettings::AVSampleFormatToFormat
static AudioFormat AVSampleFormatToFormat(AVSampleFormat format, int bits=0)
Return AVSampleFormat closest equivalent to AudioFormat.
Definition: audiooutputsettings.cpp:200
AudioOutputDX
Definition: audiooutputdx.h:13
error
static void error(const char *str,...)
Definition: vbi.cpp:42
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:28
audiooutputoss.h
AudioOutputALSA
Definition: audiooutputalsa.h:13
PulseHandler::Suspend
static bool Suspend(enum PulseAction action)
Definition: audiopulsehandler.cpp:38
AudioOutput::Error
void Error(const QString &msg)
Definition: audiooutput.cpp:277
arg
arg(title).arg(filename).arg(doDelete))
AudioOutputJACK
Definition: audiooutputjack.h:20
AudioOutput::Warn
void Warn(const QString &msg)
Definition: audiooutput.cpp:288
AudioOutputSettings::SampleSize
static int SampleSize(AudioFormat format)
Definition: audiooutputsettings.cpp:182
AudioOutputWin
Definition: audiooutputwin.h:10
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
AudioOutputALSA::GetDevices
static QMap< QString, QString > * GetDevices(const char *type)
Definition: audiooutputalsa.cpp:991
audiooutputalsa.h
ELD::connection_name
QString connection_name() const
Definition: eldutils.cpp:460
AudioConvert::Out
AudioFormat Out(void)
Definition: audioconvert.h:49
AudioOutputPulseAudio
Definition: audiooutputpulse.h:28
ELD::isValid
bool isValid() const
Definition: eldutils.cpp:425
audiooutputaudiotrack.h
LOC
#define LOC
Definition: audiooutput.cpp:49
audiooutputjack.h
AudioOutput::OpenAudio
static AudioOutput * OpenAudio(const QString &main_device, const QString &passthru_device, AudioFormat format, int channels, AVCodecID codec, int samplerate, AudioOutputSource source, bool set_initial_vol, bool passthru, int upmixer_startup=0, AudioOutputSettings *custom=nullptr)
Definition: audiooutput.cpp:58
AudioOutputCA
Implements Core Audio (Mac OS X Hardware Abstraction Layer) output.
Definition: audiooutputca.h:14
AudioSettings::FixPassThrough
void FixPassThrough(void)
Definition: audiosettings.cpp:93
AudioOutputCA::GetDevices
static QMap< QString, QString > * GetDevices(const char *type=nullptr)
Definition: audiooutputca.cpp:1747
IsPulseAudioRunning
bool IsPulseAudioRunning(void)
Is A/V Sync destruction daemon is running on this host?
Definition: mythmiscutil.cpp:682
AudioOutputDX::GetDXDevices
static QMap< int, QString > * GetDXDevices(void)
Definition: audiooutputdx.cpp:622
AudioSettings
Definition: audiosettings.h:29
audiooutputopensles.h
AudioConvert
Definition: audioconvert.h:33
AudioOutput::CanPassthrough
virtual bool CanPassthrough(int samplerate, int channels, AVCodecID codec, int profile) const
Definition: audiooutput.cpp:267
AudioOutput
Definition: audiooutput.h:26
ELD::codecs_desc
QString codecs_desc() const
Definition: eldutils.cpp:492
audiooutputnull.h
AudioOutputSettings::BestSupportedChannelsELD
int BestSupportedChannelsELD()
Reports best supported channel number, restricted to ELD range.
Definition: audiooutputsettings.cpp:554
AudioOutputSettings::canPassthrough
int canPassthrough() const
Definition: audiooutputsettings.h:78
compat.h
AudioOutputOpenSLES
Definition: audiooutputopensles.h:18
AudioOutput::GetOutputSettingsCleaned
virtual AudioOutputSettings * GetOutputSettingsCleaned(bool digital=true)
Definition: audiooutput.cpp:257
audiopulsehandler.h
PulseHandler::kPulseResume
@ kPulseResume
Definition: audiopulsehandler.h:14
AudioSettings::m_mainDevice
QString m_mainDevice
Definition: audiosettings.h:69
AudioOutputSettings::hasELD
bool hasELD() const
get the ELD flag
Definition: audiooutputsettings.cpp:542
PulseHandler::kPulseSuspend
@ kPulseSuspend
Definition: audiopulsehandler.h:13
AudioOutputSettings::canDTS
bool canDTS() const
return true if device can or may support DTS (deprecated, see canFeature())
Definition: audiooutputsettings.h:103
AudioOutput::DecodeAudio
virtual int DecodeAudio(AVCodecContext *ctx, uint8_t *buffer, int &data_size, const AVPacket *pkt)
Utility routine.
Definition: audiooutput.cpp:597
AudioOutputSettings::IsInvalid
bool IsInvalid() const
return true if class instance is marked invalid.
Definition: audiooutputsettings.h:114
AudioOutputAudioTrack
Definition: audiooutputaudiotrack.h:17
AudioOutputOSS
Definition: audiooutputoss.h:13
AudioOutput::AudioDeviceConfig
Definition: audiooutput.h:31
AudioOutputNULL
Definition: audiooutputnull.h:22
AudioOutput::GetAudioDeviceConfig
static AudioDeviceConfig * GetAudioDeviceConfig(QString &name, QString &desc, bool willsuspendpa=false)
Definition: audiooutput.cpp:304
audiooutputpulse.h
mythmiscutil.h
fillSelectionsFromDir
static void fillSelectionsFromDir(const QDir &dir, AudioOutput::ADCVect *list)
Definition: audiooutput.cpp:400
AudioOutput::SilentError
void SilentError(const QString &msg)
Definition: audiooutput.cpp:283
AudioSettings::m_format
AudioFormat m_format
Definition: audiosettings.h:71
dir
QDir dir
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1171
AudioOutput::SetStretchFactor
virtual void SetStretchFactor(float factor)
Definition: audiooutput.cpp:253
AudioConvert::Process
int Process(void *out, const void *in, int bytes, bool noclip=false)
Process Parameters: out : destination buffer where converted samples will be copied in : source buffe...
Definition: audioconvert.cpp:655
AudioOutputSettings
Definition: audiooutputsettings.h:50
audiooutput.h
audiooutputdx.h
AudioOutput::ClearError
void ClearError(void)
Definition: audiooutput.cpp:294
AudioOutputSettings::getELD
ELD & getELD(void)
retrieve ELD data
Definition: audiooutputsettings.h:176
AudioOutputSource
AudioOutputSource
Definition: audiosettings.h:21
audiooutputca.h
AudioOutputSettings::canLPCM
bool canLPCM() const
return true if device supports multichannels PCM (deprecated, see canFeature())
Definition: audiooutputsettings.h:108
AudioOutput::ClearWarning
void ClearWarning(void)
Definition: audiooutput.cpp:299
AudioConvert::InterleaveSamples
void InterleaveSamples(int channels, uint8_t *output, const uint8_t *const *input, int data_size)
Definition: audioconvert.cpp:884
ELD::product_name
QString product_name() const
Definition: eldutils.cpp:455
PulseHandler::kPulseCleanup
@ kPulseCleanup
Definition: audiopulsehandler.h:15
AudioOutput::~AudioOutput
~AudioOutput() override
Definition: audiooutput.cpp:244
AudioSettings::TrimDeviceType
void TrimDeviceType(void)
Definition: audiosettings.cpp:99
AudioFormat
AudioFormat
Definition: audiooutputsettings.h:25
AudioOutput::Cleanup
static void Cleanup(void)
Definition: audiooutput.cpp:51
AudioOutput::ADCVect
QVector< AudioDeviceConfig > ADCVect
Definition: audiooutput.h:48
AudioOutput::GetOutputSettingsUsers
virtual AudioOutputSettings * GetOutputSettingsUsers(bool digital=true)
Definition: audiooutput.cpp:262
AudioOutput::m_pulseWasSuspended
bool m_pulseWasSuspended
Definition: audiooutput.h:206
av_make_error_stdstring
char * av_make_error_stdstring(std::string &errbuf, int errnum)
Definition: mythaverror.cpp:41
AudioOutput::GetOutputList
static ADCVect * GetOutputList(void)
Definition: audiooutput.cpp:418
AudioSettings::m_channels
int m_channels
Definition: audiosettings.h:72
AudioOutputSettings::canAC3
bool canAC3() const
return true if device can or may support AC3 (deprecated, see canFeature())
Definition: audiooutputsettings.h:98
audioconvert.h