diff --git a/mythtv/libs/libmyth/audio/audiooutput.cpp b/mythtv/libs/libmyth/audio/audiooutput.cpp index 117d74c346e..31c79664faf 100644 --- a/mythtv/libs/libmyth/audio/audiooutput.cpp +++ b/mythtv/libs/libmyth/audio/audiooutput.cpp @@ -48,11 +48,11 @@ AudioOutput *AudioOutput::OpenAudio( const QString &main_device, const QString &passthru_device, AudioFormat format, int channels, int codec, int samplerate, AudioOutputSource source, bool set_initial_vol, bool passthru, - int upmixer_startup) + int upmixer_startup, AudioOutputSettings *custom) { AudioSettings settings( main_device, passthru_device, format, channels, codec, samplerate, - source, set_initial_vol, passthru, upmixer_startup); + source, set_initial_vol, passthru, upmixer_startup, custom); return OpenAudio(settings); } diff --git a/mythtv/libs/libmyth/audio/audiooutput.h b/mythtv/libs/libmyth/audio/audiooutput.h index 9367688a0b1..d0a99ace82e 100644 --- a/mythtv/libs/libmyth/audio/audiooutput.h +++ b/mythtv/libs/libmyth/audio/audiooutput.h @@ -41,7 +41,7 @@ class MPUBLIC AudioOutput : public VolumeBase, public OutputListeners const QString &audiodevice, const QString &passthrudevice, AudioFormat format, int channels, int codec, int samplerate, AudioOutputSource source, bool set_initial_vol, bool passthru, - int upmixer_startup = 0); + int upmixer_startup = 0, AudioOutputSettings *custom = NULL); static AudioOutput *OpenAudio(AudioSettings &settings, bool willsuspendpa = true); static AudioOutput *OpenAudio( diff --git a/mythtv/libs/libmyth/audio/audiooutputbase.cpp b/mythtv/libs/libmyth/audio/audiooutputbase.cpp index 62e53992360..077f5a4afa6 100644 --- a/mythtv/libs/libmyth/audio/audiooutputbase.cpp +++ b/mythtv/libs/libmyth/audio/audiooutputbase.cpp @@ -73,7 +73,7 @@ AudioOutputBase::AudioOutputBase(const AudioSettings &settings) : pSoundStretch(NULL), encoder(NULL), upmixer(NULL), source_channels(-1), source_samplerate(0), - source_bytes_per_frame(0), + source_bytes_per_frame(0), upmix_default(false), needs_upmix(false), needs_downmix(false), surround_mode(QUALITY_LOW), old_stretchfactor(1.0f), volume(80), volumeControl(QString()), @@ -144,6 +144,17 @@ AudioOutputBase::~AudioOutputBase() void AudioOutputBase::InitSettings(const AudioSettings &settings) { + if (settings.custom) + { + // got a custom audio report already, use it + // this was likely provided by the AudioTest utility + output_settings = new AudioOutputSettings; + *output_settings = *settings.custom; + max_channels = output_settings->BestSupportedChannels(); + configured_channels = max_channels; + return; + } + // Ask the subclass what we can send to the device output_settings = GetOutputSettingsUsers(); diff --git a/mythtv/libs/libmyth/audio/audiooutputbase.h b/mythtv/libs/libmyth/audio/audiooutputbase.h index 4aa34bcc1ca..ee4667ef5d8 100644 --- a/mythtv/libs/libmyth/audio/audiooutputbase.h +++ b/mythtv/libs/libmyth/audio/audiooutputbase.h @@ -181,8 +181,8 @@ class AudioOutputBase : public AudioOutput, public QThread int source_channels; int source_samplerate; int source_bytes_per_frame; - bool needs_upmix; bool upmix_default; + bool needs_upmix; bool needs_downmix; int surround_mode; float old_stretchfactor; diff --git a/mythtv/libs/libmyth/audio/audiooutputsettings.cpp b/mythtv/libs/libmyth/audio/audiooutputsettings.cpp index 9da7816e73a..0fe778a30bc 100644 --- a/mythtv/libs/libmyth/audio/audiooutputsettings.cpp +++ b/mythtv/libs/libmyth/audio/audiooutputsettings.cpp @@ -271,7 +271,7 @@ AudioOutputSettings* AudioOutputSettings::GetCleaned(bool newcopy) aosettings->m_LPCM = (mchannels > 2); if (mchannels == 2 && m_passthrough >= 0) { - VERBOSE(VB_AUDIO, LOC + QString("AC3 or DTS capable")); + VERBOSE(VB_AUDIO, LOC + QString("may be AC3 or DTS capable")); aosettings->AddSupportedChannels(6); } aosettings->m_DTS = aosettings->m_AC3 = (m_passthrough >= 0); @@ -307,7 +307,7 @@ AudioOutputSettings* AudioOutputSettings::GetUsers(bool newcopy) gCoreContext->GetNumSetting("DTSPassThru", false); bool bLPCM = aosettings->m_LPCM && (aosettings->m_passthrough == -1 || - !(bAdv && gCoreContext->GetNumSetting("StereoPCM", false))); + !gCoreContext->GetNumSetting("StereoPCM", false)); if (max_channels > 2 && !bLPCM) max_channels = 2; diff --git a/mythtv/libs/libmyth/audio/audiooutputsettings.h b/mythtv/libs/libmyth/audio/audiooutputsettings.h index fbc57a1ab11..b74522a947a 100644 --- a/mythtv/libs/libmyth/audio/audiooutputsettings.h +++ b/mythtv/libs/libmyth/audio/audiooutputsettings.h @@ -61,10 +61,13 @@ class MPUBLIC AudioOutputSettings bool canDTS() { return m_DTS; }; bool canLPCM() { return m_LPCM; }; bool IsInvalid() { return m_invalid; }; + void setAC3(bool b) { m_AC3 = b; }; + void setDTS(bool b) { m_DTS = b; }; + void setLPCM(bool b) { m_LPCM = b; }; + void SetBestSupportedChannels(int channels); private: void SortSupportedChannels(); - void SetBestSupportedChannels(int channels); /* passthrough status * -1 : no diff --git a/mythtv/libs/libmyth/audio/audiosettings.cpp b/mythtv/libs/libmyth/audio/audiosettings.cpp index f703945a984..8cf2fefc075 100644 --- a/mythtv/libs/libmyth/audio/audiosettings.cpp +++ b/mythtv/libs/libmyth/audio/audiosettings.cpp @@ -19,7 +19,8 @@ AudioSettings::AudioSettings() : use_passthru(false), source(AUDIOOUTPUT_UNKNOWN), upmixer(0), - init(false) + init(false), + custom(NULL) { } @@ -36,19 +37,28 @@ AudioSettings::AudioSettings(const AudioSettings &other) : upmixer(other.upmixer), init(true) { + if (other.custom) + { + // make a copy of it + custom = new AudioOutputSettings; + *custom = *other.custom; + } + else + custom = NULL; } AudioSettings::AudioSettings( - const QString &main_device, - const QString &passthru_device, - AudioFormat format, - int channels, - int codec, - int samplerate, - AudioOutputSource source, - bool set_initial_vol, - bool use_passthru, - int upmixer_startup) : + const QString &main_device, + const QString &passthru_device, + AudioFormat format, + int channels, + int codec, + int samplerate, + AudioOutputSource source, + bool set_initial_vol, + bool use_passthru, + int upmixer_startup, + AudioOutputSettings *custom) : main_device(main_device), passthru_device(passthru_device), format(format), @@ -61,6 +71,14 @@ AudioSettings::AudioSettings( upmixer(upmixer_startup), init(true) { + if (custom) + { + // make a copy of it + this->custom = new AudioOutputSettings; + *this->custom = *custom; + } + else + this->custom = NULL; } AudioSettings::AudioSettings( @@ -80,7 +98,8 @@ AudioSettings::AudioSettings( use_passthru(use_passthru), source(AUDIOOUTPUT_UNKNOWN), upmixer(upmixer_startup), - init(true) + init(true), + custom(NULL) { } @@ -97,8 +116,15 @@ AudioSettings::AudioSettings( use_passthru(false), source(AUDIOOUTPUT_UNKNOWN), upmixer(0), - init(false) + init(false), + custom(NULL) +{ +} + +AudioSettings::~AudioSettings() { + if (custom) + delete custom; } void AudioSettings::FixPassThrough(void) diff --git a/mythtv/libs/libmyth/audio/audiosettings.h b/mythtv/libs/libmyth/audio/audiosettings.h index d9830ef737f..3a4b433e8d9 100644 --- a/mythtv/libs/libmyth/audio/audiosettings.h +++ b/mythtv/libs/libmyth/audio/audiosettings.h @@ -26,27 +26,29 @@ class MPUBLIC AudioSettings AudioSettings(); AudioSettings(const AudioSettings &other); AudioSettings( - const QString &main_device, - const QString &passthru_device, - AudioFormat format, - int channels, - int codec, - int samplerate, - AudioOutputSource source, - bool set_initial_vol, - bool use_passthru, - int upmixer_startup = 0); + const QString &main_device, + const QString &passthru_device, + AudioFormat format, + int channels, + int codec, + int samplerate, + AudioOutputSource source, + bool set_initial_vol, + bool use_passthru, + int upmixer_startup = 0, + AudioOutputSettings *custom = NULL); - AudioSettings(AudioFormat format, - int channels, - int codec, - int samplerate, - bool use_passthru, - int upmixer_startup = 0); + AudioSettings(AudioFormat format, + int channels, + int codec, + int samplerate, + bool use_passthru, + int upmixer_startup = 0); AudioSettings(const QString &main_device, const QString &passthru_device = QString::null); + ~AudioSettings(); void FixPassThrough(void); void TrimDeviceType(void); @@ -54,17 +56,18 @@ class MPUBLIC AudioSettings QString GetPassthruDevice(void) const; public: - QString main_device; - QString passthru_device; - AudioFormat format; - int channels; - int codec; - int samplerate; - bool set_initial_vol; - bool use_passthru; - AudioOutputSource source; - int upmixer; - bool init; + QString main_device; + QString passthru_device; + AudioFormat format; + int channels; + int codec; + int samplerate; + bool set_initial_vol; + bool use_passthru; + AudioOutputSource source; + int upmixer; + bool init; + AudioOutputSettings *custom; }; #endif // _AUDIO_SETTINGS_H_ diff --git a/mythtv/libs/libmyth/settings.cpp b/mythtv/libs/libmyth/settings.cpp index b955a9bbbc6..46c7bd04e26 100644 --- a/mythtv/libs/libmyth/settings.cpp +++ b/mythtv/libs/libmyth/settings.cpp @@ -1346,6 +1346,13 @@ void ButtonSetting::setEnabled(bool fEnabled) button->setEnabled(fEnabled); } +void ButtonSetting::setLabel(QString str) +{ + if (button) + button->setText(str); + Setting::setLabel(str); +} + void ButtonSetting::setHelpText(const QString &str) { if (button) diff --git a/mythtv/libs/libmyth/settings.h b/mythtv/libs/libmyth/settings.h index 9e8335e8f47..10c993984e6 100644 --- a/mythtv/libs/libmyth/settings.h +++ b/mythtv/libs/libmyth/settings.h @@ -54,7 +54,7 @@ class MPUBLIC Configurable : public QObject virtual Setting* byName(const QString &name) = 0; // A label displayed to the user - void setLabel(QString str) { label = str; } + virtual void setLabel(QString str) { label = str; } QString getLabel(void) const { return label; } void setLabelAboveWidget(bool l = true) { labelAboveWidget = l; } @@ -580,6 +580,8 @@ class MPUBLIC ButtonSetting: public Setting virtual void setEnabled(bool b); + virtual void setLabel(QString); + virtual void setHelpText(const QString &); signals: diff --git a/mythtv/programs/mythfrontend/audiogeneralsettings.cpp b/mythtv/programs/mythfrontend/audiogeneralsettings.cpp index f20f100db50..afb7ce8418e 100644 --- a/mythtv/programs/mythfrontend/audiogeneralsettings.cpp +++ b/mythtv/programs/mythfrontend/audiogeneralsettings.cpp @@ -238,9 +238,12 @@ void AudioConfigSettings::UpdateVisibility(const QString &device) m_AudioUpmixType->setEnabled(cur_speakers > 2); } -void AudioConfigSettings::UpdateCapabilities(const QString &device) +AudioOutputSettings AudioConfigSettings::UpdateCapabilities( + const QString &device) { int max_speakers = 8; + int realmax_speakers = 8; + bool invalid = false; AudioOutputSettings settings; @@ -248,13 +251,16 @@ void AudioConfigSettings::UpdateCapabilities(const QString &device) if (!m_OutputDevice || !m_MaxAudioChannels || !m_AC3PassThrough || !m_DTSPassThrough || !m_EAC3PassThrough || !m_TrueHDPassThrough) - return; + return settings; if (!slotlock.tryLock()) // Doing a rescan of channels - return; + return settings; bool bForceDigital = gCoreContext->GetNumSetting("PassThruDeviceOverride", false); + bool bAC3 = true; + bool bDTS = true; + bool bLPCM = true; QString out = m_OutputDevice->getValue(); if (!audiodevs.contains(out)) @@ -266,13 +272,13 @@ void AudioConfigSettings::UpdateCapabilities(const QString &device) { settings = audiodevs.value(out).settings; - max_speakers = settings.BestSupportedChannels(); + realmax_speakers = max_speakers = settings.BestSupportedChannels(); - bool bAC3 = (settings.canAC3() || bForceDigital) && + bAC3 = (settings.canAC3() || bForceDigital) && m_AC3PassThrough->boolValue(); - bool bDTS = (settings.canDTS() || bForceDigital) && + bDTS = (settings.canDTS() || bForceDigital) && m_DTSPassThrough->boolValue(); - bool bLPCM = settings.canPassthrough() == -1 || + bLPCM = settings.canPassthrough() == -1 || (settings.canLPCM() && !gCoreContext->GetNumSetting("StereoPCM", false)); @@ -291,12 +297,6 @@ void AudioConfigSettings::UpdateCapabilities(const QString &device) m_EAC3PassThrough->setEnabled(canhdpassthrough); m_TrueHDPassThrough->setEnabled(canhdpassthrough); - if (canhdpassthrough && - (m_EAC3PassThrough->boolValue() || m_TrueHDPassThrough->boolValue())) - { - max_speakers = 8; - } - int cur_speakers = m_MaxAudioChannels->getValue().toInt(); if (cur_speakers > max_speakers) @@ -333,7 +333,13 @@ void AudioConfigSettings::UpdateCapabilities(const QString &device) i == cur_speakers); } } + settings.SetBestSupportedChannels(cur_speakers); + settings.setAC3(bAC3); + settings.setDTS(bDTS); + settings.setLPCM(bLPCM && (realmax_speakers > 2)); + slotlock.unlock(); + return settings; } void AudioConfigSettings::AudioAdvanced() @@ -465,6 +471,8 @@ bool AudioConfigSettings::CheckPassthrough() void AudioConfigSettings::StartAudioTest() { + AudioOutputSettings settings = UpdateCapabilities(QString::null); + QString out = m_OutputDevice->getValue(); QString passthrough = gCoreContext->GetNumSetting("PassThruDeviceOverride", false) ? @@ -472,23 +480,24 @@ void AudioConfigSettings::StartAudioTest() int channels = m_MaxAudioChannels->getValue().toInt(); QString errMsg; - AudioTestGroup audiotest(out, passthrough, channels); + AudioTestGroup audiotest(out, passthrough, channels, settings); audiotest.exec(); } AudioTestThread::AudioTestThread(QObject *parent, QString main, QString passthrough, - int channels) : + int channels, + AudioOutputSettings settings) : m_parent(parent), m_channels(channels), m_device(main), - m_passthrough(passthrough), m_interrupted(false) + m_passthrough(passthrough), m_interrupted(false), m_channel(-1) { m_audioOutput = AudioOutput::OpenAudio(m_device, m_passthrough, FORMAT_S16, m_channels, 0, 48000, AUDIOOUTPUT_VIDEO, - true, false); + true, false, 0, &settings); } QEvent::Type ChannelChangedEvent::kEventType = @@ -502,6 +511,11 @@ AudioTestThread::~AudioTestThread() delete m_audioOutput; } +void AudioTestThread::cancel() +{ + m_interrupted = true; +} + QString AudioTestThread::result() { QString errMsg; @@ -512,30 +526,47 @@ QString AudioTestThread::result() return errMsg; } -void AudioTestThread::cancel() +void AudioTestThread::setChannel(int channel) { - m_interrupted = true; + m_channel = channel; } void AudioTestThread::run() { m_interrupted = false; + int smptelayout[7][8] = { + { 0, 1 }, //stereo + { }, //not used + { }, //not used + { }, //not used + { 0, 2, 1, 5, 4, 3 }, //5.1 + { }, //not used + { 0, 2, 1, 7, 5, 4, 6, 3 }, //7.1 + }; if (m_audioOutput) { - char *frames_in = new char[m_channels * 48000 * sizeof(int16_t) + 15]; + char *frames_in = new char[m_channels * 1024 * sizeof(int16_t) + 15]; char *frames = (char *)(((long)frames_in + 15) & ~0xf); while (!m_interrupted) { - for (int i = 0; i < m_channels && !m_interrupted; i++) + int begin = 0; + int end = m_channels + 1; + if (m_channel >= 0) { - AudioOutputUtil::GeneratePinkSamples(frames, m_channels, - i, 48000); + begin = m_channel; + end = m_channel + 1; + } + + for (int i = begin; i < end && !m_interrupted; i++) + { + int current = smptelayout[m_channels - 2][i]; + if (m_parent) { QString channel; - switch(i) + switch(current) { case 0: channel = "frontleft"; @@ -559,7 +590,7 @@ void AudioTestThread::run() if (m_channels == 6) channel = "surroundright"; else - channel = "rearleft"; + channel = "rearright"; break; case 6: channel = "surroundleft"; @@ -569,24 +600,35 @@ void AudioTestThread::run() break; } QCoreApplication::postEvent( - m_parent, new ChannelChangedEvent(channel)); + m_parent, new ChannelChangedEvent(channel, + m_channel < 0)); } - if (!m_audioOutput->AddFrames(frames, 48000, -1)) + // play sample sound for about 3s + for (int j = 0; j < 144 && !m_interrupted; j++) { - VERBOSE(VB_AUDIO, "AddAudioData() " - "Audio buffer overflow, audio data lost!"); + AudioOutputUtil::GeneratePinkSamples(frames, m_channels, + current, 1000); + if (!m_audioOutput->AddFrames(frames, 1000, -1)) + { + VERBOSE(VB_AUDIO, "AddAudioData() " + "Audio buffer overflow, audio data lost!"); + } + usleep(20833-1000); // 1/48th of a second } - usleep(m_audioOutput->GetAudioBufferedTime()*1000); + m_audioOutput->Drain(); m_audioOutput->Pause(true); usleep(500000); // .5s pause m_audioOutput->Pause(false); } + if (m_channel >= 0) + break; } delete[] frames_in; } } -AudioTest::AudioTest(QString main, QString passthrough, int channels) +AudioTest::AudioTest(QString main, QString passthrough, + int channels, AudioOutputSettings settings) : VerticalConfigurationGroup(false, true, false, false), m_channels(channels), m_frontleft(NULL), m_frontright(NULL), m_center(NULL), @@ -596,7 +638,7 @@ AudioTest::AudioTest(QString main, QString passthrough, int channels) { setLabel(QObject::tr("Audio Configuration Testing")); - m_at = new AudioTestThread(this, main, passthrough, channels); + m_at = new AudioTestThread(this, main, passthrough, channels, settings); if (!m_at->result().isEmpty()) { QString msg = main + QObject::tr(" is invalid or not " @@ -620,33 +662,49 @@ AudioTest::AudioTest(QString main, QString passthrough, int channels) ConfigurationGroup *reargroup = new HorizontalConfigurationGroup(false, false); - m_frontleft = new TransButtonSetting("frontleft"); + m_frontleft = new TransButtonSetting("0"); m_frontleft->setLabel(QObject::tr("Front Left")); - m_frontright = new TransButtonSetting("frontright"); + connect(m_frontleft, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); + m_frontright = new TransButtonSetting("1"); m_frontright->setLabel(QObject::tr("Front Right")); - m_center = new TransButtonSetting("center"); + connect(m_frontright, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); + m_center = new TransButtonSetting("2"); m_center->setLabel(QObject::tr("Center")); + connect(m_center, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); frontgroup->addChild(m_frontleft); switch(m_channels) { case 8: - m_rearleft = new TransButtonSetting("rearleft"); + m_rearleft = new TransButtonSetting("6"); m_rearleft->setLabel(QObject::tr("Rear Left")); - m_rearright = new TransButtonSetting("rearright"); + connect(m_rearleft, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); + m_rearright = new TransButtonSetting("7"); m_rearright->setLabel(QObject::tr("Rear Right")); + connect(m_rearright, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); reargroup->addChild(m_rearleft); reargroup->addChild(m_rearright); case 6: - m_surroundleft = new TransButtonSetting("surroundleft"); + m_surroundleft = new TransButtonSetting("4"); m_surroundleft->setLabel(QObject::tr("Surround Left")); - m_surroundright = new TransButtonSetting("surroundright"); + connect(m_surroundleft, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); + m_surroundright = new TransButtonSetting("5"); m_surroundright->setLabel(QObject::tr("Surround Right")); - m_lfe = new TransButtonSetting("lfe"); + connect(m_surroundright, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); + m_lfe = new TransButtonSetting("3"); m_lfe->setLabel(QObject::tr("LFE")); + connect(m_lfe, + SIGNAL(pressed(QString)), this, SLOT(toggle(QString))); frontgroup->addChild(m_center); middlegroup->addChild(m_surroundleft); @@ -677,7 +735,7 @@ void AudioTest::toggle(QString str) if (m_at->isRunning()) { m_at->cancel(); - m_button->setLabel(QObject::tr("Start channels test")); + m_button->setLabel(QObject::tr("Test All")); if (m_frontleft) m_frontleft->setEnabled(true); if (m_frontright) @@ -697,10 +755,20 @@ void AudioTest::toggle(QString str) } else { + m_at->setChannel(-1); m_at->start(); m_button->setLabel(QObject::tr("Stop")); } + return; + } + int channel = str.toInt(); + if (m_at->isRunning()) + { + m_at->cancel(); + m_at->wait(); } + m_at->setChannel(channel); + m_at->start(); } bool AudioTest::event(QEvent *event) @@ -708,11 +776,15 @@ bool AudioTest::event(QEvent *event) if (event->type() != ChannelChangedEvent::kEventType) return QObject::event(event); //not handled + ChannelChangedEvent *cce = (ChannelChangedEvent*)(event); + QString channel = cce->channel; + + if (!cce->fulltest) + return false; + bool fl, fr, c, lfe, sl, sr, rl, rr; fl = fr = c = lfe = sl = sr = rl = rr = false; - ChannelChangedEvent *cce = (ChannelChangedEvent*)(event); - QString channel = cce->channel; if (channel == "frontleft") { fl = true; @@ -765,9 +837,10 @@ bool AudioTest::event(QEvent *event) } -AudioTestGroup::AudioTestGroup(QString main, QString passthrough, int channels) +AudioTestGroup::AudioTestGroup(QString main, QString passthrough, + int channels, AudioOutputSettings settings) { - addChild(new AudioTest(main, passthrough, channels)); + addChild(new AudioTest(main, passthrough, channels, settings)); } HostCheckBox *AudioMixerSettings::MythControlsVolume() diff --git a/mythtv/programs/mythfrontend/audiogeneralsettings.h b/mythtv/programs/mythfrontend/audiogeneralsettings.h index 00db8ffc4f5..654346cb69c 100644 --- a/mythtv/programs/mythfrontend/audiogeneralsettings.h +++ b/mythtv/programs/mythfrontend/audiogeneralsettings.h @@ -34,7 +34,7 @@ class AudioConfigSettings : public VerticalConfigurationGroup private slots: void UpdateVisibility(const QString&); - void UpdateCapabilities(const QString&); + AudioOutputSettings UpdateCapabilities(const QString&); void AudioRescan(); void AudioAdvanced(); void StartAudioTest(); @@ -126,18 +126,19 @@ class AudioAdvancedSettingsGroup : public ConfigurationWizard class AudioTestGroup : public ConfigurationWizard { public: - AudioTestGroup(QString main, QString passthrough, int channels); + AudioTestGroup(QString main, QString passthrough, + int channels, AudioOutputSettings settings); }; class ChannelChangedEvent : public QEvent { public: - ChannelChangedEvent(QString channame) : - QEvent(kEventType), - channel(channame) {} + ChannelChangedEvent(QString channame, bool fulltest) : + QEvent(kEventType), channel(channame), fulltest(fulltest) {} ~ChannelChangedEvent() {} QString channel; + bool fulltest; static Type kEventType; }; @@ -147,11 +148,12 @@ class AudioTestThread : public QThread public: AudioTestThread(QObject *parent, QString main, QString passthrough, - int channels); + int channels, AudioOutputSettings settings); ~AudioTestThread(); void cancel(); QString result(); + void setChannel(int channel); protected: void run(); @@ -163,13 +165,15 @@ class AudioTestThread : public QThread QString m_device; QString m_passthrough; bool m_interrupted; + int m_channel; }; class AudioTest : public VerticalConfigurationGroup { Q_OBJECT public: - AudioTest(QString main, QString passthrough, int channels); + AudioTest(QString main, QString passthrough, + int channels, AudioOutputSettings settings); ~AudioTest(); bool event(QEvent *event); diff --git a/mythtv/programs/mythfrontend/audiosettings.cpp b/mythtv/programs/mythfrontend/audiosettings.cpp deleted file mode 100644 index 0586f8f452a..00000000000 --- a/mythtv/programs/mythfrontend/audiosettings.cpp +++ /dev/null @@ -1,921 +0,0 @@ - -// -*- Mode: c++ -*- - -// Standard UNIX C headers -#include -#include -#include -#include - -// Qt headers -#include -#include -#include - -// MythTV headers -#include "mythconfig.h" -#include "mythcorecontext.h" -#include "mythdbcon.h" -#include "mythverbose.h" -#include "audiooutpututil.h" -#include "audiosettings.h" -#include "mythdialogbox.h" - -class TriggeredItem : public TriggeredConfigurationGroup -{ - public: - TriggeredItem(Setting *checkbox, ConfigurationGroup *group) : - TriggeredConfigurationGroup(false, false, false, false) - { - setTrigger(checkbox); - - addTarget("1", group); - addTarget("0", new VerticalConfigurationGroup(true)); - } - TriggeredItem(Setting *checkbox, Setting *setting) : - TriggeredConfigurationGroup(false, false, false, false) - { - setTrigger(checkbox); - - addTarget("1", setting); - addTarget("0", new VerticalConfigurationGroup(false, false)); - } -}; - -AudioDeviceComboBox::AudioDeviceComboBox(AudioConfigSettings *parent) : - HostComboBox("AudioOutputDevice", true), m_parent(parent) -{ - setLabel(QObject::tr("Audio output device")); -#ifdef USING_ALSA - QString dflt = "ALSA:default"; -#elif USING_PULSEOUTPUT - QString dflt = "PulseAudio:default"; -#elif CONFIG_DARWIN - QString dflt = "CoreAudio:"; -#elif USING_MINGW - QString dflt = "Windows:"; -#else - QString dflt = "NULL"; -#endif - QString current = gCoreContext->GetSetting(QString("AudioOutputDevice"), - dflt); - addSelection(current, current, true); - - connect(this, SIGNAL(valueChanged(const QString&)), - this, SLOT(AudioDescriptionHelp(const QString&))); -} - -void AudioDeviceComboBox::AudioRescan() -{ - AudioOutput::ADCVect &vect = m_parent->AudioDeviceVect(); - AudioOutput::ADCVect::const_iterator it; - - if (vect.empty()) - return; - - QString value = getValue(); - clearSelections(); - resetMaxCount(vect.size()); - - bool found = false; - for (it = vect.begin(); it != vect.end(); it++) - addSelection(it->name, it->name, - value == it->name ? (found = true) : false); - if (!found) - { - resetMaxCount(vect.size()+1); - addSelection(value, value, true); - } - // For some reason, it adds an empty entry, remove it - removeSelection(QString::null); -} - -void AudioDeviceComboBox::AudioDescriptionHelp(const QString &device) -{ - QString desc = m_parent->AudioDeviceMap().value(device).desc; - setHelpText(desc); -} - -AudioConfigSettings::AudioConfigSettings() : - VerticalConfigurationGroup(false, true, false, false), - m_OutputDevice(NULL), m_MaxAudioChannels(NULL), - m_AudioUpmix(NULL), m_AudioUpmixType(NULL), - m_AC3PassThrough(NULL), m_DTSPassThrough(NULL), - m_EAC3PassThrough(NULL),m_TrueHDPassThrough(NULL), - m_passthrough8(false) -{ - setLabel(QObject::tr("Audio System")); - setUseLabel(false); - - ConfigurationGroup *devicegroup = new HorizontalConfigurationGroup(false, - false); - devicegroup->addChild((m_OutputDevice = new AudioDeviceComboBox(this))); - // Rescan button - TransButtonSetting *rescan = new TransButtonSetting("rescan"); - rescan->setLabel(QObject::tr("Rescan")); - rescan->setHelpText(QObject::tr("Rescan for available audio devices. " - "Current entry will be checked and " - "capability entries populated.")); - devicegroup->addChild(rescan); - connect(rescan, SIGNAL(pressed()), this, SLOT(AudioRescan())); - addChild(devicegroup); - - QString name = m_OutputDevice->getValue(); - AudioOutput::AudioDeviceConfig *adc = - AudioOutput::GetAudioDeviceConfig(name, name, true); - if (adc->settings.IsInvalid()) - { - VERBOSE(VB_IMPORTANT, QString("Audio device %1 isn't usable " - "Check audio configuration").arg(name)); - } - audiodevs.insert(name, *adc); - devices.append(*adc); - - delete adc; - CheckPassthrough(); - - ConfigurationGroup *maingroup = new VerticalConfigurationGroup(false, - false); - addChild(maingroup); - - m_triggerDigital = new TransCheckBoxSetting(); - m_AC3PassThrough = AC3PassThrough(); - m_DTSPassThrough = DTSPassThrough(); - m_EAC3PassThrough = EAC3PassThrough(); - m_TrueHDPassThrough = TrueHDPassThrough(); - - m_cgsettings = new HorizontalConfigurationGroup(); - m_cgsettings->setLabel(QObject::tr("Digital Audio Capabilities")); - m_cgsettings->addChild(m_AC3PassThrough); - m_cgsettings->addChild(m_DTSPassThrough); - m_cgsettings->addChild(m_EAC3PassThrough); - m_cgsettings->addChild(m_TrueHDPassThrough); - - TriggeredItem *sub1 = new TriggeredItem(m_triggerDigital, m_cgsettings); - - maingroup->addChild(sub1); - - maingroup->addChild((m_MaxAudioChannels = MaxAudioChannels())); - maingroup->addChild((m_AudioUpmix = AudioUpmix())); - maingroup->addChild((m_AudioUpmixType = AudioUpmixType())); - - TransButtonSetting *test = new TransButtonSetting("test"); - test->setLabel(QObject::tr("Test")); - test->setHelpText(QObject::tr("Will play a test pattern on all configured " - "speakers")); - connect(test, SIGNAL(pressed()), this, SLOT(AudioTest())); - addChild(test); - - TransButtonSetting *advanced = new TransButtonSetting("advanced"); - advanced->setLabel(QObject::tr("Advanced Audio Settings")); - advanced->setHelpText(QObject::tr("Enable extra audio settings. Under most " - "usage all options should be unchecked")); - connect(advanced, SIGNAL(pressed()), this, SLOT(AudioAdvanced())); - addChild(advanced); - - // Set slots - connect(m_MaxAudioChannels, SIGNAL(valueChanged(const QString&)), - this, SLOT(UpdateVisibility(const QString&))); - connect(m_OutputDevice, SIGNAL(valueChanged(const QString&)), - this, SLOT(UpdateCapabilities(const QString&))); - connect(m_AC3PassThrough, SIGNAL(valueChanged(const QString&)), - this, SLOT(UpdateCapabilities(const QString&))); - connect(m_DTSPassThrough, SIGNAL(valueChanged(const QString&)), - this, SLOT(UpdateCapabilities(const QString&))); - connect(m_EAC3PassThrough, SIGNAL(valueChanged(const QString&)), - this, SLOT(UpdateCapabilities(const QString&))); - connect(m_TrueHDPassThrough, SIGNAL(valueChanged(const QString&)), - this, SLOT(UpdateCapabilities(const QString&))); - AudioRescan(); -} - -void AudioConfigSettings::AudioRescan() -{ - if (!slotlock.tryLock()) - return; - - QVector* list = - AudioOutput::GetOutputList(); - QVector::const_iterator it; - - audiodevs.clear(); - for (it = list->begin(); it != list->end(); it++) - audiodevs.insert(it->name, *it); - - devices = *list; - delete list; - - QString name = m_OutputDevice->getValue(); - if (!audiodevs.contains(name)) - { - // Scan for possible custom entry that isn't in the list - AudioOutput::AudioDeviceConfig *adc = - AudioOutput::GetAudioDeviceConfig(name, name, true); - if (adc->settings.IsInvalid()) - { - QString msg = name + QObject::tr(" is invalid or not useable."); - MythPopupBox::showOkPopup( - GetMythMainWindow(), QObject::tr("Warning"), msg); - VERBOSE(VB_IMPORTANT, QString("Audio device %1 isn't usable ") - .arg(name)); - } - audiodevs.insert(name, *adc); - devices.append(*adc); - delete adc; - } - m_OutputDevice->AudioRescan(); - slotlock.unlock(); - UpdateCapabilities(QString::null); -} - -void AudioConfigSettings::UpdateVisibility(const QString &device) -{ - if (!m_MaxAudioChannels && !m_AudioUpmix && !m_AudioUpmixType) - return; - - int cur_speakers = m_MaxAudioChannels->getValue().toInt(); - m_AudioUpmix->setEnabled(cur_speakers > 2); - m_AudioUpmixType->setEnabled(cur_speakers > 2); -} - -void AudioConfigSettings::UpdateCapabilities(const QString &device) -{ - int max_speakers = 8; - bool invalid = false; - AudioOutputSettings settings; - - // Test if everything is set yet - if (!m_OutputDevice || !m_MaxAudioChannels || - !m_AC3PassThrough || !m_DTSPassThrough || - !m_EAC3PassThrough || !m_TrueHDPassThrough) - return; - - if (!slotlock.tryLock()) // Doing a rescan of channels - return; - - bool bForceDigital = gCoreContext->GetNumSetting("PassThruDeviceOverride", - false); - - QString out = m_OutputDevice->getValue(); - if (!audiodevs.contains(out)) - { - VERBOSE(VB_AUDIO, QString("Update not found (%1)").arg(out)); - invalid = true; - } - else - { - settings = audiodevs.value(out).settings; - - max_speakers = settings.BestSupportedChannels(); - - bool bAC3 = (settings.canAC3() || bForceDigital) && - m_AC3PassThrough->boolValue(); - bool bDTS = (settings.canDTS() || bForceDigital) && - m_DTSPassThrough->boolValue(); - bool bLPCM = settings.canPassthrough() == -1 || - (settings.canLPCM() && - !gCoreContext->GetNumSetting("StereoPCM", false)); - - if (max_speakers > 2 && !bLPCM) - max_speakers = 2; - if (max_speakers == 2 && (bAC3 || bDTS)) - max_speakers = 6; - } - - m_triggerDigital->setValue(invalid || bForceDigital || - settings.canAC3() || settings.canDTS()); - m_EAC3PassThrough->setEnabled(invalid || m_passthrough8 || - (settings.canPassthrough() >= 0 && - max_speakers >= 8)); - m_TrueHDPassThrough->setEnabled(invalid || m_passthrough8 || - (settings.canPassthrough() >= 0 && - max_speakers >= 8)); - if (m_EAC3PassThrough->boolValue() || m_TrueHDPassThrough->boolValue()) - { - max_speakers = 8; - } - - int cur_speakers = m_MaxAudioChannels->getValue().toInt(); - - if (cur_speakers > max_speakers) - { - VERBOSE(VB_AUDIO, QString("Reset device %1").arg(out)); - cur_speakers = max_speakers; - } - - // Remove everything and re-add available channels - m_MaxAudioChannels->clearSelections(); - m_MaxAudioChannels->resetMaxCount(3); - for (int i = 1; i <= max_speakers; i++) - { - if (invalid || settings.IsSupportedChannels(i) || - (bForceDigital && i >= 6)) - { - QString txt; - - switch (i) - { - case 2: - txt = QObject::tr("Stereo"); - break; - case 6: - txt = QObject::tr("5.1"); - break; - case 8: - txt = QObject::tr("7.1"); - break; - default: - continue; - } - m_MaxAudioChannels->addSelection(txt, QString::number(i), - i == cur_speakers); - } - } - slotlock.unlock(); -} - -void AudioConfigSettings::AudioAdvanced() -{ - QString out = m_OutputDevice->getValue(); - bool invalid = false; - AudioOutputSettings settings; - - if (!audiodevs.contains(out)) - { - invalid = true; - } - else - { - settings = audiodevs.value(out).settings; - } - - AudioAdvancedSettingsGroup audiosettings(invalid || - (settings.canLPCM() && - settings.canPassthrough() >= 0)); - - if (audiosettings.exec() == kDialogCodeAccepted) - { - CheckPassthrough(); - UpdateCapabilities(QString::null); - } -} - -HostComboBox *AudioConfigSettings::MaxAudioChannels() -{ - QString name = "MaxChannels"; - HostComboBox *gc = new HostComboBox(name, false); - gc->setLabel(QObject::tr("Speaker configuration")); - gc->addSelection(QObject::tr("Stereo"), "2", true); // default - gc->setHelpText(QObject::tr("Select the maximum number of audio " - "channels supported by your receiver " - "and speakers.")); - return gc; -} - -HostCheckBox *AudioConfigSettings::AudioUpmix() -{ - HostCheckBox *gc = new HostCheckBox("AudioDefaultUpmix"); - gc->setLabel(QObject::tr("Upconvert stereo to 5.1 surround")); - gc->setValue(true); - gc->setHelpText(QObject::tr("If enabled, MythTV will upconvert stereo " - "to 5.1 audio. You can enable or disable " - "the upconversion during playback at any time.")); - return gc; -} - -HostComboBox *AudioConfigSettings::AudioUpmixType() -{ - HostComboBox *gc = new HostComboBox("AudioUpmixType",false); - gc->setLabel(QObject::tr("Upmix Quality")); - gc->addSelection(QObject::tr("Good"), "1"); - gc->addSelection(QObject::tr("Best"), "2", true); // default - gc->setHelpText(QObject::tr("Set the audio surround-upconversion quality.")); - return gc; -} - -HostCheckBox *AudioConfigSettings::AC3PassThrough() -{ - HostCheckBox *gc = new HostCheckBox("AC3PassThru"); - gc->setLabel(QObject::tr("Dolby Digital")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder " - "supports AC3/Dolby Digital. You must use a digital " - "connection. Uncheck if using an analog connection.")); - return gc; -} - -HostCheckBox *AudioConfigSettings::DTSPassThrough() -{ - HostCheckBox *gc = new HostCheckBox("DTSPassThru"); - gc->setLabel(QObject::tr("DTS")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder " - "supports DTS. You must use a digital connection. Uncheck " - "if using an analog connection")); - return gc; -} - -HostCheckBox *AudioConfigSettings::EAC3PassThrough() -{ - HostCheckBox *gc = new HostCheckBox("EAC3PassThru"); - gc->setLabel(QObject::tr("E-AC3/DTS-HD")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder " - "supports E-AC3 (DD+) or DTS-HD. You must use a hdmi " - "connection.")); - return gc; -} - -HostCheckBox *AudioConfigSettings::TrueHDPassThrough() -{ - HostCheckBox *gc = new HostCheckBox("TrueHDPassThru"); - gc->setLabel(QObject::tr("TrueHD")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder " - "supports Dolby TrueHD. You must use a hdmi connection.")); - return gc; -} - -bool AudioConfigSettings::CheckPassthrough() -{ - m_passthrough8 = false; - if (gCoreContext->GetNumSetting("PassThruDeviceOverride", false)) - { - QString name = gCoreContext->GetSetting("PassThruOutputDevice"); - AudioOutput::AudioDeviceConfig *adc = - AudioOutput::GetAudioDeviceConfig(name, name, true); - if (adc->settings.IsInvalid()) - { - VERBOSE(VB_IMPORTANT, QString("Passthru device %1 isn't usable " - "Check audio configuration").arg(name)); - } - else - { - if (adc->settings.BestSupportedChannels() >= 8) - { - m_passthrough8 = true; - } - } - delete adc; - } - return m_passthrough8; -} - -void AudioConfigSettings::AudioTest() -{ - QString out = m_OutputDevice->getValue(); - QString name; - int channels = m_MaxAudioChannels->getValue().toInt(); - QString errMsg; - - MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); - - SpeakerTest *st = new SpeakerTest( - mainStack, "Speaker Test", out, name, 2); - if (st->Create()) - { - mainStack->AddScreen(st); - } - else - delete st; -} - -QEvent::Type ChannelChangedEvent::kEventType = - (QEvent::Type) QEvent::registerEventType(); - -// --------------------------------------------------- - - -AudioTestThread::AudioTestThread(QObject *parent, - QString main, QString passthrough, - int channels) : - m_channels(channels), m_device(main), m_passthrough(passthrough), - m_interrupted(false) -{ - m_parent = parent; - m_audioOutput = AudioOutput::OpenAudio(m_device, - m_passthrough, - FORMAT_S16, m_channels, - 0, 48000, - AUDIOOUTPUT_VIDEO, - true, false); -} - -AudioTestThread::~AudioTestThread() -{ - cancel(); - wait(); - if (m_audioOutput) - delete m_audioOutput; -} - -QString AudioTestThread::result() -{ - QString errMsg; - if (!m_audioOutput) - errMsg = QObject::tr("Unable to create AudioOutput."); - else - errMsg = m_audioOutput->GetError(); - return errMsg; -} - -void AudioTestThread::cancel() -{ - m_interrupted = true; -} - -void AudioTestThread::run() -{ - m_interrupted = false; - - if (m_audioOutput) - { - char *frames_in = new char[m_channels * 48000 * sizeof(int16_t) + 15]; - char *frames = (char *)(((long)frames_in + 15) & ~0xf); - while (!m_interrupted) - { - for (int i = 0; i < m_channels && !m_interrupted; i++) - { - AudioOutputUtil::GeneratePinkSamples(frames, m_channels, - i, 48000); - if (m_parent) - { - QString channel; - - switch(i) - { - case 0: - channel = "frontleft"; - break; - case 1: - channel = "frontright"; - break; - case 2: - channel = "center"; - break; - case 3: - channel = "lfe"; - break; - case 4: - if (m_channels == 6) - channel = "leftsurround"; - else - channel = "rearleft"; - break; - case 5: - if (m_channels == 6) - channel = "rightsurround"; - else - channel = "rearleft"; - break; - case 6: - channel = "leftsurround"; - break; - case 7: - channel = "rightsurround"; - break; - } - QCoreApplication::postEvent( - m_parent, new ChannelChangedEvent(channel)); - } - if (!m_audioOutput->AddFrames(frames, 48000, -1)) - { - VERBOSE(VB_AUDIO, "AddAudioData() " - "Audio buffer overflow, audio data lost!"); - } - for (int j = 0; j < 16 && !m_interrupted; j++) - { - usleep(62500); //1/16th of a second - } - usleep(500000); //.5s - } - } - delete[] frames_in; - } -} - -SpeakerTest::SpeakerTest(MythScreenStack *parent, QString name, - QString main, QString passthrough, int channels) - : MythScreenType(parent, name), - m_speakerLocation(NULL), m_testButton(NULL), m_testSpeakers(NULL) -{ - m_testSpeakers = new AudioTestThread(this, main, passthrough, channels); -} - -bool SpeakerTest::Create() -{ - bool foundtheme = false; - - // Load the theme for this screen - foundtheme = LoadWindowFromXML("config-ui.xml", "audiosettings", this); - - if (!foundtheme) - return false; - - if (!m_testSpeakers->result().isEmpty()) - { - VERBOSE(VB_IMPORTANT, "Not working."); - return false; - } - - m_testButton = dynamic_cast (GetChild("test")); - m_speakerLocation = dynamic_cast (GetChild("speakerlocation")); - - if (!m_testButton || !m_speakerLocation) - { - VERBOSE(VB_IMPORTANT, "Theme is missing critical theme elements."); - return false; - } - - connect(m_testButton, SIGNAL(Clicked()), this, SLOT(toggleTest())); - - BuildFocusList(); - - return true; -} - -SpeakerTest::~SpeakerTest() -{ - if (m_testSpeakers) - { - m_testSpeakers->cancel(); - m_testSpeakers->wait(); - delete m_testSpeakers; - m_testSpeakers = NULL; - } -} - -void SpeakerTest::toggleTest(void) -{ - if (m_testSpeakers->isRunning()) - m_testSpeakers->cancel(); - else if (m_testSpeakers) - m_testSpeakers->start(); -} - -bool SpeakerTest::keyPressEvent(QKeyEvent *event) -{ - if (GetFocusWidget()->keyPressEvent(event)) - return true; - - bool handled = false; - - if (!handled && MythScreenType::keyPressEvent(event)) - handled = true; - - return handled; -} - -void SpeakerTest::customEvent(QEvent *event) -{ - if (event->type() == ChannelChangedEvent::kEventType) - { - ChannelChangedEvent *cce = (ChannelChangedEvent*)(event); - - QString channel = cce->channel; - - if (!channel.isEmpty()) - m_speakerLocation->DisplayState(channel); - } -} - -HostCheckBox *AudioMixerSettings::MythControlsVolume() -{ - HostCheckBox *gc = new HostCheckBox("MythControlsVolume"); - gc->setLabel(QObject::tr("Use internal volume controls")); - gc->setValue(true); - gc->setHelpText(QObject::tr("If enabled, MythTV will control the PCM and " - "master mixer volume. Disable this option if you prefer " - "to control the volume externally (for example, using " - "your amplifier) or if you use an external mixer program.")); - return gc; -} - -HostComboBox *AudioMixerSettings::MixerDevice() -{ - HostComboBox *gc = new HostComboBox("MixerDevice", true); - gc->setLabel(QObject::tr("Mixer device")); - -#ifdef USING_OSS - QDir dev("/dev", "mixer*", QDir::Name, QDir::System); - gc->fillSelectionsFromDir(dev); - - dev.setPath("/dev/sound"); - if (dev.exists()) - { - gc->fillSelectionsFromDir(dev); - } -#endif -#ifdef USING_ALSA - gc->addSelection("ALSA:default", "ALSA:default"); -#endif -#ifdef USING_MINGW - gc->addSelection("DirectX:", "DirectX:"); - gc->addSelection("Windows:", "Windows:"); -#endif -#if !defined(USING_MINGW) - gc->addSelection("software", "software"); - gc->setHelpText(QObject::tr("Setting the mixer device to \"software\" " - "lets MythTV control the volume of all audio at the " - "expense of a slight quality loss.")); -#endif - - return gc; -} - -const char* AudioMixerSettings::MixerControlControls[] = { "PCM", - "Master" }; - -HostComboBox *AudioMixerSettings::MixerControl() -{ - HostComboBox *gc = new HostComboBox("MixerControl", true); - gc->setLabel(QObject::tr("Mixer controls")); - for (unsigned int i = 0; i < sizeof(MixerControlControls) / sizeof(char*); - ++i) - { - gc->addSelection(QObject::tr(MixerControlControls[i]), - MixerControlControls[i]); - } - - gc->setHelpText(QObject::tr("Changing the volume adjusts the selected mixer.")); - return gc; -} - -HostSlider *AudioMixerSettings::MixerVolume() -{ - HostSlider *gs = new HostSlider("MasterMixerVolume", 0, 100, 1); - gs->setLabel(QObject::tr("Master mixer volume")); - gs->setValue(70); - gs->setHelpText(QObject::tr("Initial volume for the Master mixer. " - "This affects all sound created by the audio device. " - "Note: Do not set this too low.")); - return gs; -} - -HostSlider *AudioMixerSettings::PCMVolume() -{ - HostSlider *gs = new HostSlider("PCMMixerVolume", 0, 100, 1); - gs->setLabel(QObject::tr("PCM mixer volume")); - gs->setValue(70); - gs->setHelpText(QObject::tr("Initial volume for PCM output. Using the " - "volume keys in MythTV will adjust this parameter.")); - return gs; -} - -AudioMixerSettings::AudioMixerSettings() : - TriggeredConfigurationGroup(false, true, false, false) -{ - setLabel(QObject::tr("Audio Mixer")); - setUseLabel(false); - - Setting *volumeControl = MythControlsVolume(); - addChild(volumeControl); - - // Mixer settings - ConfigurationGroup *settings = - new VerticalConfigurationGroup(false, true, false, false); - settings->addChild(MixerDevice()); - settings->addChild(MixerControl()); - settings->addChild(MixerVolume()); - settings->addChild(PCMVolume()); - - ConfigurationGroup *dummy = - new VerticalConfigurationGroup(false, true, false, false); - - // Show Mixer config only if internal volume controls enabled - setTrigger(volumeControl); - addTarget("0", dummy); - addTarget("1", settings); -} - -AudioGeneralSettings::AudioGeneralSettings() -{ - addChild(new AudioConfigSettings()); - addChild(new AudioMixerSettings()); -} - -HostCheckBox *AudioAdvancedSettings::MPCM() -{ - HostCheckBox *gc = new HostCheckBox("StereoPCM"); - gc->setLabel(QObject::tr("Stereo PCM Only")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Enable if your amplifier or sound decoder " - "only supports 2 channels PCM (typically an old HDMI 1.0 " - "device). Multi-channels audio will be re-encoded to AC3 " - "when required")); - return gc; -} - -HostCheckBox *AudioAdvancedSettings::SRCQualityOverride() -{ - HostCheckBox *gc = new HostCheckBox("SRCQualityOverride"); - gc->setLabel(QObject::tr("Override SRC quality")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Enable to override audio sample rate " - "conversion quality.")); - return gc; -} - -HostComboBox *AudioAdvancedSettings::SRCQuality() -{ - HostComboBox *gc = new HostComboBox("SRCQuality", false); - gc->setLabel(QObject::tr("Sample rate conversion")); - gc->addSelection(QObject::tr("Disabled"), "-1"); - gc->addSelection(QObject::tr("Fastest"), "0"); - gc->addSelection(QObject::tr("Good"), "1", true); // default - gc->addSelection(QObject::tr("Best"), "2"); - gc->setHelpText(QObject::tr("Set the quality of audio sample-rate " - "conversion. \"Good\" (default) provides the best " - "compromise between CPU usage and quality. \"Disabled\" " - "lets the audio device handle sample-rate conversion.")); - return gc; -} - -HostCheckBox *AudioAdvancedSettings::Audio48kOverride() -{ - HostCheckBox *gc = new HostCheckBox("Audio48kOverride"); - gc->setLabel(QObject::tr("Force audio device output to 48kHz")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Force audio sample rate to 48kHz. " - "Some audio devices will report various rates, " - "but they ultimately crash.")); - return gc; -} - -HostCheckBox *AudioAdvancedSettings::PassThroughOverride() -{ - HostCheckBox *gc = new HostCheckBox("PassThruDeviceOverride"); - gc->setLabel(QObject::tr("Separate digital output device")); - gc->setValue(false); - gc->setHelpText(QObject::tr("Use a distinct digital output device from " - "default.")); - return gc; -} - -HostComboBox *AudioAdvancedSettings::PassThroughOutputDevice() -{ - HostComboBox *gc = new HostComboBox("PassThruOutputDevice", true); - - gc->setLabel(QObject::tr("Digital output device")); - gc->addSelection(QObject::tr("Default"), "Default"); -#ifdef USING_MINGW - gc->addSelection("DirectX:Primary Sound Driver"); -#else - gc->addSelection("ALSA:iec958:{ AES0 0x02 }", - "ALSA:iec958:{ AES0 0x02 }"); - gc->addSelection("ALSA:hdmi", "ALSA:hdmi"); - gc->addSelection("ALSA:plughw:0,3", "ALSA:plughw:0,3"); -#endif - - gc->setHelpText(QObject::tr("Deprecated. Audio output device to use for " - "digital audio. This value is currently only used " - "with ALSA and DirectX sound output.")); - return gc; -} - -AudioAdvancedSettings::AudioAdvancedSettings(bool mpcm) -{ - ConfigurationGroup *settings3 = - new HorizontalConfigurationGroup(false, false); - - m_PassThroughOverride = PassThroughOverride(); - TriggeredItem *sub3 = - new TriggeredItem(m_PassThroughOverride, PassThroughOutputDevice()); - settings3->addChild(m_PassThroughOverride); - settings3->addChild(sub3); - - ConfigurationGroup *settings4 = - new HorizontalConfigurationGroup(false, false); - Setting *srcqualityoverride = SRCQualityOverride(); - TriggeredItem *sub4 = - new TriggeredItem(srcqualityoverride, SRCQuality()); - settings4->addChild(srcqualityoverride); - settings4->addChild(sub4); - - ConfigurationGroup *settings5 = - new HorizontalConfigurationGroup(false, false); - settings5->addChild(Audio48kOverride()); - - ConfigurationGroup *settings6; - - if (mpcm) - { - settings6 = new HorizontalConfigurationGroup(false, false); - settings6->addChild(MPCM()); - } - - addChild(settings4); - addChild(settings5); - addChild(settings3); - if (mpcm) - { - addChild(settings6); - } -} - -AudioAdvancedSettingsGroup::AudioAdvancedSettingsGroup(bool mpcm) -{ - addChild(new AudioAdvancedSettings(mpcm)); -} - -// vim:set sw=4 ts=4 expandtab: diff --git a/mythtv/programs/mythfrontend/audiosettings.h b/mythtv/programs/mythfrontend/audiosettings.h deleted file mode 100644 index d4fbb67819f..00000000000 --- a/mythtv/programs/mythfrontend/audiosettings.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef MYTHAUDIOSETTINGS_H -#define MYTHAUDIOSETTINGS_H - -#include - -#include -#include -#include - -#include "settings.h" -#include "mythcontext.h" - -// libmythui -#include -#include -#include -#include - -#include "audiooutput.h" - -class AudioDeviceComboBox; - -class AudioConfigSettings : public VerticalConfigurationGroup -{ - Q_OBJECT - - public: - AudioConfigSettings(); - - typedef QMap ADCMap; - - ADCMap &AudioDeviceMap(void) { return audiodevs; }; - AudioOutput::ADCVect &AudioDeviceVect(void) { return devices; }; - - private slots: - void UpdateVisibility(const QString&); - void UpdateCapabilities(const QString&); - void AudioRescan(); - void AudioAdvanced(); - void AudioTest(); - - private: - AudioDeviceComboBox *OutputDevice(); - HostComboBox *MaxAudioChannels(); - HostCheckBox *AudioUpmix(); - HostComboBox *AudioUpmixType(); - HostCheckBox *AC3PassThrough(); - HostCheckBox *DTSPassThrough(); - HostCheckBox *EAC3PassThrough(); - HostCheckBox *TrueHDPassThrough(); - bool CheckPassthrough(); - - ConfigurationGroup *m_cgsettings; - AudioDeviceComboBox *m_OutputDevice; - HostComboBox *m_MaxAudioChannels; - HostCheckBox *m_AudioUpmix; - HostComboBox *m_AudioUpmixType; - TransCheckBoxSetting *m_triggerDigital; - TransCheckBoxSetting *m_triggerMPCM; - HostCheckBox *m_AC3PassThrough; - HostCheckBox *m_DTSPassThrough; - HostCheckBox *m_EAC3PassThrough; - HostCheckBox *m_TrueHDPassThrough; - ADCMap audiodevs; - AudioOutput::ADCVect devices; - QMutex slotlock; - bool m_passthrough8; -}; - -class AudioDeviceComboBox : public HostComboBox -{ - Q_OBJECT - public: - AudioDeviceComboBox(AudioConfigSettings*); - void AudioRescan(); - - private slots: - void AudioDescriptionHelp(const QString&); - - private: - AudioConfigSettings *m_parent; -}; - -class AudioMixerSettings : public TriggeredConfigurationGroup -{ - public: - AudioMixerSettings(); - private: - HostCheckBox *MythControlsVolume(); - HostComboBox *MixerDevice(); - HostComboBox *MixerControl(); - HostSlider *MixerVolume(); - HostSlider *PCMVolume(); - static const char *MixerControlControls[]; -}; - -class AudioGeneralSettings : public ConfigurationWizard -{ - public: - AudioGeneralSettings(); -}; - -class AudioAdvancedSettings : public VerticalConfigurationGroup -{ - public: - AudioAdvancedSettings(bool mpcm); - HostCheckBox *MPCM(); - HostCheckBox *SRCQualityOverride(); - HostComboBox *SRCQuality(); - HostCheckBox *Audio48kOverride(); - HostCheckBox *PassThroughOverride(); - HostComboBox *PassThroughOutputDevice(); - - TransCheckBoxSetting *m_triggerMPCM; - HostCheckBox *m_MPCM; - HostCheckBox *m_PassThroughOverride; -}; - -class AudioAdvancedSettingsGroup : public ConfigurationWizard -{ - public: - AudioAdvancedSettingsGroup(bool mpcm); -}; - -class ChannelChangedEvent : public QEvent -{ - public: - ChannelChangedEvent(QString channame) : - QEvent(kEventType), - channel(channame) {} - ~ChannelChangedEvent() {} - - QString channel; - - static Type kEventType; -}; - -class AudioTestThread : public QThread -{ - public: - - AudioTestThread(QObject *parent, QString main, QString passthrough, - int channels); - ~AudioTestThread(); - - void cancel(); - QString result(); - - protected: - void run(); - - private: - QObject *m_parent; - AudioOutput *m_audioOutput; - int m_channels; - QString m_device; - QString m_passthrough; - bool m_interrupted; -}; - -class SpeakerTest : public MythScreenType -{ - Q_OBJECT - - public: - - SpeakerTest(MythScreenStack *parent, QString name, - QString main, QString passthrough, int channels); - ~SpeakerTest(); - - bool Create(void); - bool keyPressEvent(QKeyEvent *); - void customEvent(QEvent *event); - - private: - MythUIStateType *m_speakerLocation; - MythUIButton *m_testButton; - - AudioTestThread *m_testSpeakers; - - private slots: - void toggleTest(void); -}; - -#endif diff --git a/mythtv/programs/mythfrontend/main.cpp b/mythtv/programs/mythfrontend/main.cpp index 2e1da5c9dd2..bf4036f93f2 100644 --- a/mythtv/programs/mythfrontend/main.cpp +++ b/mythtv/programs/mythfrontend/main.cpp @@ -35,7 +35,7 @@ using namespace std; #include "custompriority.h" #include "audiooutput.h" #include "globalsettings.h" -#include "audiosettings.h" +#include "audiogeneralsettings.h" #include "profilegroup.h" #include "playgroup.h" #include "networkcontrol.h" @@ -605,21 +605,6 @@ static void TVMenuCallback(void *data, QString &selection) AudioGeneralSettings audiosettings; audiosettings.exec(); } - else if (sel == "speaker_test") - { - MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack(); - QString passthru = gCoreContext->GetNumSetting( - "PassThruDeviceOverride", false) ? - gCoreContext->GetSetting("PassThruOutputDevice") : QString::null; - QString main = gCoreContext->GetSetting("AudioOutputDevice"); - int channels = gCoreContext->GetNumSetting("MaxChannels", 2); - SpeakerTest *st = new SpeakerTest( - mainStack, "Speaker Test", main, passthru, channels); - if (st->Create()) - mainStack->AddScreen(st); - else - delete st; - } else if (sel == "settings playback") { PlaybackSettings settings; diff --git a/mythtv/programs/mythfrontend/mythfrontend.pro b/mythtv/programs/mythfrontend/mythfrontend.pro index 2b161ff3211..dca3c035582 100644 --- a/mythtv/programs/mythfrontend/mythfrontend.pro +++ b/mythtv/programs/mythfrontend/mythfrontend.pro @@ -20,7 +20,7 @@ INSTALLS += setting QMAKE_CLEAN += $(TARGET) # Input -HEADERS += playbackbox.h viewscheduled.h globalsettings.h audiosettings.h +HEADERS += playbackbox.h viewscheduled.h globalsettings.h audiogeneralsettings.h HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h HEADERS += statusbox.h networkcontrol.h custompriority.h HEADERS += mediarenderer.h mythfexml.h playbackboxlistitem.h @@ -33,7 +33,7 @@ HEADERS += proglist.h proglist_helpers.h HEADERS += playbackboxhelper.h viewschedulediff.h HEADERS += themechooser.h -SOURCES += main.cpp playbackbox.cpp viewscheduled.cpp audiosettings.cpp +SOURCES += main.cpp playbackbox.cpp viewscheduled.cpp audiogeneralsettings.cpp SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp SOURCES += channelrecpriority.cpp statusbox.cpp networkcontrol.cpp SOURCES += mediarenderer.cpp mythfexml.cpp playbackboxlistitem.cpp diff --git a/mythtv/themes/DVR/main_settings.xml b/mythtv/themes/DVR/main_settings.xml index 9365dffe8f0..8d1b5f84b3c 100644 --- a/mythtv/themes/DVR/main_settings.xml +++ b/mythtv/themes/DVR/main_settings.xml @@ -29,13 +29,6 @@ SETTINGS AUDIOGENERAL - - - - - - - 100,100 - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mythtv/themes/defaultmenu/main_settings.xml b/mythtv/themes/defaultmenu/main_settings.xml index ceb1a0d787f..a3e43b6f4e8 100644 --- a/mythtv/themes/defaultmenu/main_settings.xml +++ b/mythtv/themes/defaultmenu/main_settings.xml @@ -29,13 +29,6 @@ SETTINGS AUDIOGENERAL - -