えんでぃの技術ブログ

えんでぃの技術ブログ

ネットワークエンジニアの視点で、IT系のお役立ち情報を提供する技術ブログです。

Linux で音が出ないときの対処法

speaker-icon

お伝えしたいこと

Linux では、しばしば 音が出ない... といったトラブルが発生します。
原因は非常にたくさんあり、正確に全てを切り分けることは困難を極めます。

今回は、私が NUC10にFedoraを導入したときに、イヤホンジャックから音が出ず、マイクも使えない問題を解消した 経験を元に、トラブル解消に役に立つ情報を紹介したいと思います (もちろんNUC10以外の方にも役立ちます)。

トラブルシューティングの記事なので、思考の過程も記載したので記事が長くなっていますが、ご了承ください。。
ただ、音声周りの問題は根が深いようですので、実際にトラブル踏んでしまった方はこの記事と同様に原因を切り分けて行くのが良いかと思います。

本記事の解説中に、ALSAPulseAudioといった専門用語を連発します。
これらについて先に知っておきたい方は、先に(参考) PulseAudioって何?を読んでみてください。

記事内リンク

この記事で紹介している解決方法は、以下の2点です。

マイク・スピーカーなどのハードウェアが認識されないトラブルに対して、snd_hda_intel の modelオプションを設定することで解決する手順は、対策に書いてあります。

ハードウェアが認識されているが単純に音が出ない場合は、先に音量設定を確認したほうが良いと思います。
GUIサウンド設定はもちろんのこと、よりデバイス寄りのレイヤーで動いているALSAやPulseAudioの音量設定も確認したほうが良いと思います (特にDebian系の方)。
ALSAやPulseAudioの音量設定の確認・修正方法については、(参考) その他の不具合原因として考えられるものをご覧ください。

環境

項目 詳細
PCモデル NUC10i5FNH
コーデックモデル Realtek ALC256
ディストリビューション Fedora 32 Server
カーネルバージョン 5.8.10-200

何が起こったか

イヤホンマイクを挿しても音が出ません。
マイクは音を拾っている...と思いきや、これもイヤホンマイクではなくPC本体に内蔵されたマイクが反応していただけでした。
上記のPC内蔵マイク以外にも、Bluetoothでペアリングしたスピーカーも正しく動作して音を出してくれました。

つまり、イヤホンジャック周りのスピーカーやマイクだけがまともに動かない状態でした。
他のハードウェアはうまく動いています。

結論を言うと、今回のトラブルの原因はLinuxサウンドドライバ (snd_hda_intel) に対する model というオプションの設定不足でした。

切り分け

デスクトップのサウンド設定を確認してみる

Cinnamon Desktop のサウンド設定を開いてみます。
下図のように右下のスピーカーアイコンから Sound Settings を開きます。
または、左下のMenu から sound と検索しても見つかります。
もちろん、system-settings (System Settings) から探しても良いです。

sound1

Output のタブ (ヘッドホンやスピーカー) を確認すると、Dummy Output と表示されます。
経験上、Output可能なデバイスが一つも検出されていないときに Dummy と表示されるようです。
イヤホンマイクを挿していてもこの表示が出るのですが、本来であれば Headphones とでも出てほしいところです。
つまり今回のケースでは、スピーカーやヘッドホンなどのデバイスが正しく認識されていないことがわかりました。
※更に厳密にいうと、NUC10というPCのイヤホンジャックの先にあるサウンドカードが正しく認識されていません

sound2

Input のタブ (マイク) を確認すると、Internal Microphone と表示されています。
これはイヤホンマイクではなく、PC内蔵のマイク (別のハードウェア) です。
使っているPCによっては、こちらも Dummy Input と出ると思います。
今回のケースではイヤホンマイクを挿しているのですが、PC内蔵のマイクしか認識されていないので、ここも何だかおかしいです。

sound3

PulseAudioのサウンド設定を見てみる

pavucontrolのインストール

PulseAudio のリアルタイムの設定変更は pacmd というコマンドラインツールでも可能なのですが、GUIツールを使ったほうが圧倒的にお手軽でオススメです。
というわけで、まずはGUIツールを入れます。

sudo dnf install pavucontrol

