From 23de184240f321cb64fde7892a1908665f036f1c Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Wed, 8 Dec 2010 16:04:00 +1100 Subject: [PATCH] Audio channel test. Made a QWidget version rather than MythUI for the time being as otherwise the audio test can't be started from the QWidget settings. The new test plays sound for 3s on each speaker. An individual speaker can be selected. The test now goes in a clockwise fashion on all speakers. Amended AudioOutput class so it can go without having to read the user settings, which during the audiotest haven't been saved yet --- mythtv/libs/libmyth/audiooutput.cpp | 4 +- mythtv/libs/libmyth/audiooutput.h | 2 +- mythtv/libs/libmyth/audiooutputbase.cpp | 13 +- mythtv/libs/libmyth/audiooutputbase.h | 2 +- mythtv/libs/libmyth/audiooutputsettings.cpp | 2 +- mythtv/libs/libmyth/audiooutputsettings.h | 5 +- mythtv/libs/libmyth/audiosettings.cpp | 52 +- mythtv/libs/libmyth/audiosettings.h | 57 +- mythtv/libs/libmyth/settings.cpp | 7 + mythtv/libs/libmyth/settings.h | 4 +- .../mythfrontend/audiogeneralsettings.cpp | 163 +++- .../mythfrontend/audiogeneralsettings.h | 18 +- .../programs/mythfrontend/audiosettings.cpp | 921 ------------------ mythtv/programs/mythfrontend/audiosettings.h | 185 ---- mythtv/programs/mythfrontend/main.cpp | 17 +- mythtv/programs/mythfrontend/mythfrontend.pro | 4 +- mythtv/themes/DVR/main_settings.xml | 7 - mythtv/themes/classic/main_settings.xml | 7 - mythtv/themes/default/config-ui.xml | 74 -- mythtv/themes/defaultmenu/main_settings.xml | 7 - 20 files changed, 232 insertions(+), 1319 deletions(-) delete mode 100644 mythtv/programs/mythfrontend/audiosettings.cpp delete mode 100644 mythtv/programs/mythfrontend/audiosettings.h diff --git a/mythtv/libs/libmyth/audiooutput.cpp b/mythtv/libs/libmyth/audiooutput.cpp index 117d74c346e..31c79664faf 100644 --- a/mythtv/libs/libmyth/audiooutput.cpp +++ b/mythtv/libs/libmyth/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/audiooutput.h b/mythtv/libs/libmyth/audiooutput.h index 9367688a0b1..d0a99ace82e 100644 --- a/mythtv/libs/libmyth/audiooutput.h +++ b/mythtv/libs/libmyth/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/audiooutputbase.cpp b/mythtv/libs/libmyth/audiooutputbase.cpp index 70094bc264d..906c7c7c50a 100644 --- a/mythtv/libs/libmyth/audiooutputbase.cpp +++ b/mythtv/libs/libmyth/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/audiooutputbase.h b/mythtv/libs/libmyth/audiooutputbase.h index 4aa34bcc1ca..ee4667ef5d8 100644 --- a/mythtv/libs/libmyth/audiooutputbase.h +++ b/mythtv/libs/libmyth/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/audiooutputsettings.cpp b/mythtv/libs/libmyth/audiooutputsettings.cpp index 217b96445c2..0fe778a30bc 100644 --- a/mythtv/libs/libmyth/audiooutputsettings.cpp +++ b/mythtv/libs/libmyth/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); diff --git a/mythtv/libs/libmyth/audiooutputsettings.h b/mythtv/libs/libmyth/audiooutputsettings.h index fbc57a1ab11..b74522a947a 100644 --- a/mythtv/libs/libmyth/audiooutputsettings.h +++ b/mythtv/libs/libmyth/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/audiosettings.cpp b/mythtv/libs/libmyth/audiosettings.cpp index f703945a984..8cf2fefc075 100644 --- a/mythtv/libs/libmyth/audiosettings.cpp +++ b/mythtv/libs/libmyth/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/audiosettings.h b/mythtv/libs/libmyth/audiosettings.h index d9830ef737f..3a4b433e8d9 100644 --- a/mythtv/libs/libmyth/audiosettings.h +++ b/mythtv/libs/libmyth/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 85870efc225..adf7f2fbdb5 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" @@ -598,21 +598,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 34585d29f2d..cb67e54c84c 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 - -