Music Player Daemon(MPD)で遊んでみる5 [Rustを愛してみる]

自分で volumio や moode みたいな物をつくるにあたって、前回では、MPDのクライアントである ncmpcpp を試してみました。 よく作りこんであるなぁと感心しました。

それらのような完成度の高い物を自分で作れるのかどうかはさておき、何がしか簡単な物を作って手ごたえを得たいなぁと思い立ちました。

長い事 C++PythonJava に、お世話になってました。 ですが、最近噂の Rust と Go がすごく気になっており、ちょっと 使ってみたいなぁと思い、どーせつくるならと、チャレンジしてみることにしました。

Rust って...

私がいまさら Rust (や他の言語)のことを紹介するまでもなく、Google先生にお伺いを立てれば、いくらでもそのような記事が世の中にはあるわけですが、私風でちょっとだけ特徴を並べてみます。

  • ビルド結果が ELF バイナリ ( Linuxの場合 )

    • よそ様の記事ではあんまり書いてないけど、早く言ってよもぉー、な事です。JavaC# のような親 ( ランタイム ) がいるのかと思っていましたが、Rustでビルドした物は、C/C++ で作ったもののように、それだけで動きます。
    • 『コアライブラリが一切の上位ライブラリ、システムライブラリ、libcライブラリにリンクしていない』ので、OS自体や、ベアメタルプログラムがつくれます。keens.github.io
  • 導入がすごく簡単、コンパイル作業が楽、ライブラリ導入が簡単で楽

    • これは、よそ様の記事にいっぱいありますので詳しくは書きませんが、本当に楽です。
    • cargo というツールがとても優秀です。
    • 色々考えなくてよいのが私にはピッタリ
  • 処理速度が速い

    • 出来上がりが普通の実行バイナリなので、Python等のスクリプト言語なんかとは比べるべくもなく高速に実行されます。
    • (機能的な観点では比べるべきではないかもしれませんが、)JavaC# なんかよりも高速に実行されるようです。
    • 実行速度が速いのが大好きな私にはピッタリ
  • ヌルポがない。

    • 言語上メモリーを参照していない変数は存在できないよーな感じになっています。
    • ヌルポがない代わりに、なにも指示していないことを表現するための型があります。Option<T>
    • 無理やりやればできます。が そんな必要はほぼ無い です。
    • でっかいプログラムつくるときはとても『安心・安全』
  • GC(ガーベージコレクター)が無い。

    • 基本的には値はスタック上で生成されること、また値に対する変数の振る舞いが、所有しているのか、参照しているのかをコンパイル時に厳しくチェックすることで、その値を破棄するタイミングがコンパイルタイムで決定的なものとなることより、ガーベージコレクターという概念自体が不要となっています。
    • 参照カウント方式でヒープを使うことが出来ます。
    • GC嫌いな私にはピッタリ
  • 静的な型付け、極めて賢い型推論

    • これも大きなプログラムを書く時にはとてもありがたいものです。
    • 関数の引数型、戻り型などより型推論できるため変数の型を指定しなくてもよいです。
    • もしくは、変数の型を指定する代わりに、関数の型を省略できます。なにげにすごい発想です。
  • 値に対して、『所有、借用』『不変性、可変性』に対して厳しい。

    • 値はたった一つの変数しか『所有』は出来ない。他の変数(関数呼び出し含む)に代入すると元の変数すら使えないです。同じ値をつかいたければ参照で『借用』することになります。
    • 単に『この変数は変更不可』『この変数は変更可能』だけのレベルではなく、もっと高度なルールがあります。一例としては、『変更不可な借用』を保持する変数が生きている限り、『変更可能な借用』をする変数を生成することは出来ません。
    • なにげにすごい発想です。 上記のルールをコンパイルタイムで厳しくチェックして、エラーにします。
    • これに慣れるのがちょっとめんどくさい
  • オブジェクト指向ではない。テンプレート指向のものはある。

    • C++ や他の言語のようなオブジェクト指向的なものはありません。
    • 代わりといっては語弊がありますが、テンプレート指向的なものはあります。Traits
    • これに慣れるのがちょっとめんどくさい
  • 非汎用ライブラリが無い

    • Pythonのような「電池付属 ("Battery Included")」では無いです。
    • 代わりに crates.ioというライブラリパッケージサイトが利用できます。
    • ちょっと残念だけど、いかにもRust的ではある
  • コンパイラ様のエラーメッセージが異常にリッチでビックリ

    • GCCなどのエラーからしてみたらすごく丁寧です。
    • エラー修正に対する修正のヒントを出してくれます。変数のタイプミスなんかも『これじゃないの?』みたいに提案してくれます。
  • 世界で愛されている*

    • 『Stack Overflowの2020年版Developer Surveyで、Rustが5年連続で最も愛されているプログラミング言語となっている』そーです。news.mynavi.jp
    • 私もやっとちょっとだけその愛がわかってきたのですが、最初はイライラして嫌いになるところでした。

『うん。Rust なかなか良いぞ。』と思った私でした。

でも、google先生に『rust 学習曲線』とお伺い立てるとわかるのですが、習得がむつかしい言語のようです。

うむ。まぁでもやってみようか。

どんなアプリを作るか

MDP に関しては、 正直 telnet があれば、大抵のことは全部できてしまいます。

でもそれでは身も蓋もありませんし、実際に telnet で操作するときに、音楽ファイルのパス名を入れるのがかなり煩わしいのです。 音楽ファイルのパス名が、どーしても長い物になりますし、パス中に空白がある場合は、" で囲むという必要があるのです。

最初のアプリなので、壮大なものは出来ません。

そーだ。Shell風にMDPを操作するアプリってのはどーだろー。

っと思い至りました。

  • コンソールで動く。
  • ls でファイルやディレクトリが見れる。
  • cdディレクトリが移動できる。
  • 短いコマンドで、再生や停止ができる。

みたいな感じを目標にしました。

どんなアプリができたか。

はい。こちら、どん!

github.com

英文とか多分しっちゃかめっちゃかだとは思うのですが、完成したのでGitHubで公開してみました。

英語なぁ....プログラムなら書けるのに、英語はなぁ...

作った上での雑感

久しぶりの新たな言語への挑戦

思えば私が以前に新しい言語を習得したのはずーっと昔でした。そこそこ色々な言語を使ってきたわけなのですが、よく使ってきた言語でいえば、

  • C
    • 30年くらい前ですか... 年がばれそーですが...そのころは 8bit 機全盛でしたね
  • C++
    • 本格的に使い始めたのは、C に対して少々あとです。
  • Python
    • 意外と付き合いは長く、20年位前から使っています。
  • Java
    • 20年位前から使っています。正直好きではなかったのですが...
  • C#
    • 7~8年くらい前かな。Javaよりはずっと好きです。