この先 pavucontrol ベースで見ていきます。
対応するpacmdコマンドを知りたい方は、(参考) 回避策をお読みください。

pavucontrolによる設定確認

pavucontrolは、デスクトップのMenu から PulseAudio Volume Control を検索して実行するか、pavucontrol コマンドを実行することで起動できます。

では、pavucontrol を起動し、Configurationタブを開いて設定を確認してみます (CLIでは pacmd list-cards 相当)。
私の環境では、Analog Stereo Input と出てきました。
トラブっている環境によっては、 off と出てきます。

sound3_2

実は、ここの設定もおかしいです。
音声の Input (入力) は、マイクなどを表します (デバイスからPCへの音声データ入力、という意味)。
Input の指定では、マイクから音を拾えますが、スピーカーから音を出すことはありません。
本来は、ここが Duplex という設定であるべきです。
Duplex = Input + Output です。音声入力 (マイク) と音声出力 (スピーカー/イヤホン) を両方使いたい場合は、Duplex が適用されている必要があります

上記画像のプロファイル名をクリックし、Duplex や Inputの部分がどうなっているかを確認してみましょう。

profile_unavailable

(Unavailable) と表示されています。。
Linux Kernel ではデフォルトでjack_detect が有効になっており、イヤホンジャックの抜き挿しを検知できる仕組みになっています。
ここでUnavailable と表示されているのは、イヤホンジャックに物理的に何も接続されていないか、ドライバの動作不具合などによってスピーカーやヘッドホンが正しく認識されていないためです。
今回の場合、イヤホンを挿しているにも関わらず (Unavailable) と表示されているので、やはりトラブルが発生しています。

手動で PulseAudio の Profile を Duplex に変更してみる

(Unavailable) と表示されたプロファイルも、PulseAudio 起動時にこのプロファイルが自動選択されないだけで、手動で選択することができます。
というわけで、手動でプロファイルをDuplexに変えてみます。

sound4

手動でPulseAudio のプロファイルを Duplex に変更したところ、音声が出るようになりました。

↓デスクトップ環境のサウンド設定でも、ヘッドホンがOutputとして正しく認識されています。

sound6

↓ただ残念ながら、Inputのタブではイヤホンマイクは認識されていません。
今回はPulseAudioのProfileをInputからDuplex (Input+Output) に変えただけなので、Input側が改善していないのは予想通りです。

sound3

原因

ここまでの切り分けで原因がはっきりしてきました。

  • イヤホンジャックにヘッドホンやスピーカーを挿しても、デバイスが正しく認識されていない (何らかの原因でjack_detectがうまく働いていない?)
  • PulseAudio側のProfile自動選択に影響し、本来Duplexが選択されるべきところがInputのみになってしまった
    • Duplexを手動選択することでOutputデバイス (イヤホン) は正しく利用できる状態になった
    • しかし、Inputデバイス (イヤホンマイク) は改善されなかった

完全に対処するには、「デバイスが正しく認識されていない」状態をどうにかする必要があります。
「デバイスの認識」と言えばドライバかなと思い調べたところ、今回は運良くヒットしました。
詳細は次の(参考) カーネルのドキュメント抜粋に譲りますが、要約すると以下のようになります。

  • Linuxサウンドドライバは、サウンドカードがIntel製か他社製かに関わらず必ず snd-hda-intel である
  • HDA (High-Definition Audio) の構成要素は、コントローラチップとコーデックチップである
  • コントローラチップは、多くの場合正しく動作する
  • 一方、 コーデックチップはBIOSが壊れていたり、ベンダー固有の実装が必要だったりの理由で、デフォルトの構成では動作しないことが多い
    • ドライバ関連のトラブルの大半がコレ
  • これらの問題を解消するためには、ドライバーに model というオプションを記載する必要がある
    • model は fixup とも呼ばれます
  • model 名はプリセットされたもの。モデルの選択肢はカーネルバージョンアップのたびに増える (はず)
  • 現在搭載しているコーデックチップのモデルを調査し、動きそうな「モデル」を適用して動かしてみるのが主な切り分け方法
  • 動作するモデルがない場合の選択肢は、主に以下

そして、私のパソコン (NUC10i5FNH) の場合は、運良く動作するモデルがあった ということになります。
次のセクションである対策に続きます。

