MythTV  0.26-pre
setupwizard_audio.cpp
Go to the documentation of this file.
00001 // qt
00002 #include <QString>
00003 #include <QVariant>
00004 
00005 // myth
00006 #include <mythcontext.h>
00007 #include <mythdbcon.h>
00008 #include <mythdirs.h>
00009 #include <mythprogressdialog.h>
00010 
00011 #include <audiooutpututil.h>
00012 
00013 #include "audiogeneralsettings.h"
00014 #include "setupwizard_general.h"
00015 #include "setupwizard_audio.h"
00016 #include "setupwizard_video.h"
00017 
00018 AudioSetupWizard::AudioSetupWizard(MythScreenStack *parent,
00019                                    MythScreenType *previous,
00020                                    const char *name)
00021     : MythScreenType(parent, name),
00022       m_outputlist(NULL),                m_testThread(NULL),
00023       m_generalScreen(previous),         m_audioDeviceButtonList(NULL),
00024       m_speakerNumberButtonList(NULL),   m_dtsCheck(NULL),
00025       m_ac3Check(NULL),                  m_eac3Check(NULL),
00026       m_truehdCheck(NULL),               m_dtshdCheck(NULL),
00027       m_testSpeakerButton(NULL),         m_nextButton(NULL),
00028       m_prevButton(NULL),                m_maxspeakers(2),
00029       m_lastAudioDevice("")
00030 {
00031 }
00032 
00033 bool AudioSetupWizard::Create()
00034 {
00035     bool foundtheme = false;
00036 
00037     // Load the theme for this screen
00038     foundtheme = LoadWindowFromXML("config-ui.xml", "audiowizard", this);
00039 
00040     if (!foundtheme)
00041         return false;
00042 
00043     m_audioDeviceButtonList =
00044         dynamic_cast<MythUIButtonList *> (GetChild("audiodevices"));
00045     m_speakerNumberButtonList =
00046         dynamic_cast<MythUIButtonList *> (GetChild("speakers"));
00047 
00048     m_dtsCheck = dynamic_cast<MythUICheckBox *> (GetChild("dtscheck"));
00049     m_ac3Check = dynamic_cast<MythUICheckBox *> (GetChild("ac3check"));
00050     m_eac3Check = dynamic_cast<MythUICheckBox *> (GetChild("eac3check"));
00051     m_truehdCheck = dynamic_cast<MythUICheckBox *> (GetChild("truehdcheck"));
00052     m_dtshdCheck = dynamic_cast<MythUICheckBox *> (GetChild("dtshdcheck"));
00053 
00054     m_testSpeakerButton =
00055         dynamic_cast<MythUIButton *> (GetChild("testspeakers"));
00056 
00057     m_nextButton = dynamic_cast<MythUIButton *> (GetChild("next"));
00058     m_prevButton = dynamic_cast<MythUIButton *> (GetChild("previous"));
00059 
00060     if (!m_audioDeviceButtonList || !m_speakerNumberButtonList ||
00061         !m_dtsCheck || !m_ac3Check || !m_eac3Check || !m_truehdCheck ||
00062         !m_dtshdCheck || !m_testSpeakerButton || !m_nextButton || !m_prevButton)
00063     {
00064         LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
00065         return false;
00066     }
00067 
00068     // Pre-set the widgets to their database values
00069     // Buttonlists are set in load()
00070 
00071     int dtsSetting = gCoreContext->GetNumSetting("DTSPassThru", 0);
00072     if (dtsSetting == 1)
00073         m_dtsCheck->SetCheckState(MythUIStateType::Full);
00074 
00075     int ac3Setting = gCoreContext->GetNumSetting("AC3PassThru", 0);
00076     if (ac3Setting == 1)
00077         m_ac3Check->SetCheckState(MythUIStateType::Full);
00078 
00079     int eac3Setting = gCoreContext->GetNumSetting("EAC3PassThru", 0);
00080     if (eac3Setting == 1)
00081         m_eac3Check->SetCheckState(MythUIStateType::Full);
00082 
00083     int truehdSetting = gCoreContext->GetNumSetting("TrueHDPassThru", 0);
00084     if (truehdSetting == 1)
00085         m_truehdCheck->SetCheckState(MythUIStateType::Full);
00086 
00087     int dtshdSetting = gCoreContext->GetNumSetting("DTSHDPassThru", 0);
00088     if (dtshdSetting == 1)
00089         m_dtshdCheck->SetCheckState(MythUIStateType::Full);
00090 
00091     // Help Text
00092 
00093     // Buttonlists
00094     m_audioDeviceButtonList->SetHelpText( tr("Select from one of the "
00095                                     "audio devices detected on your system.  When "
00096                                     "satisfied, you can test audio before moving "
00097                                     "on.  If you fail to configure audio, video "
00098                                     "playback may fail as well.") );
00099     m_speakerNumberButtonList->SetHelpText( tr("Select the number of speakers you "
00100                                     "have.") );
00101 
00102     // Checkboxes
00103     m_dtsCheck->SetHelpText( tr("Select this checkbox if your receiver "
00104                                    "is capable of playing DTS.") );
00105     m_ac3Check->SetHelpText( tr("Select this checkbox if your receiver "
00106                                    "is capable of playing AC-3 (Dolby Digital).") );
00107     m_eac3Check->SetHelpText( tr("Select this checkbox if your receiver "
00108                                    "is capable of playing E-AC-3 (Dolby Digital Plus).") );
00109     m_truehdCheck->SetHelpText( tr("Select this checkbox if your receiver "
00110                                    "is capable of playing TrueHD.") );
00111     m_dtshdCheck->SetHelpText( tr("Select this checkbox if your receiver "
00112                                    "is capable of playing DTS-HD.") );
00113 
00114     // Buttons
00115     m_testSpeakerButton->SetHelpText( tr("Test your audio settings by playing "
00116                                     "noise through each speaker.") );
00117     m_nextButton->SetHelpText( tr("Save these changes and move on to the next "
00118                                   "configuration step.") );
00119     m_prevButton->SetHelpText( tr("Return to the previous configuration step.") );
00120 
00121     // I hate to SetText but it's the only way to make it reliably bi-modal
00122     m_testSpeakerButton->SetText(tr("Test Speakers"));
00123 
00124     connect(m_testSpeakerButton, SIGNAL(Clicked()), this, SLOT(toggleSpeakers()));
00125     connect(m_nextButton, SIGNAL(Clicked()), this, SLOT(slotNext()));
00126     connect(m_prevButton, SIGNAL(Clicked()), this, SLOT(slotPrevious()));
00127 
00128     QString message = tr("Discovering audio devices...");
00129     LoadInBackground(message);
00130 
00131     BuildFocusList();
00132 
00133     return true;
00134 }
00135 
00136 AudioSetupWizard::~AudioSetupWizard()
00137 {
00138     if (m_testThread)
00139     {
00140         m_testThread->cancel();
00141         m_testThread->wait();
00142         delete m_testThread;
00143     }
00144     if (m_outputlist)
00145     {
00146         delete m_outputlist;
00147     }
00148 }
00149 
00150 void AudioSetupWizard::Load(void)
00151 {
00152     m_outputlist = AudioOutput::GetOutputList();
00153 }
00154 
00155 void AudioSetupWizard::Init(void)
00156 {
00157     QString current = gCoreContext->GetSetting(QString("AudioOutputDevice"));
00158     bool found = false;
00159 
00160     if (!current.isEmpty())
00161     {
00162         for (AudioOutput::ADCVect::const_iterator it = m_outputlist->begin();
00163              it != m_outputlist->end(); ++it)
00164         {
00165             if (it->name == current)
00166             {
00167                 found = true;
00168                 break;
00169             }
00170         }
00171         if (!found)
00172         {
00173             AudioOutput::AudioDeviceConfig *adc =
00174                 AudioOutput::GetAudioDeviceConfig(current, current, true);
00175             if (adc->settings.IsInvalid())
00176             {
00177                 LOG(VB_GENERAL, LOG_ERR, QString("Audio device %1 isn't usable")
00178                     .arg(current));
00179             }
00180             else
00181             {
00182                     // only insert the device if it is valid
00183                 m_outputlist->insert(0, *adc);
00184             }
00185             delete adc;
00186         }
00187     }
00188     for (AudioOutput::ADCVect::const_iterator it = m_outputlist->begin();
00189          it != m_outputlist->end(); ++it)
00190     {
00191         QString name = it->name;
00192         MythUIButtonListItem *output =
00193                 new MythUIButtonListItem(m_audioDeviceButtonList, name);
00194         output->SetData(name);
00195     }
00196     if (found)
00197     {
00198         m_audioDeviceButtonList->SetValueByData(qVariantFromValue(current));
00199     }
00200 
00201     m_maxspeakers = gCoreContext->GetNumSetting("MaxChannels", 2);
00202     m_lastAudioDevice = m_audioDeviceButtonList->GetItemCurrent()->GetText();
00203 
00204     // Update list for default audio device
00205     UpdateCapabilities();
00206 
00207     connect(m_ac3Check,
00208             SIGNAL(valueChanged()), SLOT(UpdateCapabilitiesAC3()));
00209     connect(m_audioDeviceButtonList,
00210             SIGNAL(itemSelected(MythUIButtonListItem*)),
00211             SLOT(UpdateCapabilities(MythUIButtonListItem*)));
00212 }
00213 
00214 AudioOutputSettings AudioSetupWizard::UpdateCapabilities(bool restore, bool AC3)
00215 {
00216     QString out = m_audioDeviceButtonList->GetItemCurrent()->GetText();
00217     int max_speakers = 8;
00218     int realmax_speakers = 8;
00219 
00220     AudioOutputSettings settings;
00221 
00222     for (AudioOutput::ADCVect::const_iterator it = m_outputlist->begin();
00223          it != m_outputlist->end(); ++it)
00224     {
00225         if (it->name == out)
00226         {
00227             settings = it->settings;
00228             break;
00229         }
00230     }
00231 
00232     realmax_speakers = max_speakers = settings.BestSupportedChannels();
00233 
00234     bool bAC3  = settings.canFeature(FEATURE_AC3);
00235     bool bDTS  = settings.canFeature(FEATURE_DTS);
00236     bool bLPCM = settings.canFeature(FEATURE_LPCM);
00237     bool bEAC3 = settings.canFeature(FEATURE_EAC3);
00238     bool bTRUEHD = settings.canFeature(FEATURE_TRUEHD);
00239     bool bDTSHD = settings.canFeature(FEATURE_DTSHD);
00240 
00241     bAC3    ? m_ac3Check->Show() : m_ac3Check->Hide();
00242     bDTS    ? m_dtsCheck->Show() : m_dtsCheck->Hide();
00243     bEAC3   ? m_eac3Check->Show() : m_eac3Check->Hide();
00244     bTRUEHD ? m_truehdCheck->Show() : m_truehdCheck->Hide();
00245     bDTSHD  ? m_dtshdCheck->Show() : m_dtshdCheck->Hide();
00246 
00247     bAC3 &= (m_ac3Check->GetCheckState() == MythUIStateType::Full);
00248     bDTS &= (m_dtsCheck->GetCheckState() == MythUIStateType::Full);
00249 
00250     if (max_speakers > 2 && !bLPCM)
00251         max_speakers = 2;
00252     if (max_speakers == 2 && bAC3)
00253     {
00254         max_speakers = 6;
00255         if (AC3)
00256         {
00257             restore = true;
00258         }
00259     }
00260 
00261     int cur_speakers = m_maxspeakers;
00262 
00263     if (m_speakerNumberButtonList->GetItemCurrent() != NULL)
00264     {
00265         cur_speakers = qVariantValue<int>
00266             (m_speakerNumberButtonList->GetItemCurrent()->GetData());
00267     }
00268     if (cur_speakers > m_maxspeakers)
00269     {
00270         m_maxspeakers = cur_speakers;
00271     }
00272     if (restore)
00273     {
00274         cur_speakers = m_maxspeakers;
00275     }
00276 
00277     if (cur_speakers > max_speakers)
00278     {
00279         LOG(VB_AUDIO, LOG_INFO, QString("Reset device %1").arg(out));
00280         cur_speakers = max_speakers;
00281     }
00282 
00283         // Remove everything and re-add available channels
00284     m_speakerNumberButtonList->Reset();
00285     for (int i = 1; i <= max_speakers; i++)
00286     {
00287         if (settings.IsSupportedChannels(i))
00288         {
00289             switch (i)
00290             {
00291                 case 2:
00292                 {
00293                     MythUIButtonListItem *stereo =
00294                         new MythUIButtonListItem(m_speakerNumberButtonList,
00295                                                  QObject::tr("Stereo"));
00296                     stereo->SetData(2);
00297                     break;
00298                 }
00299                 case 6:
00300                 {
00301                     MythUIButtonListItem *sixchan =
00302                         new MythUIButtonListItem(m_speakerNumberButtonList,
00303                                                  QObject::tr("5.1 Channel Audio"));
00304                     sixchan->SetData(6);
00305                     break;
00306                 }
00307                 case 8:
00308                 {
00309                     MythUIButtonListItem *eightchan =
00310                         new MythUIButtonListItem(m_speakerNumberButtonList,
00311                                                  QObject::tr("7.1 Channel Audio"));
00312                     eightchan->SetData(8);
00313                     break;
00314                 }
00315                 default:
00316                     continue;
00317             }
00318         }
00319     }
00320     m_speakerNumberButtonList->SetValueByData(qVariantFromValue(cur_speakers));
00321 
00322         // Return values is used by audio test
00323         // where we mainly are interested by the number of channels
00324         // if we support AC3 and/or LPCM
00325     settings.SetBestSupportedChannels(cur_speakers);
00326     settings.setFeature(bAC3, FEATURE_AC3);
00327     settings.setFeature(bLPCM && realmax_speakers > 2, FEATURE_LPCM);
00328 
00329     return settings;
00330 }
00331 
00332 AudioOutputSettings AudioSetupWizard::UpdateCapabilities(
00333     MythUIButtonListItem* item)
00334 {
00335     bool restore = false;
00336     if (item)
00337     {
00338         restore = item->GetText() != m_lastAudioDevice;
00339         m_lastAudioDevice = item->GetText();
00340     }
00341     return UpdateCapabilities(restore);
00342 }
00343 
00344 AudioOutputSettings AudioSetupWizard::UpdateCapabilitiesAC3(void)
00345 {
00346     return UpdateCapabilities(false, true);
00347 }
00348 
00349 void AudioSetupWizard::slotNext(void)
00350 {
00351     if (m_testThread)
00352     {
00353         toggleSpeakers();
00354     }
00355 
00356     save();
00357 
00358     MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00359     VideoSetupWizard *sw = new VideoSetupWizard(mainStack, m_generalScreen,
00360                                                 this, "videosetupwizard");
00361 
00362     if (sw->Create())
00363     {
00364         mainStack->AddScreen(sw);
00365     }
00366     else
00367         delete sw;
00368 }
00369 
00370 void AudioSetupWizard::save(void)
00371 {
00372     // reset advanced audio config to default values
00373     gCoreContext->SaveSetting("StereoPCM", false);
00374     gCoreContext->SaveSetting("Audio48kOverride", false);
00375     gCoreContext->SaveSetting("HBRPassthru", true);
00376     gCoreContext->SaveSetting("PassThruDeviceOverride", false);
00377     gCoreContext->SaveSetting("PassThruOutputDevice", QString::null);
00378 
00379     int channels = qVariantValue<int>
00380         (m_speakerNumberButtonList->GetItemCurrent()->GetData());
00381     gCoreContext->SaveSetting("MaxChannels", channels);
00382 
00383     QString device =
00384         m_audioDeviceButtonList->GetItemCurrent()->GetText();
00385     gCoreContext->SaveSetting("AudioOutputDevice", device);
00386 
00387     bool ac3State = (m_ac3Check->GetCheckState() == MythUIStateType::Full);
00388     gCoreContext->SaveSetting("AC3PassThru", ac3State);
00389 
00390     bool dtsState = (m_dtsCheck->GetCheckState() == MythUIStateType::Full);
00391     gCoreContext->SaveSetting("DTSPassThru", dtsState);
00392 
00393     bool eac3State = (m_eac3Check->GetCheckState() == MythUIStateType::Full);
00394     gCoreContext->SaveSetting("EAC3PassThru", eac3State);
00395 
00396     bool truehdState = (m_truehdCheck->GetCheckState() == MythUIStateType::Full);
00397     gCoreContext->SaveSetting("TrueHDPassThru", truehdState);
00398 
00399     bool dtshdState = (m_dtshdCheck->GetCheckState() == MythUIStateType::Full);
00400     gCoreContext->SaveSetting("DTSHDPassThru", dtshdState);
00401 }
00402 
00403 void AudioSetupWizard::slotPrevious(void)
00404 {
00405     Close();
00406 }
00407 
00408 bool AudioSetupWizard::keyPressEvent(QKeyEvent *event)
00409 {
00410     if (GetFocusWidget()->keyPressEvent(event))
00411         return true;
00412 
00413     bool handled = false;
00414 
00415     if (!handled && MythScreenType::keyPressEvent(event))
00416         handled = true;
00417 
00418     return handled;
00419 }
00420 
00421 void AudioSetupWizard::toggleSpeakers(void)
00422 {
00423     if (m_testThread)
00424     {
00425         m_testThread->cancel();
00426         m_testThread->wait();
00427         delete m_testThread;
00428         m_testThread = NULL;
00429         m_testSpeakerButton->SetText(tr("Test Speakers"));
00430         return;
00431     }
00432 
00433     AudioOutputSettings settings = UpdateCapabilities(false);
00434     QString out = m_audioDeviceButtonList->GetItemCurrent()->GetText();
00435     int channels =
00436         qVariantValue<int> (m_speakerNumberButtonList->GetItemCurrent()->GetData());
00437 
00438     m_testThread =
00439         new AudioTestThread(this, out, out, channels, settings, false);
00440     if (!m_testThread->result().isEmpty())
00441     {
00442         QString msg = QObject::tr("Audio device is invalid or not useable.");
00443         MythPopupBox::showOkPopup(
00444             GetMythMainWindow(), QObject::tr("Warning"), msg);
00445         delete m_testThread;
00446         m_testThread = NULL;
00447     }
00448     else
00449     {
00450         m_testThread->start();
00451         m_testSpeakerButton->SetText(tr("Stop Speaker Test"));
00452     }
00453 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends