00001
00002 #include <cmath>
00003 #include <limits>
00004
00005
00006 #include <unistd.h>
00007 #include <sys/time.h>
00008
00009
00010 #include <QMutexLocker>
00011
00012
00013 #include "compat.h"
00014 #include "audiooutputbase.h"
00015 #include "audiooutputdigitalencoder.h"
00016 #include "audiooutpututil.h"
00017 #include "audiooutputdownmix.h"
00018 #include "SoundTouch.h"
00019 #include "freesurround.h"
00020 #include "spdifencoder.h"
00021 #include "mythlogging.h"
00022
00023 #define LOC QString("AO: ")
00024
00025 #define WPOS audiobuffer + org_waud
00026 #define RPOS audiobuffer + raud
00027 #define ABUF audiobuffer
00028 #define STST soundtouch::SAMPLETYPE
00029 #define AOALIGN(x) (((long)&x + 15) & ~0xf);
00030
00031
00032 #define UPMIX_CHANNEL_MASK ((1<<1)|(1<<2)|(1<<5)|1<<7)
00033 #define IS_VALID_UPMIX_CHANNEL(ch) ((1 << (ch)) & UPMIX_CHANNEL_MASK)
00034
00035 const char *AudioOutputBase::quality_string(int q)
00036 {
00037 switch(q)
00038 {
00039 case QUALITY_DISABLED: return "disabled";
00040 case QUALITY_LOW: return "low";
00041 case QUALITY_MEDIUM: return "medium";
00042 case QUALITY_HIGH: return "high";
00043 default: return "unknown";
00044 }
00045 }
00046
00047 AudioOutputBase::AudioOutputBase(const AudioSettings &settings) :
00048 MThread("AudioOutputBase"),
00049
00050 channels(-1), codec(CODEC_ID_NONE),
00051 bytes_per_frame(0), output_bytes_per_frame(0),
00052 format(FORMAT_NONE), output_format(FORMAT_NONE),
00053 samplerate(-1), effdsp(0),
00054 fragment_size(0), soundcard_buffer_size(0),
00055
00056 main_device(settings.GetMainDevice()),
00057 passthru_device(settings.GetPassthruDevice()),
00058 m_discretedigital(false), passthru(false),
00059 enc(false), reenc(false),
00060 stretchfactor(1.0f),
00061 eff_stretchfactor(100000),
00062
00063 source(settings.source), killaudio(false),
00064
00065 pauseaudio(false), actually_paused(false),
00066 was_paused(false), unpause_when_ready(false),
00067
00068 set_initial_vol(settings.set_initial_vol),
00069 buffer_output_data_for_use(false),
00070
00071 configured_channels(0),
00072 max_channels(0),
00073 src_quality(QUALITY_MEDIUM),
00074
00075
00076 output_settingsraw(NULL), output_settings(NULL),
00077 output_settingsdigitalraw(NULL), output_settingsdigital(NULL),
00078 need_resampler(false), src_ctx(NULL),
00079
00080 pSoundStretch(NULL),
00081 encoder(NULL), upmixer(NULL),
00082 source_channels(-1), source_samplerate(0),
00083 source_bytes_per_frame(0), upmix_default(false),
00084 needs_upmix(false), needs_downmix(false),
00085 surround_mode(QUALITY_LOW), old_stretchfactor(1.0f),
00086 volume(80), volumeControl(QString()),
00087
00088 processing(false),
00089
00090 frames_buffered(0),
00091
00092 audio_thread_exists(false),
00093
00094 audiotime(0),
00095 raud(0), waud(0),
00096 audbuf_timecode(0),
00097
00098 killAudioLock(QMutex::NonRecursive),
00099 current_seconds(-1), source_bitrate(-1),
00100
00101 memory_corruption_test0(0xdeadbeef),
00102 memory_corruption_test1(0xdeadbeef),
00103 src_out(NULL), kAudioSRCOutputSize(0),
00104 memory_corruption_test2(0xdeadbeef),
00105 memory_corruption_test3(0xdeadbeef),
00106 m_configure_succeeded(false),m_length_last_data(0),
00107 m_spdifenc(NULL), m_forcedprocessing(false)
00108 {
00109 src_in = (float *)AOALIGN(src_in_buf);
00110 memset(&src_data, 0, sizeof(SRC_DATA));
00111 memset(src_in_buf, 0, sizeof(src_in_buf));
00112 memset(audiobuffer, 0, sizeof(audiobuffer));
00113
00114
00115 if (gCoreContext->GetNumSetting("SRCQualityOverride", false))
00116 {
00117 src_quality = gCoreContext->GetNumSetting("SRCQuality", QUALITY_MEDIUM);
00118
00119 if (src_quality > QUALITY_HIGH)
00120 src_quality = QUALITY_HIGH;
00121
00122 VBAUDIO(QString("SRC quality = %1").arg(quality_string(src_quality)));
00123 }
00124 }
00125
00131 AudioOutputBase::~AudioOutputBase()
00132 {
00133 if (!killaudio)
00134 VBERROR("Programmer Error: "
00135 "~AudioOutputBase called, but KillAudio has not been called!");
00136
00137
00138 delete output_settings;
00139 delete output_settingsraw;
00140 if (output_settings != output_settingsdigital)
00141 {
00142 delete output_settingsdigital;
00143 delete output_settingsdigitalraw;
00144 }
00145
00146 if (kAudioSRCOutputSize > 0)
00147 delete[] src_out;
00148
00149 assert(memory_corruption_test0 == 0xdeadbeef);
00150 assert(memory_corruption_test1 == 0xdeadbeef);
00151 assert(memory_corruption_test2 == 0xdeadbeef);
00152 assert(memory_corruption_test3 == 0xdeadbeef);
00153 }
00154
00155 void AudioOutputBase::InitSettings(const AudioSettings &settings)
00156 {
00157 if (settings.custom)
00158 {
00159
00160
00161 output_settings = new AudioOutputSettings;
00162 *output_settings = *settings.custom;
00163 output_settingsdigital = output_settings;
00164 max_channels = output_settings->BestSupportedChannels();
00165 configured_channels = max_channels;
00166 return;
00167 }
00168
00169
00170 output_settings = GetOutputSettingsUsers(false);
00171 output_settingsdigital = GetOutputSettingsUsers(true);
00172
00173 max_channels = max(output_settings->BestSupportedChannels(),
00174 output_settingsdigital->BestSupportedChannels());
00175 configured_channels = max_channels;
00176
00177 upmix_default = max_channels > 2 ?
00178 gCoreContext->GetNumSetting("AudioDefaultUpmix", false) :
00179 false;
00180 if (settings.upmixer == 1)
00181 upmix_default = false;
00182 else if (settings.upmixer == 2)
00183 upmix_default = true;
00184 }
00185
00191 AudioOutputSettings* AudioOutputBase::GetOutputSettingsCleaned(bool digital)
00192 {
00193
00194
00195 if (!m_discretedigital || !digital)
00196 {
00197 digital = false;
00198 if (output_settingsraw)
00199 return output_settingsraw;
00200 }
00201 else if (output_settingsdigitalraw)
00202 return output_settingsdigitalraw;
00203
00204 AudioOutputSettings* aosettings = GetOutputSettings(digital);
00205 if (aosettings)
00206 aosettings->GetCleaned();
00207 else
00208 aosettings = new AudioOutputSettings(true);
00209
00210 if (digital)
00211 return (output_settingsdigitalraw = aosettings);
00212 else
00213 return (output_settingsraw = aosettings);
00214 }
00215
00221 AudioOutputSettings* AudioOutputBase::GetOutputSettingsUsers(bool digital)
00222 {
00223 if (!m_discretedigital || !digital)
00224 {
00225 digital = false;
00226 if (output_settings)
00227 return output_settings;
00228 }
00229 else if (output_settingsdigital)
00230 return output_settingsdigital;
00231
00232 AudioOutputSettings* aosettings = new AudioOutputSettings;
00233
00234 *aosettings = *GetOutputSettingsCleaned(digital);
00235 aosettings->GetUsers();
00236
00237 if (digital)
00238 return (output_settingsdigital = aosettings);
00239 else
00240 return (output_settings = aosettings);
00241 }
00242
00246 bool AudioOutputBase::CanPassthrough(int samplerate, int channels,
00247 int codec, int profile) const
00248 {
00249 DigitalFeature arg = FEATURE_NONE;
00250 bool ret = !(internal_vol && SWVolume());
00251
00252 switch(codec)
00253 {
00254 case CODEC_ID_AC3:
00255 arg = FEATURE_AC3;
00256 break;
00257 case CODEC_ID_DTS:
00258 switch(profile)
00259 {
00260 case FF_PROFILE_DTS:
00261 case FF_PROFILE_DTS_ES:
00262 case FF_PROFILE_DTS_96_24:
00263 arg = FEATURE_DTS;
00264 break;
00265 case FF_PROFILE_DTS_HD_HRA:
00266 case FF_PROFILE_DTS_HD_MA:
00267 arg = FEATURE_DTSHD;
00268 break;
00269 default:
00270 break;
00271 }
00272 break;
00273 case CODEC_ID_EAC3:
00274 arg = FEATURE_EAC3;
00275 break;
00276 case CODEC_ID_TRUEHD:
00277 arg = FEATURE_TRUEHD;
00278 break;
00279 }
00280
00281 ret &= output_settingsdigital->canFeature(arg);
00282 ret &= output_settingsdigital->IsSupportedFormat(FORMAT_S16);
00283 ret &= output_settingsdigital->IsSupportedRate(samplerate);
00284
00285 ret &= !((samplerate != 48000) &&
00286 gCoreContext->GetNumSetting("Audio48kOverride", false));
00287
00288
00289 ret &= samplerate >= 44100;
00290 if (!ret)
00291 return false;
00292
00293
00294 ret &= max_channels >= 6 && channels > 2;
00295
00296
00297 ret |= max_channels == 2;
00298
00299 return ret;
00300 }
00301
00305 void AudioOutputBase::SetSourceBitrate(int rate)
00306 {
00307 if (rate > 0)
00308 source_bitrate = rate;
00309 }
00310
00316 void AudioOutputBase::SetStretchFactorLocked(float lstretchfactor)
00317 {
00318 if (stretchfactor == lstretchfactor && pSoundStretch)
00319 return;
00320
00321 stretchfactor = lstretchfactor;
00322
00323 int channels = needs_upmix || needs_downmix ?
00324 configured_channels : source_channels;
00325 if (channels < 1 || channels > 8 || !m_configure_succeeded)
00326 return;
00327
00328 bool willstretch = stretchfactor < 0.99f || stretchfactor > 1.01f;
00329 eff_stretchfactor = (int)(100000.0f * lstretchfactor + 0.5);
00330
00331 if (pSoundStretch)
00332 {
00333 if (!willstretch && m_forcedprocessing)
00334 {
00335 m_forcedprocessing = false;
00336 processing = false;
00337 delete pSoundStretch;
00338 pSoundStretch = NULL;
00339 VBGENERAL(QString("Cancelling time stretch"));
00340 bytes_per_frame = m_previousbpf;
00341 waud = raud = 0;
00342 reset_active.Ref();
00343 }
00344 else
00345 {
00346 VBGENERAL(QString("Changing time stretch to %1")
00347 .arg(stretchfactor));
00348 pSoundStretch->setTempo(stretchfactor);
00349 }
00350 }
00351 else if (willstretch)
00352 {
00353 VBGENERAL(QString("Using time stretch %1").arg(stretchfactor));
00354 pSoundStretch = new soundtouch::SoundTouch();
00355 pSoundStretch->setSampleRate(samplerate);
00356 pSoundStretch->setChannels(channels);
00357 pSoundStretch->setTempo(stretchfactor);
00358 pSoundStretch->setSetting(SETTING_SEQUENCE_MS, 35);
00359
00360
00361
00362 if (!processing)
00363 {
00364 processing = true;
00365 m_forcedprocessing = true;
00366 m_previousbpf = bytes_per_frame;
00367 bytes_per_frame = source_channels *
00368 AudioOutputSettings::SampleSize(FORMAT_FLT);
00369 waud = raud = 0;
00370 reset_active.Ref();
00371 }
00372 }
00373 }
00374
00378 void AudioOutputBase::SetStretchFactor(float lstretchfactor)
00379 {
00380 QMutexLocker lock(&audio_buflock);
00381 SetStretchFactorLocked(lstretchfactor);
00382 }
00383
00387 float AudioOutputBase::GetStretchFactor(void) const
00388 {
00389 return stretchfactor;
00390 }
00391
00395 bool AudioOutputBase::IsUpmixing(void)
00396 {
00397 return needs_upmix && upmixer;
00398 }
00399
00403 bool AudioOutputBase::ToggleUpmix(void)
00404 {
00405
00406 if (max_channels == 2 || source_channels > 2 || passthru)
00407 return false;
00408
00409 upmix_default = !upmix_default;
00410
00411 const AudioSettings settings(format, source_channels, codec,
00412 source_samplerate, passthru);
00413 Reconfigure(settings);
00414 return IsUpmixing();
00415 }
00416
00420 bool AudioOutputBase::CanUpmix(void)
00421 {
00422 return !passthru && source_channels <= 2 && max_channels > 2;
00423 }
00424
00425
00426
00427
00428
00429 bool AudioOutputBase::SetupPassthrough(int codec, int codec_profile,
00430 int &samplerate_tmp, int &channels_tmp)
00431 {
00432 if (codec == CODEC_ID_DTS &&
00433 !output_settingsdigital->canFeature(FEATURE_DTSHD))
00434 {
00435
00436
00437 codec_profile = FF_PROFILE_DTS;
00438 }
00439 QString log = AudioOutputSettings::GetPassthroughParams(
00440 codec, codec_profile,
00441 samplerate_tmp, channels_tmp,
00442 output_settingsdigital->GetMaxHDRate() == 768000);
00443 VBAUDIO("Setting " + log + " passthrough");
00444
00445 if (m_spdifenc)
00446 {
00447 delete m_spdifenc;
00448 }
00449
00450 m_spdifenc = new SPDIFEncoder("spdif", codec);
00451 if (m_spdifenc->Succeeded() && codec == CODEC_ID_DTS)
00452 {
00453 switch(codec_profile)
00454 {
00455 case FF_PROFILE_DTS:
00456 case FF_PROFILE_DTS_ES:
00457 case FF_PROFILE_DTS_96_24:
00458 m_spdifenc->SetMaxHDRate(0);
00459 break;
00460 case FF_PROFILE_DTS_HD_HRA:
00461 case FF_PROFILE_DTS_HD_MA:
00462 m_spdifenc->SetMaxHDRate(samplerate_tmp * channels_tmp / 2);
00463 break;
00464 }
00465 }
00466
00467 if (!m_spdifenc->Succeeded())
00468 {
00469 delete m_spdifenc;
00470 m_spdifenc = NULL;
00471 return false;
00472 }
00473 return true;
00474 }
00475
00476 AudioOutputSettings *AudioOutputBase::OutputSettings(bool digital)
00477 {
00478 if (digital)
00479 return output_settingsdigital;
00480 return output_settings;
00481 }
00482
00488 void AudioOutputBase::Reconfigure(const AudioSettings &orig_settings)
00489 {
00490 AudioSettings settings = orig_settings;
00491 int lsource_channels = settings.channels;
00492 int lconfigured_channels = configured_channels;
00493 bool lneeds_upmix = false;
00494 bool lneeds_downmix = false;
00495 bool lreenc = false;
00496 bool lenc = false;
00497
00498 if (!settings.use_passthru)
00499 {
00500
00501 lconfigured_channels =
00502 (upmix_default && lsource_channels <= 2) ? 6 : lsource_channels;
00503 bool cando_channels =
00504 output_settings->IsSupportedChannels(lconfigured_channels);
00505
00506
00507 lenc = output_settingsdigital->canFeature(FEATURE_AC3) &&
00508 (!output_settings->canFeature(FEATURE_LPCM) &&
00509 lconfigured_channels > 2 && lconfigured_channels <= 6);
00510
00511 if (!lenc && !cando_channels)
00512 {
00513
00514
00515
00516 switch (lconfigured_channels)
00517 {
00518 case 7:
00519 lconfigured_channels = 8;
00520 break;
00521 case 8:
00522 case 5:
00523 lconfigured_channels = 6;
00524 break;
00525 case 6:
00526 case 4:
00527 case 3:
00528 case 2:
00529 lconfigured_channels = 2;
00530 break;
00531 case 1:
00532 lconfigured_channels = upmix_default ? 6 : 2;
00533 break;
00534 default:
00535 lconfigured_channels = 2;
00536 break;
00537 }
00538 }
00539
00540
00541 if (lsource_channels <= 6)
00542 lconfigured_channels = min(lconfigured_channels, 6);
00543 lconfigured_channels = min(lconfigured_channels, max_channels);
00544
00545
00546
00547
00548 lenc = output_settingsdigital->canFeature(FEATURE_AC3) &&
00549 ((!output_settings->canFeature(FEATURE_LPCM) &&
00550 lconfigured_channels > 2) ||
00551 !output_settings->IsSupportedChannels(lconfigured_channels));
00552
00553
00554
00555 if (output_settingsdigital->canFeature(FEATURE_AC3) &&
00556 (settings.codec == CODEC_ID_AC3 || settings.codec == CODEC_ID_DTS))
00557 {
00558 lreenc = true;
00559 }
00560
00561
00562 if (IS_VALID_UPMIX_CHANNEL(settings.channels) &&
00563 settings.channels < lconfigured_channels)
00564 {
00565 VBAUDIO(QString("Needs upmix from %1 -> %2 channels")
00566 .arg(settings.channels).arg(lconfigured_channels));
00567 settings.channels = lconfigured_channels;
00568 lneeds_upmix = true;
00569 }
00570 else if (settings.channels > lconfigured_channels)
00571 {
00572 VBAUDIO(QString("Needs downmix from %1 -> %2 channels")
00573 .arg(settings.channels).arg(lconfigured_channels));
00574 settings.channels = lconfigured_channels;
00575 lneeds_downmix = true;
00576 }
00577 }
00578
00579 ClearError();
00580
00581 bool general_deps = true;
00582
00583
00584
00585 int samplerate_tmp, channels_tmp;
00586 if (settings.use_passthru)
00587 {
00588 samplerate_tmp = settings.samplerate;
00589 SetupPassthrough(settings.codec, settings.codec_profile,
00590 samplerate_tmp, channels_tmp);
00591 general_deps = samplerate == samplerate_tmp && channels == channels_tmp;
00592 }
00593
00594
00595 general_deps &=
00596 settings.format == format &&
00597 settings.samplerate == source_samplerate &&
00598 settings.use_passthru == passthru &&
00599 lconfigured_channels == configured_channels &&
00600 lneeds_upmix == needs_upmix && lreenc == reenc &&
00601 lsource_channels == source_channels &&
00602 lneeds_downmix == needs_downmix;
00603
00604 if (general_deps && m_configure_succeeded)
00605 {
00606 VBAUDIO("Reconfigure(): No change -> exiting");
00607 return;
00608 }
00609
00610 KillAudio();
00611
00612 QMutexLocker lock(&audio_buflock);
00613 QMutexLocker lockav(&avsync_lock);
00614
00615 waud = raud = 0;
00616 reset_active.Clear();
00617 actually_paused = processing = m_forcedprocessing = false;
00618
00619 channels = settings.channels;
00620 source_channels = lsource_channels;
00621 reenc = lreenc;
00622 codec = settings.codec;
00623 passthru = settings.use_passthru;
00624 configured_channels = lconfigured_channels;
00625 needs_upmix = lneeds_upmix;
00626 needs_downmix = lneeds_downmix;
00627 format = output_format = settings.format;
00628 source_samplerate = samplerate = settings.samplerate;
00629 enc = lenc;
00630
00631 killaudio = pauseaudio = false;
00632 was_paused = true;
00633
00634
00635
00636 if (source_channels <= 0 || format <= 0 || samplerate <= 0)
00637 {
00638 SilentError(QString("Aborting Audio Reconfigure. ") +
00639 QString("Invalid audio parameters ch %1 fmt %2 @ %3Hz")
00640 .arg(source_channels).arg(format).arg(samplerate));
00641 return;
00642 }
00643
00644 VBAUDIO(QString("Original codec was %1, %2, %3 kHz, %4 channels")
00645 .arg(ff_codec_id_string((CodecID)codec))
00646 .arg(output_settings->FormatToString(format))
00647 .arg(samplerate/1000)
00648 .arg(source_channels));
00649
00650 if (needs_downmix && source_channels > 8)
00651 {
00652 Error("Aborting Audio Reconfigure. "
00653 "Can't handle audio with more than 8 channels.");
00654 return;
00655 }
00656
00657 VBAUDIO(QString("enc(%1), passthru(%2), features (%3) "
00658 "configured_channels(%4), %5 channels supported(%6) "
00659 "max_channels(%7)")
00660 .arg(enc)
00661 .arg(passthru)
00662 .arg(output_settingsdigital->FeaturesToString())
00663 .arg(configured_channels)
00664 .arg(channels)
00665 .arg(OutputSettings(enc || passthru)->IsSupportedChannels(channels))
00666 .arg(max_channels));
00667
00668 int dest_rate = 0;
00669
00670
00671
00672 if ((samplerate != 48000 &&
00673 gCoreContext->GetNumSetting("Audio48kOverride", false)) ||
00674 (enc && (samplerate > 48000)))
00675 {
00676 VBAUDIO("Forcing resample to 48 kHz");
00677 if (src_quality < 0)
00678 src_quality = QUALITY_MEDIUM;
00679 need_resampler = true;
00680 dest_rate = 48000;
00681 }
00682
00683
00684 else if ((need_resampler =
00685 !OutputSettings(enc || passthru)->IsSupportedRate(samplerate)))
00686 {
00687 dest_rate = OutputSettings(enc)->NearestSupportedRate(samplerate);
00688 }
00689
00690 if (need_resampler && src_quality > QUALITY_DISABLED)
00691 {
00692 int error;
00693 samplerate = dest_rate;
00694
00695 VBGENERAL(QString("Resampling from %1 kHz to %2 kHz with quality %3")
00696 .arg(settings.samplerate/1000).arg(samplerate/1000)
00697 .arg(quality_string(src_quality)));
00698
00699 int chans = needs_downmix ? configured_channels : source_channels;
00700
00701 src_ctx = src_new(2-src_quality, chans, &error);
00702 if (error)
00703 {
00704 Error(QString("Error creating resampler: %1")
00705 .arg(src_strerror(error)));
00706 src_ctx = NULL;
00707 return;
00708 }
00709
00710 src_data.src_ratio = (double)samplerate / settings.samplerate;
00711 src_data.data_in = src_in;
00712 int newsize = (int)(kAudioSRCInputSize * src_data.src_ratio + 15)
00713 & ~0xf;
00714
00715 if (kAudioSRCOutputSize < newsize)
00716 {
00717 kAudioSRCOutputSize = newsize;
00718 VBAUDIO(QString("Resampler allocating %1").arg(newsize));
00719 if (src_out)
00720 delete[] src_out;
00721 src_out = new float[kAudioSRCOutputSize];
00722 }
00723 src_data.data_out = src_out;
00724 src_data.output_frames = kAudioSRCOutputSize / chans;
00725 src_data.end_of_input = 0;
00726 }
00727
00728 if (enc)
00729 {
00730 if (reenc)
00731 VBAUDIO("Reencoding decoded AC-3/DTS to AC-3");
00732
00733 VBAUDIO(QString("Creating AC-3 Encoder with sr = %1, ch = %2")
00734 .arg(samplerate).arg(configured_channels));
00735
00736 encoder = new AudioOutputDigitalEncoder();
00737 if (!encoder->Init(CODEC_ID_AC3, 448000, samplerate,
00738 configured_channels))
00739 {
00740 Error("AC-3 encoder initialization failed");
00741 delete encoder;
00742 encoder = NULL;
00743 enc = false;
00744
00745 needs_upmix = false;
00746 }
00747 }
00748
00749 if (passthru)
00750 {
00751
00752 channels = channels_tmp;
00753 samplerate = samplerate_tmp;
00754 format = output_format = FORMAT_S16;
00755 source_bytes_per_frame = channels *
00756 output_settings->SampleSize(format);
00757 }
00758 else
00759 {
00760 source_bytes_per_frame = source_channels *
00761 output_settings->SampleSize(format);
00762 }
00763
00764
00765 if (need_resampler || needs_upmix || needs_downmix ||
00766 stretchfactor != 1.0f || (internal_vol && SWVolume()) ||
00767 (enc && output_format != FORMAT_S16) ||
00768 !OutputSettings(enc || passthru)->IsSupportedFormat(output_format))
00769 {
00770 VBAUDIO("Audio processing enabled");
00771 processing = true;
00772 if (enc)
00773 output_format = FORMAT_S16;
00774 else
00775 output_format = output_settings->BestSupportedFormat();
00776 }
00777
00778 bytes_per_frame = processing ?
00779 sizeof(float) : output_settings->SampleSize(format);
00780 bytes_per_frame *= channels;
00781
00782 if (enc)
00783 channels = 2;
00784
00785 output_bytes_per_frame = channels *
00786 output_settings->SampleSize(output_format);
00787
00788 VBGENERAL(
00789 QString("Opening audio device '%1' ch %2(%3) sr %4 sf %5 reenc %6")
00790 .arg(main_device).arg(channels).arg(source_channels).arg(samplerate)
00791 .arg(output_settings->FormatToString(output_format)).arg(reenc));
00792
00793 audbuf_timecode = audiotime = frames_buffered = 0;
00794 current_seconds = source_bitrate = -1;
00795 effdsp = samplerate * 100;
00796
00797
00798 if (!OpenDevice())
00799 {
00800 if (GetError().isEmpty())
00801 Error("Aborting reconfigure");
00802 else
00803 VBGENERAL("Aborting reconfigure");
00804 m_configure_succeeded = false;
00805 return;
00806 }
00807
00808 VBAUDIO(QString("Audio fragment size: %1").arg(fragment_size));
00809
00810
00811 if (set_initial_vol && internal_vol && SWVolume())
00812 {
00813 VBAUDIO("Software volume enabled");
00814 volumeControl = gCoreContext->GetSetting("MixerControl", "PCM");
00815 volumeControl += "MixerVolume";
00816 volume = gCoreContext->GetNumSetting(volumeControl, 80);
00817 }
00818
00819 VolumeBase::SetChannels(configured_channels);
00820 VolumeBase::SyncVolume();
00821 VolumeBase::UpdateVolume();
00822
00823 if (needs_upmix && IS_VALID_UPMIX_CHANNEL(source_channels) &&
00824 configured_channels > 2)
00825 {
00826 surround_mode = gCoreContext->GetNumSetting("AudioUpmixType", QUALITY_HIGH);
00827 if ((upmixer = new FreeSurround(samplerate, source == AUDIOOUTPUT_VIDEO,
00828 (FreeSurround::SurroundMode)surround_mode)))
00829 VBAUDIO(QString("Create %1 quality upmixer done")
00830 .arg(quality_string(surround_mode)));
00831 else
00832 {
00833 VBERROR("Failed to create upmixer");
00834 needs_upmix = false;
00835 }
00836 }
00837
00838 VBAUDIO(QString("Audio Stretch Factor: %1").arg(stretchfactor));
00839 SetStretchFactorLocked(old_stretchfactor);
00840
00841
00842 prepareVisuals();
00843
00844 if (unpause_when_ready)
00845 pauseaudio = actually_paused = true;
00846
00847 m_configure_succeeded = true;
00848
00849 StartOutputThread();
00850
00851 VBAUDIO("Ending Reconfigure()");
00852 }
00853
00854 bool AudioOutputBase::StartOutputThread(void)
00855 {
00856 if (audio_thread_exists)
00857 return true;
00858
00859 start();
00860 audio_thread_exists = true;
00861
00862 return true;
00863 }
00864
00865
00866 void AudioOutputBase::StopOutputThread(void)
00867 {
00868 if (audio_thread_exists)
00869 {
00870 wait();
00871 audio_thread_exists = false;
00872 }
00873 }
00874
00878 void AudioOutputBase::KillAudio()
00879 {
00880 killAudioLock.lock();
00881
00882 VBAUDIO("Killing AudioOutputDSP");
00883 killaudio = true;
00884 StopOutputThread();
00885 QMutexLocker lock(&audio_buflock);
00886
00887 if (pSoundStretch)
00888 {
00889 delete pSoundStretch;
00890 pSoundStretch = NULL;
00891 old_stretchfactor = stretchfactor;
00892 stretchfactor = 1.0f;
00893 }
00894
00895 if (encoder)
00896 {
00897 delete encoder;
00898 encoder = NULL;
00899 }
00900
00901 if (upmixer)
00902 {
00903 delete upmixer;
00904 upmixer = NULL;
00905 }
00906
00907 if (src_ctx)
00908 {
00909 src_delete(src_ctx);
00910 src_ctx = NULL;
00911 }
00912
00913 needs_upmix = need_resampler = enc = false;
00914
00915 CloseDevice();
00916
00917 killAudioLock.unlock();
00918 }
00919
00920 void AudioOutputBase::Pause(bool paused)
00921 {
00922 if (unpause_when_ready)
00923 return;
00924 VBAUDIO(QString("Pause %1").arg(paused));
00925 if (pauseaudio != paused)
00926 was_paused = pauseaudio;
00927 pauseaudio = paused;
00928 actually_paused = false;
00929 }
00930
00931 void AudioOutputBase::PauseUntilBuffered()
00932 {
00933 Reset();
00934 Pause(true);
00935 unpause_when_ready = true;
00936 }
00937
00941 void AudioOutputBase::Reset()
00942 {
00943 QMutexLocker lock(&audio_buflock);
00944 QMutexLocker lockav(&avsync_lock);
00945
00946 audbuf_timecode = audiotime = frames_buffered = 0;
00947 if (encoder)
00948 {
00949 waud = raud = 0;
00950 memset(audiobuffer, 0, kAudioRingBufferSize);
00951 }
00952 else
00953 {
00954 waud = raud;
00955 }
00956 reset_active.Ref();
00957 current_seconds = -1;
00958 was_paused = !pauseaudio;
00959
00960 if (needs_upmix && upmixer)
00961 upmixer->flush();
00962 if (pSoundStretch)
00963 pSoundStretch->clear();
00964 if (encoder)
00965 encoder->clear();
00966
00967
00968 prepareVisuals();
00969 }
00970
00977 void AudioOutputBase::SetTimecode(int64_t timecode)
00978 {
00979 audbuf_timecode = audiotime = timecode;
00980 frames_buffered = (timecode * source_samplerate) / 1000;
00981 }
00982
00989 void AudioOutputBase::SetEffDsp(int dsprate)
00990 {
00991 VBAUDIO(QString("SetEffDsp: %1").arg(dsprate));
00992 effdsp = dsprate;
00993 }
00994
00998 inline int AudioOutputBase::audiolen()
00999 {
01000 if (waud >= raud)
01001 return waud - raud;
01002 else
01003 return kAudioRingBufferSize - (raud - waud);
01004 }
01005
01009 int AudioOutputBase::audiofree()
01010 {
01011 return kAudioRingBufferSize - audiolen() - 1;
01012
01013
01014
01015 }
01016
01024 int AudioOutputBase::audioready()
01025 {
01026 if (passthru || enc || bytes_per_frame == output_bytes_per_frame)
01027 return audiolen();
01028 else
01029 return audiolen() * output_bytes_per_frame / bytes_per_frame;
01030 }
01031
01035 int64_t AudioOutputBase::GetAudiotime(void)
01036 {
01037 if (audbuf_timecode == 0 || !m_configure_succeeded)
01038 return 0;
01039
01040 int obpf = output_bytes_per_frame;
01041 int64_t oldaudiotime;
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057 QMutexLocker lockav(&avsync_lock);
01058
01059 int soundcard_buffer = GetBufferedOnSoundcard();
01060
01061
01062
01063 int main_buffer = audioready();
01064
01065 oldaudiotime = audiotime;
01066
01067
01068
01069
01070
01071 audiotime = audbuf_timecode - (
01072 ((int64_t)(main_buffer + soundcard_buffer) * eff_stretchfactor) /
01073 (effdsp * obpf));
01074
01075
01076
01077
01078 if (audiotime < oldaudiotime)
01079 audiotime = oldaudiotime;
01080
01081 VBAUDIOTS(QString("GetAudiotime audt=%1 atc=%2 mb=%3 sb=%4 tb=%5 "
01082 "sr=%6 obpf=%7 bpf=%8 sf=%9 %10 %11")
01083 .arg(audiotime).arg(audbuf_timecode)
01084 .arg(main_buffer)
01085 .arg(soundcard_buffer)
01086 .arg(main_buffer+soundcard_buffer)
01087 .arg(samplerate).arg(obpf).arg(bytes_per_frame).arg(stretchfactor)
01088 .arg((main_buffer + soundcard_buffer) * eff_stretchfactor)
01089 .arg(((main_buffer + soundcard_buffer) * eff_stretchfactor ) /
01090 (effdsp * obpf))
01091 );
01092
01093 return audiotime;
01094 }
01095
01101 void AudioOutputBase::SetAudiotime(int frames, int64_t timecode)
01102 {
01103 int64_t processframes_stretched = 0;
01104 int64_t processframes_unstretched = 0;
01105 int64_t old_audbuf_timecode = audbuf_timecode;
01106
01107 if (!m_configure_succeeded)
01108 return;
01109
01110 if (needs_upmix && upmixer)
01111 processframes_unstretched -= upmixer->frameLatency();
01112
01113 if (pSoundStretch)
01114 {
01115 processframes_unstretched -= pSoundStretch->numUnprocessedSamples();
01116 processframes_stretched -= pSoundStretch->numSamples();
01117 }
01118
01119 if (encoder)
01120 {
01121 processframes_stretched -= encoder->Buffered();
01122 }
01123
01124 audbuf_timecode =
01125 timecode + ((frames + processframes_unstretched * 100000) +
01126 (processframes_stretched * eff_stretchfactor)
01127 ) / effdsp;
01128
01129
01130
01131
01132 if (audbuf_timecode < old_audbuf_timecode)
01133 audiotime = 0;
01134
01135 VBAUDIOTS(QString("SetAudiotime atc=%1 tc=%2 f=%3 pfu=%4 pfs=%5")
01136 .arg(audbuf_timecode)
01137 .arg(timecode)
01138 .arg(frames)
01139 .arg(processframes_unstretched)
01140 .arg(processframes_stretched));
01141 #ifdef AUDIOTSTESTING
01142 GetAudiotime();
01143 #endif
01144 }
01145
01151 int64_t AudioOutputBase::GetAudioBufferedTime(void)
01152 {
01153 int64_t ret = audbuf_timecode - GetAudiotime();
01154
01155 if (ret < 0)
01156 return 0;
01157 return ret;
01158 }
01159
01163 void AudioOutputBase::SetSWVolume(int new_volume, bool save)
01164 {
01165 volume = new_volume;
01166 if (save && volumeControl != NULL)
01167 gCoreContext->SaveSetting(volumeControl, volume);
01168 }
01169
01173 int AudioOutputBase::GetSWVolume()
01174 {
01175 return volume;
01176 }
01177
01186 int AudioOutputBase::CheckFreeSpace(int &frames)
01187 {
01188 int bpf = bytes_per_frame;
01189 int len = frames * bpf;
01190 int afree = audiofree();
01191
01192 if (len <= afree)
01193 return len;
01194
01195 VBERROR(QString("Audio buffer overflow, %1 frames lost!")
01196 .arg(frames - (afree / bpf)));
01197
01198 frames = afree / bpf;
01199 len = frames * bpf;
01200
01201 if (!src_ctx)
01202 return len;
01203
01204 int error = src_reset(src_ctx);
01205 if (error)
01206 {
01207 VBERROR(QString("Error occurred while resetting resampler: %1")
01208 .arg(src_strerror(error)));
01209 src_ctx = NULL;
01210 }
01211
01212 return len;
01213 }
01214
01221 int AudioOutputBase::CopyWithUpmix(char *buffer, int frames, uint &org_waud)
01222 {
01223 int len = CheckFreeSpace(frames);
01224 int bdiff = kAudioRingBufferSize - org_waud;
01225 int bpf = bytes_per_frame;
01226 int off = 0;
01227
01228 if (!needs_upmix)
01229 {
01230 int num = len;
01231
01232 if (bdiff <= num)
01233 {
01234 memcpy(WPOS, buffer, bdiff);
01235 num -= bdiff;
01236 off = bdiff;
01237 org_waud = 0;
01238 }
01239 if (num > 0)
01240 memcpy(WPOS, buffer + off, num);
01241 org_waud = (org_waud + num) % kAudioRingBufferSize;
01242 return len;
01243 }
01244
01245
01246 if (configured_channels == 2 && source_channels == 1)
01247 {
01248 int bdFrames = bdiff / bpf;
01249 if (bdFrames <= frames)
01250 {
01251 AudioOutputUtil::MonoToStereo(WPOS, buffer, bdFrames);
01252 frames -= bdFrames;
01253 off = bdFrames * sizeof(float);
01254 org_waud = 0;
01255 }
01256 if (frames > 0)
01257 AudioOutputUtil::MonoToStereo(WPOS, buffer + off, frames);
01258
01259 org_waud = (org_waud + frames * bpf) % kAudioRingBufferSize;
01260 return len;
01261 }
01262
01263
01264
01265 off = processing ? sizeof(float) : output_settings->SampleSize(format);
01266 off *= source_channels;
01267
01268 int i = 0;
01269 len = 0;
01270 int nFrames, bdFrames;
01271 while (i < frames)
01272 {
01273 i += upmixer->putFrames(buffer + i * off, frames - i, source_channels);
01274 nFrames = upmixer->numFrames();
01275 if (!nFrames)
01276 continue;
01277
01278 len += CheckFreeSpace(nFrames);
01279
01280 bdFrames = (kAudioRingBufferSize - org_waud) / bpf;
01281 if (bdFrames < nFrames)
01282 {
01283 if ((org_waud % bpf) != 0)
01284 {
01285 VBERROR(QString("Upmixing: org_waud = %1 (bpf = %2)")
01286 .arg(org_waud)
01287 .arg(bpf));
01288 }
01289 upmixer->receiveFrames((float *)(WPOS), bdFrames);
01290 nFrames -= bdFrames;
01291 org_waud = 0;
01292 }
01293 if (nFrames > 0)
01294 upmixer->receiveFrames((float *)(WPOS), nFrames);
01295
01296 org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
01297 }
01298 return len;
01299 }
01300
01306 bool AudioOutputBase::AddFrames(void *in_buffer, int in_frames,
01307 int64_t timecode)
01308 {
01309 return AddData(in_buffer, in_frames * source_bytes_per_frame, timecode,
01310 in_frames);
01311 }
01312
01318 bool AudioOutputBase::AddData(void *in_buffer, int in_len,
01319 int64_t timecode, int )
01320 {
01321 int frames = in_len / source_bytes_per_frame;
01322 void *buffer = in_buffer;
01323 int bpf = bytes_per_frame;
01324 int len = in_len;
01325 bool music = false;
01326 int bdiff;
01327
01328 if (!m_configure_succeeded)
01329 {
01330 LOG(VB_GENERAL, LOG_ERR, "AddData called with audio framework not "
01331 "initialised");
01332 m_length_last_data = 0;
01333 return false;
01334 }
01335
01336
01337
01338 if (unpause_when_ready && pauseaudio && audioready() > fragment_size << 2)
01339 {
01340 unpause_when_ready = false;
01341 Pause(false);
01342 }
01343
01344
01345 QMutexLocker lock(&audio_buflock);
01346
01347 uint org_waud = waud;
01348 int afree = audiofree();
01349 int used = kAudioRingBufferSize - afree;
01350
01351 if (passthru && m_spdifenc)
01352 {
01353 if (processing)
01354 {
01355
01356
01357
01358
01359
01360 LOG(VB_AUDIO, LOG_INFO,
01361 "Passthrough activated with audio processing. Dropping audio");
01362 return false;
01363 }
01364
01365 m_spdifenc->WriteFrame((unsigned char *)in_buffer, len);
01366 len = m_spdifenc->GetProcessedSize();
01367 if (len > 0)
01368 {
01369 buffer = in_buffer = m_spdifenc->GetProcessedBuffer();
01370 m_spdifenc->Reset();
01371 frames = len / source_bytes_per_frame;
01372 }
01373 else
01374 frames = 0;
01375 }
01376 m_length_last_data = (int64_t)
01377 ((double)(len * 1000) / (source_samplerate * source_bytes_per_frame));
01378
01379 VBAUDIOTS(QString("AddData frames=%1, bytes=%2, used=%3, free=%4, "
01380 "timecode=%5 needsupmix=%6")
01381 .arg(frames).arg(len).arg(used).arg(afree).arg(timecode)
01382 .arg(needs_upmix));
01383
01384
01385 if (timecode < 0)
01386 {
01387 timecode = (frames_buffered * 1000) / source_samplerate;
01388 frames_buffered += frames;
01389 music = true;
01390 }
01391
01392 if (hasVisual())
01393 {
01394
01395 dispatchVisual((uchar *)in_buffer, len, timecode, source_channels,
01396 output_settings->FormatToBits(format));
01397 }
01398
01399
01400 if (processing)
01401 {
01402
01403 len = sizeof(*src_in_buf) /
01404 AudioOutputSettings::SampleSize(format) * len;
01405
01406
01407 if (needs_downmix)
01408 len = (len * configured_channels ) / source_channels;
01409
01410
01411 if (need_resampler && src_ctx)
01412 len = (int)ceilf(float(len) * src_data.src_ratio);
01413
01414 if (needs_upmix)
01415 len = (len * configured_channels ) / source_channels;
01416
01417
01418 if (needs_upmix && upmixer)
01419 len += upmixer->numUnprocessedFrames() * bpf;
01420
01421
01422 if (pSoundStretch)
01423 len += (pSoundStretch->numUnprocessedSamples() +
01424 (int)(pSoundStretch->numSamples() / stretchfactor)) * bpf;
01425 }
01426
01427 if (len > afree)
01428 {
01429 VBAUDIOTS("Buffer is full, AddData returning false");
01430 return false;
01431 }
01432
01433 int frames_remaining = frames;
01434 int frames_final = 0;
01435 int maxframes = (kAudioSRCInputSize / source_channels) & ~0xf;
01436 int offset = 0;
01437
01438 while(frames_remaining > 0)
01439 {
01440 buffer = (char *)in_buffer + offset;
01441 frames = frames_remaining;
01442 len = frames * source_bytes_per_frame;
01443
01444 if (processing)
01445 {
01446 if (frames > maxframes)
01447 {
01448 frames = maxframes;
01449 len = frames * source_bytes_per_frame;
01450 offset += len;
01451 }
01452
01453 len = AudioOutputUtil::toFloat(format, src_in, buffer, len);
01454 }
01455
01456 frames_remaining -= frames;
01457
01458
01459 if (needs_downmix)
01460 if(AudioOutputDownmix::DownmixFrames(source_channels,
01461 configured_channels,
01462 src_in, src_in, frames) < 0)
01463 VBERROR("Error occurred while downmixing");
01464
01465
01466 if (need_resampler && src_ctx)
01467 {
01468 src_data.input_frames = frames;
01469 int error = src_process(src_ctx, &src_data);
01470
01471 if (error)
01472 VBERROR(QString("Error occurred while resampling audio: %1")
01473 .arg(src_strerror(error)));
01474
01475 buffer = src_out;
01476 frames = src_data.output_frames_gen;
01477 }
01478 else if (processing)
01479 buffer = src_in;
01480
01481
01482
01483
01484
01485
01486 if ((len = CopyWithUpmix((char *)buffer, frames, org_waud)) <= 0)
01487 {
01488 continue;
01489 }
01490
01491 frames = len / bpf;
01492 frames_final += frames;
01493
01494 bdiff = kAudioRingBufferSize - waud;
01495 if ((len % bpf) != 0 && bdiff < len)
01496 {
01497 VBERROR(QString("AddData: Corruption likely: len = %1 (bpf = %2)")
01498 .arg(len)
01499 .arg(bpf));
01500 }
01501 if ((bdiff % bpf) != 0 && bdiff < len)
01502 {
01503 VBERROR(QString("AddData: Corruption likely: bdiff = %1 (bpf = %2)")
01504 .arg(bdiff)
01505 .arg(bpf));
01506 }
01507
01508 if (pSoundStretch)
01509 {
01510
01511 org_waud = waud;
01512 int bdFrames = bdiff / bpf;
01513
01514 if (bdiff < len)
01515 {
01516 pSoundStretch->putSamples((STST *)(WPOS), bdFrames);
01517 pSoundStretch->putSamples((STST *)ABUF, (len - bdiff) / bpf);
01518 }
01519 else
01520 pSoundStretch->putSamples((STST *)(WPOS), frames);
01521
01522 int nFrames = pSoundStretch->numSamples();
01523 if (nFrames > frames)
01524 CheckFreeSpace(nFrames);
01525
01526 len = nFrames * bpf;
01527
01528 if (nFrames > bdFrames)
01529 {
01530 nFrames -= pSoundStretch->receiveSamples((STST *)(WPOS),
01531 bdFrames);
01532 org_waud = 0;
01533 }
01534 if (nFrames > 0)
01535 nFrames = pSoundStretch->receiveSamples((STST *)(WPOS),
01536 nFrames);
01537
01538 org_waud = (org_waud + nFrames * bpf) % kAudioRingBufferSize;
01539 }
01540
01541 if (internal_vol && SWVolume())
01542 {
01543 org_waud = waud;
01544 int num = len;
01545
01546 if (bdiff <= num)
01547 {
01548 AudioOutputUtil::AdjustVolume(WPOS, bdiff, volume,
01549 music, needs_upmix && upmixer);
01550 num -= bdiff;
01551 org_waud = 0;
01552 }
01553 if (num > 0)
01554 AudioOutputUtil::AdjustVolume(WPOS, num, volume,
01555 music, needs_upmix && upmixer);
01556 org_waud = (org_waud + num) % kAudioRingBufferSize;
01557 }
01558
01559 if (encoder)
01560 {
01561 org_waud = waud;
01562 int to_get = 0;
01563
01564 if (bdiff < len)
01565 {
01566 encoder->Encode(WPOS, bdiff, processing ? FORMAT_FLT : format);
01567 to_get = encoder->Encode(ABUF, len - bdiff,
01568 processing ? FORMAT_FLT : format);
01569 }
01570 else
01571 {
01572 to_get = encoder->Encode(WPOS, len,
01573 processing ? FORMAT_FLT : format);
01574 }
01575
01576 if (bdiff <= to_get)
01577 {
01578 encoder->GetFrames(WPOS, bdiff);
01579 to_get -= bdiff ;
01580 org_waud = 0;
01581 }
01582 if (to_get > 0)
01583 encoder->GetFrames(WPOS, to_get);
01584
01585 org_waud = (org_waud + to_get) % kAudioRingBufferSize;
01586 }
01587
01588 waud = org_waud;
01589 }
01590
01591 SetAudiotime(frames_final, timecode);
01592
01593 return true;
01594 }
01595
01599 void AudioOutputBase::Status()
01600 {
01601 long ct = GetAudiotime();
01602
01603 if (ct < 0)
01604 ct = 0;
01605
01606 if (source_bitrate == -1)
01607 source_bitrate = source_samplerate * source_channels *
01608 output_settings->FormatToBits(format);
01609
01610 if (ct / 1000 != current_seconds)
01611 {
01612 current_seconds = ct / 1000;
01613 OutputEvent e(current_seconds, ct, source_bitrate, source_samplerate,
01614 output_settings->FormatToBits(format), source_channels);
01615 dispatch(e);
01616 }
01617 }
01618
01623 void AudioOutputBase::GetBufferStatus(uint &fill, uint &total)
01624 {
01625 fill = kAudioRingBufferSize - audiofree();
01626 total = kAudioRingBufferSize;
01627 }
01628
01634 void AudioOutputBase::OutputAudioLoop(void)
01635 {
01636 uchar *zeros = new uchar[fragment_size];
01637 uchar *fragment_buf = new uchar[fragment_size + 16];
01638 uchar *fragment = (uchar *)AOALIGN(fragment_buf[0]);
01639 memset(zeros, 0, fragment_size);
01640
01641
01642 int zero_fragment_size = 8 * samplerate * output_bytes_per_frame / 1000;
01643 if (zero_fragment_size > fragment_size)
01644 zero_fragment_size = fragment_size;
01645
01646 while (!killaudio)
01647 {
01648 if (pauseaudio)
01649 {
01650 if (!actually_paused)
01651 {
01652 VBAUDIO("OutputAudioLoop: audio paused");
01653 OutputEvent e(OutputEvent::Paused);
01654 dispatch(e);
01655 was_paused = true;
01656 }
01657
01658 actually_paused = true;
01659 audiotime = 0;
01660
01661 WriteAudio(zeros, zero_fragment_size);
01662 continue;
01663 }
01664 else
01665 {
01666 if (was_paused)
01667 {
01668 VBAUDIO("OutputAudioLoop: Play Event");
01669 OutputEvent e(OutputEvent::Playing);
01670 dispatch(e);
01671 was_paused = false;
01672 }
01673 }
01674
01675
01676 int ready = audioready();
01677
01678
01679 if (fragment_size > ready)
01680 {
01681 if (ready > 0)
01682 VBAUDIOTS(QString("audio waiting for buffer to fill: "
01683 "have %1 want %2")
01684 .arg(ready).arg(fragment_size));
01685
01686 usleep(10000);
01687 continue;
01688 }
01689
01690 #ifdef AUDIOTSTESTING
01691 VBAUDIOTS("WriteAudio Start");
01692 #endif
01693 Status();
01694
01695
01696
01697 reset_active.TestAndDeref();
01698 volatile uint next_raud = raud;
01699 if (GetAudioData(fragment, fragment_size, true, &next_raud))
01700 {
01701 if (!reset_active.TestAndDeref())
01702 {
01703 WriteAudio(fragment, fragment_size);
01704 if (!reset_active.TestAndDeref())
01705 raud = next_raud;
01706 }
01707 }
01708 #ifdef AUDIOTSTESTING
01709 GetAudiotime();
01710 VBAUDIOTS("WriteAudio Done");
01711 #endif
01712
01713 }
01714
01715 delete[] zeros;
01716 delete[] fragment_buf;
01717 VBAUDIO("OutputAudioLoop: Stop Event");
01718 OutputEvent e(OutputEvent::Stopped);
01719 dispatch(e);
01720 }
01721
01729 int AudioOutputBase::GetAudioData(uchar *buffer, int size, bool full_buffer,
01730 volatile uint *local_raud)
01731 {
01732
01733 #define LRPOS audiobuffer + *local_raud
01734
01735
01736 int avail_size = audioready();
01737 int frag_size = size;
01738 int written_size = size;
01739
01740 if (local_raud == NULL)
01741 local_raud = &raud;
01742
01743 if (!full_buffer && (size > avail_size))
01744 {
01745
01746 frag_size = avail_size;
01747 written_size = frag_size;
01748 }
01749
01750 if (!avail_size || (frag_size > avail_size))
01751 return 0;
01752
01753 int bdiff = kAudioRingBufferSize - raud;
01754
01755 int obytes = output_settings->SampleSize(output_format);
01756 bool fromFloats = processing && !enc && output_format != FORMAT_FLT;
01757
01758
01759 if (fromFloats && obytes != sizeof(float))
01760 frag_size *= sizeof(float) / obytes;
01761
01762 int off = 0;
01763
01764 if (bdiff <= frag_size)
01765 {
01766 if (fromFloats)
01767 off = AudioOutputUtil::fromFloat(output_format, buffer,
01768 LRPOS, bdiff);
01769 else
01770 {
01771 memcpy(buffer, LRPOS, bdiff);
01772 off = bdiff;
01773 }
01774
01775 frag_size -= bdiff;
01776 *local_raud = 0;
01777 }
01778 if (frag_size > 0)
01779 {
01780 if (fromFloats)
01781 AudioOutputUtil::fromFloat(output_format, buffer + off,
01782 LRPOS, frag_size);
01783 else
01784 memcpy(buffer + off, LRPOS, frag_size);
01785 }
01786
01787 *local_raud += frag_size;
01788
01789
01790 MuteState mute_state = GetMuteState();
01791 if (!enc && !passthru &&
01792 written_size && configured_channels > 1 &&
01793 (mute_state == kMuteLeft || mute_state == kMuteRight))
01794 {
01795 AudioOutputUtil::MuteChannel(obytes << 3, configured_channels,
01796 mute_state == kMuteLeft ? 0 : 1,
01797 buffer, written_size);
01798 }
01799
01800 return written_size;
01801 }
01802
01806 void AudioOutputBase::Drain()
01807 {
01808 while (audioready() > fragment_size)
01809 usleep(1000);
01810 }
01811
01815 void AudioOutputBase::run(void)
01816 {
01817 RunProlog();
01818 VBAUDIO(QString("kickoffOutputAudioLoop: pid = %1").arg(getpid()));
01819 OutputAudioLoop();
01820 VBAUDIO("kickoffOutputAudioLoop exiting");
01821 RunEpilog();
01822 }
01823
01824 int AudioOutputBase::readOutputData(unsigned char*, int)
01825 {
01826 VBERROR("AudioOutputBase should not be getting asked to readOutputData()");
01827 return 0;
01828 }