Аудио HDMI на системе Оптимус

У Robert Martin есть превосходное статья о принципе замены Лисков . Это обсуждает тонкие и not-so-subtle пути, которыми может быть нарушен принцип.

Некоторые соответствующие части статьи (отмечают, что второй пример в большой степени сжат):

А Простой Пример Нарушения LSP

Одно из самых явных нарушений этого принципа является использованием Информации о типах во время выполнения (RTTI) C++ для выбора функции, основанной на типе объекта. т.е.:

void DrawShape(const Shape& s)
{
  if (typeid(s) == typeid(Square))
    DrawSquare(static_cast(s)); 
  else if (typeid(s) == typeid(Circle))
    DrawCircle(static_cast(s));
}

Очевидно эти DrawShape функция плохо формируется. Это должно знать о каждой возможной производной Shape класс, и это должно быть изменено каждый раз, когда новые производные Shape создаются. Действительно, многие просматривают структуру этой функции как анафема на Объектно-ориентированное проектирование.

Квадрат и Прямоугольник, Более тонкое Нарушение.

Однако существуют другие, намного более тонкие, способы нарушить LSP. Рассмотрите заявление, которое использует Rectangle класс, как описано ниже:

class Rectangle
{
  public:
    void SetWidth(double w) {itsWidth=w;}
    void SetHeight(double h) {itsHeight=w;}
    double GetHeight() const {return itsHeight;}
    double GetWidth() const {return itsWidth;}
  private:
    double itsWidth;
    double itsHeight;
};

[...] Предполагают, что однажды пользователи требуют способности управлять квадратами в дополнение к прямоугольникам. [...]

Очевидно, квадрат является прямоугольником для всех нормальных намерений и целей. Так как отношения ISA содержат, логично смоделировать Square класс, как получаемый от Rectangle. [...]

Square наследуется SetWidth и SetHeight функции. Эти функции являются совершенно несоответствующими для Square, так как ширина и высота квадрата идентичны. Это должно быть значительной подсказкой, что существует проблема с дизайном. Однако существует способ обойти проблему. Мы могли переопределить SetWidth и SetHeight [...]

, Но рассмотреть следующую функцию:

void f(Rectangle& r)
{
  r.SetWidth(32); // calls Rectangle::SetWidth
}

, Если мы передаем ссылку на Square объект в эту функцию, эти Square, объект будет поврежден потому что высота won’t быть измененным. Это - четкое нарушение LSP. Функция не работает на производные своих аргументов.

[...]

2
задан 19.05.2020, 04:57

1 ответ

Мне удалось получить аудиовыход HDMI, работающий над моим ноутбуком с "NVIDIA Corporation GF116M [GeForce GT 555M/635M]" GPU, с помощью драйвера Nvidia и главный Nvidia. Процесс является довольно замысловатым, и необходимо выполнить его после каждой перезагрузки. Я записал сценарий, который автоматизирует процесс как можно больше. Его комментарии объясняют, что это делает. ( Редактирование: , Если Вам не нравится выполнять сценарий, можно также выполнить процедуру, описанную здесь: https://askubuntu.com/a/660910/73753)

#!/bin/bash

# Check if we are executing as root
if [ $UID != 0 ]; then
    echo "This script must be run as root."; exit
fi

# The nvidia driver cannot be loaded while we are configuring the GPU.
# Check whether the nvidia kernel is loaded:
if grep nvidia /proc/modules; then
    # It is. Check if we have HDMI audio
    if lspci | grep 01:00.1; then
        # Yes, so we are already done.
        echo "The following list should contain HDMI audio devices"
        aplay -l
        alsa reload
        echo "--> You are done!"; exit
    else
        # No, disable output through nvidia:
        prime-select intel
        echo "Please reboot. Afterwards rerun this script."; exit
    fi
fi

# Make sure that the GPU is powered
if ! lspci -H1 | grep 01:00.0; then
    if ! grep OFF /proc/acpi/bbswitch; then
        echo "ERROR: GPU is listed in lspci -H1, but bbswitch thinks it is off"; exit 1
    fi
    # Turn on the discrete GPU (to get it listed in `lspci -H1`)
    echo ON > /proc/acpi/bbswitch
    if ! grep ON /proc/acpi/bbswitch; then
        echo "ERROR: Failed to turn on the GPU"; exit 1
    fi
fi

# Check if the GPU's audio chip is powered
if ! lspci -H1 | grep 01:00.1; then
    echo "Suspend the pc and resume it again. This will turn on the audio chip on the discrete GPU. Afterwards rerun this script."; exit
fi

# The output of 'lscpi -H1' should now contain 2 lines similar to:
# 01:00.0 VGA compatible controller: NVIDIA Corporation GF116M [GeForce GT 555M/635M] (rev a1)
# 01:00.1 Audio device: NVIDIA Corporation GF116 High Definition Audio Controller (rev a1)

# Now we need to rescan for the GPU such that the audio chip is found as well
if lspci | grep 01:00.0; then
    # Now we 'unmount' the GPU
    # the nvidia driver is not loaded, otherwise this step would eventualy cause your computer to freeze/hang
    echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove
    # Wait a bit
    sleep 1
    # Check if this succeeded
    if ! lspci | grep 01:00.0; then
        echo "ERROR: Failed to remove the GPU (or so it seems, you can try again)"; exit 1
    fi
fi

if ! lspci | grep 01:00.0; then
    # Rescan
    echo 1 > /sys/bus/pci/rescan
    if ! lspci | grep 01:00.1; then
        echo "ERROR: Rescan did not find the audio chip"; exit 1
    fi

    # The output of 'lspci' should now contain 2 lines similar to:
    # 01:00.0 VGA compatible controller: NVIDIA Corporation GF116M [GeForce GT 555M/635M] (rev a1)
    # 01:00.1 Audio device: NVIDIA Corporation GF116 High Definition Audio Controller (rev a1)

    # Now we are ready to restart X11 using the nvidia driver
    prime-select nvidia
    echo "Please log out and in again. Afterwards rerun this script."; exit
fi

echo "ERROR: Something went wrong"; exit 1
4
ответ дан 19.05.2020, 04:58
  • 1
    Или случайно или это было удачное предположение. Это имеет смысл, хотя, поскольку это в основном выполняет код ACPI для выключения и включения GPU снова. Как только я заметил, что это заставило 01:00.1 появиться в выводе lspci, я все еще должен был выяснить, как заставить его появиться без загрузка драйвера Nvidia сначала. Я предполагаю, что провел 10 взятых на пробу часов и ошибка, пока я не закончил с этим. К сожалению, несколько месяцев спустя я сделал обновление распределения, и оно прекратило работать. – daveslab 19.05.2020, 04:58
  • 2
    Я использовал сценарий на Ubuntu 16.04 и после того, как это попросило, чтобы я вышел из системы, и входить в систему я убрал журнал и разрушенный ноутбук.:-( – dasilvj 19.05.2020, 04:58
  • 3
    Какое-либо новое решение на этом? Сценарий больше не работает над Ubuntu 16.04 – Michael Borgwardt 19.05.2020, 04:59
  • 4
    Это работает отлично. Как Вы выясняли, чтобы приостановить и перезапустить?! Так или иначе мне был нужен один заключительный шаг, чтобы заставить HDMI аудиовыход обнаруживаться в " Звуковой Settings". wiki.archlinux.org/index.php/PulseAudio/… – JesperE 19.05.2020, 04:59

Теги

Похожие вопросы