(参考) カーネルのドキュメント抜粋

上記のサウンドドライバとモデルの話の情報源を示すため、Linux Kernel Documentation から一部内容を抜粋しました。
情報ソースが気になる方は、以下をクリックして読んでみてください。
訳もつけておきました。

対策

概要

対策方法ですが、snd-hda-intel ドライバに model というパラメータを渡すことになります。
設定ファイルを書いて再起動すれば反映されます。
再起動後、サウンド設定を開いて問題が解消されたかどうかを確認します (イヤホンマイクが認識され、音が出たりマイクの音に反応していれば成功)。 モデル名を変えつつ何度も試行錯誤します。
かなり根気のいる作業になります。。。

とはいえ、私は2候補しか選択肢がなく、2つ目で運良く解決しました。

以下に詳しい手順を記載します。

コーデックチップの model を特定する

grep -i codec /proc/asound/card*/codec#* を実行することで特定できます。

[stopendy@pc ~]$ grep -i codec /proc/asound/card*/codec#*
/proc/asound/card0/codec#0:Codec: Realtek ALC256
/proc/asound/card0/codec#2:Codec: Intel Kabylake HDMI
[stopendy@pc ~]$ 

私の環境ではコーデックチップが2つあるので、2つ表示されたようです。
「どちらが目的のコーデックなのか」ですが、正直なところ勘...でしょうか?

私の場合はイヤホンジャックを直したいので、消去法で ALC256 になります。
HDMI (画面接続用規格) ではないですからね。
ちなみにRealtek はハードウェアベンダー名です。

参考までに、似たような情報を得られるコマンド出力も貼っておきます。
こちらはハードウェアベンダー名とモデル名が別々に表示されます。

[stopendy@pc ~]$ cat /sys/class/sound/hwC*D*/vendor_name
Realtek
Intel
[stopendy@pc ~]$ cat /sys/class/sound/hwC*D*/chip_name
ALC256
Kabylake HDMI
[stopendy@pc ~]$ 

さて、モデル名が ざっくり ALC256と判明しました。
ALC256は、残念ながらドライバに渡せる model オプションとは別の値です
この文字列をヒントに、適したmodel を手動で試していく必要があるのです。。。

model 名を探す

下記URLがモデル名の一覧です。

https://www.kernel.org/doc/html/latest/sound/hd-audio/models.html

URLに latest と記載があるとおり、あくまで最新版のカーネルに関するリスト です。
不安な方は uname -rカーネルバージョンを確認の上、正しいバージョンのドキュメントを参照してください。

提供されているドキュメントのバージョンはこちらから確認できます。
URLの中からlatestの部分を環境に合わせたバージョン番号に置き換えてご確認ください。

さて、今回探したいのは ALC256 なわけですが、alc256 で検索すると以下の2つがヒットします。

Intel NUCi5FNHASUSではないので不安がよぎりますが、運良く alc256-asus-mic でうまく動作したので、今回はそちらを使います。
本当に運が良かったです。
パッチ書いてくれた方、ありがとうございます。

model オプションを反映する

