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