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