MythTV  master
audiooutputbase.cpp
Go to the documentation of this file.
1 // C++ headers
2 #include <algorithm>
3 #include <cmath>
4 #include <limits>
5 
6 // POSIX headers
7 #include <unistd.h>
8 #include <sys/time.h>
9 
10 // Qt headers
11 #include <QMutexLocker>
12 
13 // MythTV headers
14 #include "compat.h"
15 #include "audiooutputbase.h"
17 #include "audiooutpututil.h"
18 #include "audiooutputdownmix.h"
19 #include "SoundTouch.h"
20 #include "freesurround.h"
21 #include "spdifencoder.h"
22 #include "mythlogging.h"
23 #include "mythconfig.h"
24 
25 // AC3 encode currently disabled for Android
26 #if defined(Q_OS_ANDROID)
27 #define DISABLE_AC3_ENCODE
28 #endif
29 
30 #define LOC QString("AOBase: ")
31 
32 // Replacing "m_audioBuffer + org_waud" with
33 // "&m_audioBuffer[org_waud]" should provide bounds
34 // checking with c++17 arrays.
35 #define WPOS (&m_audioBuffer[org_waud])
36 #define RPOS (&m_audioBuffer[m_raud])
37 #define ABUF (&m_audioBuffer[0])
38 #define STST soundtouch::SAMPLETYPE
39 #define AOALIGN(x) (((long)&(x) + 15) & ~0xf);
40 
41 // 1,2,5 and 7 channels are currently valid for upmixing if required
42 #define UPMIX_CHANNEL_MASK ((1<<1)|(1<<2)|(1<<5)|1<<7)
43 #define IS_VALID_UPMIX_CHANNEL(ch) ((1 << (ch)) & UPMIX_CHANNEL_MASK)
44 
46 {
47  switch(q)
48  {
49  case QUALITY_DISABLED: return "disabled";
50  case QUALITY_LOW: return "low";
51  case QUALITY_MEDIUM: return "medium";
52  case QUALITY_HIGH: return "high";
53  default: return "unknown";
54  }
55 }
56 
58  MThread("AudioOutputBase"),
59  // protected
60  m_mainDevice(settings.GetMainDevice()),
61  m_passthruDevice(settings.GetPassthruDevice()),
62  m_source(settings.m_source),
63  m_setInitialVol(settings.m_setInitialVol)
64 {
65  m_srcIn = m_srcInBuf.data();
66 
67  if (m_mainDevice.startsWith("AudioTrack:"))
68  m_usesSpdif = false;
69  // Handle override of SRC quality settings
70  if (gCoreContext->GetBoolSetting("SRCQualityOverride", false))
71  {
73  // Extra test to keep backward compatibility with earlier SRC setting
76 
77  VBAUDIO(QString("SRC quality = %1").arg(quality_string(m_srcQuality)));
78  }
79 }
80 
87 {
88  if (!m_killAudio)
89  VBERROR("Programmer Error: "
90  "~AudioOutputBase called, but KillAudio has not been called!");
91 
92  // We got this from a subclass, delete it
93  delete m_outputSettings;
94  delete m_outputSettingsRaw;
96  {
99  }
100 
101  if (m_kAudioSRCOutputSize > 0)
102  delete[] m_srcOut;
103 
104 #ifndef NDEBUG
105  assert(m_memoryCorruptionTest0 == 0xdeadbeef);
106  assert(m_memoryCorruptionTest1 == 0xdeadbeef);
107  assert(m_memoryCorruptionTest2 == 0xdeadbeef);
108  assert(m_memoryCorruptionTest3 == 0xdeadbeef);
109 #else
110  Q_UNUSED(m_memoryCorruptionTest0);
111  Q_UNUSED(m_memoryCorruptionTest1);
112  Q_UNUSED(m_memoryCorruptionTest2);
113  Q_UNUSED(m_memoryCorruptionTest3);
114 #endif
115 }
116 
118 {
119  if (settings.m_custom)
120  {
121  // got a custom audio report already, use it
122  // this was likely provided by the AudioTest utility
124  *m_outputSettings = *settings.m_custom;
128  return;
129  }
130 
131  // Ask the subclass what we can send to the device
134 
138 
140  gCoreContext->GetBoolSetting("AudioDefaultUpmix", false) :
141  false;
142  if (settings.m_upmixer == 1) // music, upmixer off
143  m_upmixDefault = false;
144  else if (settings.m_upmixer == 2) // music, upmixer on
145  m_upmixDefault = true;
146 }
147 
154 {
155  // If we've already checked the port, use the cache
156  // version instead
157  if (!m_discreteDigital || !digital)
158  {
159  digital = false;
161  return m_outputSettingsRaw;
162  }
165 
166  AudioOutputSettings* aosettings = GetOutputSettings(digital);
167  if (aosettings)
168  aosettings->GetCleaned();
169  else
170  aosettings = new AudioOutputSettings(true);
171 
172  if (digital)
173  return (m_outputSettingsDigitalRaw = aosettings);
174  return (m_outputSettingsRaw = aosettings);
175 }
176 
183 {
184  if (!m_discreteDigital || !digital)
185  {
186  digital = false;
187  if (m_outputSettings)
188  return m_outputSettings;
189  }
190  else if (m_outputSettingsDigital)
192 
193  auto* aosettings = new AudioOutputSettings;
194 
195  *aosettings = *GetOutputSettingsCleaned(digital);
196  aosettings->GetUsers();
197 
198  if (digital)
199  return (m_outputSettingsDigital = aosettings);
200  return (m_outputSettings = aosettings);
201 }
202 
206 bool AudioOutputBase::CanPassthrough(int samplerate, int channels,
207  AVCodecID codec, int profile) const
208 {
210  bool ret = !(m_internalVol && SWVolume());
211 
212  switch(codec)
213  {
214  case AV_CODEC_ID_AC3:
215  arg = FEATURE_AC3;
216  break;
217  case AV_CODEC_ID_DTS:
218  switch(profile)
219  {
220  case FF_PROFILE_DTS:
221  case FF_PROFILE_DTS_ES:
222  case FF_PROFILE_DTS_96_24:
223  arg = FEATURE_DTS;
224  break;
225  case FF_PROFILE_DTS_HD_HRA:
226  case FF_PROFILE_DTS_HD_MA:
227  arg = FEATURE_DTSHD;
228  break;
229  default:
230  break;
231  }
232  break;
233  case AV_CODEC_ID_EAC3:
234  arg = FEATURE_EAC3;
235  break;
236  case AV_CODEC_ID_TRUEHD:
238  break;
239  default:
240  arg = FEATURE_NONE;
241  break;
242  }
243  // we can't passthrough any other codecs than those defined above
246  ret &= m_outputSettingsDigital->IsSupportedRate(samplerate);
247  // if we must resample to 48kHz ; we can't passthrough
248  ret &= !((samplerate != 48000) &&
249  gCoreContext->GetBoolSetting("Audio48kOverride", false));
250  // Don't know any cards that support spdif clocked at < 44100
251  // Some US cable transmissions have 2ch 32k AC-3 streams
252  ret &= samplerate >= 44100;
253  if (!ret)
254  return false;
255  // Will passthrough if surround audio was defined. Amplifier will
256  // do the downmix if required
257  bool willupmix = m_maxChannels >= 6 && (channels <= 2 && m_upmixDefault);
258  ret &= !willupmix;
259  // unless audio is configured for stereo. We can passthrough otherwise
260  ret |= m_maxChannels == 2;
261 
262  return ret;
263 }
264 
269 {
270  if (rate > 0)
271  m_sourceBitRate = rate;
272 }
273 
279 void AudioOutputBase::SetStretchFactorLocked(float lstretchfactor)
280 {
281  if (m_stretchFactor == lstretchfactor && m_pSoundStretch)
282  return;
283 
284  m_stretchFactor = lstretchfactor;
285 
286  int channels = m_needsUpmix || m_needsDownmix ?
288  if (channels < 1 || channels > 8 || !m_configureSucceeded)
289  return;
290 
291  bool willstretch = m_stretchFactor < 0.99F || m_stretchFactor > 1.01F;
292  m_effStretchFactor = lroundf(100000.0F * lstretchfactor);
293 
294  if (m_pSoundStretch)
295  {
296  if (!willstretch && m_forcedProcessing)
297  {
298  m_forcedProcessing = false;
299  m_processing = false;
300  delete m_pSoundStretch;
301  m_pSoundStretch = nullptr;
302  VBGENERAL(QString("Cancelling time stretch"));
304  m_waud = m_raud = 0;
305  m_resetActive.Ref();
306  }
307  else
308  {
309  VBGENERAL(QString("Changing time stretch to %1")
310  .arg(m_stretchFactor));
311  m_pSoundStretch->setTempo(m_stretchFactor);
312  }
313  }
314  else if (willstretch)
315  {
316  VBGENERAL(QString("Using time stretch %1").arg(m_stretchFactor));
317  m_pSoundStretch = new soundtouch::SoundTouch();
318  m_pSoundStretch->setSampleRate(m_sampleRate);
319  m_pSoundStretch->setChannels(channels);
320  m_pSoundStretch->setTempo(m_stretchFactor);
321 #if ARCH_ARM || defined(Q_OS_ANDROID)
322  // use less demanding settings for Raspberry pi
323  m_pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 82);
324  m_pSoundStretch->setSetting(SETTING_USE_AA_FILTER, 0);
325  m_pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, 1);
326 #else
327  m_pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
328 #endif
329  /* If we weren't already processing we need to turn on float conversion
330  adjust sample and frame sizes accordingly and dump the contents of
331  the audiobuffer */
332  if (!m_processing)
333  {
334  m_processing = true;
335  m_forcedProcessing = true;
340  m_waud = m_raud = 0;
341  m_resetActive.Ref();
343  m_pauseAudio = true;
344  m_actuallyPaused = false;
345  m_unpauseWhenReady = true;
346  }
347  }
348 }
349 
353 void AudioOutputBase::SetStretchFactor(float lstretchfactor)
354 {
355  QMutexLocker lock(&m_audioBufLock);
356  SetStretchFactorLocked(lstretchfactor);
357 }
358 
363 {
364  return m_stretchFactor;
365 }
366 
371 {
372  return m_needsUpmix && m_upmixer;
373 }
374 
379 {
380  // Can only upmix from mono/stereo to 6 ch
381  if (m_maxChannels == 2 || m_sourceChannels > 2)
382  return false;
383 
385 
388  m_upmixDefault ? false : m_passthru);
389  Reconfigure(settings);
390  return IsUpmixing();
391 }
392 
397 {
398  return m_sourceChannels <= 2 && m_maxChannels > 2;
399 }
400 
401 /*
402  * Setup samplerate and number of channels for passthrough
403  * Create SPDIF encoder and true if successful
404  */
405 bool AudioOutputBase::SetupPassthrough(AVCodecID codec, int codec_profile,
406  int &samplerate_tmp, int &channels_tmp)
407 {
408  if (codec == AV_CODEC_ID_DTS &&
410  {
411  // We do not support DTS-HD bitstream so force extraction of the
412  // DTS core track instead
413  codec_profile = FF_PROFILE_DTS;
414  }
416  codec, codec_profile,
417  samplerate_tmp, channels_tmp,
419  VBAUDIO("Setting " + log + " passthrough");
420 
421  delete m_spdifEnc;
422 
423  // No spdif encoder needed for certain devices
424  if (m_usesSpdif)
425  m_spdifEnc = new SPDIFEncoder("spdif", codec);
426  else
427  m_spdifEnc = nullptr;
428  if (m_spdifEnc && m_spdifEnc->Succeeded() && codec == AV_CODEC_ID_DTS)
429  {
430  switch(codec_profile)
431  {
432  case FF_PROFILE_DTS:
433  case FF_PROFILE_DTS_ES:
434  case FF_PROFILE_DTS_96_24:
436  break;
437  case FF_PROFILE_DTS_HD_HRA:
438  case FF_PROFILE_DTS_HD_MA:
439  m_spdifEnc->SetMaxHDRate(samplerate_tmp * channels_tmp / 2);
440  break;
441  }
442  }
443 
444  if (m_spdifEnc && !m_spdifEnc->Succeeded())
445  {
446  delete m_spdifEnc;
447  m_spdifEnc = nullptr;
448  return false;
449  }
450  return true;
451 }
452 
454 {
455  if (digital)
457  return m_outputSettings;
458 }
459 
465 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
466 {
467  AudioSettings settings = orig_settings;
468  int lsource_channels = settings.m_channels;
469  int lconfigured_channels = m_configuredChannels;
470  bool lneeds_upmix = false;
471  bool lneeds_downmix = false;
472  bool lreenc = false;
473  bool lenc = false;
474 
475  if (!settings.m_usePassthru)
476  {
477  // Do we upmix stereo or mono?
478  lconfigured_channels =
479  (m_upmixDefault && lsource_channels <= 2) ? 6 : lsource_channels;
480  bool cando_channels =
481  m_outputSettings->IsSupportedChannels(lconfigured_channels);
482 
483  // check if the number of channels could be transmitted via AC3 encoding
484 #ifndef DISABLE_AC3_ENCODE
487  lconfigured_channels > 2 && lconfigured_channels <= 6);
488 #endif
489  if (!lenc && !cando_channels)
490  {
491  // if hardware doesn't support source audio configuration
492  // we will upmix/downmix to what we can
493  // (can safely assume hardware supports stereo)
494  switch (lconfigured_channels)
495  {
496  case 7:
497  lconfigured_channels = 8;
498  break;
499  case 8:
500  case 5:
501  lconfigured_channels = 6;
502  break;
503  case 6:
504  case 4:
505  case 3:
506  case 2: //Will never happen
507  lconfigured_channels = 2;
508  break;
509  case 1:
510  lconfigured_channels = m_upmixDefault ? 6 : 2;
511  break;
512  default:
513  lconfigured_channels = 2;
514  break;
515  }
516  }
517  // Make sure we never attempt to output more than what we can
518  // the upmixer can only upmix to 6 channels when source < 6
519  if (lsource_channels <= 6)
520  lconfigured_channels = std::min(lconfigured_channels, 6);
521  lconfigured_channels = std::min(lconfigured_channels, m_maxChannels);
522  /* Encode to AC-3 if we're allowed to passthru but aren't currently
523  and we have more than 2 channels but multichannel PCM is not
524  supported or if the device just doesn't support the number of
525  channels */
526 #ifndef DISABLE_AC3_ENCODE
529  lconfigured_channels > 2) ||
530  !m_outputSettings->IsSupportedChannels(lconfigured_channels));
531  /* Might we reencode a bitstream that's been decoded for timestretch?
532  If the device doesn't support the number of channels - see below */
534  (settings.m_codec == AV_CODEC_ID_AC3 ||
535  settings.m_codec == AV_CODEC_ID_DTS))
536  {
537  lreenc = true;
538  }
539 #endif
540  // Enough channels? Upmix if not, but only from mono/stereo/5.0 to 5.1
541  if (IS_VALID_UPMIX_CHANNEL(settings.m_channels) &&
542  settings.m_channels < lconfigured_channels)
543  {
544  VBAUDIO(QString("Needs upmix from %1 -> %2 channels")
545  .arg(settings.m_channels).arg(lconfigured_channels));
546  settings.m_channels = lconfigured_channels;
547  lneeds_upmix = true;
548  }
549  else if (settings.m_channels > lconfigured_channels)
550  {
551  VBAUDIO(QString("Needs downmix from %1 -> %2 channels")
552  .arg(settings.m_channels).arg(lconfigured_channels));
553  settings.m_channels = lconfigured_channels;
554  lneeds_downmix = true;
555  }
556  }
557 
558  ClearError();
559 
560  bool general_deps = true;
561 
562  /* Set samplerate_tmp and channels_tmp to appropriate values
563  if passing through */
564  int samplerate_tmp = 0;
565  int channels_tmp = 0;
566  if (settings.m_usePassthru)
567  {
568  samplerate_tmp = settings.m_sampleRate;
569  SetupPassthrough(settings.m_codec, settings.m_codecProfile,
570  samplerate_tmp, channels_tmp);
571  general_deps = m_sampleRate == samplerate_tmp && m_channels == channels_tmp;
572  general_deps &= m_format == m_outputFormat && m_format == FORMAT_S16;
573  }
574  else
575  {
576  general_deps =
577  settings.m_format == m_format && lsource_channels == m_sourceChannels;
578  }
579 
580  // Check if anything has changed
581  general_deps &=
582  settings.m_sampleRate == m_sourceSampleRate &&
583  settings.m_usePassthru == m_passthru &&
584  lconfigured_channels == m_configuredChannels &&
585  lneeds_upmix == m_needsUpmix && lreenc == m_reEnc &&
586  lneeds_downmix == m_needsDownmix;
587 
588  if (general_deps && m_configureSucceeded)
589  {
590  VBAUDIO("Reconfigure(): No change -> exiting");
591  // if passthrough, source channels may have changed
592  m_sourceChannels = lsource_channels;
593  return;
594  }
595 
596  KillAudio();
597 
598  QMutexLocker lock(&m_audioBufLock);
599  QMutexLocker lockav(&m_avsyncLock);
600 
601  m_waud = m_raud = 0;
604 
605  m_channels = settings.m_channels;
606  m_sourceChannels = lsource_channels;
607  m_reEnc = lreenc;
608  m_codec = settings.m_codec;
609  m_passthru = settings.m_usePassthru;
610  m_configuredChannels = lconfigured_channels;
611  m_needsUpmix = lneeds_upmix;
612  m_needsDownmix = lneeds_downmix;
613  m_format = m_outputFormat = settings.m_format;
615  m_enc = lenc;
616 
617  m_killAudio = m_pauseAudio = false;
618  m_wasPaused = true;
619 
620  // Don't try to do anything if audio hasn't been
621  // initialized yet (e.g. rubbish was provided)
622  if (m_sourceChannels <= 0 || m_format <= 0 || m_sampleRate <= 0)
623  {
624  SilentError(QString("Aborting Audio Reconfigure. ") +
625  QString("Invalid audio parameters ch %1 fmt %2 @ %3Hz")
627  return;
628  }
629 
630  VBAUDIO(QString("Original codec was %1, %2, %3 kHz, %4 channels")
631  .arg(ff_codec_id_string(m_codec))
633  .arg(m_sampleRate/1000)
634  .arg(m_sourceChannels));
635 
636  if (m_needsDownmix && m_sourceChannels > 8)
637  {
638  Error(QObject::tr("Aborting Audio Reconfigure. "
639  "Can't handle audio with more than 8 channels."));
640  return;
641  }
642 
643  VBAUDIO(QString("enc(%1), passthru(%2), features (%3) "
644  "configured_channels(%4), %5 channels supported(%6) "
645  "max_channels(%7)")
646  .arg(m_enc)
647  .arg(m_passthru)
650  .arg(m_channels)
651  .arg(OutputSettings(m_enc || m_passthru)->IsSupportedChannels(m_channels))
652  .arg(m_maxChannels));
653 
654  int dest_rate = 0;
655 
656  // Force resampling if we are encoding to AC3 and sr > 48k
657  // or if 48k override was checked in settings
658  if ((m_sampleRate != 48000 &&
659  gCoreContext->GetBoolSetting("Audio48kOverride", false)) ||
660  (m_enc && (m_sampleRate > 48000)))
661  {
662  VBAUDIO("Forcing resample to 48 kHz");
663  if (m_srcQuality < 0)
665  m_needResampler = true;
666  dest_rate = 48000;
667  }
668  // this will always be false for passthrough audio as
669  // CanPassthrough() already tested these conditions
670  else if ((m_needResampler =
671  !OutputSettings(m_enc || m_passthru)->IsSupportedRate(m_sampleRate)))
672  {
674  }
675 
677  {
678  m_sampleRate = dest_rate;
679 
680  VBGENERAL(QString("Resampling from %1 kHz to %2 kHz with quality %3")
681  .arg(settings.m_sampleRate/1000).arg(m_sampleRate/1000)
683 
685 
686  int error = 0;
687  m_srcCtx = src_new(2-m_srcQuality, chans, &error);
688  if (error)
689  {
690  Error(QObject::tr("Error creating resampler: %1")
691  .arg(src_strerror(error)));
692  m_srcCtx = nullptr;
693  return;
694  }
695 
696  m_srcData.src_ratio = (double)m_sampleRate / settings.m_sampleRate;
697  m_srcData.data_in = m_srcIn;
698  int newsize = (int)(kAudioSRCInputSize * m_srcData.src_ratio + 15)
699  & ~0xf;
700 
701  if (m_kAudioSRCOutputSize < newsize)
702  {
703  m_kAudioSRCOutputSize = newsize;
704  VBAUDIO(QString("Resampler allocating %1").arg(newsize));
705  delete[] m_srcOut;
706  m_srcOut = new float[m_kAudioSRCOutputSize];
707  }
708  m_srcData.data_out = m_srcOut;
709  m_srcData.output_frames = m_kAudioSRCOutputSize / chans;
710  m_srcData.end_of_input = 0;
711  }
712 
713  if (m_enc)
714  {
715  if (m_reEnc)
716  VBAUDIO("Reencoding decoded AC-3/DTS to AC-3");
717 
718  VBAUDIO(QString("Creating AC-3 Encoder with sr = %1, ch = %2")
720 
722  if (!m_encoder->Init(AV_CODEC_ID_AC3, 448000, m_sampleRate,
724  {
725  Error(QObject::tr("AC-3 encoder initialization failed"));
726  delete m_encoder;
727  m_encoder = nullptr;
728  m_enc = false;
729  // upmixing will fail if we needed the encoder
730  m_needsUpmix = false;
731  }
732  }
733 
734  if (m_passthru)
735  {
736  //AC3, DTS, DTS-HD MA and TrueHD all use 16 bits samples
737  m_channels = channels_tmp;
738  m_sampleRate = samplerate_tmp;
742  }
743  else
744  {
747  }
748 
749  // Turn on float conversion?
751  m_stretchFactor != 1.0F || (m_internalVol && SWVolume()) ||
752  (m_enc && m_outputFormat != FORMAT_S16) ||
753  !OutputSettings(m_enc || m_passthru)->IsSupportedFormat(m_outputFormat))
754  {
755  VBAUDIO("Audio processing enabled");
756  m_processing = true;
757  if (m_enc)
758  m_outputFormat = FORMAT_S16; // Output s16le for AC-3 encoder
759  else
761  }
762 
764  sizeof(float) : AudioOutputSettings::SampleSize(m_format);
766 
767  if (m_enc)
768  m_channels = 2; // But only post-encoder
769 
772 
773  VBGENERAL(
774  QString("Opening audio device '%1' ch %2(%3) sr %4 sf %5 reenc %6")
777 
780  m_effDsp = m_sampleRate * 100;
781 
782  // Actually do the device specific open call
783  if (!OpenDevice())
784  {
785  if (GetError().isEmpty())
786  Error(QObject::tr("Aborting reconfigure"));
787  else
788  VBGENERAL("Aborting reconfigure");
789  m_configureSucceeded = false;
790  return;
791  }
792 
793  VBAUDIO(QString("Audio fragment size: %1").arg(m_fragmentSize));
794 
795  // Only used for software volume
797  {
798  VBAUDIO("Software volume enabled");
799  m_volumeControl = gCoreContext->GetSetting("MixerControl", "PCM");
800  m_volumeControl += "MixerVolume";
802  }
803 
807 
809  {
813  VBAUDIO(QString("Create %1 quality upmixer done")
815  }
816 
817  VBAUDIO(QString("Audio Stretch Factor: %1").arg(m_stretchFactor));
819 
820  // Setup visualisations, zero the visualisations buffers
821  prepareVisuals();
822 
823  if (m_unpauseWhenReady)
825 
826  m_configureSucceeded = true;
827 
829 
830  VBAUDIO("Ending Reconfigure()");
831 }
832 
834 {
836  return true;
837 
838  start();
839  m_audioThreadExists = true;
840 
841  return true;
842 }
843 
844 
846 {
848  {
849  wait();
850  m_audioThreadExists = false;
851  }
852 }
853 
858 {
859  m_killAudioLock.lock();
860 
861  VBAUDIO("Killing AudioOutputDSP");
862  m_killAudio = true;
864  QMutexLocker lock(&m_audioBufLock);
865 
866  if (m_pSoundStretch)
867  {
868  delete m_pSoundStretch;
869  m_pSoundStretch = nullptr;
871  m_stretchFactor = 1.0F;
872  }
873 
874  if (m_encoder)
875  {
876  delete m_encoder;
877  m_encoder = nullptr;
878  }
879 
880  if (m_upmixer)
881  {
882  delete m_upmixer;
883  m_upmixer = nullptr;
884  }
885 
886  if (m_srcCtx)
887  {
888  src_delete(m_srcCtx);
889  m_srcCtx = nullptr;
890  }
891 
892  m_needsUpmix = m_needResampler = m_enc = false;
893 
894  CloseDevice();
895 
896  m_killAudioLock.unlock();
897 }
898 
899 void AudioOutputBase::Pause(bool paused)
900 {
901  if (!paused && m_unpauseWhenReady)
902  return;
903  VBAUDIO(QString("Pause %1").arg(paused));
904  if (m_pauseAudio != paused)
906  m_pauseAudio = paused;
907  m_unpauseWhenReady = false;
908  m_actuallyPaused = false;
909 }
910 
912 {
913  Reset();
914  Pause(true);
915  m_unpauseWhenReady = true;
916 }
917 
922 {
923  QMutexLocker lock(&m_audioBufLock);
924  QMutexLocker lockav(&m_avsyncLock);
925 
927  if (m_encoder)
928  {
929  m_waud = m_raud = 0; // empty ring buffer
930  m_audioBuffer.fill(0);
931  }
932  else
933  {
934  m_waud = m_raud; // empty ring buffer
935  }
936  m_resetActive.Ref();
937  m_currentSeconds = -1;
939  m_unpauseWhenReady = false;
940  // clear any state that could remember previous audio in any active filters
941  if (m_needsUpmix && m_upmixer)
942  m_upmixer->flush();
943  if (m_pSoundStretch)
944  m_pSoundStretch->clear();
945  if (m_encoder)
946  m_encoder->clear();
947 
948  // Setup visualisations, zero the visualisations buffers
949  prepareVisuals();
950 }
951 
958 void AudioOutputBase::SetTimecode(int64_t timecode)
959 {
960  m_audbufTimecode = m_audioTime = timecode;
961  m_framesBuffered = (timecode * m_sourceSampleRate) / 1000;
962 }
963 
970 void AudioOutputBase::SetEffDsp(int dsprate)
971 {
972  VBAUDIO(QString("SetEffDsp: %1").arg(dsprate));
973  m_effDsp = dsprate;
974 }
975 
979 inline int AudioOutputBase::audiolen() const
980 {
981  if (m_waud >= m_raud)
982  return m_waud - m_raud;
983  return kAudioRingBufferSize - (m_raud - m_waud);
984 }
985 
990 {
991  return kAudioRingBufferSize - audiolen() - 1;
992  /* There is one wasted byte in the buffer. The case where waud = raud is
993  interpreted as an empty buffer, so the fullest the buffer can ever
994  be is kAudioRingBufferSize - 1. */
995 }
996 
1005 {
1007  return audiolen();
1009 }
1010 
1015 {
1017  return 0;
1018 
1019  // output bits per 10 frames
1020  int64_t obpf = 0;
1021 
1022  if (m_passthru && !usesSpdif())
1023  obpf = m_sourceBitRate * 10 / m_sourceSampleRate;
1024  else if (m_enc && !usesSpdif())
1025  {
1026  // re-encode bitrate is hardcoded at 448000
1027  obpf = 448000 * 10 / m_sourceSampleRate;
1028  }
1029  else
1030  obpf = static_cast<int64_t>(m_outputBytesPerFrame) * 80;
1031 
1032  /* We want to calculate 'audiotime', which is the timestamp of the audio
1033  Which is leaving the sound card at this instant.
1034 
1035  We use these variables:
1036 
1037  'effdsp' is 100 * frames/sec
1038 
1039  'audbuf_timecode' is the timecode in milliseconds of the
1040  audio that has just been written into the buffer.
1041 
1042  'eff_stretchfactor' is stretch factor * 100,000
1043 
1044  'totalbuffer' is the total # of bytes in our audio buffer, and the
1045  sound card's buffer. */
1046 
1047 
1048  QMutexLocker lockav(&m_avsyncLock);
1049 
1050  int64_t soundcard_buffer = GetBufferedOnSoundcard(); // bytes
1051 
1052  /* audioready tells us how many bytes are in audiobuffer
1053  scaled appropriately if output format != internal format */
1054  int64_t main_buffer = audioready();
1055 
1056  int64_t oldaudiotime = m_audioTime;
1057 
1058  /* timecode is the stretch adjusted version
1059  of major post-stretched buffer contents
1060  processing latencies are catered for in AddData/SetAudiotime
1061  to eliminate race */
1062 
1063  m_audioTime = m_audbufTimecode - (m_effDsp && obpf ?
1064  ((main_buffer + soundcard_buffer) * int64_t(m_effStretchFactor)
1065  * 80 / int64_t(m_effDsp) / obpf) : 0);
1066 
1067  /* audiotime should never go backwards, but we might get a negative
1068  value if GetBufferedOnSoundcard() isn't updated by the driver very
1069  quickly (e.g. ALSA) */
1070  if (m_audioTime < oldaudiotime)
1071  m_audioTime = oldaudiotime;
1072 
1073  VBAUDIOTS(QString("GetAudiotime audt=%1 abtc=%2 mb=%3 sb=%4 tb=%5 "
1074  "sr=%6 obpf=%7 bpf=%8 esf=%9 edsp=%10 sbr=%11")
1075  .arg(m_audioTime).arg(m_audbufTimecode) // 1, 2
1076  .arg(main_buffer) // 3
1077  .arg(soundcard_buffer) // 4
1078  .arg(main_buffer+soundcard_buffer) // 5
1079  .arg(m_sampleRate).arg(obpf) // 6, 7
1080  .arg(m_bytesPerFrame) // 8
1081  .arg(m_effStretchFactor) // 9
1082  .arg(m_effDsp).arg(m_sourceBitRate) // 10, 11
1083  );
1084 
1085  return m_audioTime;
1086 }
1087 
1093 void AudioOutputBase::SetAudiotime(int frames, int64_t timecode)
1094 {
1095  int64_t processframes_stretched = 0;
1096  int64_t processframes_unstretched = 0;
1097  int64_t old_audbuf_timecode = m_audbufTimecode;
1098 
1099  if (!m_configureSucceeded)
1100  return;
1101 
1102  if (m_needsUpmix && m_upmixer)
1103  processframes_unstretched -= m_upmixer->frameLatency();
1104 
1105  if (m_pSoundStretch)
1106  {
1107  processframes_unstretched -= m_pSoundStretch->numUnprocessedSamples();
1108  processframes_stretched -= m_pSoundStretch->numSamples();
1109  }
1110 
1111  if (m_encoder)
1112  {
1113  processframes_stretched -= m_encoder->Buffered();
1114  }
1115 
1117  timecode + (m_effDsp ? ((frames + processframes_unstretched) * 100000 +
1118  (processframes_stretched * m_effStretchFactor)
1119  ) / m_effDsp : 0);
1120 
1121  // check for timecode wrap and reset audiotime if detected
1122  // timecode will always be monotonic asc if not seeked and reset
1123  // happens if seek or pause happens
1124  if (m_audbufTimecode < old_audbuf_timecode)
1125  m_audioTime = 0;
1126 
1127  VBAUDIOTS(QString("SetAudiotime atc=%1 tc=%2 f=%3 pfu=%4 pfs=%5")
1129  .arg(timecode)
1130  .arg(frames)
1131  .arg(processframes_unstretched)
1132  .arg(processframes_stretched));
1133 #ifdef AUDIOTSTESTING
1134  GetAudiotime();
1135 #endif
1136 }
1137 
1144 {
1145  int64_t ret = m_audbufTimecode - GetAudiotime();
1146  // Pulse can give us values that make this -ve
1147  if (ret < 0)
1148  return 0;
1149  return ret;
1150 }
1151 
1155 void AudioOutputBase::SetSWVolume(int new_volume, bool save)
1156 {
1157  m_volume = new_volume;
1158  if (save && m_volumeControl != nullptr)
1160 }
1161 
1166 {
1167  return m_volume;
1168 }
1169 
1179 {
1180  int bpf = m_bytesPerFrame;
1181  int len = frames * bpf;
1182  int afree = audiofree();
1183 
1184  if (len <= afree)
1185  return len;
1186 
1187  VBERROR(QString("Audio buffer overflow, %1 frames lost!")
1188  .arg(frames - (afree / bpf)));
1189 
1190  frames = afree / bpf;
1191  len = frames * bpf;
1192 
1193  if (!m_srcCtx)
1194  return len;
1195 
1196  int error = src_reset(m_srcCtx);
1197  if (error)
1198  {
1199  VBERROR(QString("Error occurred while resetting resampler: %1")
1200  .arg(src_strerror(error)));
1201  m_srcCtx = nullptr;
1202  }
1203 
1204  return len;
1205 }
1206 
1213 int AudioOutputBase::CopyWithUpmix(char *buffer, int frames, uint &org_waud)
1214 {
1215  int len = CheckFreeSpace(frames);
1216  int bdiff = kAudioRingBufferSize - org_waud;
1217  int bpf = m_bytesPerFrame;
1218  int off = 0;
1219 
1220  if (!m_needsUpmix)
1221  {
1222  int num = len;
1223 
1224  if (bdiff <= num)
1225  {
1226  memcpy(WPOS, buffer, bdiff);
1227  num -= bdiff;
1228  off = bdiff;
1229  org_waud = 0;
1230  }
1231  if (num > 0)
1232  memcpy(WPOS, buffer + off, num);
1233  org_waud = (org_waud + num) % kAudioRingBufferSize;
1234  return len;
1235  }
1236 
1237  // Convert mono to stereo as most devices can't accept mono
1238  if (!m_upmixer)
1239  {
1240  // we're always in the case
1241  // m_configuredChannels == 2 && m_sourceChannels == 1
1242  int bdFrames = bdiff / bpf;
1243  if (bdFrames <= frames)
1244  {
1245  AudioOutputUtil::MonoToStereo(WPOS, buffer, bdFrames);
1246  frames -= bdFrames;
1247  off = bdFrames * sizeof(float); // 1 channel of floats
1248  org_waud = 0;
1249  }
1250  if (frames > 0)
1251  AudioOutputUtil::MonoToStereo(WPOS, buffer + off, frames);
1252 
1253  org_waud = (org_waud + frames * bpf) % kAudioRingBufferSize;
1254  return len;
1255  }
1256 
1257  // Upmix to 6ch via FreeSurround
1258  // Calculate frame size of input
1259  off = m_processing ? sizeof(float) : AudioOutputSettings::SampleSize(m_format);
1260  off *= m_sourceChannels;
1261 
1262  int i = 0;
1263  len = 0;
1264  while (i < frames)
1265  {
1266  i += m_upmixer->putFrames(buffer + i * off, frames - i, m_sourceChannels);
1267  int nFrames = m_upmixer->numFrames();
1268  if (!nFrames)
1269  continue;
1270 
1271  len += CheckFreeSpace(nFrames);
1272 
1273  int bdFrames = (kAudioRingBufferSize - org_waud) / bpf;
1274  if (bdFrames < nFrames)
1275  {
1276  if ((org_waud % bpf) != 0)
1277  {
1278  VBERROR(QString("Upmixing: org_waud = %1 (bpf = %2)")
1279  .arg(org_waud)
1280  .arg(bpf));
1281  }
1282  m_upmixer->receiveFrames((float *)(WPOS), bdFrames);
1283  nFrames -= bdFrames;
1284  org_waud = 0;
1285  }
1286  if (nFrames > 0)
1287  m_upmixer->receiveFrames((float *)(WPOS), nFrames);
1288 
1289  org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
1290  }
1291  return len;
1292 }
1293 
1299 bool AudioOutputBase::AddFrames(void *in_buffer, int in_frames,
1300  int64_t timecode)
1301 {
1302  return AddData(in_buffer, in_frames * m_sourceBytesPerFrame, timecode,
1303  in_frames);
1304 }
1305 
1311 bool AudioOutputBase::AddData(void *in_buffer, int in_len,
1312  int64_t timecode, int /*in_frames*/)
1313 {
1314  int frames = in_len / m_sourceBytesPerFrame;
1315  int bpf = m_bytesPerFrame;
1316  int len = in_len;
1317  bool music = false;
1318 
1319  if (!m_configureSucceeded)
1320  {
1321  LOG(VB_GENERAL, LOG_ERR, "AddData called with audio framework not "
1322  "initialised");
1323  m_lengthLastData = 0;
1324  return false;
1325  }
1326 
1327  /* See if we're waiting for new samples to be buffered before we unpause
1328  post channel change, seek, etc. Wait for 4 fragments to be buffered */
1330  {
1331  m_unpauseWhenReady = false;
1332  Pause(false);
1333  }
1334 
1335  // Don't write new samples if we're resetting the buffer or reconfiguring
1336  QMutexLocker lock(&m_audioBufLock);
1337 
1338  uint org_waud = m_waud;
1339  int afree = audiofree();
1340  int used = kAudioRingBufferSize - afree;
1341 
1342  if (m_passthru && m_spdifEnc)
1343  {
1344  if (m_processing)
1345  {
1346  /*
1347  * We shouldn't encounter this case, but it can occur when
1348  * timestretch just got activated. So we will just drop the
1349  * data
1350  */
1351  LOG(VB_AUDIO, LOG_INFO,
1352  "Passthrough activated with audio processing. Dropping audio");
1353  return false;
1354  }
1355  // mux into an IEC958 packet
1356  m_spdifEnc->WriteFrame((unsigned char *)in_buffer, len);
1357  len = m_spdifEnc->GetProcessedSize();
1358  if (len > 0)
1359  {
1360  in_buffer = m_spdifEnc->GetProcessedBuffer();
1361  m_spdifEnc->Reset();
1362  frames = len / m_sourceBytesPerFrame;
1363  }
1364  else
1365  frames = 0;
1366  }
1367  m_lengthLastData = (int64_t)
1368  ((double)(len * 1000) / (m_sourceSampleRate * m_sourceBytesPerFrame));
1369 
1370  VBAUDIOTS(QString("AddData frames=%1, bytes=%2, used=%3, free=%4, "
1371  "timecode=%5 needsupmix=%6")
1372  .arg(frames).arg(len).arg(used).arg(afree).arg(timecode)
1373  .arg(m_needsUpmix));
1374 
1375  // Mythmusic doesn't give us timestamps
1376  if (timecode < 0)
1377  {
1378  timecode = (m_framesBuffered * 1000) / m_sourceSampleRate;
1379  m_framesBuffered += frames;
1380  music = true;
1381  }
1382 
1383  if (hasVisual())
1384  {
1385  // Send original samples to any attached visualisations
1386  dispatchVisual((uchar *)in_buffer, len, timecode, m_sourceChannels,
1388  }
1389 
1390  // Calculate amount of free space required in ringbuffer
1391  if (m_processing)
1392  {
1393  int sampleSize = AudioOutputSettings::SampleSize(m_format);
1394  if (sampleSize <= 0)
1395  {
1396  // Would lead to division by zero (or unexpected results if negative)
1397  VBERROR("Sample size is <= 0, AddData returning false");
1398  return false;
1399  }
1400 
1401  // Final float conversion space requirement
1402  len = sizeof(m_srcInBuf[0]) / sampleSize * len;
1403 
1404  // Account for changes in number of channels
1405  if (m_needsDownmix)
1406  len = (len * m_configuredChannels ) / m_sourceChannels;
1407 
1408  // Check we have enough space to write the data
1409  if (m_needResampler && m_srcCtx)
1410  len = lround(ceil(static_cast<double>(len) * m_srcData.src_ratio));
1411 
1412  if (m_needsUpmix)
1413  len = (len * m_configuredChannels ) / m_sourceChannels;
1414 
1415  // Include samples in upmix buffer that may be flushed
1416  if (m_needsUpmix && m_upmixer)
1417  len += m_upmixer->numUnprocessedFrames() * bpf;
1418 
1419  // Include samples in soundstretch buffers
1420  if (m_pSoundStretch)
1421  len += (m_pSoundStretch->numUnprocessedSamples() +
1422  (int)(m_pSoundStretch->numSamples() / m_stretchFactor)) * bpf;
1423  }
1424 
1425  if (len > afree)
1426  {
1427  VBERROR("Buffer is full, AddData returning false");
1428  return false; // would overflow
1429  }
1430 
1431  int frames_remaining = frames;
1432  int frames_final = 0;
1433  int maxframes = (kAudioSRCInputSize / m_sourceChannels) & ~0xf;
1434  int offset = 0;
1435 
1436  while(frames_remaining > 0)
1437  {
1438  void *buffer = (char *)in_buffer + offset;
1439  frames = frames_remaining;
1440  len = frames * m_sourceBytesPerFrame;
1441 
1442  if (m_processing)
1443  {
1444  if (frames > maxframes)
1445  {
1446  frames = maxframes;
1447  len = frames * m_sourceBytesPerFrame;
1448  offset += len;
1449  }
1450  // Convert to floats
1451  AudioOutputUtil::toFloat(m_format, m_srcIn, buffer, len);
1452  }
1453 
1454  frames_remaining -= frames;
1455 
1456  // Perform downmix if necessary
1457  if (m_needsDownmix)
1458  {
1461  m_srcIn, m_srcIn, frames) < 0)
1462  VBERROR("Error occurred while downmixing");
1463  }
1464 
1465  // Resample if necessary
1466  if (m_needResampler && m_srcCtx)
1467  {
1468  m_srcData.input_frames = frames;
1469  int error = src_process(m_srcCtx, &m_srcData);
1470 
1471  if (error)
1472  VBERROR(QString("Error occurred while resampling audio: %1")
1473  .arg(src_strerror(error)));
1474 
1475  buffer = m_srcOut;
1476  frames = m_srcData.output_frames_gen;
1477  }
1478  else if (m_processing)
1479  buffer = m_srcIn;
1480 
1481  /* we want the timecode of the last sample added but we are given the
1482  timecode of the first - add the time in ms that the frames added
1483  represent */
1484 
1485  // Copy samples into audiobuffer, with upmix if necessary
1486  if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
1487  {
1488  continue;
1489  }
1490 
1491  frames = len / bpf;
1492  frames_final += frames;
1493 
1494  int bdiff = kAudioRingBufferSize - m_waud;
1495  if ((len % bpf) != 0 && bdiff < len)
1496  {
1497  VBERROR(QString("AddData: Corruption likely: len = %1 (bpf = %2)")
1498  .arg(len)
1499  .arg(bpf));
1500  }
1501  if ((bdiff % bpf) != 0 && bdiff < len)
1502  {
1503  VBERROR(QString("AddData: Corruption likely: bdiff = %1 (bpf = %2)")
1504  .arg(bdiff)
1505  .arg(bpf));
1506  }
1507 
1508  if (m_pSoundStretch)
1509  {
1510  // does not change the timecode, only the number of samples
1511  org_waud = m_waud;
1512  int bdFrames = bdiff / bpf;
1513 
1514  if (bdiff < len)
1515  {
1516  m_pSoundStretch->putSamples((STST *)(WPOS), bdFrames);
1517  m_pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf);
1518  }
1519  else
1520  m_pSoundStretch->putSamples((STST *)(WPOS), frames);
1521 
1522  int nFrames = m_pSoundStretch->numSamples();
1523  if (nFrames > frames)
1524  CheckFreeSpace(nFrames);
1525 
1526  len = nFrames * bpf;
1527 
1528  if (nFrames > bdFrames)
1529  {
1530  nFrames -= m_pSoundStretch->receiveSamples((STST *)(WPOS),
1531  bdFrames);
1532  org_waud = 0;
1533  }
1534  if (nFrames > 0)
1535  nFrames = m_pSoundStretch->receiveSamples((STST *)(WPOS),
1536  nFrames);
1537 
1538  org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
1539  }
1540 
1541  if (m_internalVol && SWVolume())
1542  {
1543  org_waud = m_waud;
1544  int num = len;
1545 
1546  if (bdiff <= num)
1547  {
1549  music, m_needsUpmix && m_upmixer);
1550  num -= bdiff;
1551  org_waud = 0;
1552  }
1553  if (num > 0)
1555  music, m_needsUpmix && m_upmixer);
1556  org_waud = (org_waud + num) % kAudioRingBufferSize;
1557  }
1558 
1559  if (m_encoder)
1560  {
1561  org_waud = m_waud;
1562  int to_get = 0;
1563 
1564  if (bdiff < len)
1565  {
1567  to_get = m_encoder->Encode(ABUF, len - bdiff,
1569  }
1570  else
1571  {
1572  to_get = m_encoder->Encode(WPOS, len,
1574  }
1575 
1576  if (bdiff <= to_get)
1577  {
1578  m_encoder->GetFrames(WPOS, bdiff);
1579  to_get -= bdiff ;
1580  org_waud = 0;
1581  }
1582  if (to_get > 0)
1583  m_encoder->GetFrames(WPOS, to_get);
1584 
1585  org_waud = (org_waud + to_get) % kAudioRingBufferSize;
1586  }
1587 
1588  m_waud = org_waud;
1589  }
1590 
1591  SetAudiotime(frames_final, timecode);
1592 
1593  return true;
1594 }
1595 
1600 {
1601  long ct = GetAudiotime();
1602 
1603  if (ct < 0)
1604  ct = 0;
1605 
1606  if (m_sourceBitRate == -1)
1609 
1610  if (ct / 1000 != m_currentSeconds)
1611  {
1612  m_currentSeconds = ct / 1000;
1615  dispatch(e);
1616  }
1617 }
1618 
1624 {
1625  fill = kAudioRingBufferSize - audiofree();
1626  total = kAudioRingBufferSize;
1627 }
1628 
1635 {
1636  auto *zeros = new uchar[m_fragmentSize];
1637  auto *fragment_buf = new uchar[m_fragmentSize + 16];
1638  auto *fragment = (uchar *)AOALIGN(fragment_buf[0]);
1639  memset(zeros, 0, m_fragmentSize);
1640 
1641  // to reduce startup latency, write silence in 8ms chunks
1642  int zero_fragment_size = 8 * m_sampleRate * m_outputBytesPerFrame / 1000;
1643  if (zero_fragment_size > m_fragmentSize)
1644  zero_fragment_size = m_fragmentSize;
1645 
1646  while (!m_killAudio)
1647  {
1648  if (m_pauseAudio)
1649  {
1650  if (!m_actuallyPaused)
1651  {
1652  VBAUDIO("OutputAudioLoop: audio paused");
1654  dispatch(e);
1655  m_wasPaused = true;
1656  }
1657 
1658  m_actuallyPaused = true;
1659  m_audioTime = 0; // mark 'audiotime' as invalid.
1660 
1661  WriteAudio(zeros, zero_fragment_size);
1662  continue;
1663  }
1664 
1665  if (m_wasPaused)
1666  {
1667  VBAUDIO("OutputAudioLoop: Play Event");
1669  dispatch(e);
1670  m_wasPaused = false;
1671  }
1672 
1673  /* do audio output */
1674  int ready = audioready();
1675 
1676  // wait for the buffer to fill with enough to play
1677  if (m_fragmentSize > ready)
1678  {
1679  if (ready > 0) // only log if we're sending some audio
1680  {
1681  VBAUDIOTS(QString("audio waiting for buffer to fill: "
1682  "have %1 want %2")
1683  .arg(ready).arg(m_fragmentSize));
1684  }
1685 
1686  usleep(10000);
1687  continue;
1688  }
1689 
1690 #ifdef AUDIOTSTESTING
1691  VBAUDIOTS("WriteAudio Start");
1692 #endif
1693  Status();
1694 
1695  // delay setting raud until after phys buffer is filled
1696  // so GetAudiotime will be accurate without locking
1698  volatile uint next_raud = m_raud;
1699  if (GetAudioData(fragment, m_fragmentSize, true, &next_raud))
1700  {
1701  if (!m_resetActive.TestAndDeref())
1702  {
1703  WriteAudio(fragment, m_fragmentSize);
1704  if (!m_resetActive.TestAndDeref())
1705  m_raud = next_raud;
1706  }
1707  }
1708 #ifdef AUDIOTSTESTING
1709  GetAudiotime();
1710  VBAUDIOTS("WriteAudio Done");
1711 #endif
1712 
1713  }
1714 
1715  delete[] zeros;
1716  delete[] fragment_buf;
1717  VBAUDIO("OutputAudioLoop: Stop Event");
1719  dispatch(e);
1720 }
1721 
1729 int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer,
1730  volatile uint *local_raud)
1731 {
1732 
1733 #define LRPOS (&m_audioBuffer[*local_raud])
1734  // re-check audioready() in case things changed.
1735  // for example, ClearAfterSeek() might have run
1736  int avail_size = audioready();
1737  int frag_size = size;
1738  int written_size = size;
1739 
1740  if (local_raud == nullptr)
1741  local_raud = &m_raud;
1742 
1743  if (!full_buffer && (size > avail_size))
1744  {
1745  // when full_buffer is false, return any available data
1746  frag_size = avail_size;
1747  written_size = frag_size;
1748  }
1749 
1750  if (!avail_size || (frag_size > avail_size))
1751  return 0;
1752 
1753  int bdiff = kAudioRingBufferSize - m_raud;
1754 
1756 
1757  if (obytes <= 0)
1758  return 0;
1759 
1760  bool fromFloats = m_processing && !m_enc && m_outputFormat != FORMAT_FLT;
1761 
1762  // Scale if necessary
1763  if (fromFloats && obytes != sizeof(float))
1764  frag_size *= sizeof(float) / obytes;
1765 
1766  int off = 0;
1767 
1768  if (bdiff <= frag_size)
1769  {
1770  if (fromFloats)
1771  {
1773  LRPOS, bdiff);
1774  }
1775  else
1776  {
1777  memcpy(buffer, LRPOS, bdiff);
1778  off = bdiff;
1779  }
1780 
1781  frag_size -= bdiff;
1782  *local_raud = 0;
1783  }
1784  if (frag_size > 0)
1785  {
1786  if (fromFloats)
1787  {
1789  LRPOS, frag_size);
1790  }
1791  else
1792  {
1793  memcpy(buffer + off, LRPOS, frag_size);
1794  }
1795  }
1796 
1797  *local_raud += frag_size;
1798 
1799  // Mute individual channels through mono->stereo duplication
1800  MuteState mute_state = GetMuteState();
1801  if (!m_enc && !m_passthru &&
1802  written_size && m_configuredChannels > 1 &&
1803  (mute_state == kMuteLeft || mute_state == kMuteRight))
1804  {
1806  mute_state == kMuteLeft ? 0 : 1,
1807  buffer, written_size);
1808  }
1809 
1810  return written_size;
1811 }
1812 
1817 {
1818  while (!m_pauseAudio && audioready() > m_fragmentSize)
1819  usleep(1000);
1820  if (m_pauseAudio)
1821  {
1822  // Audio is paused and can't be drained, clear ringbuffer
1823  QMutexLocker lock(&m_audioBufLock);
1824 
1825  m_waud = m_raud = 0;
1826  }
1827 }
1828 
1833 {
1834  RunProlog();
1835  VBAUDIO(QString("kickoffOutputAudioLoop: pid = %1").arg(getpid()));
1836  OutputAudioLoop();
1837  VBAUDIO("kickoffOutputAudioLoop exiting");
1838  RunEpilog();
1839 }
1840 
1841 int AudioOutputBase::readOutputData(unsigned char* /*read_buffer*/, size_t /*max_length*/)
1842 {
1843  VBERROR("AudioOutputBase should not be getting asked to readOutputData()");
1844  return 0;
1845 }
AudioOutputBase::m_srcOut
float * m_srcOut
Definition: audiooutputbase.h:287
AudioOutput::GetError
QString GetError(void) const
Definition: audiooutput.h:146
AudioOutputBase::m_enc
bool m_enc
Definition: audiooutputbase.h:187
AudioOutputBase::m_outputSettingsRaw
AudioOutputSettings * m_outputSettingsRaw
Definition: audiooutputbase.h:222
AudioOutputBase::m_srcIn
float * m_srcIn
Definition: audiooutputbase.h:280
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
AudioOutputBase::Reset
void Reset(void) override
Reset the audiobuffer, timecode and mythmusic visualisation.
Definition: audiooutputbase.cpp:921
AudioOutputBase::m_pSoundStretch
soundtouch::SoundTouch * m_pSoundStretch
Definition: audiooutputbase.h:228
AudioOutputSettings::IsSupportedChannels
bool IsSupportedChannels(int channels)
Definition: audiooutputsettings.cpp:243
AudioOutputBase::m_discreteDigital
bool m_discreteDigital
Definition: audiooutputbase.h:184
AudioOutputDigitalEncoder::GetFrames
size_t GetFrames(void *ptr, int maxlen)
Definition: audiooutputdigitalencoder.cpp:301
AudioOutputSettings::IsSupportedRate
bool IsSupportedRate(int rate)
Definition: audiooutputsettings.cpp:84
SPDIFEncoder::Succeeded
bool Succeeded() const
Definition: spdifencoder.h:24
AudioOutputBase::Pause
void Pause(bool paused) override
Definition: audiooutputbase.cpp:899
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:288
AudioOutputBase::m_raud
volatile uint m_raud
Audio circular buffer.
Definition: audiooutputbase.h:268
AudioOutputBase::CheckFreeSpace
int CheckFreeSpace(int &frames)
Check that there's enough space in the audiobuffer to write the provided number of frames.
Definition: audiooutputbase.cpp:1178
IS_VALID_UPMIX_CHANNEL
#define IS_VALID_UPMIX_CHANNEL(ch)
Definition: audiooutputbase.cpp:43
VBAUDIO
#define VBAUDIO(str)
Definition: audiooutputbase.h:19
FreeSurround::SurroundMode
SurroundMode
Definition: freesurround.h:30
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:28
STST
#define STST
Definition: audiooutputbase.cpp:38
AudioOutputBase::m_currentSeconds
long m_currentSeconds
Definition: audiooutputbase.h:278
AudioOutputBase::audiolen
int audiolen() const
Get the number of bytes in the audiobuffer.
Definition: audiooutputbase.cpp:979
AudioOutputDigitalEncoder::Init
bool Init(AVCodecID codec_id, int bitrate, int samplerate, int channels)
Definition: audiooutputdigitalencoder.cpp:88
AudioOutputBase::m_resetActive
AsyncLooseLock m_resetActive
Definition: audiooutputbase.h:274
kMuteRight
@ kMuteRight
Definition: volumebase.h:9
OutputEvent
Definition: output.h:30
AudioOutputBase::m_avsyncLock
QMutex m_avsyncLock
must hold avsync_lock to read or write 'audiotime' and 'audiotime_updated'
Definition: audiooutputbase.h:258
audiooutpututil.h
ABUF
#define ABUF
Definition: audiooutputbase.cpp:37
AudioOutputBase::m_forcedProcessing
bool m_forcedProcessing
Definition: audiooutputbase.h:303
spdifencoder.h
AudioOutputBase::CanPassthrough
bool CanPassthrough(int samplerate, int channels, AVCodecID codec, int profile) const override
Test if we can output digital audio and if sample rate is supported.
Definition: audiooutputbase.cpp:206
AudioOutputDigitalEncoder::Encode
size_t Encode(void *buf, int len, AudioFormat format)
Definition: audiooutputdigitalencoder.cpp:145
AudioOutputBase::m_needResampler
bool m_needResampler
Definition: audiooutputbase.h:226
AudioOutputBase::m_audbufTimecode
int64_t m_audbufTimecode
timecode of audio most recently placed into buffer
Definition: audiooutputbase.h:273
AudioOutput::Error
void Error(const QString &msg)
Definition: audiooutput.cpp:275
AudioOutputBase::CloseDevice
virtual void CloseDevice(void)=0
AudioOutputBase::m_configureSucceeded
bool m_configureSucceeded
Definition: audiooutputbase.h:295
OutputEvent::Stopped
static Type Stopped
Definition: output.h:67
AudioOutputBase::m_memoryCorruptionTest2
uint m_memoryCorruptionTest2
Definition: audiooutputbase.h:289
AudioOutputBase::SetupPassthrough
bool SetupPassthrough(AVCodecID codec, int codec_profile, int &samplerate_tmp, int &channels_tmp)
Definition: audiooutputbase.cpp:405
AudioOutputUtil::toFloat
static int toFloat(AudioFormat format, void *out, const void *in, int bytes)
Convert integer samples to floats.
Definition: audiooutpututil.cpp:70
AudioOutputBase::audiofree
int audiofree() const
Get the free space in the audiobuffer in bytes.
Definition: audiooutputbase.cpp:989
FEATURE_AC3
@ FEATURE_AC3
Definition: audiooutputsettings.h:37
AudioOutputBase::m_previousBpf
int m_previousBpf
Definition: audiooutputbase.h:304
SPDIFEncoder::Reset
void Reset()
Reset the internal encoder buffer.
Definition: spdifencoder.cpp:156
VolumeBase::m_internalVol
bool m_internalVol
Definition: volumebase.h:41
FreeSurround::numFrames
uint numFrames() const
Definition: freesurround.cpp:447
AudioOutputBase::KillAudio
void KillAudio(void)
Kill the output thread and cleanup.
Definition: audiooutputbase.cpp:857
AudioOutputSettings::FormatToBits
static int FormatToBits(AudioFormat format)
Definition: audiooutputsettings.cpp:149
AudioOutputBase::readOutputData
int readOutputData(unsigned char *read_buffer, size_t max_length) override
Definition: audiooutputbase.cpp:1841
arg
arg(title).arg(filename).arg(doDelete))
AudioOutputBase::GetStretchFactor
float GetStretchFactor(void) const override
Get the timetretch factor.
Definition: audiooutputbase.cpp:362
AudioSettings::m_codecProfile
int m_codecProfile
Definition: audiosettings.h:75
VBERROR
#define VBERROR(str)
Definition: audiooutputbase.h:22
AudioOutputSettings::SampleSize
static int SampleSize(AudioFormat format)
Definition: audiooutputsettings.cpp:179
FreeSurround
Definition: freesurround.h:27
VolumeBase::SyncVolume
void SyncVolume(void)
Definition: volumebase.cpp:208
AudioOutputDigitalEncoder::clear
void clear()
Definition: audiooutputdigitalencoder.cpp:314
FEATURE_TRUEHD
@ FEATURE_TRUEHD
Definition: audiooutputsettings.h:41
AudioOutputBase::IsUpmixing
bool IsUpmixing(void) override
Source is currently being upmixed.
Definition: audiooutputbase.cpp:370
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:198
AudioOutputBase::SetEffDsp
void SetEffDsp(int dsprate) override
Set the effective DSP rate.
Definition: audiooutputbase.cpp:970
FEATURE_EAC3
@ FEATURE_EAC3
Definition: audiooutputsettings.h:40
AudioOutputBase::quality_string
static const char * quality_string(int q)
Definition: audiooutputbase.cpp:45
freesurround.h
MythObservable::dispatch
void dispatch(const MythEvent &event)
Dispatch an event to all listeners.
Definition: mythobservable.cpp:73
AudioOutputBase::m_sampleRate
int m_sampleRate
Definition: audiooutputbase.h:177
OutputListeners::error
void error(const QString &e)
Definition: output.cpp:29
AudioOutputBase::m_volume
int m_volume
Definition: audiooutputbase.h:239
AudioOutputBase::m_sourceChannels
int m_sourceChannels
Definition: audiooutputbase.h:232
FreeSurround::putFrames
uint putFrames(void *buffer, uint numFrames, uint numChannels)
Definition: freesurround.cpp:146
AudioOutputBase::m_killAudio
bool m_killAudio
Definition: audiooutputbase.h:194
OutputListeners::hasVisual
bool hasVisual(void)
Definition: output.h:102
FreeSurround::numUnprocessedFrames
uint numUnprocessedFrames() const
Definition: freesurround.cpp:442
AudioOutputBase::m_lengthLastData
int64_t m_lengthLastData
Definition: audiooutputbase.h:296
AudioOutputBase::GetBufferedOnSoundcard
virtual int GetBufferedOnSoundcard(void) const =0
Return the size in bytes of frames currently in the audio buffer adjusted with the audio playback lat...
AudioOutputBase::m_kAudioSRCOutputSize
int m_kAudioSRCOutputSize
Definition: audiooutputbase.h:288
MuteState
MuteState
Definition: volumebase.h:6
AudioOutputSettings::GetCleaned
AudioOutputSettings * GetCleaned(bool newcopy=false)
Returns capabilities supported by the audio device amended to take into account the digital audio opt...
Definition: audiooutputsettings.cpp:302
AudioSettings::m_sampleRate
int m_sampleRate
Definition: audiosettings.h:76
AudioSettings
Definition: audiosettings.h:29
AudioOutputBase::m_mainDevice
QString m_mainDevice
Definition: audiooutputbase.h:182
AudioOutputUtil::MonoToStereo
static void MonoToStereo(void *dst, const void *src, int samples)
Convert a mono stream to stereo by copying and interleaving samples.
Definition: audiooutpututil.cpp:90
audiooutputdigitalencoder.h
AudioOutputBase::SetTimecode
void SetTimecode(int64_t timecode) override
Set the timecode of the samples most recently added to the audiobuffer.
Definition: audiooutputbase.cpp:958
AsyncLooseLock::Ref
void Ref()
Definition: audiooutputbase.h:39
AudioOutputBase::Drain
void Drain(void) override
Block until all available frames have been written to the device.
Definition: audiooutputbase.cpp:1816
AudioOutputBase::m_stretchFactor
float m_stretchFactor
Definition: audiooutputbase.h:190
AudioOutputBase::SetAudiotime
void SetAudiotime(int frames, int64_t timecode)
Set the timecode of the top of the ringbuffer Exclude all other processing elements as they dont vary...
Definition: audiooutputbase.cpp:1093
AudioOutputBase::m_unpauseWhenReady
bool m_unpauseWhenReady
Definition: audiooutputbase.h:199
AudioOutputBase::m_srcInBuf
std::array< float, kAudioSRCInputSize > m_srcInBuf
Definition: audiooutputbase.h:285
AudioOutputDigitalEncoder
Definition: audiooutputdigitalencoder.h:15
AudioOutputBase::m_upmixer
FreeSurround * m_upmixer
Definition: audiooutputbase.h:230
OutputEvent::Playing
static Type Playing
Definition: output.h:63
AudioOutputBase::m_killAudioLock
QMutex m_killAudioLock
Definition: audiooutputbase.h:276
mythlogging.h
AudioOutputBase::m_srcQuality
int m_srcQuality
Definition: audiooutputbase.h:212
LRPOS
#define LRPOS
AudioOutputBase::m_volumeControl
QString m_volumeControl
Definition: audiooutputbase.h:240
AudioOutputBase::m_audioThreadExists
bool m_audioThreadExists
Definition: audiooutputbase.h:246
hardwareprofile.scan.profile
profile
Definition: scan.py:99
AudioOutputSettings::GetMaxHDRate
int GetMaxHDRate() const
return the highest iec958 rate supported.
Definition: audiooutputsettings.cpp:414
AudioOutputBase::m_format
AudioFormat m_format
Definition: audiooutputbase.h:175
AudioOutputBase::AudioOutputBase
AudioOutputBase(const AudioSettings &settings)
Definition: audiooutputbase.cpp:57
AudioOutputBase::m_waud
volatile uint m_waud
Definition: audiooutputbase.h:269
FEATURE_NONE
@ FEATURE_NONE
Definition: audiooutputsettings.h:36
AudioOutputDigitalEncoder::Buffered
int Buffered(void) const
Definition: audiooutputdigitalencoder.h:26
AudioOutputBase::m_sourceSampleRate
int m_sourceSampleRate
Definition: audiooutputbase.h:214
AudioOutputBase::QUALITY_LOW
@ QUALITY_LOW
Definition: audiooutputbase.h:208
AudioOutputSettings::BestSupportedChannels
int BestSupportedChannels()
Definition: audiooutputsettings.cpp:253
FEATURE_DTS
@ FEATURE_DTS
Definition: audiooutputsettings.h:38
AudioOutputBase::GetOutputSettingsCleaned
AudioOutputSettings * GetOutputSettingsCleaned(bool digital=true) override
Returns capabilities supported by the audio device amended to take into account the digital audio opt...
Definition: audiooutputbase.cpp:153
compat.h
SPDIFEncoder::SetMaxHDRate
bool SetMaxHDRate(int rate)
Set the maximum HD rate.
Definition: spdifencoder.cpp:167
AudioOutputBase::m_needsUpmix
bool m_needsUpmix
Definition: audiooutputbase.h:235
AudioOutputBase::m_effStretchFactor
int m_effStretchFactor
Definition: audiooutputbase.h:191
AudioOutputBase::StopOutputThread
virtual void StopOutputThread(void)
Definition: audiooutputbase.cpp:845
AOALIGN
#define AOALIGN(x)
Definition: audiooutputbase.cpp:39
FORMAT_FLT
@ FORMAT_FLT
Definition: audiooutputsettings.h:32
VBGENERAL
#define VBGENERAL(str)
Definition: audiooutputbase.h:21
AudioOutputBase::Reconfigure
void Reconfigure(const AudioSettings &settings) override
(Re)Configure AudioOutputBase
Definition: audiooutputbase.cpp:465
AudioOutputBase::GetOutputSettings
virtual AudioOutputSettings * GetOutputSettings(bool)
Definition: audiooutputbase.h:140
AudioOutputBase::~AudioOutputBase
~AudioOutputBase() override
Destructor.
Definition: audiooutputbase.cpp:86
AudioOutputBase::m_memoryCorruptionTest1
uint m_memoryCorruptionTest1
Definition: audiooutputbase.h:286
FEATURE_LPCM
@ FEATURE_LPCM
Definition: audiooutputsettings.h:39
AudioOutputBase::m_oldStretchFactor
float m_oldStretchFactor
Definition: audiooutputbase.h:238
AudioOutputBase::GetAudioData
int GetAudioData(uchar *buffer, int buf_size, bool full_buffer, volatile uint *local_raud=nullptr)
Copy frames from the audiobuffer into the buffer provided.
Definition: audiooutputbase.cpp:1729
VolumeBase::GetMuteState
virtual MuteState GetMuteState(void) const
Definition: volumebase.cpp:149
FreeSurround::frameLatency
uint frameLatency() const
Definition: freesurround.cpp:452
AudioOutputBase::m_maxChannels
int m_maxChannels
Definition: audiooutputbase.h:204
AudioSettings::m_upmixer
int m_upmixer
Definition: audiosettings.h:80
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:211
AudioOutputBase::m_outputSettingsDigitalRaw
AudioOutputSettings * m_outputSettingsDigitalRaw
Definition: audiooutputbase.h:224
AudioSettings::m_custom
AudioOutputSettings * m_custom
custom contains a pointer to the audio device capabilities if defined, AudioOutput will not try to au...
Definition: audiosettings.h:92
AudioOutputBase::m_pauseAudio
bool m_pauseAudio
Definition: audiooutputbase.h:196
SPDIFEncoder::GetProcessedSize
int GetProcessedSize()
Definition: spdifencoder.cpp:139
AudioOutputBase::QUALITY_MEDIUM
@ QUALITY_MEDIUM
Definition: audiooutputbase.h:209
AudioOutputBase::GetAudioBufferedTime
int64_t GetAudioBufferedTime(void) override
Get the difference in timecode between the samples that are about to become audible and the samples m...
Definition: audiooutputbase.cpp:1143
kMuteLeft
@ kMuteLeft
Definition: volumebase.h:8
AudioOutputSettings::canFeature
bool canFeature(DigitalFeature arg) const
return DigitalFeature mask.
Definition: audiooutputsettings.h:89
AudioOutputBase::kAudioRingBufferSize
static const uint kAudioRingBufferSize
Audio Buffer Size – should be divisible by 32,24,16,12,10,8,6,4,2..
Definition: audiooutputbase.h:124
FreeSurround::flush
void flush()
Definition: freesurround.cpp:415
AudioOutputBase::run
void run() override
Main routine for the output thread.
Definition: audiooutputbase.cpp:1832
AudioOutputBase::m_sourceBytesPerFrame
int m_sourceBytesPerFrame
Definition: audiooutputbase.h:233
uint
unsigned int uint
Definition: compat.h:140
SPDIFEncoder::WriteFrame
void WriteFrame(unsigned char *data, int size)
Encode data through created muxer unsigned char data: pointer to data to encode int size: size of dat...
Definition: spdifencoder.cpp:100
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:56
VolumeBase::SWVolume
bool SWVolume(void) const
Definition: volumebase.cpp:105
AudioOutputBase::m_upmixDefault
bool m_upmixDefault
Definition: audiooutputbase.h:234
AudioOutputBase::GetAudiotime
int64_t GetAudiotime(void) override
Calculate the timecode of the samples that are about to become audible.
Definition: audiooutputbase.cpp:1014
AudioOutputBase::m_passthru
bool m_passthru
Definition: audiooutputbase.h:186
AudioOutputBase::OutputAudioLoop
void OutputAudioLoop(void)
Run in the output thread, write frames to the output device as they become available and there's spac...
Definition: audiooutputbase.cpp:1634
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:929
AudioOutputBase::m_outputFormat
AudioFormat m_outputFormat
Definition: audiooutputbase.h:176
AudioOutputBase::m_encoder
AudioOutputDigitalEncoder * m_encoder
Definition: audiooutputbase.h:229
AudioOutputBase::m_reEnc
bool m_reEnc
Definition: audiooutputbase.h:188
AudioOutputBase::GetSWVolume
int GetSWVolume(void) override
Get the volume for software volume control.
Definition: audiooutputbase.cpp:1165
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:923
AudioOutputBase::audioready
int audioready() const
Get the scaled number of bytes in the audiobuffer, i.e.
Definition: audiooutputbase.cpp:1004
AudioOutputBase::AddFrames
bool AddFrames(void *buffer, int frames, int64_t timecode) override
Add frames to the audiobuffer and perform any required processing.
Definition: audiooutputbase.cpp:1299
AudioOutputBase::m_channels
int m_channels
Definition: audiooutputbase.h:171
AudioOutputBase::CopyWithUpmix
int CopyWithUpmix(char *buffer, int frames, uint &org_waud)
Copy frames into the audiobuffer, upmixing en route if necessary.
Definition: audiooutputbase.cpp:1213
AudioOutputBase::m_configuredChannels
int m_configuredChannels
Definition: audiooutputbase.h:203
AudioOutputBase::m_setInitialVol
bool m_setInitialVol
Definition: audiooutputbase.h:200
OutputEvent::Paused
static Type Paused
Definition: output.h:66
audiooutputdownmix.h
AudioOutputBase::m_spdifEnc
SPDIFEncoder * m_spdifEnc
Definition: audiooutputbase.h:300
AudioOutputBase::m_codec
AVCodecID m_codec
Definition: audiooutputbase.h:172
AudioOutputBase::SetSWVolume
void SetSWVolume(int new_volume, bool save) override
Set the volume for software volume control.
Definition: audiooutputbase.cpp:1155
AudioOutputBase::CanUpmix
bool CanUpmix(void) override
Upmixing of the current source is available if requested.
Definition: audiooutputbase.cpp:396
AudioSettings::m_usePassthru
bool m_usePassthru
Definition: audiosettings.h:78
AudioOutputBase::Status
virtual void Status(void)
Report status via an OutputEvent.
Definition: audiooutputbase.cpp:1599
assert
#define assert(x)
Definition: audiooutputalsa.cpp:18
AudioOutputBase::WriteAudio
virtual void WriteAudio(unsigned char *aubuf, int size)=0
AudioOutputBase::m_outputBytesPerFrame
int m_outputBytesPerFrame
Definition: audiooutputbase.h:174
audiooutputbase.h
AudioOutputBase::m_sourceBitRate
long m_sourceBitRate
Definition: audiooutputbase.h:213
AudioOutputDownmix::DownmixFrames
static int DownmixFrames(int channels_in, int channels_out, float *dst, const float *src, int frames)
Definition: audiooutputdownmix.cpp:169
AudioOutput::SilentError
void SilentError(const QString &msg)
Definition: audiooutput.cpp:281
AUDIOOUTPUT_VIDEO
@ AUDIOOUTPUT_VIDEO
Definition: audiosettings.h:23
AudioSettings::m_format
AudioFormat m_format
Definition: audiosettings.h:72
AudioOutputBase::m_actuallyPaused
bool m_actuallyPaused
Definition: audiooutputbase.h:197
AudioOutputBase::m_memoryCorruptionTest0
uint m_memoryCorruptionTest0
Definition: audiooutputbase.h:284
AudioOutputSettings::IsSupportedFormat
bool IsSupportedFormat(AudioFormat format)
Definition: audiooutputsettings.cpp:133
AudioOutputSettings::GetPassthroughParams
static QString GetPassthroughParams(int codec, int codec_profile, int &samplerate, int &channels, bool canDTSHDMA)
Setup samplerate and number of channels for passthrough.
Definition: audiooutputsettings.cpp:454
AudioOutputBase::m_wasPaused
bool m_wasPaused
Definition: audiooutputbase.h:198
AudioOutputBase::m_surroundMode
int m_surroundMode
Definition: audiooutputbase.h:237
AudioOutputUtil::AdjustVolume
static void AdjustVolume(void *buffer, int len, int volume, bool music, bool upmix)
Adjust the volume of samples.
Definition: audiooutpututil.cpp:101
AudioOutputBase::m_processing
bool m_processing
Definition: audiooutputbase.h:242
AsyncLooseLock::Clear
void Clear()
Definition: audiooutputbase.h:38
AudioOutputSettings
Definition: audiooutputsettings.h:50
AudioOutputBase::usesSpdif
bool usesSpdif() const
Definition: audiooutputbase.h:167
WPOS
#define WPOS
Definition: audiooutputbase.cpp:35
AudioOutputSettings::NearestSupportedRate
int NearestSupportedRate(int rate)
Definition: audiooutputsettings.cpp:100
AudioOutputBase::QUALITY_DISABLED
@ QUALITY_DISABLED
Definition: audiooutputbase.h:207
AudioOutputBase::SetStretchFactor
void SetStretchFactor(float factor) override
Set the timestretch factor.
Definition: audiooutputbase.cpp:353
AudioOutputBase::m_bytesPerFrame
int m_bytesPerFrame
Definition: audiooutputbase.h:173
DigitalFeature
DigitalFeature
Definition: audiooutputsettings.h:35
AudioOutputBase::m_effDsp
int m_effDsp
Definition: audiooutputbase.h:178
SPDIFEncoder::GetProcessedBuffer
unsigned char * GetProcessedBuffer()
Definition: spdifencoder.cpp:146
AudioOutputBase::InitSettings
void InitSettings(const AudioSettings &settings)
Definition: audiooutputbase.cpp:117
AudioOutputBase::QUALITY_HIGH
@ QUALITY_HIGH
Definition: audiooutputbase.h:210
AudioOutputBase::OpenDevice
virtual bool OpenDevice(void)=0
common.utilities.log
def log(debug, txt)
Definition: utilities.py:7
AudioOutputBase::PauseUntilBuffered
void PauseUntilBuffered(void) override
Definition: audiooutputbase.cpp:911
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:49
AudioOutputBase::StartOutputThread
virtual bool StartOutputThread(void)
Definition: audiooutputbase.cpp:833
AudioOutputBase::AddData
bool AddData(void *buffer, int len, int64_t timecode, int frames) override
Add data to the audiobuffer and perform any required processing.
Definition: audiooutputbase.cpp:1311
AudioOutput::ClearError
void ClearError(void)
Definition: audiooutput.cpp:292
AudioOutputBase::m_audioBuffer
std::array< uchar, kAudioRingBufferSize > m_audioBuffer
main audio buffer
Definition: audiooutputbase.h:293
AudioOutputBase::m_audioBufLock
QMutex m_audioBufLock
Writes to the audiobuffer, reconfigures and audiobuffer resets can only take place while holding this...
Definition: audiooutputbase.h:252
AudioOutputSettings::FeaturesToString
static QString FeaturesToString(DigitalFeature arg)
Display in human readable form the digital features supported by the output device.
Definition: audiooutputsettings.cpp:443
AudioOutputBase::m_source
AudioOutputSource m_source
Definition: audiooutputbase.h:192
AudioOutputBase::GetOutputSettingsUsers
AudioOutputSettings * GetOutputSettingsUsers(bool digital=false) override
Returns capabilities supported by the audio device amended to take into account the digital audio opt...
Definition: audiooutputbase.cpp:182
VolumeBase::SetChannels
void SetChannels(int new_channels)
Definition: volumebase.cpp:217
OutputListeners::dispatchVisual
void dispatchVisual(uchar *b, unsigned long b_len, unsigned long written, int chan, int prec)
Definition: output.cpp:49
VolumeBase::UpdateVolume
void UpdateVolume(void)
Definition: volumebase.cpp:177
AudioOutputSettings::FormatToString
static const char * FormatToString(AudioFormat format)
Definition: audiooutputsettings.cpp:164
AudioOutputBase::SetStretchFactorLocked
void SetStretchFactorLocked(float factor)
Set the timestretch factor.
Definition: audiooutputbase.cpp:279
AudioOutputBase::m_fragmentSize
int m_fragmentSize
Definition: audiooutputbase.h:179
AudioSettings::m_codec
AVCodecID m_codec
Definition: audiosettings.h:74
AudioOutputSettings::BestSupportedFormat
AudioFormat BestSupportedFormat()
Definition: audiooutputsettings.cpp:142
AudioOutputUtil::fromFloat
static int fromFloat(AudioFormat format, void *out, const void *in, int bytes)
Convert float samples to integers.
Definition: audiooutpututil.cpp:81
AudioOutputBase::m_audioTime
int64_t m_audioTime
timecode of audio leaving the soundcard (same units as timecodes)
Definition: audiooutputbase.h:263
SPDIFEncoder
Definition: spdifencoder.h:15
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:898
MThread::wait
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:305
AudioOutputBase::m_outputSettings
AudioOutputSettings * m_outputSettings
Definition: audiooutputbase.h:223
AudioOutputBase::GetBufferStatus
void GetBufferStatus(uint &fill, uint &total) override
Fill in the number of bytes in the audiobuffer and the total size of the audiobuffer.
Definition: audiooutputbase.cpp:1623
AudioOutputBase::m_framesBuffered
int64_t m_framesBuffered
Definition: audiooutputbase.h:244
FEATURE_DTSHD
@ FEATURE_DTSHD
Definition: audiooutputsettings.h:42
FreeSurround::receiveFrames
uint receiveFrames(void *buffer, uint maxFrames)
Definition: freesurround.cpp:311
AudioOutputUtil::MuteChannel
static void MuteChannel(int obits, int channels, int ch, void *buffer, int bytes)
Mute individual channels through mono->stereo duplication.
Definition: audiooutpututil.cpp:179
AudioOutputBase::m_srcCtx
SRC_STATE * m_srcCtx
Definition: audiooutputbase.h:227
MThread::usleep
static void usleep(unsigned long time)
Definition: mthread.cpp:342
OutputListeners::prepareVisuals
void prepareVisuals()
Definition: output.cpp:62
AudioOutputBase::m_usesSpdif
bool m_usesSpdif
Definition: audiooutputbase.h:299
AudioOutputBase::kAudioSRCInputSize
static const uint kAudioSRCInputSize
Definition: audiooutputbase.h:120
AudioOutputBase::m_memoryCorruptionTest3
uint m_memoryCorruptionTest3
Definition: audiooutputbase.h:294
AudioOutputBase::ToggleUpmix
bool ToggleUpmix(void) override
Toggle between stereo and upmixed 5.1 if the source material is stereo.
Definition: audiooutputbase.cpp:378
AudioOutputBase::m_srcData
SRC_DATA m_srcData
Definition: audiooutputbase.h:283
AudioOutputBase::SetSourceBitrate
void SetSourceBitrate(int rate) override
Set the bitrate of the source material, reported in periodic OutputEvents.
Definition: audiooutputbase.cpp:268
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:915
AudioOutputBase::m_outputSettingsDigital
AudioOutputSettings * m_outputSettingsDigital
Definition: audiooutputbase.h:225
AudioSettings::m_channels
int m_channels
Definition: audiosettings.h:73
VBAUDIOTS
#define VBAUDIOTS(str)
Definition: audiooutputbase.h:20
AudioOutputBase::m_needsDownmix
bool m_needsDownmix
Definition: audiooutputbase.h:236
AsyncLooseLock::TestAndDeref
bool TestAndDeref()
Definition: audiooutputbase.h:40
AudioOutputBase::OutputSettings
AudioOutputSettings * OutputSettings(bool digital=true)
Definition: audiooutputbase.cpp:453