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_main_device(settings.GetMainDevice()),
60  m_passthru_device(settings.GetPassthruDevice()),
61  source(settings.m_source),
62  m_set_initial_vol(settings.m_set_initial_vol)
63 {
64  m_src_in = (float *)AOALIGN(m_src_in_buf);
65  memset(&m_src_data, 0, sizeof(SRC_DATA));
66  memset(m_src_in_buf, 0, sizeof(m_src_in_buf));
67  memset(m_audiobuffer, 0, sizeof(m_audiobuffer));
68 
69  if (m_main_device.startsWith("OpenMAX:")
70  || m_main_device.startsWith("AudioTrack:"))
71  m_usesSpdif = false;
72  // Handle override of SRC quality settings
73  if (gCoreContext->GetBoolSetting("SRCQualityOverride", false))
74  {
76  // Extra test to keep backward compatibility with earlier SRC setting
79 
80  VBAUDIO(QString("SRC quality = %1").arg(quality_string(m_src_quality)));
81  }
82 }
83 
90 {
91  if (!m_killaudio)
92  VBERROR("Programmer Error: "
93  "~AudioOutputBase called, but KillAudio has not been called!");
94 
95  // We got this from a subclass, delete it
96  delete m_output_settings;
97  delete m_output_settingsraw;
99  {
102  }
103 
104  if (m_kAudioSRCOutputSize > 0)
105  delete[] m_src_out;
106 
107 #ifndef NDEBUG
108  assert(m_memory_corruption_test0 == 0xdeadbeef);
109  assert(m_memory_corruption_test1 == 0xdeadbeef);
110  assert(m_memory_corruption_test2 == 0xdeadbeef);
111  assert(m_memory_corruption_test3 == 0xdeadbeef);
112 #else
113  Q_UNUSED(m_memory_corruption_test0);
114  Q_UNUSED(m_memory_corruption_test1);
115  Q_UNUSED(m_memory_corruption_test2);
116  Q_UNUSED(m_memory_corruption_test3);
117 #endif
118 }
119 
121 {
122  if (settings.m_custom)
123  {
124  // got a custom audio report already, use it
125  // this was likely provided by the AudioTest utility
127  *m_output_settings = *settings.m_custom;
131  return;
132  }
133 
134  // Ask the subclass what we can send to the device
137 
141 
143  gCoreContext->GetBoolSetting("AudioDefaultUpmix", false) :
144  false;
145  if (settings.m_upmixer == 1) // music, upmixer off
146  m_upmix_default = false;
147  else if (settings.m_upmixer == 2) // music, upmixer on
148  m_upmix_default = true;
149 }
150 
157 {
158  // If we've already checked the port, use the cache
159  // version instead
160  if (!m_discretedigital || !digital)
161  {
162  digital = false;
164  return m_output_settingsraw;
165  }
168 
169  AudioOutputSettings* aosettings = GetOutputSettings(digital);
170  if (aosettings)
171  aosettings->GetCleaned();
172  else
173  aosettings = new AudioOutputSettings(true);
174 
175  if (digital)
176  return (m_output_settingsdigitalraw = aosettings);
177  return (m_output_settingsraw = aosettings);
178 }
179 
186 {
187  if (!m_discretedigital || !digital)
188  {
189  digital = false;
190  if (m_output_settings)
191  return m_output_settings;
192  }
193  else if (m_output_settingsdigital)
195 
196  AudioOutputSettings* aosettings = new AudioOutputSettings;
197 
198  *aosettings = *GetOutputSettingsCleaned(digital);
199  aosettings->GetUsers();
200 
201  if (digital)
202  return (m_output_settingsdigital = aosettings);
203  return (m_output_settings = aosettings);
204 }
205 
209 bool AudioOutputBase::CanPassthrough(int samplerate, int channels,
210  AVCodecID codec, int profile) const
211 {
213  bool ret = !(internal_vol && SWVolume());
214 
215  switch(codec)
216  {
217  case AV_CODEC_ID_AC3:
218  arg = FEATURE_AC3;
219  break;
220  case AV_CODEC_ID_DTS:
221  switch(profile)
222  {
223  case FF_PROFILE_DTS:
224  case FF_PROFILE_DTS_ES:
225  case FF_PROFILE_DTS_96_24:
226  arg = FEATURE_DTS;
227  break;
228  case FF_PROFILE_DTS_HD_HRA:
229  case FF_PROFILE_DTS_HD_MA:
230  arg = FEATURE_DTSHD;
231  break;
232  default:
233  break;
234  }
235  break;
236  case AV_CODEC_ID_EAC3:
237  arg = FEATURE_EAC3;
238  break;
239  case AV_CODEC_ID_TRUEHD:
240  arg = FEATURE_TRUEHD;
241  break;
242  default:
243  arg = FEATURE_NONE;
244  break;
245  }
246  // we can't passthrough any other codecs than those defined above
249  ret &= m_output_settingsdigital->IsSupportedRate(samplerate);
250  // if we must resample to 48kHz ; we can't passthrough
251  ret &= !((samplerate != 48000) &&
252  gCoreContext->GetBoolSetting("Audio48kOverride", false));
253  // Don't know any cards that support spdif clocked at < 44100
254  // Some US cable transmissions have 2ch 32k AC-3 streams
255  ret &= samplerate >= 44100;
256  if (!ret)
257  return false;
258  // Will passthrough if surround audio was defined. Amplifier will
259  // do the downmix if required
260  bool willupmix = m_max_channels >= 6 && (channels <= 2 && m_upmix_default);
261  ret &= !willupmix;
262  // unless audio is configured for stereo. We can passthrough otherwise
263  ret |= m_max_channels == 2;
264 
265  return ret;
266 }
267 
272 {
273  if (rate > 0)
274  m_source_bitrate = rate;
275 }
276 
282 void AudioOutputBase::SetStretchFactorLocked(float lstretchfactor)
283 {
284  if (m_stretchfactor == lstretchfactor && m_pSoundStretch)
285  return;
286 
287  m_stretchfactor = lstretchfactor;
288 
289  int channels = m_needs_upmix || m_needs_downmix ?
291  if (channels < 1 || channels > 8 || !m_configure_succeeded)
292  return;
293 
294  bool willstretch = m_stretchfactor < 0.99F || m_stretchfactor > 1.01F;
295  m_eff_stretchfactor = lroundf(100000.0F * lstretchfactor);
296 
297  if (m_pSoundStretch)
298  {
299  if (!willstretch && m_forcedprocessing)
300  {
301  m_forcedprocessing = false;
302  m_processing = false;
303  delete m_pSoundStretch;
304  m_pSoundStretch = nullptr;
305  VBGENERAL(QString("Cancelling time stretch"));
307  m_waud = m_raud = 0;
309  }
310  else
311  {
312  VBGENERAL(QString("Changing time stretch to %1")
313  .arg(m_stretchfactor));
314  m_pSoundStretch->setTempo(m_stretchfactor);
315  }
316  }
317  else if (willstretch)
318  {
319  VBGENERAL(QString("Using time stretch %1").arg(m_stretchfactor));
320  m_pSoundStretch = new soundtouch::SoundTouch();
321  m_pSoundStretch->setSampleRate(m_samplerate);
322  m_pSoundStretch->setChannels(channels);
323  m_pSoundStretch->setTempo(m_stretchfactor);
324 #if ARCH_ARM || defined(Q_OS_ANDROID)
325  // use less demanding settings for Raspberry pi
326  m_pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 82);
327  m_pSoundStretch->setSetting(SETTING_USE_AA_FILTER, 0);
328  m_pSoundStretch->setSetting(SETTING_USE_QUICKSEEK, 1);
329 #else
330  m_pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
331 #endif
332  /* If we weren't already processing we need to turn on float conversion
333  adjust sample and frame sizes accordingly and dump the contents of
334  the audiobuffer */
335  if (!m_processing)
336  {
337  m_processing = true;
338  m_forcedprocessing = true;
343  m_waud = m_raud = 0;
346  m_pauseaudio = true;
347  m_actually_paused = false;
348  m_unpause_when_ready = true;
349  }
350  }
351 }
352 
356 void AudioOutputBase::SetStretchFactor(float lstretchfactor)
357 {
358  QMutexLocker lock(&m_audio_buflock);
359  SetStretchFactorLocked(lstretchfactor);
360 }
361 
366 {
367  return m_stretchfactor;
368 }
369 
374 {
375  return m_needs_upmix && m_upmixer;
376 }
377 
382 {
383  // Can only upmix from mono/stereo to 6 ch
384  if (m_max_channels == 2 || m_source_channels > 2)
385  return false;
386 
388 
391  m_upmix_default ? false : m_passthru);
392  Reconfigure(settings);
393  return IsUpmixing();
394 }
395 
400 {
401  return m_source_channels <= 2 && m_max_channels > 2;
402 }
403 
404 /*
405  * Setup samplerate and number of channels for passthrough
406  * Create SPDIF encoder and true if successful
407  */
408 bool AudioOutputBase::SetupPassthrough(AVCodecID codec, int codec_profile,
409  int &samplerate_tmp, int &channels_tmp)
410 {
411  if (codec == AV_CODEC_ID_DTS &&
413  {
414  // We do not support DTS-HD bitstream so force extraction of the
415  // DTS core track instead
416  codec_profile = FF_PROFILE_DTS;
417  }
419  codec, codec_profile,
420  samplerate_tmp, channels_tmp,
422  VBAUDIO("Setting " + log + " passthrough");
423 
424  delete m_spdifenc;
425 
426  // No spdif encoder needed for certain devices
427  if (m_usesSpdif)
428  m_spdifenc = new SPDIFEncoder("spdif", codec);
429  else
430  m_spdifenc = nullptr;
431  if (m_spdifenc && m_spdifenc->Succeeded() && codec == AV_CODEC_ID_DTS)
432  {
433  switch(codec_profile)
434  {
435  case FF_PROFILE_DTS:
436  case FF_PROFILE_DTS_ES:
437  case FF_PROFILE_DTS_96_24:
439  break;
440  case FF_PROFILE_DTS_HD_HRA:
441  case FF_PROFILE_DTS_HD_MA:
442  m_spdifenc->SetMaxHDRate(samplerate_tmp * channels_tmp / 2);
443  break;
444  }
445  }
446 
447  if (m_spdifenc && !m_spdifenc->Succeeded())
448  {
449  delete m_spdifenc;
450  m_spdifenc = nullptr;
451  return false;
452  }
453  return true;
454 }
455 
457 {
458  if (digital)
460  return m_output_settings;
461 }
462 
468 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
469 {
470  AudioSettings settings = orig_settings;
471  int lsource_channels = settings.m_channels;
472  int lconfigured_channels = m_configured_channels;
473  bool lneeds_upmix = false;
474  bool lneeds_downmix = false;
475  bool lreenc = false;
476  bool lenc = false;
477 
478  if (!settings.m_use_passthru)
479  {
480  // Do we upmix stereo or mono?
481  lconfigured_channels =
482  (m_upmix_default && lsource_channels <= 2) ? 6 : lsource_channels;
483  bool cando_channels =
484  m_output_settings->IsSupportedChannels(lconfigured_channels);
485 
486  // check if the number of channels could be transmitted via AC3 encoding
487 #ifndef DISABLE_AC3_ENCODE
490  lconfigured_channels > 2 && lconfigured_channels <= 6);
491 #endif
492  if (!lenc && !cando_channels)
493  {
494  // if hardware doesn't support source audio configuration
495  // we will upmix/downmix to what we can
496  // (can safely assume hardware supports stereo)
497  switch (lconfigured_channels)
498  {
499  case 7:
500  lconfigured_channels = 8;
501  break;
502  case 8:
503  case 5:
504  lconfigured_channels = 6;
505  break;
506  case 6:
507  case 4:
508  case 3:
509  case 2: //Will never happen
510  lconfigured_channels = 2;
511  break;
512  case 1:
513  lconfigured_channels = m_upmix_default ? 6 : 2;
514  break;
515  default:
516  lconfigured_channels = 2;
517  break;
518  }
519  }
520  // Make sure we never attempt to output more than what we can
521  // the upmixer can only upmix to 6 channels when source < 6
522  if (lsource_channels <= 6)
523  lconfigured_channels = min(lconfigured_channels, 6);
524  lconfigured_channels = min(lconfigured_channels, m_max_channels);
525  /* Encode to AC-3 if we're allowed to passthru but aren't currently
526  and we have more than 2 channels but multichannel PCM is not
527  supported or if the device just doesn't support the number of
528  channels */
529 #ifndef DISABLE_AC3_ENCODE
532  lconfigured_channels > 2) ||
533  !m_output_settings->IsSupportedChannels(lconfigured_channels));
534  /* Might we reencode a bitstream that's been decoded for timestretch?
535  If the device doesn't support the number of channels - see below */
537  (settings.m_codec == AV_CODEC_ID_AC3 ||
538  settings.m_codec == AV_CODEC_ID_DTS))
539  {
540  lreenc = true;
541  }
542 #endif
543  // Enough channels? Upmix if not, but only from mono/stereo/5.0 to 5.1
544  if (IS_VALID_UPMIX_CHANNEL(settings.m_channels) &&
545  settings.m_channels < lconfigured_channels)
546  {
547  VBAUDIO(QString("Needs upmix from %1 -> %2 channels")
548  .arg(settings.m_channels).arg(lconfigured_channels));
549  settings.m_channels = lconfigured_channels;
550  lneeds_upmix = true;
551  }
552  else if (settings.m_channels > lconfigured_channels)
553  {
554  VBAUDIO(QString("Needs downmix from %1 -> %2 channels")
555  .arg(settings.m_channels).arg(lconfigured_channels));
556  settings.m_channels = lconfigured_channels;
557  lneeds_downmix = true;
558  }
559  }
560 
561  ClearError();
562 
563  bool general_deps = true;
564 
565  /* Set samplerate_tmp and channels_tmp to appropriate values
566  if passing through */
567  int samplerate_tmp, channels_tmp;
568  if (settings.m_use_passthru)
569  {
570  samplerate_tmp = settings.m_samplerate;
571  SetupPassthrough(settings.m_codec, settings.m_codec_profile,
572  samplerate_tmp, channels_tmp);
573  general_deps = m_samplerate == samplerate_tmp && m_channels == channels_tmp;
574  general_deps &= m_format == m_output_format && m_format == FORMAT_S16;
575  }
576  else
577  {
578  general_deps =
579  settings.m_format == m_format && lsource_channels == m_source_channels;
580  }
581 
582  // Check if anything has changed
583  general_deps &=
584  settings.m_samplerate == m_source_samplerate &&
585  settings.m_use_passthru == m_passthru &&
586  lconfigured_channels == m_configured_channels &&
587  lneeds_upmix == m_needs_upmix && lreenc == m_reenc &&
588  lneeds_downmix == m_needs_downmix;
589 
590  if (general_deps && m_configure_succeeded)
591  {
592  VBAUDIO("Reconfigure(): No change -> exiting");
593  // if passthrough, source channels may have changed
594  m_source_channels = lsource_channels;
595  return;
596  }
597 
598  KillAudio();
599 
600  QMutexLocker lock(&m_audio_buflock);
601  QMutexLocker lockav(&m_avsync_lock);
602 
603  m_waud = m_raud = 0;
606 
607  m_channels = settings.m_channels;
608  m_source_channels = lsource_channels;
609  m_reenc = lreenc;
610  m_codec = settings.m_codec;
611  m_passthru = settings.m_use_passthru;
612  m_configured_channels = lconfigured_channels;
613  m_needs_upmix = lneeds_upmix;
614  m_needs_downmix = lneeds_downmix;
615  m_format = m_output_format = settings.m_format;
617  m_enc = lenc;
618 
619  m_killaudio = m_pauseaudio = false;
620  m_was_paused = true;
621 
622  // Don't try to do anything if audio hasn't been
623  // initialized yet (e.g. rubbish was provided)
624  if (m_source_channels <= 0 || m_format <= 0 || m_samplerate <= 0)
625  {
626  SilentError(QString("Aborting Audio Reconfigure. ") +
627  QString("Invalid audio parameters ch %1 fmt %2 @ %3Hz")
628  .arg(m_source_channels).arg(m_format).arg(m_samplerate));
629  return;
630  }
631 
632  VBAUDIO(QString("Original codec was %1, %2, %3 kHz, %4 channels")
633  .arg(ff_codec_id_string(m_codec))
635  .arg(m_samplerate/1000)
636  .arg(m_source_channels));
637 
639  {
640  Error(QObject::tr("Aborting Audio Reconfigure. "
641  "Can't handle audio with more than 8 channels."));
642  return;
643  }
644 
645  VBAUDIO(QString("enc(%1), passthru(%2), features (%3) "
646  "configured_channels(%4), %5 channels supported(%6) "
647  "max_channels(%7)")
648  .arg(m_enc)
649  .arg(m_passthru)
652  .arg(m_channels)
653  .arg(OutputSettings(m_enc || m_passthru)->IsSupportedChannels(m_channels))
654  .arg(m_max_channels));
655 
656  int dest_rate = 0;
657 
658  // Force resampling if we are encoding to AC3 and sr > 48k
659  // or if 48k override was checked in settings
660  if ((m_samplerate != 48000 &&
661  gCoreContext->GetBoolSetting("Audio48kOverride", false)) ||
662  (m_enc && (m_samplerate > 48000)))
663  {
664  VBAUDIO("Forcing resample to 48 kHz");
665  if (m_src_quality < 0)
667  m_need_resampler = true;
668  dest_rate = 48000;
669  }
670  // this will always be false for passthrough audio as
671  // CanPassthrough() already tested these conditions
672  else if ((m_need_resampler =
673  !OutputSettings(m_enc || m_passthru)->IsSupportedRate(m_samplerate)))
674  {
676  }
677 
679  {
680  int error;
681  m_samplerate = dest_rate;
682 
683  VBGENERAL(QString("Resampling from %1 kHz to %2 kHz with quality %3")
684  .arg(settings.m_samplerate/1000).arg(m_samplerate/1000)
686 
688 
689  m_src_ctx = src_new(2-m_src_quality, chans, &error);
690  if (error)
691  {
692  Error(QObject::tr("Error creating resampler: %1")
693  .arg(src_strerror(error)));
694  m_src_ctx = nullptr;
695  return;
696  }
697 
698  m_src_data.src_ratio = (double)m_samplerate / settings.m_samplerate;
699  m_src_data.data_in = m_src_in;
700  int newsize = (int)(kAudioSRCInputSize * m_src_data.src_ratio + 15)
701  & ~0xf;
702 
703  if (m_kAudioSRCOutputSize < newsize)
704  {
705  m_kAudioSRCOutputSize = newsize;
706  VBAUDIO(QString("Resampler allocating %1").arg(newsize));
707  delete[] m_src_out;
708  m_src_out = new float[m_kAudioSRCOutputSize];
709  }
710  m_src_data.data_out = m_src_out;
711  m_src_data.output_frames = m_kAudioSRCOutputSize / chans;
712  m_src_data.end_of_input = 0;
713  }
714 
715  if (m_enc)
716  {
717  if (m_reenc)
718  VBAUDIO("Reencoding decoded AC-3/DTS to AC-3");
719 
720  VBAUDIO(QString("Creating AC-3 Encoder with sr = %1, ch = %2")
722 
724  if (!m_encoder->Init(AV_CODEC_ID_AC3, 448000, m_samplerate,
726  {
727  Error(QObject::tr("AC-3 encoder initialization failed"));
728  delete m_encoder;
729  m_encoder = nullptr;
730  m_enc = false;
731  // upmixing will fail if we needed the encoder
732  m_needs_upmix = false;
733  }
734  }
735 
736  if (m_passthru)
737  {
738  //AC3, DTS, DTS-HD MA and TrueHD all use 16 bits samples
739  m_channels = channels_tmp;
740  m_samplerate = samplerate_tmp;
744  }
745  else
746  {
749  }
750 
751  // Turn on float conversion?
753  m_stretchfactor != 1.0F || (internal_vol && SWVolume()) ||
754  (m_enc && m_output_format != FORMAT_S16) ||
755  !OutputSettings(m_enc || m_passthru)->IsSupportedFormat(m_output_format))
756  {
757  VBAUDIO("Audio processing enabled");
758  m_processing = true;
759  if (m_enc)
760  m_output_format = FORMAT_S16; // Output s16le for AC-3 encoder
761  else
763  }
764 
766  sizeof(float) : AudioOutputSettings::SampleSize(m_format);
768 
769  if (m_enc)
770  m_channels = 2; // But only post-encoder
771 
774 
775  VBGENERAL(
776  QString("Opening audio device '%1' ch %2(%3) sr %4 sf %5 reenc %6")
779 
782  m_effdsp = m_samplerate * 100;
783 
784  // Actually do the device specific open call
785  if (!OpenDevice())
786  {
787  if (GetError().isEmpty())
788  Error(QObject::tr("Aborting reconfigure"));
789  else
790  VBGENERAL("Aborting reconfigure");
791  m_configure_succeeded = false;
792  return;
793  }
794 
795  VBAUDIO(QString("Audio fragment size: %1").arg(m_fragment_size));
796 
797  // Only used for software volume
799  {
800  VBAUDIO("Software volume enabled");
801  m_volumeControl = gCoreContext->GetSetting("MixerControl", "PCM");
802  m_volumeControl += "MixerVolume";
804  }
805 
809 
811  {
815  VBAUDIO(QString("Create %1 quality upmixer done")
817  }
818 
819  VBAUDIO(QString("Audio Stretch Factor: %1").arg(m_stretchfactor));
821 
822  // Setup visualisations, zero the visualisations buffers
823  prepareVisuals();
824 
827 
828  m_configure_succeeded = true;
829 
831 
832  VBAUDIO("Ending Reconfigure()");
833 }
834 
836 {
838  return true;
839 
840  start();
841  m_audio_thread_exists = true;
842 
843  return true;
844 }
845 
846 
848 {
850  {
851  wait();
852  m_audio_thread_exists = false;
853  }
854 }
855 
860 {
861  m_killAudioLock.lock();
862 
863  VBAUDIO("Killing AudioOutputDSP");
864  m_killaudio = true;
866  QMutexLocker lock(&m_audio_buflock);
867 
868  if (m_pSoundStretch)
869  {
870  delete m_pSoundStretch;
871  m_pSoundStretch = nullptr;
873  m_stretchfactor = 1.0F;
874  }
875 
876  if (m_encoder)
877  {
878  delete m_encoder;
879  m_encoder = nullptr;
880  }
881 
882  if (m_upmixer)
883  {
884  delete m_upmixer;
885  m_upmixer = nullptr;
886  }
887 
888  if (m_src_ctx)
889  {
890  src_delete(m_src_ctx);
891  m_src_ctx = nullptr;
892  }
893 
895 
896  CloseDevice();
897 
898  m_killAudioLock.unlock();
899 }
900 
901 void AudioOutputBase::Pause(bool paused)
902 {
903  if (!paused && m_unpause_when_ready)
904  return;
905  VBAUDIO(QString("Pause %1").arg(paused));
906  if (m_pauseaudio != paused)
908  m_pauseaudio = paused;
909  m_unpause_when_ready = false;
910  m_actually_paused = false;
911 }
912 
914 {
915  Reset();
916  Pause(true);
917  m_unpause_when_ready = true;
918 }
919 
924 {
925  QMutexLocker lock(&m_audio_buflock);
926  QMutexLocker lockav(&m_avsync_lock);
927 
929  if (m_encoder)
930  {
931  m_waud = m_raud = 0; // empty ring buffer
933  }
934  else
935  {
936  m_waud = m_raud; // empty ring buffer
937  }
939  m_current_seconds = -1;
941  // clear any state that could remember previous audio in any active filters
942  if (m_needs_upmix && m_upmixer)
943  m_upmixer->flush();
944  if (m_pSoundStretch)
945  m_pSoundStretch->clear();
946  if (m_encoder)
947  m_encoder->clear();
948 
949  // Setup visualisations, zero the visualisations buffers
950  prepareVisuals();
951 }
952 
959 void AudioOutputBase::SetTimecode(int64_t timecode)
960 {
961  m_audbuf_timecode = m_audiotime = timecode;
962  m_frames_buffered = (timecode * m_source_samplerate) / 1000;
963 }
964 
971 void AudioOutputBase::SetEffDsp(int dsprate)
972 {
973  VBAUDIO(QString("SetEffDsp: %1").arg(dsprate));
974  m_effdsp = dsprate;
975 }
976 
980 inline int AudioOutputBase::audiolen() const
981 {
982  if (m_waud >= m_raud)
983  return m_waud - m_raud;
984  return kAudioRingBufferSize - (m_raud - m_waud);
985 }
986 
991 {
992  return kAudioRingBufferSize - audiolen() - 1;
993  /* There is one wasted byte in the buffer. The case where waud = raud is
994  interpreted as an empty buffer, so the fullest the buffer can ever
995  be is kAudioRingBufferSize - 1. */
996 }
997 
1006 {
1008  return audiolen();
1010 }
1011 
1016 {
1018  return 0;
1019 
1020  // output bits per 10 frames
1021  int64_t obpf;
1022 
1023  if (m_passthru && !usesSpdif())
1024  obpf = m_source_bitrate * 10 / m_source_samplerate;
1025  else
1026  if (m_enc && !usesSpdif())
1027  {
1028  // re-encode bitrate is hardcoded at 448000
1029  obpf = 448000 * 10 / m_source_samplerate;
1030  }
1031  else
1032  obpf = m_output_bytes_per_frame * 80;
1033 
1034  int64_t oldaudiotime;
1035 
1036  /* We want to calculate '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  'effdsp' is 100 * frames/sec
1042 
1043  'audbuf_timecode' is the timecode in milliseconds of the
1044  audio that has just been written into the buffer.
1045 
1046  'eff_stretchfactor' 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_avsync_lock);
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  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_audbuf_timecode - (m_effdsp && obpf ?
1068  ((main_buffer + soundcard_buffer) * int64_t(m_eff_stretchfactor)
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).arg(m_audbuf_timecode) // 1, 2
1080  .arg(main_buffer) // 3
1081  .arg(soundcard_buffer) // 4
1082  .arg(main_buffer+soundcard_buffer) // 5
1083  .arg(m_samplerate).arg(obpf) // 6, 7
1084  .arg(m_bytes_per_frame) // 8
1085  .arg(m_eff_stretchfactor) // 9
1086  .arg(m_effdsp).arg(m_source_bitrate) // 10, 11
1087  );
1088 
1089  return m_audiotime;
1090 }
1091 
1097 void AudioOutputBase::SetAudiotime(int frames, int64_t timecode)
1098 {
1099  int64_t processframes_stretched = 0;
1100  int64_t processframes_unstretched = 0;
1101  int64_t old_audbuf_timecode = m_audbuf_timecode;
1102 
1103  if (!m_configure_succeeded)
1104  return;
1105 
1106  if (m_needs_upmix && m_upmixer)
1107  processframes_unstretched -= m_upmixer->frameLatency();
1108 
1109  if (m_pSoundStretch)
1110  {
1111  processframes_unstretched -= m_pSoundStretch->numUnprocessedSamples();
1112  processframes_stretched -= m_pSoundStretch->numSamples();
1113  }
1114 
1115  if (m_encoder)
1116  {
1117  processframes_stretched -= m_encoder->Buffered();
1118  }
1119 
1121  timecode + (m_effdsp ? ((frames + processframes_unstretched) * 100000 +
1122  (processframes_stretched * m_eff_stretchfactor)
1123  ) / m_effdsp : 0);
1124 
1125  // check for timecode wrap and reset audiotime if detected
1126  // timecode will always be monotonic asc if not seeked and reset
1127  // happens if seek or pause happens
1128  if (m_audbuf_timecode < old_audbuf_timecode)
1129  m_audiotime = 0;
1130 
1131  VBAUDIOTS(QString("SetAudiotime atc=%1 tc=%2 f=%3 pfu=%4 pfs=%5")
1132  .arg(m_audbuf_timecode)
1133  .arg(timecode)
1134  .arg(frames)
1135  .arg(processframes_unstretched)
1136  .arg(processframes_stretched));
1137 #ifdef AUDIOTSTESTING
1138  GetAudiotime();
1139 #endif
1140 }
1141 
1148 {
1149  int64_t ret = m_audbuf_timecode - GetAudiotime();
1150  // Pulse can give us values that make this -ve
1151  if (ret < 0)
1152  return 0;
1153  return ret;
1154 }
1155 
1159 void AudioOutputBase::SetSWVolume(int new_volume, bool save)
1160 {
1161  m_volume = new_volume;
1162  if (save && m_volumeControl != nullptr)
1164 }
1165 
1170 {
1171  return m_volume;
1172 }
1173 
1183 {
1184  int bpf = m_bytes_per_frame;
1185  int len = frames * bpf;
1186  int afree = audiofree();
1187 
1188  if (len <= afree)
1189  return len;
1190 
1191  VBERROR(QString("Audio buffer overflow, %1 frames lost!")
1192  .arg(frames - (afree / bpf)));
1193 
1194  frames = afree / bpf;
1195  len = frames * bpf;
1196 
1197  if (!m_src_ctx)
1198  return len;
1199 
1200  int error = src_reset(m_src_ctx);
1201  if (error)
1202  {
1203  VBERROR(QString("Error occurred while resetting resampler: %1")
1204  .arg(src_strerror(error)));
1205  m_src_ctx = nullptr;
1206  }
1207 
1208  return len;
1209 }
1210 
1217 int AudioOutputBase::CopyWithUpmix(char *buffer, int frames, uint &org_waud)
1218 {
1219  int len = CheckFreeSpace(frames);
1220  int bdiff = kAudioRingBufferSize - org_waud;
1221  int bpf = m_bytes_per_frame;
1222  int off = 0;
1223 
1224  if (!m_needs_upmix)
1225  {
1226  int num = len;
1227 
1228  if (bdiff <= num)
1229  {
1230  memcpy(WPOS, buffer, bdiff);
1231  num -= bdiff;
1232  off = bdiff;
1233  org_waud = 0;
1234  }
1235  if (num > 0)
1236  memcpy(WPOS, buffer + off, num);
1237  org_waud = (org_waud + num) % kAudioRingBufferSize;
1238  return len;
1239  }
1240 
1241  // Convert mono to stereo as most devices can't accept mono
1242  if (!m_upmixer)
1243  {
1244  // we're always in the case
1245  // m_configured_channels == 2 && m_source_channels == 1
1246  int bdFrames = bdiff / bpf;
1247  if (bdFrames <= frames)
1248  {
1249  AudioOutputUtil::MonoToStereo(WPOS, buffer, bdFrames);
1250  frames -= bdFrames;
1251  off = bdFrames * sizeof(float); // 1 channel of floats
1252  org_waud = 0;
1253  }
1254  if (frames > 0)
1255  AudioOutputUtil::MonoToStereo(WPOS, buffer + off, frames);
1256 
1257  org_waud = (org_waud + frames * bpf) % kAudioRingBufferSize;
1258  return len;
1259  }
1260 
1261  // Upmix to 6ch via FreeSurround
1262  // Calculate frame size of input
1263  off = m_processing ? sizeof(float) : AudioOutputSettings::SampleSize(m_format);
1264  off *= m_source_channels;
1265 
1266  int i = 0;
1267  len = 0;
1268  while (i < frames)
1269  {
1270  i += m_upmixer->putFrames(buffer + i * off, frames - i, m_source_channels);
1271  int nFrames = m_upmixer->numFrames();
1272  if (!nFrames)
1273  continue;
1274 
1275  len += CheckFreeSpace(nFrames);
1276 
1277  int bdFrames = (kAudioRingBufferSize - org_waud) / bpf;
1278  if (bdFrames < nFrames)
1279  {
1280  if ((org_waud % bpf) != 0)
1281  {
1282  VBERROR(QString("Upmixing: org_waud = %1 (bpf = %2)")
1283  .arg(org_waud)
1284  .arg(bpf));
1285  }
1286  m_upmixer->receiveFrames((float *)(WPOS), bdFrames);
1287  nFrames -= bdFrames;
1288  org_waud = 0;
1289  }
1290  if (nFrames > 0)
1291  m_upmixer->receiveFrames((float *)(WPOS), nFrames);
1292 
1293  org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
1294  }
1295  return len;
1296 }
1297 
1303 bool AudioOutputBase::AddFrames(void *in_buffer, int in_frames,
1304  int64_t timecode)
1305 {
1306  return AddData(in_buffer, in_frames * m_source_bytes_per_frame, timecode,
1307  in_frames);
1308 }
1309 
1315 bool AudioOutputBase::AddData(void *in_buffer, int in_len,
1316  int64_t timecode, int /*in_frames*/)
1317 {
1318  int frames = in_len / m_source_bytes_per_frame;
1319  int bpf = m_bytes_per_frame;
1320  int len = in_len;
1321  bool music = false;
1322  int bdiff;
1323 
1324  if (!m_configure_succeeded)
1325  {
1326  LOG(VB_GENERAL, LOG_ERR, "AddData called with audio framework not "
1327  "initialised");
1328  m_length_last_data = 0;
1329  return false;
1330  }
1331 
1332  /* See if we're waiting for new samples to be buffered before we unpause
1333  post channel change, seek, etc. Wait for 4 fragments to be buffered */
1335  {
1336  m_unpause_when_ready = false;
1337  Pause(false);
1338  }
1339 
1340  // Don't write new samples if we're resetting the buffer or reconfiguring
1341  QMutexLocker lock(&m_audio_buflock);
1342 
1343  uint org_waud = m_waud;
1344  int afree = audiofree();
1345  int used = kAudioRingBufferSize - afree;
1346 
1347  if (m_passthru && m_spdifenc)
1348  {
1349  if (m_processing)
1350  {
1351  /*
1352  * We shouldn't encounter this case, but it can occur when
1353  * timestretch just got activated. So we will just drop the
1354  * data
1355  */
1356  LOG(VB_AUDIO, LOG_INFO,
1357  "Passthrough activated with audio processing. Dropping audio");
1358  return false;
1359  }
1360  // mux into an IEC958 packet
1361  m_spdifenc->WriteFrame((unsigned char *)in_buffer, len);
1362  len = m_spdifenc->GetProcessedSize();
1363  if (len > 0)
1364  {
1365  in_buffer = m_spdifenc->GetProcessedBuffer();
1366  m_spdifenc->Reset();
1368  }
1369  else
1370  frames = 0;
1371  }
1372  m_length_last_data = (int64_t)
1373  ((double)(len * 1000) / (m_source_samplerate * m_source_bytes_per_frame));
1374 
1375  VBAUDIOTS(QString("AddData frames=%1, bytes=%2, used=%3, free=%4, "
1376  "timecode=%5 needsupmix=%6")
1377  .arg(frames).arg(len).arg(used).arg(afree).arg(timecode)
1378  .arg(m_needs_upmix));
1379 
1380  // Mythmusic doesn't give us timestamps
1381  if (timecode < 0)
1382  {
1383  timecode = (m_frames_buffered * 1000) / m_source_samplerate;
1385  music = true;
1386  }
1387 
1388  if (hasVisual())
1389  {
1390  // Send original samples to any attached visualisations
1391  dispatchVisual((uchar *)in_buffer, len, timecode, m_source_channels,
1393  }
1394 
1395  // Calculate amount of free space required in ringbuffer
1396  if (m_processing)
1397  {
1398  int sampleSize = AudioOutputSettings::SampleSize(m_format);
1399  if (sampleSize <= 0)
1400  {
1401  // Would lead to division by zero (or unexpected results if negative)
1402  VBERROR("Sample size is <= 0, AddData returning false");
1403  return false;
1404  }
1405 
1406  // Final float conversion space requirement
1407  len = sizeof(*m_src_in_buf) / sampleSize * len;
1408 
1409  // Account for changes in number of channels
1410  if (m_needs_downmix)
1411  len = (len * m_configured_channels ) / m_source_channels;
1412 
1413  // Check we have enough space to write the data
1414  if (m_need_resampler && m_src_ctx)
1415  len = lround(ceil(static_cast<double>(len) * m_src_data.src_ratio));
1416 
1417  if (m_needs_upmix)
1418  len = (len * m_configured_channels ) / m_source_channels;
1419 
1420  // Include samples in upmix buffer that may be flushed
1421  if (m_needs_upmix && m_upmixer)
1422  len += m_upmixer->numUnprocessedFrames() * bpf;
1423 
1424  // Include samples in soundstretch buffers
1425  if (m_pSoundStretch)
1426  len += (m_pSoundStretch->numUnprocessedSamples() +
1427  (int)(m_pSoundStretch->numSamples() / m_stretchfactor)) * bpf;
1428  }
1429 
1430  if (len > afree)
1431  {
1432  VBERROR("Buffer is full, AddData returning false");
1433  return false; // would overflow
1434  }
1435 
1436  int frames_remaining = frames;
1437  int frames_final = 0;
1438  int maxframes = (kAudioSRCInputSize / m_source_channels) & ~0xf;
1439  int offset = 0;
1440 
1441  while(frames_remaining > 0)
1442  {
1443  void *buffer = (char *)in_buffer + offset;
1444  frames = frames_remaining;
1446 
1447  if (m_processing)
1448  {
1449  if (frames > maxframes)
1450  {
1451  frames = maxframes;
1453  offset += len;
1454  }
1455  // Convert to floats
1457  }
1458 
1459  frames_remaining -= frames;
1460 
1461  // Perform downmix if necessary
1462  if (m_needs_downmix)
1465  m_src_in, m_src_in, frames) < 0)
1466  VBERROR("Error occurred while downmixing");
1467 
1468  // Resample if necessary
1469  if (m_need_resampler && m_src_ctx)
1470  {
1471  m_src_data.input_frames = frames;
1472  int error = src_process(m_src_ctx, &m_src_data);
1473 
1474  if (error)
1475  VBERROR(QString("Error occurred while resampling audio: %1")
1476  .arg(src_strerror(error)));
1477 
1478  buffer = m_src_out;
1479  frames = m_src_data.output_frames_gen;
1480  }
1481  else if (m_processing)
1482  buffer = m_src_in;
1483 
1484  /* we want the timecode of the last sample added but we are given the
1485  timecode of the first - add the time in ms that the frames added
1486  represent */
1487 
1488  // Copy samples into audiobuffer, with upmix if necessary
1489  if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
1490  {
1491  continue;
1492  }
1493 
1494  frames = len / bpf;
1495  frames_final += frames;
1496 
1497  bdiff = kAudioRingBufferSize - m_waud;
1498  if ((len % bpf) != 0 && bdiff < len)
1499  {
1500  VBERROR(QString("AddData: Corruption likely: len = %1 (bpf = %2)")
1501  .arg(len)
1502  .arg(bpf));
1503  }
1504  if ((bdiff % bpf) != 0 && bdiff < len)
1505  {
1506  VBERROR(QString("AddData: Corruption likely: bdiff = %1 (bpf = %2)")
1507  .arg(bdiff)
1508  .arg(bpf));
1509  }
1510 
1511  if (m_pSoundStretch)
1512  {
1513  // does not change the timecode, only the number of samples
1514  org_waud = m_waud;
1515  int bdFrames = bdiff / bpf;
1516 
1517  if (bdiff < len)
1518  {
1519  m_pSoundStretch->putSamples((STST *)(WPOS), bdFrames);
1520  m_pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf);
1521  }
1522  else
1523  m_pSoundStretch->putSamples((STST *)(WPOS), frames);
1524 
1525  int nFrames = m_pSoundStretch->numSamples();
1526  if (nFrames > frames)
1527  CheckFreeSpace(nFrames);
1528 
1529  len = nFrames * bpf;
1530 
1531  if (nFrames > bdFrames)
1532  {
1533  nFrames -= m_pSoundStretch->receiveSamples((STST *)(WPOS),
1534  bdFrames);
1535  org_waud = 0;
1536  }
1537  if (nFrames > 0)
1538  nFrames = m_pSoundStretch->receiveSamples((STST *)(WPOS),
1539  nFrames);
1540 
1541  org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
1542  }
1543 
1544  if (internal_vol && SWVolume())
1545  {
1546  org_waud = m_waud;
1547  int num = len;
1548 
1549  if (bdiff <= num)
1550  {
1552  music, m_needs_upmix && m_upmixer);
1553  num -= bdiff;
1554  org_waud = 0;
1555  }
1556  if (num > 0)
1558  music, m_needs_upmix && m_upmixer);
1559  org_waud = (org_waud + num) % kAudioRingBufferSize;
1560  }
1561 
1562  if (m_encoder)
1563  {
1564  org_waud = m_waud;
1565  int to_get = 0;
1566 
1567  if (bdiff < len)
1568  {
1570  to_get = m_encoder->Encode(ABUF, len - bdiff,
1572  }
1573  else
1574  {
1575  to_get = m_encoder->Encode(WPOS, len,
1577  }
1578 
1579  if (bdiff <= to_get)
1580  {
1581  m_encoder->GetFrames(WPOS, bdiff);
1582  to_get -= bdiff ;
1583  org_waud = 0;
1584  }
1585  if (to_get > 0)
1586  m_encoder->GetFrames(WPOS, to_get);
1587 
1588  org_waud = (org_waud + to_get) % kAudioRingBufferSize;
1589  }
1590 
1591  m_waud = org_waud;
1592  }
1593 
1594  SetAudiotime(frames_final, timecode);
1595 
1596  return true;
1597 }
1598 
1603 {
1604  long ct = GetAudiotime();
1605 
1606  if (ct < 0)
1607  ct = 0;
1608 
1609  if (m_source_bitrate == -1)
1612 
1613  if (ct / 1000 != m_current_seconds)
1614  {
1615  m_current_seconds = ct / 1000;
1618  dispatch(e);
1619  }
1620 }
1621 
1627 {
1628  fill = kAudioRingBufferSize - audiofree();
1629  total = kAudioRingBufferSize;
1630 }
1631 
1638 {
1639  uchar *zeros = new uchar[m_fragment_size];
1640  uchar *fragment_buf = new uchar[m_fragment_size + 16];
1641  uchar *fragment = (uchar *)AOALIGN(fragment_buf[0]);
1642  memset(zeros, 0, m_fragment_size);
1643 
1644  // to reduce startup latency, write silence in 8ms chunks
1645  int zero_fragment_size = 8 * m_samplerate * m_output_bytes_per_frame / 1000;
1646  if (zero_fragment_size > m_fragment_size)
1647  zero_fragment_size = m_fragment_size;
1648 
1649  while (!m_killaudio)
1650  {
1651  if (m_pauseaudio)
1652  {
1653  if (!m_actually_paused)
1654  {
1655  VBAUDIO("OutputAudioLoop: audio paused");
1657  dispatch(e);
1658  m_was_paused = true;
1659  }
1660 
1661  m_actually_paused = true;
1662  m_audiotime = 0; // mark 'audiotime' as invalid.
1663 
1664  WriteAudio(zeros, zero_fragment_size);
1665  continue;
1666  }
1667 
1668  if (m_was_paused)
1669  {
1670  VBAUDIO("OutputAudioLoop: Play Event");
1672  dispatch(e);
1673  m_was_paused = false;
1674  }
1675 
1676  /* do audio output */
1677  int ready = audioready();
1678 
1679  // wait for the buffer to fill with enough to play
1680  if (m_fragment_size > ready)
1681  {
1682  if (ready > 0) // only log if we're sending some audio
1683  VBAUDIOTS(QString("audio waiting for buffer to fill: "
1684  "have %1 want %2")
1685  .arg(ready).arg(m_fragment_size));
1686 
1687  usleep(10000);
1688  continue;
1689  }
1690 
1691 #ifdef AUDIOTSTESTING
1692  VBAUDIOTS("WriteAudio Start");
1693 #endif
1694  Status();
1695 
1696  // delay setting raud until after phys buffer is filled
1697  // so GetAudiotime will be accurate without locking
1699  volatile uint next_raud = m_raud;
1700  if (GetAudioData(fragment, m_fragment_size, true, &next_raud))
1701  {
1703  {
1704  WriteAudio(fragment, m_fragment_size);
1706  m_raud = next_raud;
1707  }
1708  }
1709 #ifdef AUDIOTSTESTING
1710  GetAudiotime();
1711  VBAUDIOTS("WriteAudio Done");
1712 #endif
1713 
1714  }
1715 
1716  delete[] zeros;
1717  delete[] fragment_buf;
1718  VBAUDIO("OutputAudioLoop: Stop Event");
1720  dispatch(e);
1721 }
1722 
1730 int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer,
1731  volatile uint *local_raud)
1732 {
1733 
1734 #define LRPOS (m_audiobuffer + *local_raud)
1735  // re-check audioready() in case things changed.
1736  // for example, ClearAfterSeek() might have run
1737  int avail_size = audioready();
1738  int frag_size = size;
1739  int written_size = size;
1740 
1741  if (local_raud == nullptr)
1742  local_raud = &m_raud;
1743 
1744  if (!full_buffer && (size > avail_size))
1745  {
1746  // when full_buffer is false, return any available data
1747  frag_size = avail_size;
1748  written_size = frag_size;
1749  }
1750 
1751  if (!avail_size || (frag_size > avail_size))
1752  return 0;
1753 
1754  int bdiff = kAudioRingBufferSize - m_raud;
1755 
1757 
1758  if (obytes <= 0)
1759  return 0;
1760 
1761  bool fromFloats = m_processing && !m_enc && m_output_format != FORMAT_FLT;
1762 
1763  // Scale if necessary
1764  if (fromFloats && obytes != sizeof(float))
1765  frag_size *= sizeof(float) / obytes;
1766 
1767  int off = 0;
1768 
1769  if (bdiff <= frag_size)
1770  {
1771  if (fromFloats)
1773  LRPOS, bdiff);
1774  else
1775  {
1776  memcpy(buffer, LRPOS, bdiff);
1777  off = bdiff;
1778  }
1779 
1780  frag_size -= bdiff;
1781  *local_raud = 0;
1782  }
1783  if (frag_size > 0)
1784  {
1785  if (fromFloats)
1787  LRPOS, frag_size);
1788  else
1789  memcpy(buffer + off, LRPOS, frag_size);
1790  }
1791 
1792  *local_raud += frag_size;
1793 
1794  // Mute individual channels through mono->stereo duplication
1795  MuteState mute_state = GetMuteState();
1796  if (!m_enc && !m_passthru &&
1797  written_size && m_configured_channels > 1 &&
1798  (mute_state == kMuteLeft || mute_state == kMuteRight))
1799  {
1801  mute_state == kMuteLeft ? 0 : 1,
1802  buffer, written_size);
1803  }
1804 
1805  return written_size;
1806 }
1807 
1812 {
1813  while (!m_pauseaudio && audioready() > m_fragment_size)
1814  usleep(1000);
1815  if (m_pauseaudio)
1816  {
1817  // Audio is paused and can't be drained, clear ringbuffer
1818  QMutexLocker lock(&m_audio_buflock);
1819 
1820  m_waud = m_raud = 0;
1821  }
1822 }
1823 
1828 {
1829  RunProlog();
1830  VBAUDIO(QString("kickoffOutputAudioLoop: pid = %1").arg(getpid()));
1831  OutputAudioLoop();
1832  VBAUDIO("kickoffOutputAudioLoop exiting");
1833  RunEpilog();
1834 }
1835 
1836 int AudioOutputBase::readOutputData(unsigned char* /*read_buffer*/, int /*max_length*/)
1837 {
1838  VBERROR("AudioOutputBase should not be getting asked to readOutputData()");
1839  return 0;
1840 }
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
virtual void CloseDevice(void)=0
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)
void InitSettings(const AudioSettings &settings)
virtual bool OpenDevice(void)=0
QMutex m_audio_buflock
Writes to the audiobuffer, reconfigures and audiobuffer resets can only take place while holding this...
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
QMutex m_avsync_lock
must hold avsync_lock to read or write 'audiotime' and 'audiotime_updated'
bool Init(AVCodecID codec_id, int bitrate, int samplerate, int channels)
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
void SaveSetting(const QString &key, int newValue)
void error(const QString &e)
Definition: output.cpp:30
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...
unsigned int uint
Definition: compat.h:140
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)
SRC_STATE * m_src_ctx
uchar m_audiobuffer[kAudioRingBufferSize]
main audio buffer
AudioFormat m_format
int64_t m_audiotime
timecode of audio leaving the soundcard (same units as timecodes)
AudioOutputSource source
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.
int64_t m_audbuf_timecode
timecode of audio most recently placed into buffer
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
int audiolen() const
Get the number of bytes in the audiobuffer.
AudioFormat BestSupportedFormat()
void SetSourceBitrate(int rate) override
Set the bitrate of the source material, reported in periodic OutputEvents.
#define WPOS
AudioOutputSettings * m_output_settingsdigital
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
uint m_memory_corruption_test3
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
uint m_memory_corruption_test0
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.
AudioFormat m_output_format
uint m_memory_corruption_test1
def log(debug, txt)
Definition: utilities.py:5
bool canFeature(DigitalFeature arg)
return DigitalFeature mask.
virtual void Status(void)
Report status via an OutputEvent.
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.
float m_src_in_buf[kAudioSRCInputSize+16]
bool internal_vol
Definition: volumebase.h:41
bool SetupPassthrough(AVCodecID codec, int codec_profile, int &samplerate_tmp, int &channels_tmp)
AVCodecID m_codec
Definition: audiosettings.h:69
uint m_memory_corruption_test2
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
#define LRPOS
void PauseUntilBuffered(void) override
virtual bool StartOutputThread(void)
bool Succeeded()
Definition: spdifencoder.h:24
int64_t m_frames_buffered
int GetNumSetting(const QString &key, int defaultval=0)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
AudioOutputSettings * m_output_settings
AudioOutputSettings * GetCleaned(bool newcopy=false)
Returns capabilities supported by the audio device amended to take into account the digital audio opt...
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)
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
SPDIFEncoder * m_spdifenc
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.
AsyncLooseLock m_reset_active
int GetMaxHDRate()
return the highest iec958 rate supported.
unsigned char * GetProcessedBuffer()
Definition: spdifencoder.h:22
AudioOutputSettings * m_output_settingsraw
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.
AudioOutputSettings * GetUsers(bool newcopy=false)
Returns capabilities supported by the audio device amended to take into account the digital audio opt...
DigitalFeature
const char * frames[3]
Definition: element.c:46
void Drain(void) override
Block until all available frames have been written to the device.
const char * quality_string(int q)
uint numUnprocessedFrames()
void ClearError(void)
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)
static Type Stopped
Definition: output.h:65
int64_t m_length_last_data
AudioOutputSettings * m_output_settingsdigitalraw
int readOutputData(unsigned char *read_buffer, int max_length) override