Linuxにおいて、ドライバはカーネルモジュールとして実装されるそうです (lsmod | grep -E 'snd_hda_intel|snd-hda-intel' で確認できます)。
そして、カーネルモジュールにオプションを与えるには、/etc/modprobe.d/*.conf に記述した上でOS再起動してやればOKです。

構文については man modprobe.d を参照ですが、options modulename option=value といった形式で記載していきます。
コンフィグファイルは新しいものを作るのが良いと思います。
新規で作ったことがわかりやすいので。

ということで、今回は /etc/modprobe.d/stopendy.conf に以下のファイルを作ります。
(ファイル名は各自変えてくださいね。また、ファイル書き換えにはroot権限が必要です)

# This file is manually made by stopendy.
######################################################

# add an option to specify a codec model to prevent the jack_detect issue
options snd_hda_intel model=alc256-asus-mic

# で始まる行はコメントなので、省略しても結構です。
また、model=の後の文字列は環境によって異なるので、先の手順で特定したモデル名で各自置き換えてください (NUC10の方は上記で動くはず!)。

再起動して設定を反映します。

reboot

直ったことを確認する

再起動完了したら、動作確認します。
OS再起動後でも良いので、ヘッドセットなどをイヤホンジャックに挿しておいてください。
jack_detection があるので、挿していないと認識されません。

デスクトップのサウンド設定

Menuから Sound で検索し、デスクトップ環境のサウンド設定を開きます。

Input、Output のタブを確認すると、イヤホンマイクがそれぞれの画面で認識されていることがわかります。
また画像では表現できませんが、実際にこの環境で オンライン飲み会 音声入出力ができることも確認できました。

sound6

sound7

PulseAudioのサウンド設定

続いて、Menu から PulseAudio Volume Control (pavucontrol) を起動し、Configuration タブを開きます。
下記画像のとおり、OS起動後に自動で Analog Stereo Duplex が選択されています。
バイスが正しく認識されているので、Unavailable になったりはしません。

sound5

コマンドの場合、pacmd list-cards で確認できます。

長くなりましたが、ドライバのモデル指定により、今回のイヤホンジャックから音が出ず、マイクも使えない問題が無事解決しました!

(参考) 回避策

上記対策が実施できない方向けの回避策です。
必要な方のみ 以下の手順を実施ください。

最新のパソコンを導入した場合、残念ながらドライバのモデルが提供されておらず、上記で対応できないケースもあると思います。
そんな時のために、ワークアラウンドとして デスクトップログイン後に自動でPulseAudioのプロファイルを指定する方法 を紹介します。

ただこの方法、手動で PulseAudio の Profile を Duplex に変更してみるにも記載があったとおり、完璧ではありません。
私の環境では、イヤホンジャックに挿したイヤホンから音は出ました。
ただ、イヤホンマイクは相変わらず認識されないままでした。

それでもやらないよりはマシなので、新しいmodel が追加されるまでの間、こちらでやり過ごすのも手かなと思います。

使うコマンド

pacmd set-card-profile <サウンドカードのIndex番号、またはサウンドカード名> <プロファイル名> です。
pacmd はPulseAudio の設定を変更するCLIツールです。

ただ、このコマンドはデスクトップ環境に再ログインするたびに設定が消えてしまいます。
なので、このコマンドをGUIログインのたびに実行するように設定します。
Windowsでいうところの「スタートアップ」ですね。
XDG (X Desktop Group) 互換のデスクトップ環境であれば、~/.config/autostart/*.desktop ファイルに必要な情報を記述すればOKです。

サウンドカードのIndex番号を調べる

pacmd list-cards | grep -E 'index:|name:|device.*description|device.vendor.name|device.string' コマンドで確認します。

以下の出力を例にすると、Indexが0、カード名が alsa_card.pci-0000_00_1f.3 です。
コマンドにはこれらのどちらかを指定すれば良いのですが、alsa_card.pci-0000_00_1f.3 の方が確実な気がします。
Index番号は何かのきっかけで変わる可能性があるかも...と思いました。

[stopendy@pc ~]$ pacmd list-cards | grep -E 'index:|name:|device.*description|device.vendor.name|device.string'
    index: 0
    name: <alsa_card.pci-0000_00_1f.3>
        device.vendor.name = "Intel Corporation"
        device.string = "0"
        device.description = "Built-in Audio"
[stopendy@pc ~]$ 

指定したいプロファイル名を調べる

pavucontrol のプロファイル名表示を頼りに探します。
例えば Analog Stereo Duplex (ちなみにこれはProfile Description) に固定したい場合は、以下のコマンドでプロファイル名を調べられます。

[stopendy@pc ~]$ pacmd list-cards | grep 'Analog Stereo Duplex'
        output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (priority 6565, available: no)
[stopendy@pc ~]$ 

上記サンプルでは、 output:analog-stereo+input:analog-stereo がプロファイル名になります。
長い。

コマンドを手動実行し、プロファイルを変更してみる

上記の結果より、今回は以下のコマンドを実行すれば変更できることがわかりました。

pacmd set-card-profile alsa_card.pci-0000_00_1f.3 output:analog-stereo+input:analog-stereo

PulseAudio Volume Control (pavucontrol)Configuration タブを確認し、コマンド実行によってプロファイルが変わったことを確認できればOKです。

デスクトップログイン時に自動実行するよう登録する

まずはCinnamon Desktop におけるやり方から紹介します。
他の環境でもできるよう、CLIでのやり方も最後に簡単に紹介します。

左下のMenu から Startup Applications を起動します。
PulseAudio が自動起動に登録されていました。
ペンのアイコンから試しに開いてみたのが以下の画像です。
Startup Delay が 0になっていますね。
これは、デスクトップログイン直後に即時起動するという意味です。
ここを1以上にすると、秒単位で実行タイミングを遅延させることができます。

startup1

では、先ほど動作確認した PulseAudio のプロファイルをセットするコマンドをスタートアップに登録しましょう。
+ のアイコンからプログラムを追加します。
そして、以下のように入力します。

startup2

項目
Name Custom_pacmd_set_card_profile
Command pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
Comment Set PulseAudio card profile manually. This should be executed after PulseAudio starts
Startup delay 1

Command は環境に合わせて変更してください。
NameComment はわかりやすいように記載すれば良いと思います。
Startup delay は、1以上にしてください。PulseAudio 起動よりも後に実行してほしいためです。

上記の通り登録すると、設定ファイルが以下のパスに生成されます。
デスクトップ環境に Startup Application 相当の機能がない場合は、以下のファイルを直接作っても同じだと思います。

[stopendy@pc ~]$ cat ~/.config/autostart/Custom_pacmd_set_card_profile.desktop 
[Desktop Entry]
Type=Application
Exec=pacmd set-card-profile 0 output:analog-stereo+input:analog-stereo
X-GNOME-Autostart-enabled=true
NoDisplay=false
Hidden=false
Name[en_US]=Custom_pacmd_set_card_profile
Comment[en_US]=Set PulseAudio card profile manually. This should be executed after PulseAudio starts
X-GNOME-Autostart-Delay=2
[stopendy@pc ~]$ 

余談ですが、既存のスタートアップファイルはユーザー個別ではなくシステムワイドな設定として、/etc/xdg/autostart/*.desktop に配置されています。

設定が完了したら、再ログインの上でPulseAudio Volume Control (pavucontrol)Configuration タブを確認し、Profile が自動設定されていることを確認しましょう。
CLIの場合は、pacmd list-cards で確認できます。

(参考) その他の不具合原因として考えられるもの

バイスは認識されているんだけど、何故か音が出ない。
デスクトップの音量設定もミュートじゃないのに。

そういった方はこちらを参考にしてみてください。

私は今回踏んでいませんが、世の中一般としては以下の切り分けも必要だと言われています。

  • ALSAがミュート、または音量ゼロになっていないか?
  • PulseAudioでミュート、または音量ゼロになっていないか?

それぞれ確認と修正方法を紹介します。

ちなみに他の掲示板で「ユーザーを audio,pulse,pulse-access といったグループに所属させないとダメ」といったことが書かれているのを見たことがありますが、少なくとも私が使っているFedora 32 + Cinnamon Desktop では関係ありませんでした。
私のメインユーザーは上記グループに所属していませんが、全く不具合は起こっていません (追加しても音が出ない問題は解決しませんでした)。

ALSAの音量確認

alsamixer コマンドを実行します。
すると以下の画面に移動します。

alsamixer_1_master

左上にPulseAudio と書かれているので、ここを弄るとシステム全体に影響します。
操作方法は以下の通りです。

入力キー 意味
h ヘルプ表示
w 音量増加
x 音量減少
操作対象の音量バーの切り替え
q 左耳の音量増加
e 右耳の音量増加
z 左耳の音量減少
c 右耳の音量減少
m ミュート、ミュート解除
F6s サウンドカードの切り替え
Esc 画面を閉じる (設定は即時反映のため保存は不要)

F6キーを押して、サウンドバイスごとの音量も確認します。
↑↓キーでHDA Intel PCH を選択し、Enter キーで確定します。

alsamixer_3_select_sound_card

alsamixer_4_realtek

上記に示した画像が正しく動いている構成の例です。

音量バー、及び音量を表すオレンジ色の数字がゼロや小さい値ではないことを確認してください。音量が小さい場合は↑キーなどで大きくしてみてください。

また、ミュートになっていないことも確認してください。
音声バーの下の緑色の「00」の部分が「MM」となっている場合は、mキーでミュートを解除してみてください。
上記画像で、左から3番目の「S/PDIF」の部分ががミュートになっているのでご参考までに。

PulseAudio の音量確認

PulseAudio の設定は PulseAudio Volume Control (pavucontrol) で行うのが楽です。
PulseAudio Volume Control を起動し、各タブで音量がミュートになっていないか、音量が小さすぎないかを確認します。

例として、Input (スピーカー) のタブの画像で説明します。
下記画像の赤枠部分を確認し、画像のようにミュートになっていないことと、音量がゼロではないことを確認してみてください。

pavu_input

コマンドの場合は、 pacmd list-sinks でスピーカーなどのOutputタブ相当の情報が、pacmd list-sources でマイクなどのInputタブ相当の情報が確認できます。

(参考) 切り分けに役立ちそうなコマンドの列挙

今回私が色々調べた中で役に立ちそうなコマンドをここに書いておきます。
/proc/sys を含むコマンドはLinuxカーネルaplayALSApacmdはPulseAudioのコマンドです。

  • 認識されているハードウェアのメーカーやモデルなどの情報
    • sudo lspci -v | grep Audio -A10
    • grep -i codec /proc/asound/card*/codec#*
    • cat /sys/class/sound/hwC*D*/vendor_name
    • cat /sys/class/sound/hwC*D*/chip_name
    • cat /sys/class/sound/hwC*D*/modelname
    • aplay -l | grep ^card
  • ALSAの音量、ミュート設定
    • alsamixer
  • PulseAudioの音量、ミュート設定 (sources = input = マイクなど)
    • pacmd list-sources | grep -E 'index:|name:|state:|^\s*volume:|muted:|device.*description|device.vendor.name|device.string|alsa.id'
  • PulseAudioの音量、ミュート設定 (sinks = output = スピーカーなど)
    • pacmd list-sinks | grep -E 'index:|name:|state:|^\s*volume:|muted:|device.*description|device.vendor.name|device.string|alsa.id'
  • PulseAudioのプロファイルの定義が書いてある場所
    • grep 'Analog Stereo Duplex' /usr/share/pulseaudio/alsa-mixer/profile-sets/*

(参考) PulseAudioって何?

こちらにわかりやすく説明されています。
以上!

mickey-happygolucky.hatenablog.com

...なのですが、本文でも超簡単に書いておきます。

PulseAudio とは、音声系の入出力を集約管理する音声サーバーです。
ブラウザなどで音楽を聞いているとき、 ブラウザ > PulseAudio > ALSA > カーネル(ドライバ) > ハードウェア (スピーカー、ヘッドホン) に届きます。
マイクで音を拾う際は逆向きの経路です。マイク > カーネル > ALSA > PulseAudio > 録音ソフトなど ですね。

ALSAとPulseAudio の関係性は、上記URLでわかりやすく説明されているので良かったら読んでみてください。
ざっくり、アプリ <--> PulseAudio <--> ALSA <--> カーネル <--> デバイス のパスで音声データがやり取りされており、どこか1箇所でもトラブっていたら音声のトラブルが起きる」といったイメージで良いのかなと思います。
もちろん構成次第で例外はあると思うのですが、デフォルトの構成であれば上記から大きく外れることはないでしょう。

上記ブログでは、より具体的に図を交えてわかりやすく解説されています。
気になる方はぜひ立ち寄ってみてください。
オススメです。

まとめ

今回はコーデックのモデルを設定することで、NUC10で音が出ない問題を解消しました。
その派生として、音が出ない問題を切り分ける中で得られた知見を共有しました。

皆さんもトラブった場合は、以下の部分を中心に確認してみると良いと思います。

  • ALSA、PulseAudio それぞれにおいてハードウェアが認識されているか?
  • サウンドドライバのモデルを正しく指定しているか? (デフォルトでは動かないことが多い)
  • サウンドミキサーがミュートになっていないか? (掲示板の事例を見る限り、このケースは最近少ないかも)

特に、サウンドドライバは、モデルを指定しないと多くの場合動作してくれない というのが衝撃でした。。

Linux PC構築関連リンク集

endy-tech.hatenablog.jp