std::string CGUIDialogAudioDSPSettings::GetSettingsLabel(CSetting *pSetting)
{
  if (pSetting->GetLabel() == 15041)
  {
    const std::string &settingId = pSetting->GetId();

    int ptr = -1;
    AE_DSP_ADDON addon;
    if (settingId.substr(0, 27) == SETTING_STREAM_INFO_MODE_CPU_USAGE)
    {
      ptr = strtol(settingId.substr(27).c_str(), NULL, 0);
      if (ptr >= 0 && CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_ActiveModes[ptr]->AddonID(), addon))
        return m_ActiveModesData[ptr].MenuName;
    }
    else
    {
      if (settingId.substr(0, 21) == SETTING_AUDIO_MASTER_SETTINGS_MENUS)
        ptr = strtol(settingId.substr(21).c_str(), NULL, 0);
      else if (settingId.substr(0, 19) == SETTING_AUDIO_PROC_SETTINGS_MENUS)
        ptr = strtol(settingId.substr(19).c_str(), NULL, 0);

      if (ptr >= 0 && CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_Menus[ptr].addonId, addon))
        return g_localizeStrings.GetAddonString(addon->ID(), m_Menus[ptr].hook.iLocalizedStringId);
    }
  }

  return GetLocalizedString(pSetting->GetLabel());
}
Exemple #2
0
bool CActiveAEDSP::GetAudioDSPAddonName(int iAddonId, std::string &strName) const
{
  bool bReturn(false);
  AE_DSP_ADDON addon;
  if ((bReturn = GetReadyAudioDSPAddon(iAddonId, addon)) == true)
    strName = addon->GetAudioDSPName();

  return bReturn;
}
Exemple #3
0
void CActiveAEDSP::UpdateAddons()
{
  AE_DSP_ADDON dspAddon;

  BinaryAddonBaseList addonInfos;
  CServiceBroker::GetBinaryAddonManager().GetAddonInfos(addonInfos, false, ADDON_ADSPDLL);
  if (addonInfos.empty())
    return;

  for (auto &addonInfo : addonInfos)
  {
    bool bEnabled = !CServiceBroker::GetAddonMgr().IsAddonDisabled(addonInfo->ID());
    if (bEnabled && (!IsKnownAudioDSPAddon(addonInfo->ID()) || !IsReadyAudioDSPAddon(addonInfo)))
    {
      std::hash<std::string> hasher;
      int iAddonId = static_cast<int>(hasher(addonInfo->ID()));
      if (iAddonId < 0)
        iAddonId = -iAddonId;

      if (IsKnownAudioDSPAddon(addonInfo->ID()))
      {
        AE_DSP_ADDON dspAddon;
        GetAudioDSPAddon(iAddonId, dspAddon);
        dspAddon->Create(iAddonId);
      }
      else
      {
        AE_DSP_ADDON dspAddon = std::make_shared<CActiveAEDSPAddon>(addonInfo);
        dspAddon.get()->Create(iAddonId);
        CSingleLock lock(m_critSection);
        // register the add-on
        if (m_addonMap.find(iAddonId) == m_addonMap.end())
        {
          m_addonMap.insert(std::make_pair(iAddonId, dspAddon));
          m_addonNameIds.insert(make_pair(addonInfo->ID(), iAddonId));
        }
      }
    }
    else if (!bEnabled && IsKnownAudioDSPAddon(addonInfo->ID()))
    {
      CLog::Log(LOGDEBUG, "Disabling AudioDSP add-on: %s", addonInfo->ID().c_str());

      CSingleLock lock(m_critSection);
      AE_DSP_ADDONMAP::iterator iter = m_addonMap.find(GetAudioDSPAddonId(addonInfo->ID()));
      if (iter != m_addonMap.end())
      {
        m_addonMap.erase(iter);
        m_addonToDestroy.push_back(dspAddon);
      }
    }
  }

  TriggerModeUpdate();
}
Exemple #4
0
void CActiveAEDSP::UpdateAddons()
{
  VECADDONS addons;
  AE_DSP_ADDON dspAddon;

  CAddonMgr::GetInstance().GetAddons(addons, ADDON_ADSPDLL);

  if (addons.empty())
    return;

  for (auto &addon : addons)
  {
    bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID());
    if (bEnabled && (!IsKnownAudioDSPAddon(addon) || !IsReadyAudioDSPAddon(addon)))
    {
      std::hash<std::string> hasher;
      int iAddonId = static_cast<int>(hasher(addon->ID()));
      if (iAddonId < 0)
        iAddonId = -iAddonId;

      /* create and open database */
      if (!m_databaseDSP.IsOpen())
        m_databaseDSP.Open();

      if (IsKnownAudioDSPAddon(addon))
      {
        AE_DSP_ADDON dspAddon;
        GetAudioDSPAddon(iAddonId, dspAddon);
        dspAddon->Create(iAddonId);
      }
      else
      {
        AE_DSP_ADDON dspAddon = std::dynamic_pointer_cast<CActiveAEDSPAddon>(addon);
        if (!dspAddon)
        {
          CLog::Log(LOGERROR, "CActiveAEDSP::UpdateAndInitialiseAddons - severe error, incorrect add type");
          continue;
        }

        dspAddon.get()->Create(iAddonId);
        // register the add-on
        if (m_addonMap.find(iAddonId) == m_addonMap.end())
        {
          m_addonMap.insert(std::make_pair(iAddonId, dspAddon));
          m_addonNameIds.insert(make_pair(addon->ID(), iAddonId));
        }
      }
    }
  }

  TriggerModeUpdate();
}
Exemple #5
0
bool CActiveAEDSP::TranslateCharInfo(DWORD dwInfo, std::string &strValue) const
{
  bool bReturn(true);

  CSingleLock lock(m_critSection);

  if (!IsProcessing() || !m_usedProcesses[m_activeProcessId])
    return false;

  CActiveAEDSPModePtr activeMaster = m_usedProcesses[m_activeProcessId]->GetActiveMasterMode();
  if (activeMaster == NULL)
    return false;

  switch (dwInfo)
  {
  case ADSP_ACTIVE_STREAM_TYPE:
    strValue = g_localizeStrings.Get(GetStreamTypeName(m_usedProcesses[m_activeProcessId]->GetUsedStreamType()));
    break;
  case ADSP_DETECTED_STREAM_TYPE:
    strValue = g_localizeStrings.Get(GetStreamTypeName(m_usedProcesses[m_activeProcessId]->GetDetectedStreamType()));
    break;
  case ADSP_MASTER_NAME:
    {
      AE_DSP_ADDON addon;
      int modeId = activeMaster->ModeID();
      if (modeId == AE_DSP_MASTER_MODE_ID_PASSOVER || modeId >= AE_DSP_MASTER_MODE_ID_INTERNAL_TYPES)
        strValue = g_localizeStrings.Get(activeMaster->ModeName());
      else if (CActiveAEDSP::GetInstance().GetAudioDSPAddon(activeMaster->AddonID(), addon))
        strValue = g_localizeStrings.GetAddonString(addon->ID(), activeMaster->ModeName());
    }
    break;
  case ADSP_MASTER_INFO:
    bReturn = m_usedProcesses[m_activeProcessId]->GetMasterModeStreamInfoString(strValue);
    break;
  case ADSP_MASTER_OWN_ICON:
    strValue = activeMaster->IconOwnModePath();
    break;
  case ADSP_MASTER_OVERRIDE_ICON:
    strValue = activeMaster->IconOverrideModePath();
    break;
  default:
    strValue.clear();
    bReturn = false;
    break;
  };

  return bReturn;
}
Exemple #6
0
//@{
bool CActiveAEDSP::StopAudioDSPAddon(AddonPtr addon, bool bRestart)
{
  CSingleLock lock(m_critSection);

  int iId = GetAudioDSPAddonId(addon);
  AE_DSP_ADDON mappedAddon;
  if (GetReadyAudioDSPAddon(iId, mappedAddon))
  {
    if (bRestart)
      mappedAddon->ReCreate();
    else
      mappedAddon->Destroy();

    return true;
  }

  return false;
}
Exemple #7
0
bool CActiveAEDSP::UpdateAddons(void)
{
    VECADDONS addons;
    AE_DSP_ADDON dspAddon;
    bool bReturn(CAddonMgr::GetInstance().GetAddons(ADDON_ADSPDLL, addons, true));
    size_t usableAddons;

    if (bReturn)
    {
        CSingleLock lock(m_critUpdateSection);
        m_addons = addons;
    }

    usableAddons = m_addons.size();

    /* handle "new" addons which aren't yet in the db - these have to be added first */
    for (VECADDONS::const_iterator itr = addons.begin(); itr != addons.end(); ++itr)
    {
        dspAddon = std::dynamic_pointer_cast<CActiveAEDSPAddon>(*itr);

        bool newRegistration = false;
        if (RegisterAudioDSPAddon(dspAddon, &newRegistration) < 0 || newRegistration)
        {
            CAddonMgr::GetInstance().DisableAddon(dspAddon->ID());
            --usableAddons;
        }
    }

    if ((!bReturn || usableAddons == 0) && !m_noAddonWarningDisplayed &&
            !CAddonMgr::GetInstance().HasAddons(ADDON_ADSPDLL, false) &&
            IsActivated())
    {
        // No audio DSP add-ons could be found
        // You need a add-on installed for the process of audio DSP signal. System becomes disabled.
        m_noAddonWarningDisplayed = true;
        CGUIDialogOK::ShowAndGetInput(CVariant{19273}, CVariant{19274});
        CSettings::GetInstance().SetBool(CSettings::SETTING_AUDIOOUTPUT_DSPADDONSENABLED, false);
        CGUIMessage msg(GUI_MSG_UPDATE, WINDOW_SETTINGS_SYSTEM, 0);
        g_windowManager.SendThreadMessage(msg, WINDOW_SETTINGS_SYSTEM);
        CApplicationMessenger::GetInstance().SendMsg(TMSG_SETAUDIODSPSTATE, ACTIVE_AE_DSP_STATE_OFF);
    }

    return bReturn;
}
void CGUIDialogAudioDSPSettings::GetAudioDSPMenus(CSettingGroup *group, AE_DSP_MENUHOOK_CAT category)
{
  AE_DSP_ADDONMAP addonMap;
  if (CActiveAEDSP::GetInstance().GetEnabledAudioDSPAddons(addonMap) > 0)
  {
    for (AE_DSP_ADDONMAP_ITR itr = addonMap.begin(); itr != addonMap.end(); itr++)
    {
      AE_DSP_MENUHOOKS hooks;
      if (CActiveAEDSP::GetInstance().GetMenuHooks(itr->second->GetID(), category, hooks))
      {
        for (unsigned int i = 0; i < hooks.size(); i++)
        {
          if (category != hooks[i].category || (category != AE_DSP_MENUHOOK_MISCELLANEOUS &&
              !m_ActiveStreamProcess->IsMenuHookModeActive(hooks[i].category, itr->second->GetID(), hooks[i].iRelevantModeId)))
            continue;

          MenuHookMember menu;
          menu.addonId                  = itr->second->GetID();
          menu.hook.category            = hooks[i].category;
          menu.hook.iHookId             = hooks[i].iHookId;
          menu.hook.iLocalizedStringId  = hooks[i].iLocalizedStringId;
          menu.hook.iRelevantModeId     = hooks[i].iRelevantModeId;
          m_Menus.push_back(menu);
        }
      }
    }
  }

  for (unsigned int i = 0; i < m_Menus.size(); i++)
  {
    AE_DSP_ADDON addon;
    if (CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_Menus[i].addonId, addon) && category == m_Menus[i].hook.category)
    {
      std::string modeName = g_localizeStrings.GetAddonString(addon->ID(), m_Menus[i].hook.iLocalizedStringId);
      if (modeName.empty())
        modeName = g_localizeStrings.Get(15041);

      std::string setting = StringUtils::Format("%s%i", SETTING_AUDIO_PROC_SETTINGS_MENUS, i);
      AddButton(group, setting, 15041, 0);
    }
  }
}
bool CGUIDialogAudioDSPSettings::OpenAudioDSPMenu(unsigned int setupEntry)
{
  if (setupEntry >= m_Menus.size())
    return false;

  AE_DSP_ADDON addon;
  if (!CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_Menus[setupEntry].addonId, addon))
    return false;

  AE_DSP_MENUHOOK       hook;
  AE_DSP_MENUHOOK_DATA  hookData;

  hook.category           = m_Menus[setupEntry].hook.category;
  hook.iHookId            = m_Menus[setupEntry].hook.iHookId;
  hook.iLocalizedStringId = m_Menus[setupEntry].hook.iLocalizedStringId;
  hook.iRelevantModeId    = m_Menus[setupEntry].hook.iRelevantModeId;
  hookData.category       = m_Menus[setupEntry].hook.category;
  switch (hookData.category)
  {
    case AE_DSP_MENUHOOK_PRE_PROCESS:
    case AE_DSP_MENUHOOK_MASTER_PROCESS:
    case AE_DSP_MENUHOOK_RESAMPLE:
    case AE_DSP_MENUHOOK_POST_PROCESS:
      hookData.data.iStreamId = m_ActiveStreamId;
      break;
    default:
      break;
  }

  /*!
   * @note the addon dialog becomes always opened on the back of Kodi ones for this reason a
   * "<animation effect="fade" start="100" end="0" time="400" condition="Window.IsVisible(Addon)">Conditional</animation>"
   * on skin is needed to hide dialog.
   */
  addon->CallMenuHook(hook, hookData);

  return true;
}
Exemple #10
0
bool CActiveAEDSP::GetMenuHooks(int iDSPAddonID, AE_DSP_MENUHOOK_CAT cat, AE_DSP_MENUHOOKS &hooks)
{
  bool bReturn(false);

  if (iDSPAddonID < 0)
    return bReturn;

  AE_DSP_ADDON addon;
  if (GetReadyAudioDSPAddon(iDSPAddonID, addon) && addon->HaveMenuHooks(cat))
  {
    AE_DSP_MENUHOOKS *addonhooks = addon->GetMenuHooks();
    for (unsigned int i = 0; i < addonhooks->size(); ++i)
    {
      if (cat == AE_DSP_MENUHOOK_ALL || addonhooks->at(i).category == cat)
      {
        hooks.push_back(addonhooks->at(i));
        bReturn = true;
      }
    }
  }

  return bReturn;
}
Exemple #11
0
int CGUIDialogAudioDSPManager::helper_GetDialogId(CActiveAEDSPModePtr &ModePointer, AE_DSP_MENUHOOK_CAT &MenuHook, AE_DSP_ADDON &Addon, std::string AddonName)
{
    int dialogId = 0;

    if (ModePointer->HasSettingsDialog())
    {
        AE_DSP_MENUHOOKS hooks;

        // Find first general settings dialog about mode
        if (CServiceBroker::GetADSP().GetMenuHooks(ModePointer->AddonID(), AE_DSP_MENUHOOK_SETTING, hooks))
        {
            for (unsigned int i = 0; i < hooks.size() && dialogId == 0; i++)
            {
                if (hooks[i].iRelevantModeId == ModePointer->AddonModeNumber())
                {
                    dialogId = hooks[i].iHookId;
                }
            }
        }

        // If nothing was present, check for playback settings
        if (dialogId == 0 && CServiceBroker::GetADSP().GetMenuHooks(ModePointer->AddonID(), MenuHook, hooks))
        {
            for (unsigned int i = 0; i < hooks.size() && (dialogId == 0 || dialogId != -1); i++)
            {
                if (hooks[i].iRelevantModeId == ModePointer->AddonModeNumber())
                {
                    if (!hooks[i].bNeedPlayback)
                    {
                        dialogId = hooks[i].iHookId;
                    }
                    else
                    {
                        dialogId = -1;
                    }
                }
            }
        }

        if (dialogId == 0)
            CLog::Log(LOGERROR, "DSP Dialog Manager - %s - Present marked settings dialog of mode %s on addon %s not found",
                      __FUNCTION__,
                      g_localizeStrings.GetAddonString(Addon->ID(), ModePointer->ModeName()).c_str(),
                      AddonName.c_str());
    }

    return dialogId;
}
int CGUIDialogAudioDSPManager::helper_GetDialogId(CActiveAEDSPModePtr &ModePointer, AE_DSP_MENUHOOK_CAT &MenuHook, AE_DSP_ADDON &Addon, std::string AddonName)
{
  int dialogId = 0;

  if (ModePointer->HasSettingsDialog())
  {
    AE_DSP_MENUHOOKS hooks;
    
    if (dialogId == 0)
      CLog::Log(LOGERROR, "DSP Dialog Manager - %s - Present marked settings dialog of mode %s on addon %s not found",
                            __FUNCTION__,
                            g_localizeStrings.GetAddonString(Addon->ID(), ModePointer->ModeName()).c_str(),
                            AddonName.c_str());
  }

  return dialogId;
}
Exemple #13
0
bool CActiveAEDSP::GetReadyAudioDSPAddon(int iAddonId, AE_DSP_ADDON &addon) const
{
  if (GetAudioDSPAddon(iAddonId, addon))
    return addon->ReadyToUse();
  return false;
}
Exemple #14
0
bool CActiveAEDSP::UpdateAndInitialiseAudioDSPAddons(bool bInitialiseAllAudioDSPAddons /* = false */)
{
  bool bReturn(true);
  VECADDONS map;
  VECADDONS disableAddons;
  {
    CSingleLock lock(m_critUpdateSection);
    map = m_addons;
  }

  if (map.empty())
    return false;

  for (unsigned iAddonPtr = 0; iAddonPtr < map.size(); ++iAddonPtr)
  {
    const AddonPtr dspAddon = map.at(iAddonPtr);
    bool bEnabled = !CAddonMgr::GetInstance().IsAddonDisabled(dspAddon->ID());

    if (!bEnabled && IsKnownAudioDSPAddon(dspAddon))
    {
      CSingleLock lock(m_critUpdateSection);
      /* stop the dsp addon and remove it from the db */
      StopAudioDSPAddon(dspAddon, false);
      VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), dspAddon);
      if (addonPtr != m_addons.end())
        m_addons.erase(addonPtr);

    }
    else if (bEnabled && (bInitialiseAllAudioDSPAddons || !IsKnownAudioDSPAddon(dspAddon) || !IsReadyAudioDSPAddon(dspAddon)))
    {
      bool bDisabled(false);

      /* register the add-on in the audio dsp db, and create the CActiveAEDSPAddon instance */
      int iAddonId = RegisterAudioDSPAddon(dspAddon);
      if (iAddonId < 0)
      {
        /* failed to register or create the add-on, disable it */
        CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to register add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str());
        disableAddons.push_back(dspAddon);
        bDisabled = true;
      }
      else
      {
        ADDON_STATUS status(ADDON_STATUS_UNKNOWN);
        AE_DSP_ADDON addon;
        {
          CSingleLock lock(m_critUpdateSection);
          if (!GetAudioDSPAddon(iAddonId, addon))
          {
            CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to find add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str());
            disableAddons.push_back(dspAddon);
            bDisabled = true;
          }
        }

        /* re-check the enabled status. newly installed dsps get disabled when they're added to the db */
        if (!bDisabled && !CAddonMgr::GetInstance().IsAddonDisabled(addon->ID()) && (status = addon->Create(iAddonId)) != ADDON_STATUS_OK)
        {
          CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to create add-on %s, status = %d", __FUNCTION__, dspAddon->Name().c_str(), status);
          if (!addon.get() || !addon->DllLoaded() || status == ADDON_STATUS_PERMANENT_FAILURE)
          {
            /* failed to load the dll of this add-on, disable it */
            CLog::Log(LOGWARNING, "ActiveAE DSP - %s - failed to load the dll for add-on %s, disabling it", __FUNCTION__, dspAddon->Name().c_str());
            disableAddons.push_back(dspAddon);
            bDisabled = true;
          }
        }
      }

      if (bDisabled && IsActivated())
        CGUIDialogOK::ShowAndGetInput(24070, 24071, 16029, 0);
    }
  }

  /* disable add-ons that failed to initialise */
  if (!disableAddons.empty())
  {
    CSingleLock lock(m_critUpdateSection);
    for (VECADDONS::iterator itr = disableAddons.begin(); itr != disableAddons.end(); ++itr)
    {
      /* disable in the add-on db */
      CAddonMgr::GetInstance().DisableAddon((*itr)->ID());

      /* remove from the audio dsp add-on list */
      VECADDONS::iterator addonPtr = std::find(m_addons.begin(), m_addons.end(), *itr);
      if (addonPtr != m_addons.end())
        m_addons.erase(addonPtr);
    }
  }

  return bReturn;
}
Exemple #15
0
CFileItem *CGUIDialogAudioDSPManager::helper_CreateModeListItem(CActiveAEDSPModePtr &ModePointer, AE_DSP_MENUHOOK_CAT &MenuHook, int *ContinuesNo)
{
    CFileItem *pItem = NULL;

    if (!ContinuesNo)
    {
        return pItem;
    }

    // start to get Addon and Mode properties
    const int AddonID = ModePointer->AddonID();

    std::string addonName;
    if (!CServiceBroker::GetADSP().GetAudioDSPAddonName(AddonID, addonName))
    {
        return pItem;
    }

    AE_DSP_ADDON addon;
    if (!CServiceBroker::GetADSP().GetAudioDSPAddon(AddonID, addon))
    {
        return pItem;
    }

    std::string modeName = g_localizeStrings.GetAddonString(addon->ID(), ModePointer->ModeName());

    std::string description;
    if (ModePointer->ModeDescription() > -1)
    {
        description = g_localizeStrings.GetAddonString(addon->ID(), ModePointer->ModeDescription());
    }
    else
    {
        description = g_localizeStrings.Get(15063);
    }

    bool isActive = ModePointer->IsEnabled();
    int number = ModePointer->ModePosition();
    int dialogId = helper_GetDialogId(ModePointer, MenuHook, addon, addonName);
    // end to get Addon and Mode properties

    if (isActive)
    {
        if (number <= 0)
        {
            number = *ContinuesNo;
            (*ContinuesNo)++;
        }

        std::string str = StringUtils::Format("%i:%i:%i:%s",
                                              number,
                                              AddonID,
                                              ModePointer->AddonModeNumber(),
                                              ModePointer->AddonModeName().c_str());

        pItem = new CFileItem(str);
    }
    else
    {
        pItem = new CFileItem(modeName);
    }

    // set list item properties
    pItem->SetProperty("ActiveMode", isActive);
    pItem->SetProperty("Number", number);
    pItem->SetLabel(modeName);
    pItem->SetProperty("Description", description);
    pItem->SetProperty("Help", ModePointer->ModeHelp());
    if (ModePointer->IconOwnModePath().empty())
        pItem->SetIconImage("DefaultAddonAudioDSP.png");
    else
        pItem->SetIconImage(ModePointer->IconOwnModePath());
    pItem->SetProperty("SettingsDialog", dialogId);
    pItem->SetProperty("AddonId", AddonID);
    pItem->SetProperty("AddonModeNumber", ModePointer->AddonModeNumber());
    pItem->SetLabel2(addonName);
    pItem->SetProperty("Changed", false);

    return pItem;
}
Exemple #16
0
bool CGUIDialogAudioDSPManager::OnContextButton(int itemNumber, CONTEXT_BUTTON button, int listType)
{
    CFileItemPtr pItem;
    int listSize = 0;
    if (listType == LIST_ACTIVE)
    {
        pItem = m_activeItems[m_iCurrentType]->Get(itemNumber);
        listSize = m_activeItems[m_iCurrentType]->Size();
    }
    else if (listType == LIST_AVAILABLE)
    {
        pItem = m_availableItems[m_iCurrentType]->Get(itemNumber);
        listSize = m_availableItems[m_iCurrentType]->Size();
    }

    /* Check file item is in list range and get his pointer */
    if (!pItem || itemNumber < 0 || itemNumber >= listSize)
    {
        return false;
    }

    if (button == CONTEXT_BUTTON_HELP)
    {
        /*!
        * Open audio dsp addon mode help text dialog
        */
        AE_DSP_ADDON addon;
        if (CServiceBroker::GetADSP().GetAudioDSPAddon((int)pItem->GetProperty("AddonId").asInteger(), addon))
        {
            CGUIDialogTextViewer* pDlgInfo = (CGUIDialogTextViewer*)g_windowManager.GetWindow(WINDOW_DIALOG_TEXT_VIEWER);
            pDlgInfo->SetHeading(g_localizeStrings.Get(15062) + " - " + pItem->GetProperty("Name").asString());
            pDlgInfo->SetText(g_localizeStrings.GetAddonString(addon->ID(), (uint32_t)pItem->GetProperty("Help").asInteger()));
            pDlgInfo->Open();
        }
    }
    else if (button == CONTEXT_BUTTON_ACTIVATE)
    {
        /*!
        * Deactivate selected processing mode
        */
        if (pItem->GetProperty("ActiveMode").asBoolean())
        {
            // remove mode from active mode list and add it to available mode list
            CFileItemPtr newItem(dynamic_cast<CFileItem*>(pItem->Clone()));
            newItem->SetProperty("ActiveMode", false);
            newItem->SetProperty("Changed", true);
            m_activeItems[m_iCurrentType]->Remove(itemNumber);
            m_availableItems[m_iCurrentType]->Add(newItem);
        }
        else
        {
            /*!
            * Activate selected processing mode
            */
            if ((m_iCurrentType == AE_DSP_MODE_TYPE_INPUT_RESAMPLE || m_iCurrentType == AE_DSP_MODE_TYPE_OUTPUT_RESAMPLE) && m_activeItems[m_iCurrentType]->Size() > 0)
            {   // if there is already an active resampler, now we remove it
                CFileItemPtr activeResampler = m_activeItems[m_iCurrentType]->Get(0);
                if (activeResampler)
                {
                    CFileItemPtr newItem(dynamic_cast<CFileItem*>(activeResampler->Clone()));
                    newItem->SetProperty("ActiveMode", false);
                    newItem->SetProperty("Changed", true);

                    m_availableItems[m_iCurrentType]->Add(newItem);
                    // clear active list, because only one active resampling mode is supported by ActiveAEDSP
                    m_activeItems[m_iCurrentType]->Clear();
                }
            }

            // remove mode from available mode list and add it to active mode list
            CFileItemPtr newItem(dynamic_cast<CFileItem*>(pItem->Clone()));

            newItem->SetProperty("Number", (int)m_activeItems[m_iCurrentType]->Size() +1);
            newItem->SetProperty("Changed", true);
            newItem->SetProperty("ActiveMode", true);

            m_availableItems[m_iCurrentType]->Remove(itemNumber);
            m_activeItems[m_iCurrentType]->Add(newItem);
        }

        m_bContainsChanges = true;
        if (m_bContinousSaving)
        {
            SaveList();
        }

        // reorder available mode list, so that the mode order is always consistent
        m_availableItems[m_iCurrentType]->ClearSortState();
        m_availableItems[m_iCurrentType]->Sort(SortByLabel, SortOrderAscending);

        // update active and available mode list
        Renumber();
        m_availableViewControl.SetItems(*m_availableItems[m_iCurrentType]);
        m_activeViewControl.SetItems(*m_activeItems[m_iCurrentType]);
    }
    else if (button == CONTEXT_BUTTON_MOVE)
    {
        m_bMovingMode = true;
        pItem->Select(true);

        CGUIListContainer *modeList = dynamic_cast<CGUIListContainer*>(GetControl(CONTROL_LIST_MODE_SELECTION));
        CGUIButtonControl *applyButton = dynamic_cast<CGUIButtonControl*>(GetControl(CONTROL_BUTTON_APPLY_CHANGES));
        CGUIButtonControl *clearActiveModesButton = dynamic_cast<CGUIButtonControl*>(GetControl(CONTROL_BUTTON_CLEAR_ACTIVE_MODES));
        if (!modeList || !applyButton || !clearActiveModesButton)
        {
            helper_LogError(__FUNCTION__);
            return false;
        }

        // if we are in MovingMode all buttons and mode selection list will be disabled!
        modeList->SetEnabled(false);
        clearActiveModesButton->SetEnabled(false);
        if (!m_bContinousSaving)
        {
            applyButton->SetEnabled(false);
        }
    }
    else if (button == CONTEXT_BUTTON_SETTINGS)
    {
        int hookId = (int)pItem->GetProperty("SettingsDialog").asInteger();
        if (hookId > 0)
        {
            AE_DSP_ADDON addon;
            if (CServiceBroker::GetADSP().GetAudioDSPAddon((int)pItem->GetProperty("AddonId").asInteger(), addon))
            {
                AE_DSP_MENUHOOK       hook;
                AE_DSP_MENUHOOK_DATA  hookData;

                hook.category           = AE_DSP_MENUHOOK_ALL;
                hook.iHookId            = hookId;
                hook.iRelevantModeId    = (unsigned int)pItem->GetProperty("AddonModeNumber").asInteger();
                hookData.category       = AE_DSP_MENUHOOK_ALL;
                hookData.data.iStreamId = -1;

                /*!
                 * @note the addon dialog becomes always opened on the back of Kodi ones for this reason a
                 * "<animation effect="fade" start="100" end="0" time="400" condition="Window.IsVisible(Addon)">Conditional</animation>"
                 * on skin is needed to hide dialog.
                 */
                addon->CallMenuHook(hook, hookData);
            }
        }
        else
        {
            CGUIDialogOK::ShowAndGetInput(19033, 0, 15040, 0);
        }
    }

    return true;
}
void CGUIDialogAudioDSPSettings::InitializeSettings()
{
  CGUIDialogSettingsManualBase::InitializeSettings();

  CSettingCategory *category = AddCategory(SETTING_AUDIO_CAT_MAIN, -1);
  if (category == NULL)
  {
    CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodspmainsettings'");
    return;
  }

  // get all necessary setting groups
  CSettingGroup *groupAudioModeSel = AddGroup(category);
  if (groupAudioModeSel == NULL)
  {
    CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupAudioModeSel'");
    return;
  }
  CSettingGroup *groupAudioVolumeSel = AddGroup(category);
  if (groupAudioVolumeSel == NULL)
  {
    CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupAudioVolumeSel'");
    return;
  }
  CSettingGroup *groupAudioSubmenuSel = AddGroup(category);
  if (groupAudioSubmenuSel == NULL)
  {
    CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupAudioSubmenuSel'");
    return;
  }
  CSettingGroup *groupSaveAsDefault = AddGroup(category);
  if (groupSaveAsDefault == NULL)
  {
    CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupSaveAsDefault'");
    return;
  }

  bool usePopup = g_SkinInfo->HasSkinFile("DialogSlider.xml");

  CVideoSettings &videoSettings = CMediaSettings::GetInstance().GetCurrentVideoSettings();

  m_audioCaps.clear();
  if (g_application.m_pPlayer->HasPlayer())
    g_application.m_pPlayer->GetAudioCapabilities(m_audioCaps);

  m_ActiveStreamId      = CActiveAEDSP::GetInstance().GetActiveStreamId();
  m_ActiveStreamProcess = CActiveAEDSP::GetInstance().GetDSPProcess(m_ActiveStreamId);
  if (m_ActiveStreamId == (unsigned int)-1 || !m_ActiveStreamProcess)
  {
    m_iCategory = FindCategoryIndex(SETTING_AUDIO_CAT_MAIN);
    Close(true);
    return;
  }

  int modeUniqueId;
  m_ActiveStreamProcess->GetMasterModeTypeInformation(m_streamTypeUsed, m_baseTypeUsed, modeUniqueId);

  int modesAvailable = 0;
  for (int i = 0; i < AE_DSP_ASTREAM_AUTO; i++)
  {
    m_MasterModes[i].clear();
    m_ActiveStreamProcess->GetAvailableMasterModes((AE_DSP_STREAMTYPE)i, m_MasterModes[i]);
    if (!m_MasterModes[i].empty()) modesAvailable++;
  }

  if (modesAvailable > 0)
  {
    /* about size() > 1, it is always the fallback (ignore of master processing) present. */
    StaticIntegerSettingOptions modeEntries;
    if (m_MasterModes[AE_DSP_ASTREAM_BASIC].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_BASIC),   AE_DSP_ASTREAM_BASIC));
    if (m_MasterModes[AE_DSP_ASTREAM_MUSIC].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_MUSIC),   AE_DSP_ASTREAM_MUSIC));
    if (m_MasterModes[AE_DSP_ASTREAM_MOVIE].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_MOVIE),   AE_DSP_ASTREAM_MOVIE));
    if (m_MasterModes[AE_DSP_ASTREAM_GAME].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_GAME),    AE_DSP_ASTREAM_GAME));
    if (m_MasterModes[AE_DSP_ASTREAM_APP].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_APP),     AE_DSP_ASTREAM_APP));
    if (m_MasterModes[AE_DSP_ASTREAM_MESSAGE].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_MESSAGE), AE_DSP_ASTREAM_MESSAGE));
    if (m_MasterModes[AE_DSP_ASTREAM_PHONE].size() > 1)
      modeEntries.push_back(std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_PHONE),   AE_DSP_ASTREAM_PHONE));
    if (modesAvailable > 1 && m_MasterModes[m_streamTypeUsed].size() > 1)
      modeEntries.insert(modeEntries.begin(), std::pair<int, int>(CActiveAEDSP::GetInstance().GetStreamTypeName(AE_DSP_ASTREAM_AUTO), AE_DSP_ASTREAM_AUTO));

    AddSpinner(groupAudioModeSel,
                SETTING_AUDIO_MAIN_STREAMTYPE, 15021, 0,
                (AE_DSP_STREAMTYPE)CMediaSettings::GetInstance().GetCurrentAudioSettings().m_MasterStreamTypeSel,
                modeEntries);
  }

  bool AddonMasterModeSetupPresent = false;
  m_ModeList.clear();
  for (unsigned int i = 0; i < m_MasterModes[m_streamTypeUsed].size(); i++)
  {
    if (m_MasterModes[m_streamTypeUsed][i])
    {
      AE_DSP_ADDON addon;
      int modeId = m_MasterModes[m_streamTypeUsed][i]->ModeID();
      if (modeId == AE_DSP_MASTER_MODE_ID_PASSOVER || modeId >= AE_DSP_MASTER_MODE_ID_INTERNAL_TYPES)
      {
        m_ModeList.push_back(make_pair(g_localizeStrings.Get(m_MasterModes[m_streamTypeUsed][i]->ModeName()), modeId));
      }
      else if (CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_MasterModes[m_streamTypeUsed][i]->AddonID(), addon))
      {
        m_ModeList.push_back(make_pair(g_localizeStrings.GetAddonString(addon->ID(), m_MasterModes[m_streamTypeUsed][i]->ModeName()), modeId));
        if (!AddonMasterModeSetupPresent)
          AddonMasterModeSetupPresent = m_MasterModes[m_streamTypeUsed][i]->HasSettingsDialog();
      }
    }
  }

  m_modeTypeUsed = CMediaSettings::GetInstance().GetCurrentAudioSettings().m_MasterModes[m_streamTypeUsed][m_baseTypeUsed];
  CSettingInt *spinner = AddSpinner(groupAudioModeSel, SETTING_AUDIO_MAIN_MODETYPE, 15022, 0, m_modeTypeUsed, AudioModeOptionFiller);
  spinner->SetOptionsFiller(AudioModeOptionFiller, this);

  ///-----------------------

  // audio settings
  // audio volume setting
  m_volume = g_application.GetVolume(false);
  if (!g_windowManager.IsWindowActive(WINDOW_DIALOG_AUDIO_OSD_SETTINGS))
  {
    CSettingNumber *settingAudioVolume = AddSlider(groupAudioVolumeSel, SETTING_AUDIO_MAIN_VOLUME, 13376, 0, m_volume, 14054, VOLUME_MINIMUM, VOLUME_MAXIMUM / 100.0f, VOLUME_MAXIMUM);
    static_cast<CSettingControlSlider*>(settingAudioVolume->GetControl())->SetFormatter(SettingFormatterPercentAsDecibel);
  }

  // audio volume amplification setting
  if (SupportsAudioFeature(IPC_AUD_AMP))
    AddSlider(groupAudioVolumeSel, SETTING_AUDIO_MAIN_VOLUME_AMPLIFICATION, 660, 0, videoSettings.m_VolumeAmplification, 14054, VOLUME_DRC_MINIMUM * 0.01f, (VOLUME_DRC_MAXIMUM - VOLUME_DRC_MINIMUM) / 6000.0f, VOLUME_DRC_MAXIMUM * 0.01f);

  ///-----------------------

  AddButton(groupAudioSubmenuSel, SETTING_AUDIO_MAIN_BUTTON_MASTER,   15025, 0, false, AddonMasterModeSetupPresent, -1);
  AddButton(groupAudioSubmenuSel, SETTING_AUDIO_MAIN_BUTTON_OUTPUT,   15026, 0, false, HaveActiveMenuHooks(AE_DSP_MENUHOOK_POST_PROCESS) || SupportsAudioFeature(IPC_AUD_OFFSET), -1);
  AddButton(groupAudioSubmenuSel, SETTING_AUDIO_MAIN_BUTTON_RESAMPLE, 15033, 0, false, HaveActiveMenuHooks(AE_DSP_MENUHOOK_RESAMPLE), -1);
  AddButton(groupAudioSubmenuSel, SETTING_AUDIO_MAIN_BUTTON_PRE_PROC, 15039, 0, false, HaveActiveMenuHooks(AE_DSP_MENUHOOK_PRE_PROCESS), -1);
  AddButton(groupAudioSubmenuSel, SETTING_AUDIO_MAIN_BUTTON_MISC,     15034, 0, false, HaveActiveMenuHooks(AE_DSP_MENUHOOK_MISCELLANEOUS), -1);
  AddButton(groupAudioSubmenuSel, SETTING_AUDIO_MAIN_BUTTON_INFO,     15027, 0, false, true, -1);

  ///-----------------------

  AddButton(groupSaveAsDefault, SETTING_AUDIO_MAIN_MAKE_DEFAULT, 12376, 0);

  m_Menus.clear();

  /**
   * Audio Master mode settings Dialog init
   */
  {
    CSettingCategory *categoryMaster = AddCategory(SETTING_AUDIO_CAT_MASTER, -1);
    if (categoryMaster == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodspmastersettings'");
      return;
    }

    CSettingGroup *groupMasterMode = AddGroup(categoryMaster);
    if (groupMasterMode == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupMasterMode'");
      return;
    }

    for (unsigned int i = 0; i < m_MasterModes[m_streamTypeUsed].size(); i++)
    {
      if (m_MasterModes[m_streamTypeUsed][i]->HasSettingsDialog())
      {
        AE_DSP_ADDON addon;
        if (CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_MasterModes[m_streamTypeUsed][i]->AddonID(), addon))
        {
          AE_DSP_MENUHOOKS hooks;
          if (CActiveAEDSP::GetInstance().GetMenuHooks(m_MasterModes[m_streamTypeUsed][i]->AddonID(), AE_DSP_MENUHOOK_MASTER_PROCESS, hooks))
          {
            for (unsigned int j = 0; j < hooks.size(); j++)
            {
              if (hooks[j].iRelevantModeId != m_MasterModes[m_streamTypeUsed][i]->AddonModeNumber())
                continue;

              MenuHookMember menu;
              menu.addonId                  = m_MasterModes[m_streamTypeUsed][i]->AddonID();
              menu.hook.category            = hooks[j].category;
              menu.hook.iHookId             = hooks[j].iHookId;
              menu.hook.iLocalizedStringId  = hooks[j].iLocalizedStringId;
              menu.hook.iRelevantModeId     = hooks[j].iRelevantModeId;
              m_Menus.push_back(menu);

              std::string setting = StringUtils::Format("%s%i", SETTING_AUDIO_MASTER_SETTINGS_MENUS, (int)m_Menus.size()-1);
              AddButton(groupMasterMode, setting, 15041, 0);
              break;
            }
          }
        }
      }
    }
  }

  /**
   * Audio post processing settings Dialog init
   */
  {
    CSettingCategory *category = AddCategory(SETTING_AUDIO_CAT_POST_PROCESS, -1);
    if (category == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodsppostsettings'");
      return;
    }

    CSettingGroup *groupInternal = AddGroup(category);
    if (groupInternal == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupInternal'");
      return;
    }

    CSettingGroup *groupAddon = AddGroup(category);
    if (groupAddon == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'groupAddon'");
      return;
    }

    // audio delay setting
    if (SupportsAudioFeature(IPC_AUD_OFFSET))
    {
      CSettingNumber *settingAudioDelay = AddSlider(groupInternal, SETTING_AUDIO_POST_PROC_AUDIO_DELAY, 297, 0, videoSettings.m_AudioDelay, 0, -g_advancedSettings.m_videoAudioDelayRange, 0.025f, g_advancedSettings.m_videoAudioDelayRange, 297, usePopup);
      static_cast<CSettingControlSlider*>(settingAudioDelay->GetControl())->SetFormatter(SettingFormatterDelay);
    }
    GetAudioDSPMenus(groupAddon, AE_DSP_MENUHOOK_POST_PROCESS);
  }

  /**
   * Audio add-on resampling setting dialog's
   */
  {
    CSettingCategory *category = AddCategory(SETTING_AUDIO_CAT_RESAMPLING, -1);
    if (category == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodspresamplesettings'");
      return;
    }
    CSettingGroup *group = AddGroup(category);
    if (group == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'group'");
      return;
    }
    GetAudioDSPMenus(group, AE_DSP_MENUHOOK_RESAMPLE);
  }

  /**
   * Audio add-on's pre processing setting dialog's
   */
  {
    CSettingCategory *category = AddCategory(SETTING_AUDIO_CAT_PRE_PROCESS, -1);
    if (category == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodsppresettings'");
      return;
    }
    CSettingGroup *group = AddGroup(category);
    if (group == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'group'");
      return;
    }
    GetAudioDSPMenus(group, AE_DSP_MENUHOOK_PRE_PROCESS);
  }

  /**
   * Audio add-on's miscellaneous setting dialog's
   */
  {
    CSettingCategory *category = AddCategory(SETTING_AUDIO_CAT_MISC, -1);
    if (category == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodspmiscsettings'");
      return;
    }
    CSettingGroup *group = AddGroup(category);
    if (group == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group 'group'");
      return;
    }
    GetAudioDSPMenus(group, AE_DSP_MENUHOOK_MISCELLANEOUS);
  }

  /**
   * Audio Information Dialog init
   */
  {
    CSettingGroup *group;
    CSettingCategory *category = AddCategory(SETTING_AUDIO_CAT_PROC_INFO, -1);
    if (category == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings category 'audiodspprocinfo'");
      return;
    }

    m_ActiveModes.clear();
    m_ActiveStreamProcess->GetActiveModes(AE_DSP_MODE_TYPE_UNDEFINED, m_ActiveModes);
    m_ActiveModesData.resize(m_ActiveModes.size());

    group = AddGroup(category, 15089);
    if (group == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group for '%s'", g_localizeStrings.Get(15089).c_str());
      return;
    }
    m_InputChannels = StringUtils::Format("%i", m_ActiveStreamProcess->GetInputChannels());
    AddInfoLabelButton(group, SETTING_STREAM_INFO_INPUT_CHANNELS, 21444, 0, m_InputChannels);
    m_InputChannelNames = m_ActiveStreamProcess->GetInputChannelNames();
    AddInfoLabelButton(group, SETTING_STREAM_INFO_INPUT_CHANNEL_NAMES, 15091, 0, m_InputChannelNames);
    m_InputSamplerate = StringUtils::Format("%i Hz", (int)m_ActiveStreamProcess->GetInputSamplerate());
    AddInfoLabelButton(group, SETTING_STREAM_INFO_INPUT_SAMPLERATE, 613, 0, m_InputSamplerate);

    group = AddGroup(category, 15090);
    if (group == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group for '%s'", g_localizeStrings.Get(15090).c_str());
      return;
    }
    m_OutputChannels = StringUtils::Format("%i", m_ActiveStreamProcess->GetOutputChannels());
    AddInfoLabelButton(group, SETTING_STREAM_INFO_OUTPUT_CHANNELS, 21444, 0, m_OutputChannels);
    m_OutputChannelNames = m_ActiveStreamProcess->GetOutputChannelNames();
    AddInfoLabelButton(group, SETTING_STREAM_INFO_OUTPUT_CHANNEL_NAMES, 15091, 0, m_OutputChannelNames);
    m_OutputSamplerate = StringUtils::Format("%i Hz", (int)m_ActiveStreamProcess->GetOutputSamplerate());
    AddInfoLabelButton(group, SETTING_STREAM_INFO_OUTPUT_SAMPLERATE, 613, 0, m_OutputSamplerate);

    group = AddGroup(category, 15081);
    if (group == NULL)
    {
      CLog::Log(LOGERROR, "CGUIDialogAudioDSPSettings: unable to setup settings group for '%s'", g_localizeStrings.Get(15081).c_str());
      return;
    }
    m_CPUUsage = StringUtils::Format("%.02f %%", m_ActiveStreamProcess->GetCPUUsage());
    AddInfoLabelButton(group, SETTING_STREAM_INFO_CPU_USAGE, 15092, 0, m_CPUUsage);

    bool foundPreProcess = false, foundPostProcess = false;
    for (unsigned int i = 0; i < m_ActiveModes.size(); i++)
    {
      AE_DSP_ADDON addon;
      if (CActiveAEDSP::GetInstance().GetAudioDSPAddon(m_ActiveModes[i]->AddonID(), addon))
      {
        std::string label;
        switch (m_ActiveModes[i]->ModeType())
        {
          case AE_DSP_MODE_TYPE_INPUT_RESAMPLE:
            group = AddGroup(category, 15087, -1, true, true);
            label = StringUtils::Format(g_localizeStrings.Get(15082).c_str(), m_ActiveStreamProcess->GetProcessSamplerate());
            break;
          case AE_DSP_MODE_TYPE_OUTPUT_RESAMPLE:
            group = AddGroup(category, 15088, -1, true, true);
            label = StringUtils::Format(g_localizeStrings.Get(15083).c_str(), m_ActiveStreamProcess->GetOutputSamplerate());
            break;
          case AE_DSP_MODE_TYPE_MASTER_PROCESS:
            group = AddGroup(category, 15084, -1, true, true);
            label = g_localizeStrings.GetAddonString(addon->ID(), m_ActiveModes[i]->ModeName());
            break;
          case AE_DSP_MODE_TYPE_PRE_PROCESS:
            if (!foundPreProcess)
            {
              foundPreProcess = true;
              group = AddGroup(category, 15085, -1, true, true);
            }
            label = g_localizeStrings.GetAddonString(addon->ID(), m_ActiveModes[i]->ModeName());
            break;
          case AE_DSP_MODE_TYPE_POST_PROCESS:
            if (!foundPostProcess)
            {
              foundPostProcess = true;
              group = AddGroup(category, 15086, -1, true, true);
            }
            label = g_localizeStrings.GetAddonString(addon->ID(), m_ActiveModes[i]->ModeName());
            break;
          default:
          {
            label += g_localizeStrings.GetAddonString(addon->ID(), m_ActiveModes[i]->ModeName());
            label += " - ";
            label += addon->GetFriendlyName();
          }
        };
        m_ActiveModesData[i].CPUUsage = StringUtils::Format("%.02f %%", m_ActiveModes[i]->CPUUsage());

        MenuHookMember menu;
        menu.addonId = -1;

        AE_DSP_MENUHOOKS hooks;
        m_ActiveModesData[i].MenuListPtr = -1;
        if (CActiveAEDSP::GetInstance().GetMenuHooks(m_ActiveModes[i]->AddonID(), AE_DSP_MENUHOOK_INFORMATION, hooks))
        {
          for (unsigned int j = 0; j < hooks.size(); j++)
          {
            if (hooks[j].iRelevantModeId != m_ActiveModes[i]->AddonModeNumber())
              continue;

            menu.addonId                  = m_ActiveModes[i]->AddonID();
            menu.hook.category            = hooks[j].category;
            menu.hook.iHookId             = hooks[j].iHookId;
            menu.hook.iLocalizedStringId  = hooks[j].iLocalizedStringId;
            menu.hook.iRelevantModeId     = hooks[j].iRelevantModeId;
            m_Menus.push_back(menu);
            m_ActiveModesData[i].MenuListPtr = m_Menus.size()-1;
            label += " ...";
            break;
          }
        }
        m_ActiveModesData[i].MenuName = label;

        std::string settingId = StringUtils::Format("%s%i", SETTING_STREAM_INFO_MODE_CPU_USAGE, i);
        AddInfoLabelButton(group, settingId, 15041, 0, m_ActiveModesData[i].CPUUsage);
      }
    }
  }
}