と、言ったところで最近は新しい言語を始めるなんてことは全くしていませんでした。

そーいえば、Python に関しては、

昔(私の習得したころ)は『組み込み用言語』という立ち位置だったと記憶しています、C++でできたアプリのマクロエンジン用に組み込みしたことがあります。RH7の頃からスクリプト言語として使ってきました。(ちなみに私はアンチ PHP です。Perlは嫌いじゃないけど使いたいわけでもない。)

実際 Python なんて昔はそんなに人気があったかというと全然そんなことなかったと思います。それが昨今では、『AI といえば Python』みたいなノリになるとは全然思いませんでした。正直、AI技術とPython言語は直結していないし、なんでPythonがAI分野で、もてはやされたのかもわかりませんがね。

いやはや、言語の未来なんてどーなるか分からんものですね。

それはさておき、そこそこ色々な言語で書いてきたんだから、Rustもさっさと覚えられるだろーと安易に考えていましたが、 いやぁ...やっぱり年とったからなのか、元来頭が固いからなのか、なかなかスラスラとは行きませんでした。

  • 新しい構文に対して、すんなりとタイプできない。
    • 構文自体があやふやなため、思った事をコードにするのに時間がかかりました。
    • どーしても他の言語の構文のパターンを書いてしまい、コンパイラ様に叱られます。特に if が C/C++ 風にしてみたり、Py風にしてみたり。変数宣言も型を前に書いてみたりと...。
  • Rust独特の特徴が理解できていない。
    • 『所有、借用』『不変性、可変性』に関しては、言葉にしずらい難しさがありました。
    • 他の言語であれば、これでいいのに、こーなのに、っていう固定観念がいろいろ邪魔をしてくれて、結果コンパイラ様に...
  • コンパイラ様が厳しい
    • コンパイルが通らなければ動かないのは、どの言語でも同じで、スクリプト言語でも少なからずそういう面はあるのですが、構文的正しければ動くものができ、ちょっと動かしては理解を深めるということができるのですが、Rustの場合、構文チェックの後にボローチェッカーという『所有、借用』『不変性、可変性』に対するチェックがあるため、それで問題がある間は動かすことが出来ません。

などと、結構悪戦苦闘させられました。『なんでこれだとダメなの』『どー書けば正解なの?』とコンパイラ様に悪態つきまくりでした。

既存の言語では『安全なコード』を作ることは『言語外のテクニック』だったのですが、Rustはそれを『言語仕様』にしてしまったため『安全じゃないコード』は テコでもコンパイルさせない ってことです。

『安全なコード』を作るための『言語外のテクニック』はそこそこ身についていたため、こーかけばいいんだろうな。と安易に書くと、コンパイラ様に叱られるわけで、結構イライラしてきます。

Rustの学習がむつかしいとされることをすごく実感しました。

ついでに Git、Github も初めてだった。

ちょっとはずかしいんですが、git つかったことなかったんです。ずっと Subversion のお世話になってたんで、いつかは git と思いつつ、ズルズルと...

ま、これから勉強します。

シンプルにできる?

ごくごくシンプルなコンソールアプリケーションを作ろうと思っていたわけです。最初は...

実際やりたいことはコマンド入力に対する応答ですから、複雑になる要素はあんまりないわけですからね。基本はRustを覚えることでしたから...

ですが、やっぱりそーは問屋が卸しませんでした。

  • MDP の通信部を外部ライブラリに頼ろうと思いましたが、なかなかいいのがありませんでした。あるにはあるのですが、非同期処理対応とかで敷居が高いものだったりして大袈裟なことになりそーでしたので、結局 TCP通信を自前で実装しました。
  • MDP のTCP接続に関して、何も送らないと60秒で切れちゃうため、色々考えた挙句、通信部分はスレッド実装となりました。簡単にしたかったのに...
  • readline風にしたかったので、rustyline を使ったのですが、これがまた結構大変で...
    • 自分のコードだけだったら『所有、借用』『不変性、可変性』に関しては苦労しないのですがね...外部ライブラリとかが絡むとなかなか都合つけるのが大変です。

などと、ややシンプルで済ますわけにはいかない都合がでてきてしまい、いろいろ苦労しました。まぁ大抵そういうモノですけどね。

Rustへの愛

芽生えました。ははは。

いや初めに思っていた作成時間の倍はかかりました。途中とってもイライラさせられました。なんでこんな言語仕様なのと思ったりもしました。

ですがなんとなく頭が Rust 脳になってきて、やっとコードが楽しくなってきました。

Rust いい言語ですよ。ただ素人にはおすすめできない気がします。いや無垢の素人さんのほーが、すんなり身につくかも...

Go って...

やっと Rust とお友達になれたところで、さて、Go はどーしましょーか。ネタとして、Goでも作ってみようかな。

Music Player Daemon(MPD)で遊んでみる 4

(以下は過去Qiitaに投稿していた内容です。)

ncmpcpp の visualizer を試してみる。

やっぱり音楽再生にはスペアナですよね。

ここにある記載をそのままやってみましたが... エラーになって起動できません。

あれ? fftw-devel 入れたのになぁ...ん?

# ./configure --help
:
  --enable-outputs        Enable outputs screen [default=no]
  --enable-visualizer     Enable music visualizer screen [default=no]
  --enable-clock          Enable clock screen [default=no]
:

default=no でした。とほほ

気を取り直して、面白そーなオプションも有効にしても一度コンパイルします。

# ./configure --enable-outputs --enable-visualizer --enable-clock
# make
# make install

ncmpcpp を起動して [8] をおすと。おおお!でたー。 [sp] を押すとパターン違いを切り替えられます。

f:id:zuntansan:20200610131012p:plain f:id:zuntansan:20200610131001p:plain f:id:zuntansan:20200610131005p:plain

おおすごい。かっこいい。コンソールアプリでよーやるなぁ。 (ちょっと音とずれているよーな気がしないでもないが...TeraTerm 経由だからだろうか...)

RaspberryPi 環境だと処理がおっつくかちょっと心配ですが、ぜひ試してみたいです。

Music Player Daemon(MPD)で遊んでみる 3

(以下は過去Qiitaに投稿していた内容です。)

mpd から MiniDLNA (ReadyDLNA) を参照してみる

