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:
237  arg = FEATURE_TRUEHD;
238  break;
239  default:
240  arg = FEATURE_NONE;
241  break;
242  }
243  // we can't passthrough any other codecs than those defined above
244  ret &= m_outputSettingsDigital->canFeature(arg);
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_framesBuffered = 0;
341  m_waud = m_raud = 0;
342  m_resetActive.Ref();
344  m_pauseAudio = true;
345  m_actuallyPaused = false;
346  m_unpauseWhenReady = true;
347  }
348  }
349 }
350 
354 void AudioOutputBase::SetStretchFactor(float lstretchfactor)
355 {
356  QMutexLocker lock(&m_audioBufLock);
357  SetStretchFactorLocked(lstretchfactor);
358 }
359 
364 {
365  return m_stretchFactor;
366 }
367 
372 {
373  return m_needsUpmix && m_upmixer;
374 }
375 
380 {
381  // Can only upmix from mono/stereo to 6 ch
382  if (m_maxChannels == 2 || m_sourceChannels > 2)
383  return false;
384 
386 
389  m_upmixDefault ? false : m_passthru);
390  Reconfigure(settings);
391  return IsUpmixing();
392 }
393 
398 {
399  return m_sourceChannels <= 2 && m_maxChannels > 2;
400 }
401 
402 /*
403  * Setup samplerate and number of channels for passthrough
404  * Create SPDIF encoder and true if successful
405  */
406 bool AudioOutputBase::SetupPassthrough(AVCodecID codec, int codec_profile,
407  int &samplerate_tmp, int &channels_tmp)
408 {
409  if (codec == AV_CODEC_ID_DTS &&
411  {
412  // We do not support DTS-HD bitstream so force extraction of the
413  // DTS core track instead
414  codec_profile = FF_PROFILE_DTS;
415  }
417  codec, codec_profile,
418  samplerate_tmp, channels_tmp,
420  VBAUDIO("Setting " + log + " passthrough");
421 
422  delete m_spdifEnc;
423 
424  // No spdif encoder needed for certain devices
425  if (m_usesSpdif)
426  m_spdifEnc = new SPDIFEncoder("spdif", codec);
427  else
428  m_spdifEnc = nullptr;
429  if (m_spdifEnc && m_spdifEnc->Succeeded() && codec == AV_CODEC_ID_DTS)
430  {
431  switch(codec_profile)
432  {
433  case FF_PROFILE_DTS:
434  case FF_PROFILE_DTS_ES:
435  case FF_PROFILE_DTS_96_24:
437  break;
438  case FF_PROFILE_DTS_HD_HRA:
439  case FF_PROFILE_DTS_HD_MA:
440  m_spdifEnc->SetMaxHDRate(samplerate_tmp * channels_tmp / 2);
441  break;
442  }
443  }
444 
445  if (m_spdifEnc && !m_spdifEnc->Succeeded())
446  {
447  delete m_spdifEnc;
448  m_spdifEnc = nullptr;
449  return false;
450  }
451  return true;
452 }
453 
455 {
456  if (digital)
458  return m_outputSettings;
459 }
460 
466 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
467 {
468  AudioSettings settings = orig_settings;
469  int lsource_channels = settings.m_channels;
470  int lconfigured_channels = m_configuredChannels;
471  bool lneeds_upmix = false;
472  bool lneeds_downmix = false;
473  bool lreenc = false;
474  bool lenc = false;
475 
476  if (!settings.m_usePassthru)
477  {
478  // Do we upmix stereo or mono?
479  lconfigured_channels =
480  (m_upmixDefault && lsource_channels <= 2) ? 6 : lsource_channels;
481  bool cando_channels =
482  m_outputSettings->IsSupportedChannels(lconfigured_channels);
483 
484  // check if the number of channels could be transmitted via AC3 encoding
485 #ifndef DISABLE_AC3_ENCODE
488  lconfigured_channels > 2 && lconfigured_channels <= 6);
489 #endif
490  if (!lenc && !cando_channels)
491  {
492  // if hardware doesn't support source audio configuration
493  // we will upmix/downmix to what we can
494  // (can safely assume hardware supports stereo)
495  switch (lconfigured_channels)
496  {
497  case 7:
498  lconfigured_channels = 8;
499  break;
500  case 8:
501  case 5:
502  lconfigured_channels = 6;
503  break;
504  case 6:
505  case 4:
506  case 3:
507  case 2: //Will never happen
508  lconfigured_channels = 2;
509  break;
510  case 1:
511  lconfigured_channels = m_upmixDefault ? 6 : 2;
512  break;
513  default:
514  lconfigured_channels = 2;
515  break;
516  }
517  }
518  // Make sure we never attempt to output more than what we can
519  // the upmixer can only upmix to 6 channels when source < 6
520  if (lsource_channels <= 6)
521  lconfigured_channels = std::min(lconfigured_channels, 6);
522  lconfigured_channels = std::min(lconfigured_channels, m_maxChannels);
523  /* Encode to AC-3 if we're allowed to passthru but aren't currently
524  and we have more than 2 channels but multichannel PCM is not
525  supported or if the device just doesn't support the number of
526  channels */
527 #ifndef DISABLE_AC3_ENCODE
530  lconfigured_channels > 2) ||
531  !m_outputSettings->IsSupportedChannels(lconfigured_channels));
532  /* Might we reencode a bitstream that's been decoded for timestretch?
533  If the device doesn't support the number of channels - see below */
535  (settings.m_codec == AV_CODEC_ID_AC3 ||
536  settings.m_codec == AV_CODEC_ID_DTS))
537  {
538  lreenc = true;
539  }
540 #endif
541  // Enough channels? Upmix if not, but only from mono/stereo/5.0 to 5.1
542  if (IS_VALID_UPMIX_CHANNEL(settings.m_channels) &&
543  settings.m_channels < lconfigured_channels)
544  {
545  VBAUDIO(QString("Needs upmix from %1 -> %2 channels")
546  .arg(settings.m_channels).arg(lconfigured_channels));
547  settings.m_channels = lconfigured_channels;
548  lneeds_upmix = true;
549  }
550  else if (settings.m_channels > lconfigured_channels)
551  {
552  VBAUDIO(QString("Needs downmix from %1 -> %2 channels")
553  .arg(settings.m_channels).arg(lconfigured_channels));
554  settings.m_channels = lconfigured_channels;
555  lneeds_downmix = true;
556  }
557  }
558 
559  ClearError();
560 
561  bool general_deps = true;
562 
563  /* Set samplerate_tmp and channels_tmp to appropriate values
564  if passing through */
565  int samplerate_tmp = 0;
566  int channels_tmp = 0;
567  if (settings.m_usePassthru)
568  {
569  samplerate_tmp = settings.m_sampleRate;
570  SetupPassthrough(settings.m_codec, settings.m_codecProfile,
571  samplerate_tmp, channels_tmp);
572  general_deps = m_sampleRate == samplerate_tmp && m_channels == channels_tmp;
573  general_deps &= m_format == m_outputFormat && m_format == FORMAT_S16;
574  }
575  else
576  {
577  general_deps =
578  settings.m_format == m_format && lsource_channels == m_sourceChannels;
579  }
580 
581  // Check if anything has changed
582  general_deps &=
583  settings.m_sampleRate == m_sourceSampleRate &&
584  settings.m_usePassthru == m_passthru &&
585  lconfigured_channels == m_configuredChannels &&
586  lneeds_upmix == m_needsUpmix && lreenc == m_reEnc &&
587  lneeds_downmix == m_needsDownmix;
588 
589  if (general_deps && m_configureSucceeded)
590  {
591  VBAUDIO("Reconfigure(): No change -> exiting");
592  // if passthrough, source channels may have changed
593  m_sourceChannels = lsource_channels;
594  return;
595  }
596 
597  KillAudio();
598 
599  QMutexLocker lock(&m_audioBufLock);
600  QMutexLocker lockav(&m_avsyncLock);
601 
602  m_waud = m_raud = 0;
605 
606  m_channels = settings.m_channels;
607  m_sourceChannels = lsource_channels;
608  m_reEnc = lreenc;
609  m_codec = settings.m_codec;
610  m_passthru = settings.m_usePassthru;
611  m_configuredChannels = lconfigured_channels;
612  m_needsUpmix = lneeds_upmix;
613  m_needsDownmix = lneeds_downmix;
614  m_format = m_outputFormat = settings.m_format;
616  m_enc = lenc;
617 
618  m_killAudio = m_pauseAudio = false;
619  m_wasPaused = true;
620 
621  // Don't try to do anything if audio hasn't been
622  // initialized yet (e.g. rubbish was provided)
623  if (m_sourceChannels <= 0 || m_format <= 0 || m_sampleRate <= 0)
624  {
625  SilentError(QString("Aborting Audio Reconfigure. ") +
626  QString("Invalid audio parameters ch %1 fmt %2 @ %3Hz")
627  .arg(m_sourceChannels).arg(m_format).arg(m_sampleRate));
628  return;
629  }
630 
631  VBAUDIO(QString("Original codec was %1, %2, %3 kHz, %4 channels")
632  .arg(ff_codec_id_string(m_codec),
634  .arg(m_sampleRate/1000)
635  .arg(m_sourceChannels));
636 
637  if (m_needsDownmix && m_sourceChannels > 8)
638  {
639  Error(QObject::tr("Aborting Audio Reconfigure. "
640  "Can't handle audio with more than 8 channels."));
641  return;
642  }
643 
644  VBAUDIO(QString("enc(%1), passthru(%2), features (%3) "
645  "configured_channels(%4), %5 channels supported(%6) "
646  "max_channels(%7)")
647  .arg(m_enc)
648  .arg(m_passthru)
651  .arg(m_channels)
652  .arg(OutputSettings(m_enc || m_passthru)->IsSupportedChannels(m_channels))
653  .arg(m_maxChannels));
654 
655  int dest_rate = 0;
656 
657  // Force resampling if we are encoding to AC3 and sr > 48k
658  // or if 48k override was checked in settings
659  if ((m_sampleRate != 48000 &&
660  gCoreContext->GetBoolSetting("Audio48kOverride", false)) ||
661  (m_enc && (m_sampleRate > 48000)))
662  {
663  VBAUDIO("Forcing resample to 48 kHz");
664  if (m_srcQuality < 0)
666  m_needResampler = true;
667  dest_rate = 48000;
668  }
669  // this will always be false for passthrough audio as
670  // CanPassthrough() already tested these conditions
671  else if ((m_needResampler =
672  !OutputSettings(m_enc || m_passthru)->IsSupportedRate(m_sampleRate)))
673  {
675  }
676 
678  {
679  m_sampleRate = dest_rate;
680 
681  VBGENERAL(QString("Resampling from %1 kHz to %2 kHz with quality %3")
682  .arg(settings.m_sampleRate/1000).arg(m_sampleRate/1000)
684 
686 
687  int error = 0;
688  m_srcCtx = src_new(2-m_srcQuality, chans, &error);
689  if (error)
690  {
691  Error(QObject::tr("Error creating resampler: %1")
692  .arg(src_strerror(error)));
693  m_srcCtx = nullptr;
694  return;
695  }
696 
697  m_srcData.src_ratio = (double)m_sampleRate / settings.m_sampleRate;
698  m_srcData.data_in = m_srcIn;
699  int newsize = (int)(kAudioSRCInputSize * m_srcData.src_ratio + 15)
700  & ~0xf;
701 
702  if (m_kAudioSRCOutputSize < newsize)
703  {
704  m_kAudioSRCOutputSize = newsize;
705  VBAUDIO(QString("Resampler allocating %1").arg(newsize));
706  delete[] m_srcOut;
707  m_srcOut = new float[m_kAudioSRCOutputSize];
708  }
709  m_srcData.data_out = m_srcOut;
710  m_srcData.output_frames = m_kAudioSRCOutputSize / chans;
711  m_srcData.end_of_input = 0;
712  }
713 
714  if (m_enc)
715  {
716  if (m_reEnc)
717  VBAUDIO("Reencoding decoded AC-3/DTS to AC-3");
718 
719  VBAUDIO(QString("Creating AC-3 Encoder with sr = %1, ch = %2")
721 
723  if (!m_encoder->Init(AV_CODEC_ID_AC3, 448000, m_sampleRate,
725  {
726  Error(QObject::tr("AC-3 encoder initialization failed"));
727  delete m_encoder;
728  m_encoder = nullptr;
729  m_enc = false;
730  // upmixing will fail if we needed the encoder
731  m_needsUpmix = false;
732  }
733  }
734 
735  if (m_passthru)
736  {
737  //AC3, DTS, DTS-HD MA and TrueHD all use 16 bits samples
738  m_channels = channels_tmp;
739  m_sampleRate = samplerate_tmp;
743  }
744  else
745  {
748  }
749 
750  // Turn on float conversion?
752  m_stretchFactor != 1.0F || (m_internalVol && SWVolume()) ||
753  (m_enc && m_outputFormat != FORMAT_S16) ||
754  !OutputSettings(m_enc || m_passthru)->IsSupportedFormat(m_outputFormat))
755  {
756  VBAUDIO("Audio processing enabled");
757  m_processing = true;
758  if (m_enc)
759  m_outputFormat = FORMAT_S16; // Output s16le for AC-3 encoder
760  else
762  }
763 
765  sizeof(float) : AudioOutputSettings::SampleSize(m_format);
767 
768  if (m_enc)
769  m_channels = 2; // But only post-encoder
770 
773 
774  VBGENERAL(
775  QString("Opening audio device '%1' ch %2(%3) sr %4 sf %5 reenc %6")
778 
780  m_framesBuffered = 0;
781  m_currentSeconds = -1s;
782  m_sourceBitRate = -1;
783  m_effDsp = m_sampleRate * 100;
784 
785  // Actually do the device specific open call
786  if (!OpenDevice())
787  {
788  if (GetError().isEmpty())
789  Error(QObject::tr("Aborting reconfigure"));
790  else
791  VBGENERAL("Aborting reconfigure");
792  m_configureSucceeded = false;
793  return;
794  }
795 
796  VBAUDIO(QString("Audio fragment size: %1").arg(m_fragmentSize));
797 
798  // Only used for software volume
800  {
801  VBAUDIO("Software volume enabled");
802  m_volumeControl = gCoreContext->GetSetting("MixerControl", "PCM");
803  m_volumeControl += "MixerVolume";
805  }
806 
810 
812  {
816  VBAUDIO(QString("Create %1 quality upmixer done")
818  }
819 
820  VBAUDIO(QString("Audio Stretch Factor: %1").arg(m_stretchFactor));
822 
823  // Setup visualisations, zero the visualisations buffers
824  prepareVisuals();
825 
826  if (m_unpauseWhenReady)
828 
829  m_configureSucceeded = true;
830 
832 
833  VBAUDIO("Ending Reconfigure()");
834 }
835 
837 {
839  return true;
840 
841  start();
842  m_audioThreadExists = true;
843 
844  return true;
845 }
846 
847 
849 {
851  {
852  wait();
853  m_audioThreadExists = false;
854  }
855 }
856 
861 {
862  m_killAudioLock.lock();
863 
864  VBAUDIO("Killing AudioOutputDSP");
865  m_killAudio = true;
867  QMutexLocker lock(&m_audioBufLock);
868 
869  if (m_pSoundStretch)
870  {
871  delete m_pSoundStretch;
872  m_pSoundStretch = nullptr;
874  m_stretchFactor = 1.0F;
875  }
876 
877  if (m_encoder)
878  {
879  delete m_encoder;
880  m_encoder = nullptr;
881  }
882 
883  if (m_upmixer)
884  {
885  delete m_upmixer;
886  m_upmixer = nullptr;
887  }
888 
889  if (m_srcCtx)
890  {
891  src_delete(m_srcCtx);
892  m_srcCtx = nullptr;
893  }
894 
895  m_needsUpmix = m_needResampler = m_enc = false;
896 
897  CloseDevice();
898 
899  m_killAudioLock.unlock();
900 }
901 
902 void AudioOutputBase::Pause(bool paused)
903 {
904  if (!paused && m_unpauseWhenReady)
905  return;
906  VBAUDIO(QString("Pause %1").arg(paused));
907  if (m_pauseAudio != paused)
909  m_pauseAudio = paused;
910  m_unpauseWhenReady = false;
911  m_actuallyPaused = false;
912 }
913 
915 {
916  Reset();
917  Pause(true);
918  m_unpauseWhenReady = true;
919 }
920 
925 {
926  QMutexLocker lock(&m_audioBufLock);
927  QMutexLocker lockav(&m_avsyncLock);
928 
930  m_framesBuffered = 0;
931  if (m_encoder)
932  {
933  m_waud = m_raud = 0; // empty ring buffer
934  m_audioBuffer.fill(0);
935  }
936  else
937  {
938  m_waud = m_raud; // empty ring buffer
939  }
940  m_resetActive.Ref();
941  m_currentSeconds = -1s;
943  m_unpauseWhenReady = false;
944  // clear any state that could remember previous audio in any active filters
945  if (m_needsUpmix && m_upmixer)
946  m_upmixer->flush();
947  if (m_pSoundStretch)
948  m_pSoundStretch->clear();
949  if (m_encoder)
950  m_encoder->clear();
951 
952  // Setup visualisations, zero the visualisations buffers
953  prepareVisuals();
954 }
955 
962 void AudioOutputBase::SetTimecode(std::chrono::milliseconds timecode)
963 {
964  m_audbufTimecode = m_audioTime = timecode;
965  m_framesBuffered = (timecode.count() * m_sourceSampleRate) / 1000;
966 }
967 
974 void AudioOutputBase::SetEffDsp(int dsprate)
975 {
976  VBAUDIO(QString("SetEffDsp: %1").arg(dsprate));
977  m_effDsp = dsprate;
978 }
979 
983 inline int AudioOutputBase::audiolen() const
984 {
985  if (m_waud >= m_raud)
986  return m_waud - m_raud;
987  return kAudioRingBufferSize - (m_raud - m_waud);
988 }
989 
994 {
995  return kAudioRingBufferSize - audiolen() - 1;
996  /* There is one wasted byte in the buffer. The case where m_waud = m_raud is
997  interpreted as an empty buffer, so the fullest the buffer can ever
998  be is kAudioRingBufferSize - 1. */
999 }
1000 
1009 {
1011  return audiolen();
1013 }
1014 
1018 std::chrono::milliseconds AudioOutputBase::GetAudiotime(void)
1019 {
1020  if (m_audbufTimecode == 0ms || !m_configureSucceeded)
1021  return 0ms;
1022 
1023  // output bits per 10 frames
1024  int64_t obpf = 0;
1025 
1026  if (m_passthru && !usesSpdif())
1027  obpf = m_sourceBitRate * 10 / m_sourceSampleRate;
1028  else if (m_enc && !usesSpdif())
1029  {
1030  // re-encode bitrate is hardcoded at 448000
1031  obpf = 448000 * 10 / m_sourceSampleRate;
1032  }
1033  else
1034  obpf = static_cast<int64_t>(m_outputBytesPerFrame) * 80;
1035 
1036  /* We want to calculate 'm_audioTime', which is the timestamp of the audio
1037  Which is leaving the sound card at this instant.
1038 
1039  We use these variables:
1040 
1041  'm_effDsp' is 100 * frames/sec
1042 
1043  'm_audbufTimecode' is the timecode in milliseconds of the
1044  audio that has just been written into the buffer.
1045 
1046  'm_effStretchFactor' is stretch factor * 100,000
1047 
1048  'totalbuffer' is the total # of bytes in our audio buffer, and the
1049  sound card's buffer. */
1050 
1051 
1052  QMutexLocker lockav(&m_avsyncLock);
1053 
1054  int64_t soundcard_buffer = GetBufferedOnSoundcard(); // bytes
1055 
1056  /* audioready tells us how many bytes are in audiobuffer
1057  scaled appropriately if output format != internal format */
1058  int64_t main_buffer = audioready();
1059 
1060  std::chrono::milliseconds oldaudiotime = m_audioTime;
1061 
1062  /* timecode is the stretch adjusted version
1063  of major post-stretched buffer contents
1064  processing latencies are catered for in AddData/SetAudiotime
1065  to eliminate race */
1066 
1067  m_audioTime = m_audbufTimecode - std::chrono::milliseconds(m_effDsp && obpf ?
1068  ((main_buffer + soundcard_buffer) * int64_t(m_effStretchFactor)
1069  * 80 / int64_t(m_effDsp) / obpf) : 0);
1070 
1071  /* audiotime should never go backwards, but we might get a negative
1072  value if GetBufferedOnSoundcard() isn't updated by the driver very
1073  quickly (e.g. ALSA) */
1074  if (m_audioTime < oldaudiotime)
1075  m_audioTime = oldaudiotime;
1076 
1077  VBAUDIOTS(QString("GetAudiotime audt=%1 abtc=%2 mb=%3 sb=%4 tb=%5 "
1078  "sr=%6 obpf=%7 bpf=%8 esf=%9 edsp=%10 sbr=%11")
1079  .arg(m_audioTime.count()) // 1
1080  .arg(m_audbufTimecode.count()) // 2
1081  .arg(main_buffer) // 3
1082  .arg(soundcard_buffer) // 4
1083  .arg(main_buffer+soundcard_buffer) // 5
1084  .arg(m_sampleRate).arg(obpf) // 6, 7
1085  .arg(m_bytesPerFrame) // 8
1086  .arg(m_effStretchFactor) // 9
1087  .arg(m_effDsp).arg(m_sourceBitRate) // 10, 11
1088  );
1089 
1090  return m_audioTime;
1091 }
1092 
1098 void AudioOutputBase::SetAudiotime(int frames, std::chrono::milliseconds timecode)
1099 {
1100  int64_t processframes_stretched = 0;
1101  int64_t processframes_unstretched = 0;
1102  std::chrono::milliseconds old_audbuf_timecode = m_audbufTimecode;
1103 
1104  if (!m_configureSucceeded)
1105  return;
1106 
1107  if (m_needsUpmix && m_upmixer)
1108  processframes_unstretched -= m_upmixer->frameLatency();
1109 
1110  if (m_pSoundStretch)
1111  {
1112  processframes_unstretched -= m_pSoundStretch->numUnprocessedSamples();
1113  processframes_stretched -= m_pSoundStretch->numSamples();
1114  }
1115 
1116  if (m_encoder)
1117  {
1118  processframes_stretched -= m_encoder->Buffered();
1119  }
1120 
1122  timecode + std::chrono::milliseconds(m_effDsp ? ((frames + processframes_unstretched) * 100000 +
1123  (processframes_stretched * m_effStretchFactor)
1124  ) / m_effDsp : 0);
1125 
1126  // check for timecode wrap and reset audiotime if detected
1127  // timecode will always be monotonic asc if not seeked and reset
1128  // happens if seek or pause happens
1129  if (m_audbufTimecode < old_audbuf_timecode)
1130  m_audioTime = 0ms;
1131 
1132  VBAUDIOTS(QString("SetAudiotime atc=%1 tc=%2 f=%3 pfu=%4 pfs=%5")
1133  .arg(m_audbufTimecode.count())
1134  .arg(timecode.count())
1135  .arg(frames)
1136  .arg(processframes_unstretched)
1137  .arg(processframes_stretched));
1138 #ifdef AUDIOTSTESTING
1139  GetAudiotime();
1140 #endif
1141 }
1142 
1148 std::chrono::milliseconds AudioOutputBase::GetAudioBufferedTime(void)
1149 {
1150  std::chrono::milliseconds ret = m_audbufTimecode - GetAudiotime();
1151  // Pulse can give us values that make this -ve
1152  if (ret < 0ms)
1153  return 0ms;
1154  return ret;
1155 }
1156 
1160 void AudioOutputBase::SetSWVolume(int new_volume, bool save)
1161 {
1162  m_volume = new_volume;
1163  if (save && m_volumeControl != nullptr)
1165 }
1166 
1171 {
1172  return m_volume;
1173 }
1174 
1184 {
1185  int bpf = m_bytesPerFrame;
1186  int len = frames * bpf;
1187  int afree = audiofree();
1188 
1189  if (len <= afree)
1190  return len;
1191 
1192  VBERROR(QString("Audio buffer overflow, %1 frames lost!")
1193  .arg(frames - (afree / bpf)));
1194 
1195  frames = afree / bpf;
1196  len = frames * bpf;
1197 
1198  if (!m_srcCtx)
1199  return len;
1200 
1201  int error = src_reset(m_srcCtx);
1202  if (error)
1203  {
1204  VBERROR(QString("Error occurred while resetting resampler: %1")
1205  .arg(src_strerror(error)));
1206  m_srcCtx = nullptr;
1207  }
1208 
1209  return len;
1210 }
1211 
1218 int AudioOutputBase::CopyWithUpmix(char *buffer, int frames, uint &org_waud)
1219 {
1220  int len = CheckFreeSpace(frames);
1221  int bdiff = kAudioRingBufferSize - org_waud;
1222  int bpf = m_bytesPerFrame;
1223  int off = 0;
1224 
1225  if (!m_needsUpmix)
1226  {
1227  int num = len;
1228 
1229  if (bdiff <= num)
1230  {
1231  memcpy(WPOS, buffer, bdiff);
1232  num -= bdiff;
1233  off = bdiff;
1234  org_waud = 0;
1235  }
1236  if (num > 0)
1237  memcpy(WPOS, buffer + off, num);
1238  org_waud = (org_waud + num) % kAudioRingBufferSize;
1239  return len;
1240  }
1241 
1242  // Convert mono to stereo as most devices can't accept mono
1243  if (!m_upmixer)
1244  {
1245  // we're always in the case
1246  // m_configuredChannels == 2 && m_sourceChannels == 1
1247  int bdFrames = bdiff / bpf;
1248  if (bdFrames <= frames)
1249  {
1250  AudioOutputUtil::MonoToStereo(WPOS, buffer, bdFrames);
1251  frames -= bdFrames;
1252  off = bdFrames * sizeof(float); // 1 channel of floats
1253  org_waud = 0;
1254  }
1255  if (frames > 0)
1256  AudioOutputUtil::MonoToStereo(WPOS, buffer + off, frames);
1257 
1258  org_waud = (org_waud + frames * bpf) % kAudioRingBufferSize;
1259  return len;
1260  }
1261 
1262  // Upmix to 6ch via FreeSurround
1263  // Calculate frame size of input
1264  off = m_processing ? sizeof(float) : AudioOutputSettings::SampleSize(m_format);
1265  off *= m_sourceChannels;
1266 
1267  int i = 0;
1268  len = 0;
1269  while (i < frames)
1270  {
1271  i += m_upmixer->putFrames(buffer + i * off, frames - i, m_sourceChannels);
1272  int nFrames = m_upmixer->numFrames();
1273  if (!nFrames)
1274  continue;
1275 
1276  len += CheckFreeSpace(nFrames);
1277 
1278  int bdFrames = (kAudioRingBufferSize - org_waud) / bpf;
1279  if (bdFrames < nFrames)
1280  {
1281  if ((org_waud % bpf) != 0)
1282  {
1283  VBERROR(QString("Upmixing: org_waud = %1 (bpf = %2)")
1284  .arg(org_waud)
1285  .arg(bpf));
1286  }
1287  m_upmixer->receiveFrames((float *)(WPOS), bdFrames);
1288  nFrames -= bdFrames;
1289  org_waud = 0;
1290  }
1291  if (nFrames > 0)
1292  m_upmixer->receiveFrames((float *)(WPOS), nFrames);
1293 
1294  org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
1295  }
1296  return len;
1297 }
1298 
1304 bool AudioOutputBase::AddFrames(void *in_buffer, int in_frames,
1305  std::chrono::milliseconds timecode)
1306 {
1307  return AddData(in_buffer, in_frames * m_sourceBytesPerFrame, timecode,
1308  in_frames);
1309 }
1310 
1316 bool AudioOutputBase::AddData(void *in_buffer, int in_len,
1317  std::chrono::milliseconds timecode,
1318  int /*in_frames*/)
1319 {
1320  int frames = in_len / m_sourceBytesPerFrame;
1321  int bpf = m_bytesPerFrame;
1322  int len = in_len;
1323  bool music = false;
1324 
1325  if (!m_configureSucceeded)
1326  {
1327  LOG(VB_GENERAL, LOG_ERR, "AddData called with audio framework not "
1328  "initialised");
1329  m_lengthLastData = 0ms;
1330  return false;
1331  }
1332 
1333  /* See if we're waiting for new samples to be buffered before we unpause
1334  post channel change, seek, etc. Wait for 4 fragments to be buffered */
1336  {
1337  m_unpauseWhenReady = false;
1338  Pause(false);
1339  }
1340 
1341  // Don't write new samples if we're resetting the buffer or reconfiguring
1342  QMutexLocker lock(&m_audioBufLock);
1343 
1344  uint org_waud = m_waud;
1345  int afree = audiofree();
1346  int used = kAudioRingBufferSize - afree;
1347 
1348  if (m_passthru && m_spdifEnc)
1349  {
1350  if (m_processing)
1351  {
1352  /*
1353  * We shouldn't encounter this case, but it can occur when
1354  * timestretch just got activated. So we will just drop the
1355  * data
1356  */
1357  LOG(VB_AUDIO, LOG_INFO,
1358  "Passthrough activated with audio processing. Dropping audio");
1359  return false;
1360  }
1361  // mux into an IEC958 packet
1362  m_spdifEnc->WriteFrame((unsigned char *)in_buffer, len);
1363  len = m_spdifEnc->GetProcessedSize();
1364  if (len > 0)
1365  {
1366  in_buffer = m_spdifEnc->GetProcessedBuffer();
1367  m_spdifEnc->Reset();
1368  frames = len / m_sourceBytesPerFrame;
1369  }
1370  else
1371  frames = 0;
1372  }
1374  ((double)(len * 1000) / (m_sourceSampleRate * m_sourceBytesPerFrame));
1375 
1376  VBAUDIOTS(QString("AddData frames=%1, bytes=%2, used=%3, free=%4, "
1377  "timecode=%5 needsupmix=%6")
1378  .arg(frames).arg(len).arg(used).arg(afree).arg(timecode.count())
1379  .arg(m_needsUpmix));
1380 
1381  // Mythmusic doesn't give us timestamps
1382  if (timecode < 0ms)
1383  {
1384  timecode = std::chrono::milliseconds((m_framesBuffered * 1000) / m_sourceSampleRate);
1385  m_framesBuffered += frames;
1386  music = true;
1387  }
1388 
1389  if (hasVisual())
1390  {
1391  // Send original samples to any attached visualisations
1392  dispatchVisual((uchar *)in_buffer, len, timecode, m_sourceChannels,
1394  }
1395 
1396  // Calculate amount of free space required in ringbuffer
1397  if (m_processing)
1398  {
1399  int sampleSize = AudioOutputSettings::SampleSize(m_format);
1400  if (sampleSize <= 0)
1401  {
1402  // Would lead to division by zero (or unexpected results if negative)
1403  VBERROR("Sample size is <= 0, AddData returning false");
1404  return false;
1405  }
1406 
1407  // Final float conversion space requirement
1408  len = sizeof(m_srcInBuf[0]) / sampleSize * len;
1409 
1410  // Account for changes in number of channels
1411  if (m_needsDownmix)
1412  len = (len * m_configuredChannels ) / m_sourceChannels;
1413 
1414  // Check we have enough space to write the data
1415  if (m_needResampler && m_srcCtx)
1416  len = lround(ceil(static_cast<double>(len) * m_srcData.src_ratio));
1417 
1418  if (m_needsUpmix)
1419  len = (len * m_configuredChannels ) / m_sourceChannels;
1420 
1421  // Include samples in upmix buffer that may be flushed
1422  if (m_needsUpmix && m_upmixer)
1423  len += m_upmixer->numUnprocessedFrames() * bpf;
1424 
1425  // Include samples in soundstretch buffers
1426  if (m_pSoundStretch)
1427  len += (m_pSoundStretch->numUnprocessedSamples() +
1428  (int)(m_pSoundStretch->numSamples() / m_stretchFactor)) * bpf;
1429  }
1430 
1431  if (len > afree)
1432  {
1433  VBERROR("Buffer is full, AddData returning false");
1434  return false; // would overflow
1435  }
1436 
1437  int frames_remaining = frames;
1438  int frames_final = 0;
1439  int maxframes = (kAudioSRCInputSize / m_sourceChannels) & ~0xf;
1440  int offset = 0;
1441 
1442  while(frames_remaining > 0)
1443  {
1444  void *buffer = (char *)in_buffer + offset;
1445  frames = frames_remaining;
1446  len = frames * m_sourceBytesPerFrame;
1447 
1448  if (m_processing)
1449  {
1450  if (frames > maxframes)
1451  {
1452  frames = maxframes;
1453  len = frames * m_sourceBytesPerFrame;
1454  offset += len;
1455  }
1456  // Convert to floats
1457  AudioOutputUtil::toFloat(m_format, m_srcIn, buffer, len);
1458  }
1459 
1460  frames_remaining -= frames;
1461 
1462  // Perform downmix if necessary
1463  if (m_needsDownmix)
1464  {
1467  m_srcIn, m_srcIn, frames) < 0)
1468  VBERROR("Error occurred while downmixing");
1469  }
1470 
1471  // Resample if necessary
1472  if (m_needResampler && m_srcCtx)
1473  {
1474  m_srcData.input_frames = frames;
1475  int error = src_process(m_srcCtx, &m_srcData);
1476 
1477  if (error)
1478  VBERROR(QString("Error occurred while resampling audio: %1")
1479  .arg(src_strerror(error)));
1480 
1481  buffer = m_srcOut;
1482  frames = m_srcData.output_frames_gen;
1483  }
1484  else if (m_processing)
1485  buffer = m_srcIn;
1486 
1487  /* we want the timecode of the last sample added but we are given the
1488  timecode of the first - add the time in ms that the frames added
1489  represent */
1490 
1491  // Copy samples into audiobuffer, with upmix if necessary
1492  if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
1493  {
1494  continue;
1495  }
1496 
1497  frames = len / bpf;
1498  frames_final += frames;
1499 
1500  int bdiff = kAudioRingBufferSize - m_waud;
1501  if ((len % bpf) != 0 && bdiff < len)
1502  {
1503  VBERROR(QString("AddData: Corruption likely: len = %1 (bpf = %2)")
1504  .arg(len)
1505  .arg(bpf));
1506  }
1507  if ((bdiff % bpf) != 0 && bdiff < len)
1508  {
1509  VBERROR(QString("AddData: Corruption likely: bdiff = %1 (bpf = %2)")
1510  .arg(bdiff)
1511  .arg(bpf));
1512  }
1513 
1514  if (m_pSoundStretch)
1515  {
1516  // does not change the timecode, only the number of samples
1517  org_waud = m_waud;
1518  int bdFrames = bdiff / bpf;
1519 
1520  if (bdiff < len)
1521  {
1522  m_pSoundStretch->putSamples((STST *)(WPOS), bdFrames);
1523  m_pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf);
1524  }
1525  else
1526  m_pSoundStretch->putSamples((STST *)(WPOS), frames);
1527 
1528  int nFrames = m_pSoundStretch->numSamples();
1529  if (nFrames > frames)
1530  CheckFreeSpace(nFrames);
1531 
1532  len = nFrames * bpf;
1533 
1534  if (nFrames > bdFrames)
1535  {
1536  nFrames -= m_pSoundStretch->receiveSamples((STST *)(WPOS),
1537  bdFrames);
1538  org_waud = 0;
1539  }
1540  if (nFrames > 0)
1541  nFrames = m_pSoundStretch->receiveSamples((STST *)(WPOS),
1542  nFrames);
1543 
1544  org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
1545  }
1546 
1547  if (m_internalVol && SWVolume())
1548  {
1549  org_waud = m_waud;
1550  int num = len;
1551 
1552  if (bdiff <= num)
1553  {
1555  music, m_needsUpmix && m_upmixer);
1556  num -= bdiff;
1557  org_waud = 0;
1558  }
1559  if (num > 0)
1561  music, m_needsUpmix && m_upmixer);
1562  org_waud = (org_waud + num) % kAudioRingBufferSize;
1563  }
1564 
1565  if (m_encoder)
1566  {
1567  org_waud = m_waud;
1568  int to_get = 0;
1569 
1570  if (bdiff < len)
1571  {
1573  to_get = m_encoder->Encode(ABUF, len - bdiff,
1575  }
1576  else
1577  {
1578  to_get = m_encoder->Encode(WPOS, len,
1580  }
1581 
1582  if (bdiff <= to_get)
1583  {
1584  m_encoder->GetFrames(WPOS, bdiff);
1585  to_get -= bdiff ;
1586  org_waud = 0;
1587  }
1588  if (to_get > 0)
1589  m_encoder->GetFrames(WPOS, to_get);
1590 
1591  org_waud = (org_waud + to_get) % kAudioRingBufferSize;
1592  }
1593 
1594  m_waud = org_waud;
1595  }
1596 
1597  SetAudiotime(frames_final, timecode);
1598 
1599  return true;
1600 }
1601 
1606 {
1607  std::chrono::milliseconds ct = GetAudiotime();
1608 
1609  if (ct < 0ms)
1610  ct = 0ms;
1611 
1612  if (m_sourceBitRate == -1)
1615 
1616  if (duration_cast<std::chrono::seconds>(ct) != m_currentSeconds)
1617  {
1618  m_currentSeconds = duration_cast<std::chrono::seconds>(ct);
1621  dispatch(e);
1622  }
1623 }
1624 
1630 {
1631  fill = kAudioRingBufferSize - audiofree();
1632  total = kAudioRingBufferSize;
1633 }
1634 
1641 {
1642  auto *zeros = new uchar[m_fragmentSize];
1643  auto *fragment_buf = new uchar[m_fragmentSize + 16];
1644  auto *fragment = (uchar *)AOALIGN(fragment_buf[0]);
1645  memset(zeros, 0, m_fragmentSize);
1646 
1647  // to reduce startup latency, write silence in 8ms chunks
1648  int zero_fragment_size = 8 * m_sampleRate * m_outputBytesPerFrame / 1000;
1649  if (zero_fragment_size > m_fragmentSize)
1650  zero_fragment_size = m_fragmentSize;
1651 
1652  while (!m_killAudio)
1653  {
1654  if (m_pauseAudio)
1655  {
1656  if (!m_actuallyPaused)
1657  {
1658  VBAUDIO("OutputAudioLoop: audio paused");
1660  dispatch(e);
1661  m_wasPaused = true;
1662  }
1663 
1664  m_actuallyPaused = true;
1665  m_audioTime = 0ms; // mark 'audiotime' as invalid.
1666 
1667  WriteAudio(zeros, zero_fragment_size);
1668  continue;
1669  }
1670 
1671  if (m_wasPaused)
1672  {
1673  VBAUDIO("OutputAudioLoop: Play Event");
1675  dispatch(e);
1676  m_wasPaused = false;
1677  }
1678 
1679  /* do audio output */
1680  int ready = audioready();
1681 
1682  // wait for the buffer to fill with enough to play
1683  if (m_fragmentSize > ready)
1684  {
1685  if (ready > 0) // only log if we're sending some audio
1686  {
1687  VBAUDIOTS(QString("audio waiting for buffer to fill: "
1688  "have %1 want %2")
1689  .arg(ready).arg(m_fragmentSize));
1690  }
1691 
1692  usleep(10ms);
1693  continue;
1694  }
1695 
1696 #ifdef AUDIOTSTESTING
1697  VBAUDIOTS("WriteAudio Start");
1698 #endif
1699  Status();
1700 
1701  // delay setting raud until after phys buffer is filled
1702  // so GetAudiotime will be accurate without locking
1704  volatile uint next_raud = m_raud;
1705  if (GetAudioData(fragment, m_fragmentSize, true, &next_raud))
1706  {
1707  if (!m_resetActive.TestAndDeref())
1708  {
1709  WriteAudio(fragment, m_fragmentSize);
1710  if (!m_resetActive.TestAndDeref())
1711  m_raud = next_raud;
1712  }
1713  }
1714 #ifdef AUDIOTSTESTING
1715  GetAudiotime();
1716  VBAUDIOTS("WriteAudio Done");
1717 #endif
1718 
1719  }
1720 
1721  delete[] zeros;
1722  delete[] fragment_buf;
1723  VBAUDIO("OutputAudioLoop: Stop Event");
1725  dispatch(e);
1726 }
1727 
1735 int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer,
1736  volatile uint *local_raud)
1737 {
1738 
1739 #define LRPOS (&m_audioBuffer[*local_raud])
1740  // re-check audioready() in case things changed.
1741  // for example, ClearAfterSeek() might have run
1742  int avail_size = audioready();
1743  int frag_size = size;
1744  int written_size = size;
1745 
1746  if (local_raud == nullptr)
1747  local_raud = &m_raud;
1748 
1749  if (!full_buffer && (size > avail_size))
1750  {
1751  // when full_buffer is false, return any available data
1752  frag_size = avail_size;
1753  written_size = frag_size;
1754  }
1755 
1756  if (!avail_size || (frag_size > avail_size))
1757  return 0;
1758 
1759  int bdiff = kAudioRingBufferSize - m_raud;
1760 
1762 
1763  if (obytes <= 0)
1764  return 0;
1765 
1766  bool fromFloats = m_processing && !m_enc && m_outputFormat != FORMAT_FLT;
1767 
1768  // Scale if necessary
1769  if (fromFloats && obytes != sizeof(float))
1770  frag_size *= sizeof(float) / obytes;
1771 
1772  int off = 0;
1773 
1774  if (bdiff <= frag_size)
1775  {
1776  if (fromFloats)
1777  {
1779  LRPOS, bdiff);
1780  }
1781  else
1782  {
1783  memcpy(buffer, LRPOS, bdiff);
1784  off = bdiff;
1785  }
1786 
1787  frag_size -= bdiff;
1788  *local_raud = 0;
1789  }
1790  if (frag_size > 0)
1791  {
1792  if (fromFloats)
1793  {
1795  LRPOS, frag_size);
1796  }
1797  else
1798  {
1799  memcpy(buffer + off, LRPOS, frag_size);
1800  }
1801  }
1802 
1803  *local_raud += frag_size;
1804 
1805  // Mute individual channels through mono->stereo duplication
1806  MuteState mute_state = GetMuteState();
1807  if (!m_enc && !m_passthru &&
1808  written_size && m_configuredChannels > 1 &&
1809  (mute_state == kMuteLeft || mute_state == kMuteRight))
1810  {
1812  mute_state == kMuteLeft ? 0 : 1,
1813  buffer, written_size);
1814  }
1815 
1816  return written_size;
1817 }
1818 
1823 {
1824  while (!m_pauseAudio && audioready() > m_fragmentSize)
1825  usleep(1ms);
1826  if (m_pauseAudio)
1827  {
1828  // Audio is paused and can't be drained, clear ringbuffer
1829  QMutexLocker lock(&m_audioBufLock);
1830 
1831  m_waud = m_raud = 0;
1832  }
1833 }
1834 
1839 {
1840  RunProlog();
1841  VBAUDIO(QString("kickoffOutputAudioLoop: pid = %1").arg(getpid()));
1842  OutputAudioLoop();
1843  VBAUDIO("kickoffOutputAudioLoop exiting");
1844  RunEpilog();
1845 }
1846 
1847 int AudioOutputBase::readOutputData(unsigned char* /*read_buffer*/, size_t /*max_length*/)
1848 {
1849  VBERROR("AudioOutputBase should not be getting asked to readOutputData()");
1850  return 0;
1851 }
AudioOutputBase::m_srcOut
float * m_srcOut
Definition: audiooutputbase.h:288
AudioOutput::GetError
QString GetError(void) const
Definition: audiooutput.h:148
AudioOutputBase::m_enc
bool m_enc
Definition: audiooutputbase.h:188
AudioOutputBase::m_outputSettingsRaw
AudioOutputSettings * m_outputSettingsRaw
Definition: audiooutputbase.h:223
AudioOutputBase::m_srcIn
float * m_srcIn
Definition: audiooutputbase.h:281
AudioOutputBase::Reset
void Reset(void) override
Reset the audiobuffer, timecode and mythmusic visualisation.
Definition: audiooutputbase.cpp:924
AudioOutputBase::m_pSoundStretch
soundtouch::SoundTouch * m_pSoundStretch
Definition: audiooutputbase.h:229
AudioOutputSettings::IsSupportedChannels
bool IsSupportedChannels(int channels)
Definition: audiooutputsettings.cpp:243
AudioOutputBase::m_discreteDigital
bool m_discreteDigital
Definition: audiooutputbase.h:185
AudioOutputBase::SetTimecode
void SetTimecode(std::chrono::milliseconds timecode) override
Set the timecode of the samples most recently added to the audiobuffer.
Definition: audiooutputbase.cpp:962
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:902
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:286
AudioOutputBase::m_raud
volatile uint m_raud
Audio circular buffer.
Definition: audiooutputbase.h:269
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:1316
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:1183
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:29
FORMAT_S16
@ FORMAT_S16
Definition: audiooutputsettings.h:28
STST
#define STST
Definition: audiooutputbase.cpp:38
AudioOutputBase::audiolen
int audiolen() const
Get the number of bytes in the audiobuffer.
Definition: audiooutputbase.cpp:983
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:275
kMuteRight
@ kMuteRight
Definition: volumebase.h:9
OutputEvent
Definition: output.h:31
AudioOutputBase::m_avsyncLock
QMutex m_avsyncLock
must hold avsync_lock to read or write 'audiotime' and 'audiotime_updated'
Definition: audiooutputbase.h:259
audiooutpututil.h
ABUF
#define ABUF
Definition: audiooutputbase.cpp:37
AudioOutputBase::m_forcedProcessing
bool m_forcedProcessing
Definition: audiooutputbase.h:304
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:227
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:296
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:303
OutputEvent::Stopped
static Type Stopped
Definition: output.h:67
AudioOutputBase::m_memoryCorruptionTest2
uint m_memoryCorruptionTest2
Definition: audiooutputbase.h:290
AudioOutputBase::SetupPassthrough
bool SetupPassthrough(AVCodecID codec, int codec_profile, int &samplerate_tmp, int &channels_tmp)
Definition: audiooutputbase.cpp:406
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:993
FEATURE_AC3
@ FEATURE_AC3
Definition: audiooutputsettings.h:37
AudioOutputBase::m_previousBpf
int m_previousBpf
Definition: audiooutputbase.h:305
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:860
AudioOutputSettings::FormatToBits
static int FormatToBits(AudioFormat format)
Definition: audiooutputsettings.cpp:149
MThread::usleep
static void usleep(std::chrono::microseconds time)
Definition: mthread.cpp:338
AudioOutputBase::readOutputData
int readOutputData(unsigned char *read_buffer, size_t max_length) override
Definition: audiooutputbase.cpp:1847
AudioOutputBase::GetAudiotime
std::chrono::milliseconds GetAudiotime(void) override
Calculate the timecode of the samples that are about to become audible.
Definition: audiooutputbase.cpp:1018
AudioOutputBase::GetStretchFactor
float GetStretchFactor(void) const override
Get the timetretch factor.
Definition: audiooutputbase.cpp:363
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:26
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:371
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:196
AudioOutputBase::SetEffDsp
void SetEffDsp(int dsprate) override
Set the effective DSP rate.
Definition: audiooutputbase.cpp:974
AudioOutputBase::m_audbufTimecode
std::chrono::milliseconds m_audbufTimecode
timecode of audio most recently placed into buffer
Definition: audiooutputbase.h:274
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:178
OutputListeners::error
void error(const QString &e)
Definition: output.cpp:29
AudioOutputBase::m_volume
int m_volume
Definition: audiooutputbase.h:240
AudioOutputBase::m_sourceChannels
int m_sourceChannels
Definition: audiooutputbase.h:233
FreeSurround::putFrames
uint putFrames(void *buffer, uint numFrames, uint numChannels)
Definition: freesurround.cpp:146
AudioOutputBase::m_killAudio
bool m_killAudio
Definition: audiooutputbase.h:195
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:1098
FreeSurround::numUnprocessedFrames
uint numUnprocessedFrames() const
Definition: freesurround.cpp:442
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:289
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:28
AudioOutputBase::m_lengthLastData
std::chrono::milliseconds m_lengthLastData
Definition: audiooutputbase.h:297
AudioOutputBase::m_mainDevice
QString m_mainDevice
Definition: audiooutputbase.h:183
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
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:1822
AudioOutputBase::m_stretchFactor
float m_stretchFactor
Definition: audiooutputbase.h:191
AudioOutputBase::m_unpauseWhenReady
bool m_unpauseWhenReady
Definition: audiooutputbase.h:200
AudioOutputBase::m_srcInBuf
std::array< float, kAudioSRCInputSize > m_srcInBuf
Definition: audiooutputbase.h:286
AudioOutputDigitalEncoder
Definition: audiooutputdigitalencoder.h:14
AudioOutputBase::m_upmixer
FreeSurround * m_upmixer
Definition: audiooutputbase.h:231
OutputEvent::Playing
static Type Playing
Definition: output.h:63
AudioOutputBase::m_killAudioLock
QMutex m_killAudioLock
Definition: audiooutputbase.h:277
mythlogging.h
AudioOutputBase::m_srcQuality
int m_srcQuality
Definition: audiooutputbase.h:213
LRPOS
#define LRPOS
AudioOutputBase::m_volumeControl
QString m_volumeControl
Definition: audiooutputbase.h:241
AudioOutputBase::m_audioThreadExists
bool m_audioThreadExists
Definition: audiooutputbase.h:247
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:176
AudioOutputBase::AudioOutputBase
AudioOutputBase(const AudioSettings &settings)
Definition: audiooutputbase.cpp:57
AudioOutputBase::m_waud
volatile uint m_waud
Definition: audiooutputbase.h:270
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:215
AudioOutputBase::QUALITY_LOW
@ QUALITY_LOW
Definition: audiooutputbase.h:209
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:236
AudioOutputBase::m_effStretchFactor
int m_effStretchFactor
Definition: audiooutputbase.h:192
AudioOutputBase::StopOutputThread
virtual void StopOutputThread(void)
Definition: audiooutputbase.cpp:848
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:466
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:287
FEATURE_LPCM
@ FEATURE_LPCM
Definition: audiooutputsettings.h:39
AudioOutputBase::m_oldStretchFactor
float m_oldStretchFactor
Definition: audiooutputbase.h:239
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:1735
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:205
AudioOutputBase::m_currentSeconds
std::chrono::seconds m_currentSeconds
Definition: audiooutputbase.h:279
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
AudioOutputBase::m_outputSettingsDigitalRaw
AudioOutputSettings * m_outputSettingsDigitalRaw
Definition: audiooutputbase.h:225
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:197
SPDIFEncoder::GetProcessedSize
int GetProcessedSize()
Definition: spdifencoder.cpp:139
AudioOutputBase::QUALITY_MEDIUM
@ QUALITY_MEDIUM
Definition: audiooutputbase.h:210
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:1838
AudioOutputBase::m_sourceBytesPerFrame
int m_sourceBytesPerFrame
Definition: audiooutputbase.h:234
uint
unsigned int uint
Definition: compat.h:144
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:60
VolumeBase::SWVolume
bool SWVolume(void) const
Definition: volumebase.cpp:105
AudioOutputBase::m_upmixDefault
bool m_upmixDefault
Definition: audiooutputbase.h:235
AudioOutputBase::m_passthru
bool m_passthru
Definition: audiooutputbase.h:187
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:1640
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:936
AudioOutputBase::m_outputFormat
AudioFormat m_outputFormat
Definition: audiooutputbase.h:177
AudioOutputBase::m_encoder
AudioOutputDigitalEncoder * m_encoder
Definition: audiooutputbase.h:230
AudioOutputBase::m_reEnc
bool m_reEnc
Definition: audiooutputbase.h:189
AudioOutputBase::GetSWVolume
int GetSWVolume(void) override
Get the volume for software volume control.
Definition: audiooutputbase.cpp:1170
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:930
AudioOutputBase::audioready
int audioready() const
Get the scaled number of bytes in the audiobuffer, i.e.
Definition: audiooutputbase.cpp:1008
AudioOutputBase::m_channels
int m_channels
Definition: audiooutputbase.h:172
AudioOutputBase::CopyWithUpmix
int CopyWithUpmix(char *buffer, int frames, uint &org_waud)
Copy frames into the audiobuffer, upmixing en route if necessary.
Definition: audiooutputbase.cpp:1218
AudioOutputBase::m_configuredChannels
int m_configuredChannels
Definition: audiooutputbase.h:204
AudioOutputBase::m_setInitialVol
bool m_setInitialVol
Definition: audiooutputbase.h:201
OutputEvent::Paused
static Type Paused
Definition: output.h:66
audiooutputdownmix.h
AudioOutputBase::m_spdifEnc
SPDIFEncoder * m_spdifEnc
Definition: audiooutputbase.h:301
AudioOutputBase::m_codec
AVCodecID m_codec
Definition: audiooutputbase.h:173
AudioOutputBase::SetSWVolume
void SetSWVolume(int new_volume, bool save) override
Set the volume for software volume control.
Definition: audiooutputbase.cpp:1160
AudioOutputBase::CanUpmix
bool CanUpmix(void) override
Upmixing of the current source is available if requested.
Definition: audiooutputbase.cpp:397
AudioSettings::m_usePassthru
bool m_usePassthru
Definition: audiosettings.h:78
AudioOutputBase::Status
virtual void Status(void)
Report status via an OutputEvent.
Definition: audiooutputbase.cpp:1605
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:175
audiooutputbase.h
AudioOutputBase::m_sourceBitRate
long m_sourceBitRate
Definition: audiooutputbase.h:214
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:198
AudioOutputBase::m_memoryCorruptionTest0
uint m_memoryCorruptionTest0
Definition: audiooutputbase.h:285
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:199
AudioOutputBase::m_surroundMode
int m_surroundMode
Definition: audiooutputbase.h:238
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:243
AsyncLooseLock::Clear
void Clear()
Definition: audiooutputbase.h:38
AudioOutputSettings
Definition: audiooutputsettings.h:49
AudioOutputBase::usesSpdif
bool usesSpdif() const
Definition: audiooutputbase.h:168
WPOS
#define WPOS
Definition: audiooutputbase.cpp:35
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:1304
AudioOutputSettings::NearestSupportedRate
int NearestSupportedRate(int rate)
Definition: audiooutputsettings.cpp:100
AudioOutputBase::QUALITY_DISABLED
@ QUALITY_DISABLED
Definition: audiooutputbase.h:208
AudioOutputBase::SetStretchFactor
void SetStretchFactor(float factor) override
Set the timestretch factor.
Definition: audiooutputbase.cpp:354
AudioOutputBase::m_bytesPerFrame
int m_bytesPerFrame
Definition: audiooutputbase.h:174
DigitalFeature
DigitalFeature
Definition: audiooutputsettings.h:35
AudioOutputBase::m_effDsp
int m_effDsp
Definition: audiooutputbase.h:179
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:211
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:914
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:836
AudioOutput::ClearError
void ClearError(void)
Definition: audiooutput.cpp:292
AudioOutputBase::m_audioBuffer
std::array< uchar, kAudioRingBufferSize > m_audioBuffer
main audio buffer
Definition: audiooutputbase.h:294
AudioOutputBase::m_audioBufLock
QMutex m_audioBufLock
Writes to the audiobuffer, reconfigures and audiobuffer resets can only take place while holding this...
Definition: audiooutputbase.h:253
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:193
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
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:180
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
SPDIFEncoder
Definition: spdifencoder.h:14
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:905
AudioOutputBase::m_outputSettings
AudioOutputSettings * m_outputSettings
Definition: audiooutputbase.h:224
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:1629
AudioOutputBase::m_framesBuffered
int64_t m_framesBuffered
Definition: audiooutputbase.h:245
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:1148
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_audioTime
std::chrono::milliseconds m_audioTime
timecode of audio leaving the soundcard (same units as timecodes)
Definition: audiooutputbase.h:264
AudioOutputBase::m_srcCtx
SRC_STATE * m_srcCtx
Definition: audiooutputbase.h:228
OutputListeners::prepareVisuals
void prepareVisuals()
Definition: output.cpp:63
AudioOutputBase::m_usesSpdif
bool m_usesSpdif
Definition: audiooutputbase.h:300
AudioOutputBase::kAudioSRCInputSize
static const uint kAudioSRCInputSize
Definition: audiooutputbase.h:120
AudioOutputBase::m_memoryCorruptionTest3
uint m_memoryCorruptionTest3
Definition: audiooutputbase.h:295
AudioOutputBase::ToggleUpmix
bool ToggleUpmix(void) override
Toggle between stereo and upmixed 5.1 if the source material is stereo.
Definition: audiooutputbase.cpp:379
AudioOutputBase::m_srcData
SRC_DATA m_srcData
Definition: audiooutputbase.h:284
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:922
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:226
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:237
AsyncLooseLock::TestAndDeref
bool TestAndDeref()
Definition: audiooutputbase.h:40
AudioOutputBase::OutputSettings
AudioOutputSettings * OutputSettings(bool digital=true)
Definition: audiooutputbase.cpp:454