注意と問題
動画でも音楽ファイルからでも音飛びする問題が発生しています。
あれこれ尽くしたことを残しておきます。
ここで行ったことを試す場合は全て自己責任でお願いします。
結論
結果から言うと90%くらい解決。
Skypeでの音声チャットはそこそこ
環境
Windows10とUbuntu18.04でデュアルブートしています。
セキュアブートはオフにしています。
ECM-PCV80UのUSBオーディオボックスをスピーカーに繋いで再生しています。
https://www.sony.jp/microphone/products/ECM-PCV80U/
CPU: Intel64 Family 6 Model 60 Stepping 3 GenuineIntel ~3201 Mhz
MB: ASUS All Series H97-PRO
Memory: 16GB
Video: NVIDIA GeForce GT 640
参考
Ubuntu 18.04 LTS BetaでUSB DACの音飛びを直しました(改)
https://blog.goo.ne.jp/takuminews/e/00820ce12a4c98d0fdeb27c456edb253
まず試したのがここです。
USBポートを入れ差して10ポートあるのですが全ポート試しました。が!ダメ!
$ cat /proc/asound/modules
0 snd_hda_intel
1 snd_hda_intel
2 snd_usb_audio
デフォルトだとこんな感じです。このsnd_usb_audioをオーディオデバイスのロード順位0にします。
以下のoptions3行をファイルの一番下に追加。
$ sudo vim /etc/modprobe.d/alsa-base.conf
~省略
options snd slots=snd_usb_audio,snd_hda_intel
options snd_usb_audio index=0
options snd_hda_intel index=1
反映させます。
$ pulseaudio -k
$ pulseaudio --start
$ cat /proc/asound/modules
0 snd_usb_audio
1 snd_hda_intel
2 snd_hda_intel
優先順位は思い通りになりましたが直りませんでした。
Ubuntuの音声入出力
Ubuntuの音周りの知識がまったくないので少し調査してみることにしました。
まずはここをご参考ください
Linux の Audio 機能をコマンドラインで設定
https://qiita.com/propella/items/4699eda71cd742cba8d3
ALSA と PluseAudio
- ALSA は色んなサウンドカードを統一的に操作出来るようにする仕組み。
- アプリは直接 ALSA を操作しなくても良い。
- あるアプリが ASLA 経由でサウンドカードを操作している間、他のアプリからそのサウンドカードを使えない。
- とはいえ、直接 ALSA を使って音声入出力を行うアプリが存在する。
- PluseAudio は複数のアプリが同時に同時にサウンドカードを使う仕組み。
- お行儀の良いアプリは ALSA ではなく、PulseAudio 経由で音声入出力を行う。
- とはいえ、直接 ASLA を使ってしまうアプリのために仮想サウンドカードの仕組みがある。
ALSAとPluseAudioが肝らしい
PluseAudioのデフォルトの入出力先を確認する
次のコマンドを叩きます。
$ pacmd list-sinks | grep name:
name: <alsa_output.usb-Sony_Corporation_UAB-80-00.iec958-stereo>
name: <alsa_output.pci-0000_00_1b.0.iec958-stereo>
2つありますね。どっちがデフォルトなのでしょうか。
grep なしで叩きます。
indexの前に * がついているので alsa_output.usb-Sony_Corporation_UAB-80-00.iec958-stereo がデフォルトになっていることが分かりました。
自分のデバイスがデフォルトになっていない場合は先程の引用先サイトに書いてあるおまじないを行いコマンドを叩けば変わります。
pacmd list-sinks
2 sink(s) available.
* index: 0
name: <alsa_output.usb-Sony_Corporation_UAB-80-00.iec958-stereo>
driver: <module-alsa-card.c>
flags: HARDWARE DECIBEL_VOLUME LATENCY
state: RUNNING
suspend cause:
priority: 9048
volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 101.46 ms
max request: 17 KiB
max rewind: 17 KiB
monitor source: 0
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
~ 省略
index: 3117
name: <alsa_output.pci-0000_00_1b.0.iec958-stereo>
driver: <module-alsa-card.c>
flags: HARDWARE HW_MUTE_CTRL DECIBEL_VOLUME LATENCY
state: IDLE
suspend cause:
priority: 9038
volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
base volume: 65536 / 100% / 0.00 dB
volume steps: 65537
muted: no
current latency: 100.83 ms
max request: 17 KiB
max rewind: 17 KiB
monitor source: 3119
sample spec: s16le 2ch 44100Hz
channel map: front-left,front-right
~ 省略
私は利用したいデバイスがデフォルトだったので特に直ったとかそいういうのは無かったです。
Ubuntuコミュニティで似た人を探す
たくさんいました。その中で新しめなものをチョイス
Audio stuttering in Ubuntu 18.04
https://askubuntu.com/questions/1044552/audio-stuttering-in-ubuntu-18-04
色々漁っていたら以下のおまじないを書くことによって解決した人もいるらしいです。
snd-hda-intelじゃなくて snd-usb-audioを使ってるんだけど意味あるのかなぁなんて思いつつ
$ sudo vim /etc/modprobe.d/alsa-base.conf
~省略~
# 以下を追記
options snd-hda-intel position_fix=1
気になったのがアンダーバーではなくてハイフン何ですよね。
優先順位の設定のときはアンダーバーだったのに。
どっちでも良いのか、優先順位の場合はアンダーバーじゃないとダメなのか良く分からないです。
もう一つ
$ sudo vim /etc/pulse/default.pa
~省略~
# 以下の行を変更する
load-module module-udev-detect
# 変更後
load-module module-udev-detect tsched=0
こちらはPulseAudioのタイマーベースのスケジューリングという機能をオフにしています。
こいつが動いているといくつかの ALSA ドライバーで問題を発生する可能性が出てくるらしい。
ONじゃないとダメなケースもあるので、うまくいかない場合はtsched=1にしていましょう
早速反映させましょう。
$ pulseaudio -k
$ pulseaudio --start
どうでしょうか?私は上記のパターンを色々試しましたがダメでした。
alsa-base.confのオプションをいじる
enableとmodelがあるっぽいです。こちらも複数のパターン試しました。
ダメでした。
options snd-hda-intel position_fix=1 enable=1 model=ideapad
options snd-hda-intel position_fix=1 enable=1 model=auto
https://github.com/spotify/linux/blob/master/Documentation/sound/alsa/ALSA-Configuration.txt
によると
position_fix は Fix DMA pointer のことらしいです。
(0 = auto, 1 = use LPIB, 2 = POSBUF)
LPIB = Link position in buffer
POSBUF = Position buffer
autoの場合POSBUFが失敗したらLPIBになるらしい
Nvidiaグラフィックドライバを入れる
UbuntuのデフォルトのグラフィックドライバがNouveauというものらしいんですよ。
私のビデオカードはNvidiaなのでNvidiaのドライバをいれたいじゃないですか。
Ubuntuコミュニティのログを漁ってるとひょんなことから直るケースってのがあったりするので私もそれにあやかろうと試してみました。
18.04になって簡単になったそうです。
開発メモ その114 Ubuntu 18.04でNvidia Driverをインストールする
https://taktak.jp/2018/05/01/2974
まずビデオカードを調べます。
$ ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd00000FC1sv000010DEsd0000093Cbc03sc00i00
vendor : NVIDIA Corporation
model : GK107 [GeForce GT 640]
driver : nvidia-340 - distro non-free
driver : nvidia-driver-390 - distro non-free recommended
driver : xserver-xorg-video-nouveau - distro free builtin
#入っていないことを確認。何やらエラーっぽいのがでます。
$ nvidia-smi
~省略~
# 自動でインストール 自分で探したりしなくて良いのは助かる!
$ sudo ubuntu-drivers autoinstall
このままrebootしてもよいのですが、競合して面倒になったら発狂ものなので、こちらを参考にNouveauドライバの無効化をします
Ubuntu 16 / 18 に GTX 1080Ti / RTX2080 の ドライバとCUDAのインストール
https://qiita.com/sasayabaku/items/2323a2c501e58c0621b6
# nouveauがあるか確認
$ lsmod | grep -i nouveau
# 以下のファイルを作ってNOUVEAUをブラックリストに入れてモジュールを停止させる
$ sudo vim /etc/modprobe.d/blacklist-nouveau.conf
blacklist nouveau
options nouveau modeset=0
# カーネルモジュールの再読込
$ sudo update-initramfs -u
# 再起動
$ sudo reboot
挙動確認
$ nvidia-smi
Wed Jun 19 21:56:03 2019
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.116 Driver Version: 390.116 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GT 640 Off | 00000000:01:00.0 N/A | N/A |
| 70% 73C P0 N/A / N/A | 636MiB / 978MiB | N/A Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| 0 Not Supported |
+-----------------------------------------------------------------------------+
何か音飛びが少なくなった\(^o^)/
もっと音飛びを無くすために
下記の「Pulseaudio におけるデフォルトのフラグメント・バッファサイズを設定する」を参考にしました。
PulseAudio/トラブルシューティング
https://wiki.archlinux.jp/index.php/PulseAudio/%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0
以下を試しました。
タイマーによるスケジューリングを無効化 (0/4)
オーディオデバイスのパラメータを調べる (1/4)
ミリ秒のフラグメントサイズとフラグメントの数を計算する (2/4)
Pulseaudio の設定ファイルを修正する (3/4)
Pulseaudio デーモンを再起動する (4/4)
$ pactl list sinks
Sink #0
State: RUNNING
Name: alsa_output.usb-Sony_Corporation_UAB-80-00.iec958-stereo
Description: UAB-80 デジタルステレオ (IEC958)
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right
Owner Module: 8
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor Source: alsa_output.usb-Sony_Corporation_UAB-80-00.iec958-stereo.monitor
Latency: 108777 usec, configured 99954 usec
Flags: HARDWARE DECIBEL_VOLUME LATENCY SET_FORMATS
Properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = "USB Audio"
alsa.id = "USB Audio"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "0"
alsa.card = "0"
alsa.card_name = "UAB-80"
alsa.long_card_name = "Sony Corporation UAB-80 at usb-0000:00:14.0-10, full speed"
alsa.driver_name = "snd_usb_audio"
device.bus_path = "pci-0000:00:14.0-usb-0:10:1.0"
sysfs.path = "/devices/pci0000:00/0000:00:14.0/usb3/3-10/3-10:1.0/sound/card0"
udev.id = "usb-Sony_Corporation_UAB-80-00"
device.bus = "usb"
device.vendor.id = "054c"
device.vendor.name = "Sony Corp."
device.product.id = "0686"
device.product.name = "UAB-80"
device.serial = "Sony_Corporation_UAB-80"
device.string = "iec958:0"
device.buffering.buffer_size = "17632"
device.buffering.fragment_size = "4408"
device.access_mode = "mmap"
device.profile.name = "iec958-stereo"
device.profile.description = "デジタルステレオ (IEC958)"
device.description = "UAB-80 デジタルステレオ (IEC958)"
alsa.mixer_name = "USB Mixer"
alsa.components = "USB054c:0686"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-usb"
ポート:
iec958-stereo-output: デジタル出力 (S/PDIF) (priority: 0)
活動中ポート: iec958-stereo-output
形式:
pcm
Sink #711
State: IDLE
Name: alsa_output.pci-0000_00_1b.0.iec958-stereo
Description: 内部オーディオ デジタルステレオ (IEC958)
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 44100Hz
Channel Map: front-left,front-right Owner Module: 9
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor Source: alsa_output.pci-0000_00_1b.0.iec958-stereo.monitor
Latency: 100758 usec, configured 99954 usec
Flags: HARDWARE HW_MUTE_CTRL DECIBEL_VOLUME LATENCY SET_FORMATS
Properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = "ALC892 Digital"
alsa.id = "ALC892 Digital"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "1"
alsa.card = "1"
alsa.card_name = "HDA Intel PCH"
alsa.long_card_name = "HDA Intel PCH at 0xf7130000 irq 28"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "pci-0000:00:1b.0"
sysfs.path = "/devices/pci0000:00/0000:00:1b.0/sound/card1"
device.bus = "pci"
device.vendor.id = "8086"
device.vendor.name = "Intel Corporation"
device.product.id = "8ca0"
device.product.name = "9 Series Chipset Family HD Audio Controller"
device.form_factor = "internal"
device.string = "iec958:1"
device.buffering.buffer_size = "17632"
device.buffering.fragment_size = "4408"
device.access_mode = "mmap"
device.profile.name = "iec958-stereo"
device.profile.description = "デジタルステレオ (IEC958)"
device.description = "内部オーディオ デジタルステレオ (IEC958)"
alsa.mixer_name = "Realtek ALC892"
alsa.components = "HDA:10ec0892,10438613,00100302"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
ポート:
iec958-stereo-output: デジタル出力 (S/PDIF) (priority: 0)
活動中ポート: iec958-stereo-output
形式:
pcm
device.buffering.buffer_size = "17632"
device.buffering.fragment_size = "4408"
ここで気づいたのですがバッファーサイズが少ないんじゃね?
とりあえずサイトの書いてあるとおりの計算方法を試してみることに
44100*16 = 705600 ビット毎秒。ステレオなら 1411200 bps
17632/1411200 = 0.0125
4408 /1411200 = 0.0031
0.0125/0.0031 = 4
大体デフォルトと同じになっちゃいましたね
/etc/pulse/daemon.confのファイルを見る
; default-fragments = 4
; default-fragment-size-msec = 25
どこかのサイトでdefault-fragmentsを上げれば音飛び解決するって書いてあったので言われたとおりにしてみます。
$ sudo vim /etc/pulse/daemon.conf
default-fragments = 8
default-fragment-size-msec = 50
$ pulseaudio -k
$ pulseaudio --start
ダメでした。
いっそ、トラブルシューティングのサイトを同じfragment-size-msecにしてやるかと思い下の数値に
default-fragments = 4
default-fragment-size-msec = 125
良くなった気がするけどまだ飛ぶ
最終的にこんな感じになりました
default-fragments = 8
default-fragment-size-msec = 125
125じゃなくても100でも結構良かったです。Google Play Musicでは音飛びは無しに!
マイクの話
ノイズが乗るのでエコー除去・ノイズキャンセルを有効にする
同じくトラブルシューティングより
PulseAudio/トラブルシューティング
https://wiki.archlinux.jp/index.php/PulseAudio/%E3%83%88%E3%83%A9%E3%83%96%E3%83%AB%E3%82%B7%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0
$ sudo vim /etc/pulse/default.pa
# Echo/Noise-Cancelationのモジュールを有効にします
load-module module-echo-cancel
音飛び解決方法まとめ
- USBならポートを変えてみる
- /etc/modprobe.d/alsa-base.confでオーディオデバイスの優先順位を変更する
- /etc/modprobe.d/alsa-base.conf で次を追記
- options snd-hda-intel position_fix=1 enable=1 model=auto
- options snd-usb-audio position_fix=1 enable=1 model=auto
- /etc/pulse/default.pa の タイマーベースのスケジューリングをオフにする。またはオンにする
- load-module module-udev-detect tsched=0
- 設定の反映は次の2つのコマンド
- pulseaudio -k
- pulseaudio --start
- ビデオカードのドライバを適切にインストールする
- デフォルトのnouveauはブラックリストに入れる
- /etc/pulse/daemon.confの次の項目の数値を高くする
- default-fragments
- default-fragment-size-msec
- ラップトップで無線LANがある場合は何かバグがあるらしい
- 何かのパッチを当てて直った人もいるがかなり古いバージョンの話
- そういえばswapファイルを無駄に作ったりしたけど書き忘れた。効果無かったからいいよね。