この CentOS8 機では、MiniDLNA を走らせています。 mpd のディレクトリ先を MiniDLNA と同じにすればいいのですが、せっかくですので mpd の upnp プラグインを有効にして、MiniDLNA にアクセスできるかやってみようと思います。

mpd.conf の修正

以下の設定を行うだけでできそーです。

database {
       plugin "upnp"
}

で、上記を mpd.conf に追加して起動しましたが、db_file が設定されているとエラーで起動できません。

Jun  3 02:32:04 exsample mpd[26467]: Jun 03 02:32 : exception: Found both 'database' (line 184) and 'db_file' (line 28) setting
Jun  3 02:32:04 exsample systemd[1]: mpd.service: Main process exited, code=exited, status=1/FAILURE

ですので、db_file をコメントアウトします。全体としてはこんな感じ。

# diff -u /etc/mpd.conf.orig /etc/mpd.conf
--- /etc/mpd.conf.orig  2020-06-02 03:26:30.748940801 -0400
+++ /etc/mpd.conf       2020-06-03 05:27:58.578204787 -0400
@@ -25,7 +25,7 @@
 # MPD to accept files over ipc socket (using file:// protocol) or streaming
 # files over an accepted protocol.
 #
-db_file "/var/lib/mpd/mpd.db"
+#db_file "/var/lib/mpd/mpd.db"
 #
 # These settings are the locations for the daemon log files for the daemon.
 # These logs are great for troubleshooting, depending on your log_level
@@ -181,6 +181,10 @@
 #       port "6600"
 #}

+database {
+       plugin "upnp"
+}
+
 # Input #######################################################################
 #

mpd をリスタートさせ、ncmpcpp で見てみると、あっさりリストに出てきました。

f:id:zuntansan:20200610130818p:plain

曲の選択も、再生も問題なくできます。曲の選択では文字化けも解消されとても快適です。

ちなみに、mpd のドキュメントをみると、neighbor plugins でも upnp ( や smbclient )を指定できるようです。ただ以下のように設定してみたのですが、ncmpcpp の ブラウザにはそれらは出てきませんでした。

neighbors {
        plugin "upnp"
}

neighbors {
        plugin "smbclient"
}

mpd 側で有効な扱いでないのか、はたまた ncmpcpp 側の問題なのか。まー今は置いておくことにします。

Music Player Daemon(MPD)で遊んでみる 2

(以下は過去Qiitaに投稿していた内容です。)

ということで、さっそく MPD と遊んでみます。 RaspberryPi で実験すればよいのですが、勉強がてら CentOS8 を使ってみます。

とりあえず、CentOS8 で...

CentOS8 の場合、 「RPM Fusion for EL 8」にパッケージがありました。

# dnf info mpd
CentOS-8 - AppStream                                                                                         7.4 kB/s | 4.3 kB     00:00
CentOS-8 - Base                                                                                              9.5 kB/s | 3.9 kB     00:00
CentOS-8 - Extras                                                                                            4.4 kB/s | 1.5 kB     00:00
Extra Packages for Enterprise Linux Modular 8 - x86_64                                                        27 kB/s | 8.2 kB     00:00
Extra Packages for Enterprise Linux 8 - x86_64                                                                26 kB/s | 4.4 kB     00:00
The Netwide Assembler                                                                                        3.1 kB/s | 3.0 kB     00:00
RPM Fusion for EL 8 - Free - Updates                                                                         3.4 kB/s | 3.7 kB     00:01
利用可能なパッケージ
名前         : mpd
エポック     : 1
バージョン   : 0.21.23
リリース     : 1.el8
Arch         : x86_64
サイズ       : 713 k
ソース       : mpd-0.21.23-1.el8.src.rpm
リポジトリー : rpmfusion-free-updates
概要         : The Music Player Daemon
URL          : https://www.musicpd.org
ライセンス   : GPLv2+
説明         : Music Player Daemon (MPD) is a flexible, powerful, server-side application for
             : playing music. Through plugins and libraries it can play a variety of sound
             : files (e.g., OGG, MP3, FLAC, AAC, WAV) and can be controlled remotely via its
             : network protocol. It can be used as a desktop music player, but is also great
             : for streaming music to a stereo system over a local network. There are many
             : GUI and command-line applications to choose from that act as a front-end for
             : browsing and playing your MPD music collection.
# dnf deplist mpd

実行結果

