Ubuntu18.04 LTS でYoutubeやGoogle Play Musicやmp3の音楽再生で音飛びする問題 

# 注意と問題
動画でも音楽ファイルからでも音飛びする問題が発生しています。
あれこれ尽くしたことを残しておきます。
ここで行ったことを試す場合は全て自己責任でお願いします。

# 結論
結果から言うと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ポートを入れ差して１０ポートあるのですが全ポート試しました。が！ダメ！

```
$ cat /proc/asound/modules
 0 snd_hda_intel
 1 snd_hda_intel
 2 snd_usb_audio
```
デフォルトだとこんな感じです。このsnd_usb_audioをオーディオデバイスのロード順位0にします。

以下のoptions３行をファイルの一番下に追加。


```
$ 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>
```

２つありますね。どっちがデフォルトなのでしょうか。

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
- 設定の反映は次の２つのコマンド
  - pulseaudio -k
  - pulseaudio --start
- ビデオカードのドライバを適切にインストールする
- デフォルトのnouveauはブラックリストに入れる
- /etc/pulse/daemon.confの次の項目の数値を高くする
  - default-fragments
  - default-fragment-size-msec
- ラップトップで無線LANがある場合は何かバグがあるらしい
- 何かのパッチを当てて直った人もいるがかなり古いバージョンの話
- そういえばswapファイルを無駄に作ったりしたけど書き忘れた。効果無かったからいいよね。