package: mpd-1:0.21.23-1.el8.x86_64
  dependency: (mpd-firewalld = 1:0.21.23-1.el8 if firewalld)
   provider: mpd-firewalld-1:0.21.23-1.el8.x86_64
  dependency: /bin/sh
   provider: bash-4.4.19-10.el8.x86_64
  dependency: libFLAC.so.8()(64bit)
   provider: flac-libs-1.3.2-9.el8.x86_64
  dependency: libWildMidi.so.2()(64bit)
   provider: wildmidi-libs-0.4.3-3.el8.x86_64
  dependency: libadplug-2.2.1.so.0()(64bit)
   provider: adplug-2.2.1-10.el8.x86_64
  dependency: libao.so.4()(64bit)
   provider: libao-1.2.0-10.el8.x86_64
  dependency: libao.so.4(LIBAO4_1.1.0)(64bit)
   provider: libao-1.2.0-10.el8.x86_64
  dependency: libasound.so.2()(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libasound.so.2(ALSA_0.9)(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libasound.so.2(ALSA_0.9.0)(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libasound.so.2(ALSA_0.9.0rc4)(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libaudiofile.so.1()(64bit)
   provider: audiofile-1:0.3.6-23.el8.x86_64
  dependency: libavahi-client.so.3()(64bit)
   provider: avahi-libs-0.7-19.el8.x86_64
  dependency: libavahi-common.so.3()(64bit)
   provider: avahi-libs-0.7-19.el8.x86_64
  dependency: libavcodec.so.58()(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavcodec.so.58(LIBAVCODEC_58)(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavformat.so.58()(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavformat.so.58(LIBAVFORMAT_58)(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavutil.so.56()(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavutil.so.56(LIBAVUTIL_56)(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libbz2.so.1()(64bit)
   provider: bzip2-libs-1.0.6-26.el8.x86_64
  dependency: libc.so.6(GLIBC_2.28)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libcdio.so.18()(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libcdio.so.18(CDIO_18)(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libcdio_cdda.so.2()(64bit)
   provider: libcdio-paranoia-10.2+0.94+2-3.el8.x86_64
  dependency: libcdio_paranoia.so.2()(64bit)
   provider: libcdio-paranoia-10.2+0.94+2-3.el8.x86_64
  dependency: libcurl.so.4()(64bit)
   provider: libcurl-7.61.1-11.el8.x86_64
   provider: libcurl-minimal-7.61.1-11.el8.x86_64
  dependency: libdbus-1.so.3()(64bit)
   provider: dbus-libs-1:1.12.8-9.el8.x86_64
  dependency: libdbus-1.so.3(LIBDBUS_1_3)(64bit)
   provider: dbus-libs-1:1.12.8-9.el8.x86_64
  dependency: libexpat.so.1()(64bit)
   provider: expat-2.2.5-3.el8.x86_64
  dependency: libfaad.so.2()(64bit)
   provider: faad2-libs-1:2.8.8-6.el8.x86_64
  dependency: libfluidsynth.so.1()(64bit)
   provider: fluidsynth-libs-1.1.11-6.el8.x86_64
  dependency: libgcc_s.so.1()(64bit)
   provider: libgcc-8.3.1-4.5.el8.x86_64
  dependency: libgcc_s.so.1(GCC_3.0)(64bit)
   provider: libgcc-8.3.1-4.5.el8.x86_64
  dependency: libgcrypt.so.20()(64bit)
   provider: libgcrypt-1.8.3-4.el8.x86_64
  dependency: libgcrypt.so.20(GCRYPT_1.6)(64bit)
   provider: libgcrypt-1.8.3-4.el8.x86_64
  dependency: libicui18n.so.60()(64bit)
   provider: libicu-60.3-2.el8_1.x86_64
  dependency: libicuuc.so.60()(64bit)
   provider: libicu-60.3-2.el8_1.x86_64
  dependency: libid3tag.so.0()(64bit)
   provider: libid3tag-0.15.1b-30.el8.x86_64
  dependency: libiso9660.so.11()(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libiso9660.so.11(ISO9660_11)(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libixml.so.10()(64bit)
   provider: libupnp-1.8.4-3.el8.x86_64
  dependency: libjack.so.0()(64bit)
   provider: jack-audio-connection-kit-1.9.12-8.el8.x86_64
  dependency: libm.so.6()(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libm.so.6(GLIBC_2.15)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libm.so.6(GLIBC_2.2.5)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libmad.so.0()(64bit)
   provider: libmad-0.15.1b-24.el8.x86_64
  dependency: libmikmod.so.3()(64bit)
   provider: libmikmod-3.3.11.1-7.el8.x86_64
  dependency: libmms.so.0()(64bit)
   provider: libmms-0.6.4-8.el8.x86_64
  dependency: libmodplug.so.1()(64bit)
   provider: libmodplug-1:0.8.9.0-9.el8.x86_64
  dependency: libmp3lame.so.0()(64bit)
   provider: lame-libs-3.100-6.el8.x86_64
  dependency: libmpdclient.so.2()(64bit)
   provider: libmpdclient-2.16-1.el8.x86_64
  dependency: libmpdclient.so.2(libmpdclient2)(64bit)
   provider: libmpdclient-2.16-1.el8.x86_64
  dependency: libmpg123.so.0()(64bit)
   provider: mpg123-libs-1.25.10-2.el8.x86_64
  dependency: libnfs.so.13()(64bit)
   provider: libnfs-4.0.0-1.el8.x86_64
  dependency: libogg.so.0()(64bit)
   provider: libogg-2:1.3.2-10.el8.x86_64
  dependency: libopenal.so.1()(64bit)
   provider: openal-soft-1.18.2-7.el8.x86_64
  dependency: libopus.so.0()(64bit)
   provider: opus-1.3-0.4.beta.el8.x86_64
  dependency: libpcre.so.1()(64bit)
   provider: pcre-8.42-4.el8.x86_64
  dependency: libpthread.so.0()(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpthread.so.0(GLIBC_2.12)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpthread.so.0(GLIBC_2.2.5)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpthread.so.0(GLIBC_2.3.2)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpulse.so.0()(64bit)
   provider: pulseaudio-libs-11.1-23.el8.x86_64
  dependency: libpulse.so.0(PULSE_0)(64bit)
   provider: pulseaudio-libs-11.1-23.el8.x86_64
  dependency: libsamplerate.so.0()(64bit)
   provider: libsamplerate-0.1.9-1.el8.x86_64
  dependency: libsamplerate.so.0(libsamplerate.so.0.0)(64bit)
   provider: libsamplerate-0.1.9-1.el8.x86_64
  dependency: libshout.so.3()(64bit)
   provider: libshout-2.2.2-19.el8.x86_64
  dependency: libsmbclient.so.0()(64bit)
   provider: libsmbclient-4.10.4-101.el8_1.x86_64
  dependency: libsmbclient.so.0(SMBCLIENT_0.1.0)(64bit)
   provider: libsmbclient-4.10.4-101.el8_1.x86_64
  dependency: libsndfile.so.1()(64bit)
   provider: libsndfile-1.0.28-8.el8.x86_64
  dependency: libsndfile.so.1(libsndfile.so.1.0)(64bit)
   provider: libsndfile-1.0.28-8.el8.x86_64
  dependency: libsoxr.so.0()(64bit)
   provider: soxr-0.1.3-4.el8.x86_64
  dependency: libsqlite3.so.0()(64bit)
   provider: sqlite-libs-3.26.0-4.el8_1.x86_64
  dependency: libstdc++.so.6()(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.11)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.3)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.5)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.8)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.9)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.11)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.14)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.18)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.19)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.20)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.21)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libsystemd.so.0()(64bit)
   provider: systemd-libs-239-18.el8_1.5.x86_64
  dependency: libsystemd.so.0(LIBSYSTEMD_209)(64bit)
   provider: systemd-libs-239-18.el8_1.5.x86_64
  dependency: libtwolame.so.0()(64bit)
   provider: twolame-libs-0.3.13-11.el8.x86_64
  dependency: libupnp.so.13()(64bit)
   provider: libupnp-1.8.4-3.el8.x86_64
  dependency: libvorbis.so.0()(64bit)
   provider: libvorbis-1:1.3.6-2.el8.x86_64
  dependency: libvorbisenc.so.2()(64bit)
   provider: libvorbis-1:1.3.6-2.el8.x86_64
  dependency: libwavpack.so.1()(64bit)
   provider: wavpack-5.1.0-9.el8.x86_64
  dependency: libyajl.so.2()(64bit)
   provider: yajl-2.1.0-10.el8.x86_64
  dependency: libz.so.1()(64bit)
   provider: zlib-1.2.11-10.el8.x86_64
  dependency: libzzip-0.so.13()(64bit)
   provider: zziplib-0.13.68-7.el8.x86_64
  dependency: rtld(GNU_HASH)
   provider: glibc-2.28-72.el8_1.1.i686
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: shadow-utils
   provider: shadow-utils-2:4.6-8.el8.x86_64
  dependency: systemd
   provider: systemd-239-18.el8_1.5.i686
   provider: systemd-239-18.el8_1.5.x86_64
[root@home ~]# dnf deplist mpd
メタデータの期限切れの最終確認: 0:03:45 時間前の 2020年06月02日 03時07分33秒 に実施しました。
package: mpd-1:0.21.23-1.el8.x86_64
  dependency: (mpd-firewalld = 1:0.21.23-1.el8 if firewalld)
   provider: mpd-firewalld-1:0.21.23-1.el8.x86_64
  dependency: /bin/sh
   provider: bash-4.4.19-10.el8.x86_64
  dependency: libFLAC.so.8()(64bit)
   provider: flac-libs-1.3.2-9.el8.x86_64
  dependency: libWildMidi.so.2()(64bit)
   provider: wildmidi-libs-0.4.3-3.el8.x86_64
  dependency: libadplug-2.2.1.so.0()(64bit)
   provider: adplug-2.2.1-10.el8.x86_64
  dependency: libao.so.4()(64bit)
   provider: libao-1.2.0-10.el8.x86_64
  dependency: libao.so.4(LIBAO4_1.1.0)(64bit)
   provider: libao-1.2.0-10.el8.x86_64
  dependency: libasound.so.2()(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libasound.so.2(ALSA_0.9)(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libasound.so.2(ALSA_0.9.0)(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libasound.so.2(ALSA_0.9.0rc4)(64bit)
   provider: alsa-lib-1.1.9-4.el8.x86_64
  dependency: libaudiofile.so.1()(64bit)
   provider: audiofile-1:0.3.6-23.el8.x86_64
  dependency: libavahi-client.so.3()(64bit)
   provider: avahi-libs-0.7-19.el8.x86_64
  dependency: libavahi-common.so.3()(64bit)
   provider: avahi-libs-0.7-19.el8.x86_64
  dependency: libavcodec.so.58()(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavcodec.so.58(LIBAVCODEC_58)(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavformat.so.58()(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavformat.so.58(LIBAVFORMAT_58)(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavutil.so.56()(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libavutil.so.56(LIBAVUTIL_56)(64bit)
   provider: ffmpeg-libs-4.2.3-2.el8.x86_64
  dependency: libbz2.so.1()(64bit)
   provider: bzip2-libs-1.0.6-26.el8.x86_64
  dependency: libc.so.6(GLIBC_2.28)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libcdio.so.18()(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libcdio.so.18(CDIO_18)(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libcdio_cdda.so.2()(64bit)
   provider: libcdio-paranoia-10.2+0.94+2-3.el8.x86_64
  dependency: libcdio_paranoia.so.2()(64bit)
   provider: libcdio-paranoia-10.2+0.94+2-3.el8.x86_64
  dependency: libcurl.so.4()(64bit)
   provider: libcurl-7.61.1-11.el8.x86_64
   provider: libcurl-minimal-7.61.1-11.el8.x86_64
  dependency: libdbus-1.so.3()(64bit)
   provider: dbus-libs-1:1.12.8-9.el8.x86_64
  dependency: libdbus-1.so.3(LIBDBUS_1_3)(64bit)
   provider: dbus-libs-1:1.12.8-9.el8.x86_64
  dependency: libexpat.so.1()(64bit)
   provider: expat-2.2.5-3.el8.x86_64
  dependency: libfaad.so.2()(64bit)
   provider: faad2-libs-1:2.8.8-6.el8.x86_64
  dependency: libfluidsynth.so.1()(64bit)
   provider: fluidsynth-libs-1.1.11-6.el8.x86_64
  dependency: libgcc_s.so.1()(64bit)
   provider: libgcc-8.3.1-4.5.el8.x86_64
  dependency: libgcc_s.so.1(GCC_3.0)(64bit)
   provider: libgcc-8.3.1-4.5.el8.x86_64
  dependency: libgcrypt.so.20()(64bit)
   provider: libgcrypt-1.8.3-4.el8.x86_64
  dependency: libgcrypt.so.20(GCRYPT_1.6)(64bit)
   provider: libgcrypt-1.8.3-4.el8.x86_64
  dependency: libicui18n.so.60()(64bit)
   provider: libicu-60.3-2.el8_1.x86_64
  dependency: libicuuc.so.60()(64bit)
   provider: libicu-60.3-2.el8_1.x86_64
  dependency: libid3tag.so.0()(64bit)
   provider: libid3tag-0.15.1b-30.el8.x86_64
  dependency: libiso9660.so.11()(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libiso9660.so.11(ISO9660_11)(64bit)
   provider: libcdio-2.0.0-3.el8.x86_64
  dependency: libixml.so.10()(64bit)
   provider: libupnp-1.8.4-3.el8.x86_64
  dependency: libjack.so.0()(64bit)
   provider: jack-audio-connection-kit-1.9.12-8.el8.x86_64
  dependency: libm.so.6()(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libm.so.6(GLIBC_2.15)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libm.so.6(GLIBC_2.2.5)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libmad.so.0()(64bit)
   provider: libmad-0.15.1b-24.el8.x86_64
  dependency: libmikmod.so.3()(64bit)
   provider: libmikmod-3.3.11.1-7.el8.x86_64
  dependency: libmms.so.0()(64bit)
   provider: libmms-0.6.4-8.el8.x86_64
  dependency: libmodplug.so.1()(64bit)
   provider: libmodplug-1:0.8.9.0-9.el8.x86_64
  dependency: libmp3lame.so.0()(64bit)
   provider: lame-libs-3.100-6.el8.x86_64
  dependency: libmpdclient.so.2()(64bit)
   provider: libmpdclient-2.16-1.el8.x86_64
  dependency: libmpdclient.so.2(libmpdclient2)(64bit)
   provider: libmpdclient-2.16-1.el8.x86_64
  dependency: libmpg123.so.0()(64bit)
   provider: mpg123-libs-1.25.10-2.el8.x86_64
  dependency: libnfs.so.13()(64bit)
   provider: libnfs-4.0.0-1.el8.x86_64
  dependency: libogg.so.0()(64bit)
   provider: libogg-2:1.3.2-10.el8.x86_64
  dependency: libopenal.so.1()(64bit)
   provider: openal-soft-1.18.2-7.el8.x86_64
  dependency: libopus.so.0()(64bit)
   provider: opus-1.3-0.4.beta.el8.x86_64
  dependency: libpcre.so.1()(64bit)
   provider: pcre-8.42-4.el8.x86_64
  dependency: libpthread.so.0()(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpthread.so.0(GLIBC_2.12)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpthread.so.0(GLIBC_2.2.5)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpthread.so.0(GLIBC_2.3.2)(64bit)
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: libpulse.so.0()(64bit)
   provider: pulseaudio-libs-11.1-23.el8.x86_64
  dependency: libpulse.so.0(PULSE_0)(64bit)
   provider: pulseaudio-libs-11.1-23.el8.x86_64
  dependency: libsamplerate.so.0()(64bit)
   provider: libsamplerate-0.1.9-1.el8.x86_64
  dependency: libsamplerate.so.0(libsamplerate.so.0.0)(64bit)
   provider: libsamplerate-0.1.9-1.el8.x86_64
  dependency: libshout.so.3()(64bit)
   provider: libshout-2.2.2-19.el8.x86_64
  dependency: libsmbclient.so.0()(64bit)
   provider: libsmbclient-4.10.4-101.el8_1.x86_64
  dependency: libsmbclient.so.0(SMBCLIENT_0.1.0)(64bit)
   provider: libsmbclient-4.10.4-101.el8_1.x86_64
  dependency: libsndfile.so.1()(64bit)
   provider: libsndfile-1.0.28-8.el8.x86_64
  dependency: libsndfile.so.1(libsndfile.so.1.0)(64bit)
   provider: libsndfile-1.0.28-8.el8.x86_64
  dependency: libsoxr.so.0()(64bit)
   provider: soxr-0.1.3-4.el8.x86_64
  dependency: libsqlite3.so.0()(64bit)
   provider: sqlite-libs-3.26.0-4.el8_1.x86_64
  dependency: libstdc++.so.6()(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.11)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.3)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.5)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.8)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.9)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.11)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.14)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.18)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.19)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.20)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.21)(64bit)
   provider: libstdc++-8.3.1-4.5.el8.x86_64
  dependency: libsystemd.so.0()(64bit)
   provider: systemd-libs-239-18.el8_1.5.x86_64
  dependency: libsystemd.so.0(LIBSYSTEMD_209)(64bit)
   provider: systemd-libs-239-18.el8_1.5.x86_64
  dependency: libtwolame.so.0()(64bit)
   provider: twolame-libs-0.3.13-11.el8.x86_64
  dependency: libupnp.so.13()(64bit)
   provider: libupnp-1.8.4-3.el8.x86_64
  dependency: libvorbis.so.0()(64bit)
   provider: libvorbis-1:1.3.6-2.el8.x86_64
  dependency: libvorbisenc.so.2()(64bit)
   provider: libvorbis-1:1.3.6-2.el8.x86_64
  dependency: libwavpack.so.1()(64bit)
   provider: wavpack-5.1.0-9.el8.x86_64
  dependency: libyajl.so.2()(64bit)
   provider: yajl-2.1.0-10.el8.x86_64
  dependency: libz.so.1()(64bit)
   provider: zlib-1.2.11-10.el8.x86_64
  dependency: libzzip-0.so.13()(64bit)
   provider: zziplib-0.13.68-7.el8.x86_64
  dependency: rtld(GNU_HASH)
   provider: glibc-2.28-72.el8_1.1.i686
   provider: glibc-2.28-72.el8_1.1.x86_64
  dependency: shadow-utils
   provider: shadow-utils-2:4.6-8.el8.x86_64
  dependency: systemd
   provider: systemd-239-18.el8_1.5.i686
   provider: systemd-239-18.el8_1.5.x86_64

結構たくさん依存関係があります。ソースからビルドしてみたかったですが、なんか大変そうなので素直にパッケージを使用することにします。あるとよさげな alsa-utils もインストールします。

# dnf install mpd 
# dnf install alsa-utils

インストールされたので、次は /etc/mpd.conf を編集します。以下を参考にしました。 * User’s Manual — Music Player Daemon 0.22 documentation * mpd.conf(5): Music Player Daemon config file - Linux man page * MPD (MUSIC PROTOCOL DAEMON)のインストール

設定のポイントは、

  1. ディレクトリ設定
  2. デーモンの listen 設定
  3. auto_update の ON/OFF
  4. Avahi の Zeroconf 設定
  5. Database セクションの設定
  6. Input セクションの設定
  7. Audio Output セクションの設定

です。デフォルトの mpd.conf から大きく変えるところは少なそうです。 とりあえず全く変更せず起動してみると、TCP/6600 で起動しました。

# systemctl start mpd.service 
# systemctl status mpd.service
● mpd.service - Music Player Daemon
   Loaded: loaded (/usr/lib/systemd/system/mpd.service; disabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-06-03 01:09:29 EDT; 2s ago
     Docs: man:mpd(1)
           man:mpd.conf(5)
 Main PID: 21163 (mpd)
    Tasks: 3 (limit: 26213)
   Memory: 7.7M
   CGroup: /system.slice/mpd.service
           mq21163 /usr/bin/mpd --no-daemon

 6月 03 01:09:28 example.net systemd[1]: Starting Music Player Daemon...
 6月 03 01:09:29 example.net mpd[21163]: Jun 03 01:09 : exception: bind to '0.0.0.0:6600' failed (continuing anyway, because binding to '[::]:6600' succeeded): Failed to bind socket: Address already in use

なんかエラー出てるけど、まぁいいか。

早速音を出してみたいと思います。ターミナルからだと、mpc, ncmpc, ncmpcpp があるとのことですが、

# dnf search mpc

libmpc.x86_64 : C library for multiple precision complex arithmetic
libmpc.i686 : C library for multiple precision complex arithmetic
libmpc.x86_64 : C library for multiple precision complex arithmetic
mpc-qt.x86_64 : A clone of Media Player Classic reimplemented in Qt
stompclt.noarch : Versatile STOMP client
libmpcdec.i686 : Musepack audio decoding library
libmpcdec.x86_64 : Musepack audio decoding library
snmpcheck.noarch : An utility to get information via SNMP protocols

mpc-qtってのがありますね。でもこれって GUI ですね。パッケージないのかな?

mpc は、mpd と同一グループでの開発のようで、いわば標準的ってやつのようです。ただソース落としてきてみてみると、Meson と Ninja というビルドシステムが必要のようで、勉強不足でよくわかんないものを入れるのに抵抗ありで、スルーしました。

鳴らすだけなら、スマホとか Windows アプリで mpd にアクセスするのもありでしょうが、やっぱりコンソールからうごかしてみたいので ncmpcpp をコンパイルして入れてみます。

ncmpcpp のコンパイル

ソースをとってきます。

wget https://rybczak.net/ncmpcpp/stable/ncmpcpp-0.8.2.tar.bz2

https://rybczak.net/ncmpcpp/ に書いてある依存のあるものを入れていきます。

  • boost-devel
  • ncurses-devel
  • readline-devel
  • libcurl-devel
  • fftw-devel
  • taglib-devel (パッケージリポジトリに無い...)
  • libicu-devel (上記ページに書いてないけど configureのログより...)
  • libmpdclient-devel (上記ページに書いてないけど、そりゃいるよねぇ...)
# dnf install boost-devel ncurses-devel readline-devel libcurl-devel fftw-devel libicu-devel libmpdclient-devel

taglib だけ -devel がないんだけど、ヘッダとかふくまれているのかな?

# dnf search taglib
=========================================================== 名前 完全一致: taglib ===========================================================
taglib.i686 : Audio Meta-Data Library
taglib.x86_64 : Audio Meta-Data Library
========================================================= 名前 & 概要 一致: taglib ==========================================================
taglib-extras.x86_64 : Taglib support for other formats
taglib-extras-devel.x86_64 : Development files for taglib-extras

# dnf download taglib

# rpm -qlp taglib-1.11.1-8.el8.x86_64.rpm
/usr/lib/.build-id
/usr/lib/.build-id/48
/usr/lib/.build-id/48/80624d22411e88d54105a67a303615e23c140b
/usr/lib/.build-id/7d
/usr/lib/.build-id/7d/fa7bc4ab31566b156b3a715dc80a7c3bc2869c
/usr/lib64/libtag.so.1
/usr/lib64/libtag.so.1.17.0
/usr/lib64/libtag_c.so.0
/usr/lib64/libtag_c.so.0.0.0
/usr/share/doc/taglib
/usr/share/doc/taglib/AUTHORS
/usr/share/doc/taglib/NEWS
/usr/share/licenses/taglib
/usr/share/licenses/taglib/COPYING.LGPL
/usr/share/licenses/taglib/COPYING.MPL

ヘッダ入ってません。残念。もしあとで困ったらソースからビルドすることとします。

さっそく configure & make & make install です。

# ./configure
# make
# # たばこた~いむ
# make install

動かしてみます。

# ncmpcpp

曲を置いてないため、曲リストが空っぽでした。 /var/lib/mpd/music に適当にファイルを設置してたあと、ブラウザ画面へ移り[2]キー、データベース更新[u]キーを押すと、それらがでてきました。 でも再生しません。曲の再生がすぐにストップしてしまいます。

/var/log/mpd/mpd.logをみてみると以下のような出力があります。

Jun 03 02:51 : exception: Failed to enable output "My Pulse Output" (pulse)
Jun 03 02:51 : exception: nested: pa_context_connect() has failed: Connection refused

mpd.conf を修正する必要がありそうです。

mpd.conf の設定

audio_output セクションを編集してみます。

pulseaudio を無効にし、alsa を有効にします。

# diff -u /etc/mpd.conf.orig /etc/mpd.conf
--- /etc/mpd.conf.orig  2020-06-02 03:26:30.748940801 -0400
+++ /etc/mpd.conf       2020-06-03 03:14:50.911571804 -0400
@@ -203,15 +207,16 @@
 #
 # An example of an ALSA output:
 #
-#audio_output {
-#      type            "alsa"
-#      name            "My ALSA Device"
-##     device          "hw:0,0"        # optional
+audio_output {
+       type            "alsa"
+       name            "My ALSA Device"
+       device          "hw:1,0"        # optional
+       mixer_type      "software"
 ##     mixer_type      "hardware"      # optional
 ##     mixer_device    "default"       # optional
 ##     mixer_control   "PCM"           # optional
 ##     mixer_index     "0"             # optional
-#}
+}
 #
 # An example of an OSS output:
 #
@@ -275,12 +280,12 @@
 #
 # An example of a pulseaudio output (streaming to a remote pulseaudio server)
 #
-audio_output {
-       type            "pulse"
-       name            "My Pulse Output"
-##     server          "remote_server"         # optional
-##     sink            "remote_server_sink"    # optional
-}
+#audio_output {
+#      type            "pulse"
+#      name            "My Pulse Output"
+###    server          "remote_server"         # optional
+###    sink            "remote_server_sink"    # optional
+#}
 #
 # An example of a winmm output (Windows multimedia API).
 #

alsa の出力先デバイスの設定である device "hw:1,0" の部分は、前もって aplay -l または aplay -L で調べておきます。

# ( LANG=C; aplay -l )
**** List of PLAYBACK Hardware Devices ****
card 0: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Generic [HD-Audio Generic], device 0: ALC1220 Analog [ALC1220 Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Generic [HD-Audio Generic], device 1: ALC1220 Digital [ALC1220 Digital]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

あらためて ncmpcpp を動かしますが、それでもなりません。うーん。

以下のコマンドを使って直接 alsa で音をだそうとしてみましたがうんともすんともいいません。

# aplay --device=hw:1,0 test.wav
# speaker-test -c2 -D hw:1,0

少し検索するとヒントを発見しました。 Linuxで音が出ないときに確認するポイント

ALSAじたいもミュートの設定をもっているので,そちらも確認する 下のように,MasterとPCMが0より大きくてミュートになっていないならOK

# alsamixer

ncurses な画面ですが使い方がよくわからない。TeraTermからだと激しく文字化けします。F6サウンドカード選択 してオンボードサウンドカードを選択してみると、まさにこれでした。Master の 値が 0 で、さらにミュートになってました。

左右キーで Master を選択し、上下で値を変更します。あと m キーでミュートの ON/OFF 切り替えです。

調整した後、あらためて ncmpcpp を動かします。おお、鳴りました。

その後いろいろググってみると、以下のコマンドでも同じ事ができました。

# amixer -c1 sset Master 80% unmute

最初は音がでないもんですから、ちょっと焦っちゃいましたけど、ざっと見返してみると、さほど難しい要素もなく動かせました。

Music Player Daemon(MPD)で遊んでみる 1

(以下は過去Qiitaに投稿していた内容です。)

RaspberryPi を使ってオーディオを楽しんでいる方々の記事を読んで、ひさびさにオーディオ熱がよみがえってきました。

RaspberryPi に DACボードを挿して、安価なデジタルアンプを通して安価なスピーカーを鳴らす。でも割といい音が出るよ。という感じの記事がよく見受けられます。 「安いけど音がよい」というフレーズに、なんとも心をゆさぶられたわけです。

構成

ハードはこんな感じです。

  • RaspberryPi3
    • これは以前から持ってたのを使います。
  • サインスマート HIFI DAC サウンドカード モジュール I2Sインターフェース Raspberry Pi B+、2 Model B対応
    • お安い DAC ボード。「HiFiBerry DAC +」と互換品らしいです。
  • FX-AUDIO- FX-2020A+ CUSTOM
    • お安いデジタルアンプ。なんでも TRIPATH 製 TA2020-020 搭載デジタルアンプは『とっても音が良い』とか...
  • ACアダプタ 12V2A
    • FX-2020A+ 用です。アマゾンの安いやつです。
  • 自作スピーカー FOSTEX FE83E ダブルバスレフ
    • 大昔に作って押し入れにしまってあった物を引っ張り出してきました。

ソフトは、Volumio と、Moode Audio を試してみました。 いずれも microSD に焼いて、RaspberryPi にさして、ブラウザからアクセスして、多少設定したらあっけなくスピーカーから音が出てきました。

色々な記事のとおり、意外なほどしっかり鳴ってくれます。まぁもっとも FE83 ですので低音は厳しいです。FX-2020A には、トーンコントロールが付いていて低音ブーストもできるのですが、あんまり上げすぎるとたいした音量でもないのにスピーカーのコーンが派手に動いてすぐ歪みが出てきます。トーンコントロールをバイパスするDIRECTモードの方が音は綺麗です。

あんまり低音の入っていないソースだと結構きれいに聞こえます。Boyce Avenue のギター弾き語りとか、すごいツヤツヤしててちょっとにんまりしてきました。当方耳が良いという自信はありませんが、これはアリですよ。

RaspberryPi に導入するソフト

RaspberryPi に導入するソフト(デストリビューション)は以下のようなものがあるそーで、どれがいいんかよくわからないです。

Volumio

ネットの記事では一番量が多いでしょうか。導入してみました。

  • DLNAサーバーのコンテンツも再生できました。
  • 操作UIがなかなかカッコいいです。
  • UIのレスポンスは、Moode Audio より良好だとおもいます。UI用に Node.js が使われているようです。レスポンスの良さは websocket によるところでしょうかね。

残念な部分

  • Bluetooth による転送(スマホ等の音を受信、外部BTスピーカーへの送信)は有料...
  • WLAN がうまくいきませんでした。色々手動でも試してみたのですが、eth0 wlan0 を同じ LAN内でDHCPにてIPアドレスを割り振ると、eth0ではUIが正しく動くが wlan0ではUIが動かないです(途中でフリーズする)。UIで使っている websocket 周りで、ブラウザにIPアドレスを返すリクエストがあるのですが、そのIPリストに eth0 のアドレスと、wlan0 に仮に振られているアドレスしかなく、wlan0 の DHCPアドレスが含まれていないたと思われます。

Moode Audio

ネットの記事でもそこそこ取り上げられています。 今のところ、Moode Audio を使っています。

  • 操作UIがややチープです。
  • PHPによる実装のためかちょっともっさりぎみ。
  • Bluetooth による転送ができました。
    • スマホからBT接続するごとに操作UI側で受付ボタン押さないといけないのはちょっと煩わしいです。
    • スマホ音が時々途切れることがあります。スマホYouTubeなんかをキャストしていると映像に対してかなり遅延があります。
  • DLNAサーバーのコンテンツも再生できました。
    • たまーにコンテンツリストがおかしくなる時があります。
    • いくつかのコンテンツで文字化けが起こりました。(設定でなんとかなるのかもしれませんが...)

RuneAudio

ネットの記事は少な目ですかね。開発が途切れているようです。OS も raspbian ではないとのことでとりあえずスルー

lightMPD

開発は日本の方のよーですね。シンプルでコンパクトが特徴のようです。

なんとなくの理解(MPD)

いずれのデストリビューションでも、「Music Player Daemon(MPD)」というデーモンが中心にあり、それに対してブラウザベースのUI(MPDクライアント、設定回り)とサーバー側の webアプリケーションがあるといったところです。あとは Bluetooth サービスってところでしょうか

  • UIに関しては、Volumio がカッコいいけど、Moode Audio はやや微妙です。
  • DLNAサーバーのコンテンツ再生対応に関しては、Volumio の方が優秀のよう。
  • Volumio の wlan には不満。
  • Bluetooth に関しては、Volumio は有料、Moode Audio は無料。ただ音切れや遅延があるとなると利用頻度は下がるかもしれないです。
  • ネットワーク周りは、ある程度決まっちゃえばそんなに変更することは無いので、コンソールから設定するほうが楽なような気がします。

などなど、いろいろ思うところが出てきます。特に UI に関しては、音楽プレーヤ部分とそれ以外の部分(ライブラリパス、ネットワーク、システム等)がありますが、後者は頻繁に使うわけではないので同一の UI に収める必要はそんなにありません。

しかも、MPDクライアントとしてスマホ用のものもあるそーで、試してはいませんが、音楽プレーヤという点ではそれらを利用するほうが良いのかもしれません。

でも待てよっと。いっそ MPDクライアントを作ってみるというのはどーなんだろう。ふつふつと思ってしましました。

目標設定

最大限の理想でいってみます。

  • MPDクライアントを自作してみます。Python か Rust を検討します。
  • DLNAサーバーのコンテンツも再生は必須。SMBサーバーへのアクセスは任意。USBデバイス上のコンテンツ再生は任意。
  • SMBサーバーは必須ではない
  • Bluetooth転送も出来ればやりたい。
  • ネットワーク周りは、コンソールで設定するものとします。
  • デストリビューションである必要はないので、必要なものはちまちま手作業でいれてみます。
  • 音楽に合わせて、UVメーター風Lチカ、スペアナ風Lチカ、なんかを作れたらいいなぁ。
  • 本当はアンプやDACの回路基板から作れたらもっと面白いんだろうけど、最近年のせいか目が辛くて無理そう。いや出来れば...
  • FE83 もいいんですけど、もちっとちゃんとしたスピーカーを準備しよう。FF125WK、FF165WK あたりが良さげに見えてきた...

何気に色々妄想してみましたが、まずは MPDクライアントの自作に対して、目途を立ててみます。 ということで次回に続く。

ブログはじめます。

久々に趣味プログラムに打ち込める時間ができました。 ただ漠然と趣味プログラムをやるよりは、何か記録に残そうかと思いブログを開設しました。

どこまで続けられるものかは分かりませんが、出来るだけ続けたいと思います。