Ubuntu 22.04 LTS アップグレードと Focusrite Scalett Solo オーディオインターフェース

Ubuntu 22.04 LTS がリリースされましたので、Raspberry Pi 400 と WSL2、そしてメインで使っている ThinkPad P14s に導入してみました。

Raspberry Pi 400:

導入済みの Ubuntu 20.04 LTS からのアップグレード。SSD 起動にしていますが、1時間ほどかかったでしょうか。無事 22.04 LTS となり、SDL の画面描画やオーディオ再生などうまく動作しているようです。

WSL2:

こちらは、Microsoft ストアより Ubuntu 22.04 LTS を選択して新規導入。ESP32/M5Stack のSDKである esp-idf に含まれる (riscv32-) gcc などのバイナリーパッケージが正常に動作することを確認。

ThinkPad P14s:

懸念していた esp-idf のバイナリーパッケージが WSL2 で正常動作しましたので、メインの ThinkPad P14s にも導入。 Ubuntu 20.04 LTS から Ubuntu 22.04LTS にアップグレードインストールしています。 30分ほど。

Wayland セッションを使うと、現在 Indicator Stickynotes(付箋)でウインドウ位置や Dock アイコンの制御、Alacritty のウインドウ描画が違和感のある感じになりましたので、いったん X.org セッションで動作させています。

ハードウェア的には 2点問題がでています。

Focusrite Scalett Solo オーディオインターフェース:

ThinkPad には USB オーディオインターフェースとして、Focusrite 社の Scalett Solo を接続していますが、ALSA からの認識で対応するサンプリングレートが低く(44100, 48000のみ)申告されてしまうという問題がでました。

$ uname -a
Linux thinkpad-p14s 5.15.0-27-generic #28-Ubuntu SMP Thu Apr 14 04:55:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ cat /proc/asound/USB/stream0
Focusrite Scarlett Solo USB at usb-0000:07:00.4-2, high speed : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S32_LE
    Channels: 2
    Endpoint: 0x01 (1 OUT) (SYNC)
    Rates: 44100, 48000
    Data packet interval: 125 us
    Bits: 24
    Channel map: FL FR

Ubuntu 20.04 LTS では次のように 44100, 48000, 88200, 96000, 176400, 192000 となります。

$ uname -a
Linux hiromasa-t420s 5.13.0-40-generic #45~20.04.1-Ubuntu SMP Mon Apr 4 09:38:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ cat /proc/asound/USB/stream0
Focusrite Scarlett Solo USB at usb-0000:00:1d.0-1.2, high speed : USB Audio

Playback:
  Status: Stop
  Interface 1
    Altset 1
    Format: S32_LE
    Channels: 2
    Endpoint: 0x01 (1 OUT) (SYNC)
    Rates: 44100, 48000, 88200, 96000, 176400, 192000
    Data packet interval: 125 us
    Bits: 24
    Channel map: FL FR

96KHz などが設定できないと、ハイレゾ系の音源や高サンプリングレートのソフトシンセの開発に支障がでるためやや悩み。

カーネルのソースを眺めていたところ、次のようなソースが追加されていることを発見。

/*
 * Many Focusrite devices supports a limited set of sampling rates per
 * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type
 * descriptor which has a non-standard bLength = 10.
 */
static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip,
					struct audioformat *fp,
					unsigned int rate)

Focusrite ではあるものの Solo が入っていないため、動作が不正しているのではないかと当たりをつけてさらにソースを追っていたところ、Skip reading sampe rate for devices というワークアラウンドフラグ(quirk_flags)がありましたので、試しに設定してみたところ、正しく(とは言わないかもですが…) 高いサンプリングレートも申告されるようになりました。(ちなみに device_setup=1 の指定で今回カーネルに追加された Focusrite のミキサードライバーが有効になるようです)

$ sudo vi /etc/modprobe.d/scarlett.conf
options snd_usb_audio vid=0x1235 pid=0x8211 device_setup=1 quirk_flags=0x1
$ cat /proc/asound/USB/stream0
Focusrite Scarlett Solo USB at usb-0000:07:00.4-2, high speed : USB Audio

Playback:
  Status: Running
    Interface = 1
    Altset = 1
    Packet Size = 144
    Momentary freq = 96000 Hz (0xc.0000)
  Interface 1
    Altset 1
    Format: S32_LE
    Channels: 2
    Endpoint: 0x01 (1 OUT) (SYNC)
    Rates: 44100, 48000, 88200, 96000, 176400, 192000
    Data packet interval: 125 us
    Bits: 24
    Channel map: FL FR

このことにより Jack も高いサンプリングレートで起動できるようになりました。(解決)

$ cat .jackdrc
/usr/bin/jackd -dalsa -dhw:USB -r96000 -p1024 -n2

ワークアラウンドなので ALSA に報告して修正してもらうのが正しいでしょうか。要調査。同件ですが Ubuntu 日本語フォーラムで質問させていただいておりました。

Apple AV アダプタ:

ThinkPad には外部の HDMI モニターを接続するために、USB-C Apple AV アダプタを転用して使っていましたが、接続したまま PC の電源を入れると画面が真っ黒になり Ubuntu 22.04 LTS がブートできない様子でした。5.15.0-27-generic にて確認。

対応する元気が出なかったので、いったん AV アダプタを使わず、本体の HDMI に直接モニターを接続するようにしたら good work となりました。(継続検証)

外部PPA と Snap アプリケーション:

登録している PPA は次のとおりです。

http://jp.archive.ubuntu.com/ubuntu jammy InRelease
http://jp.archive.ubuntu.com/ubuntu jammy-updates InRelease [109 kB]
http://jp.archive.ubuntu.com/ubuntu jammy-backports InRelease
http://packages.microsoft.com/repos/edge stable InRelease
http://jp.archive.ubuntu.com/ubuntu jammy-updates/main amd64 DEP-11 Metadata [6,632 B]
http://jp.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 DEP-11 Metadata [19.2 kB]
https://packages.microsoft.com/repos/code stable InRelease [10.4 kB]
https://packages.microsoft.com/repos/code stable/main arm64 Packages [82.7 kB]
http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
https://packages.microsoft.com/repos/code stable/main armhf Packages [82.6 kB]
http://archive.ubuntu.com/ubuntu jammy InRelease
http://ppa.launchpad.net/mmk2410/intellij-idea/ubuntu jammy InRelease
https://deb.nodesource.com/node_16.x focal InRelease
http://security.ubuntu.com/ubuntu jammy-security/main amd64 DEP-11 Metadata [6,632 B]
https://ppa.launchpadcontent.net/kicad/kicad-6.0-releases/ubuntu jammy InRelease

VSCode や Microsoft Edge、KiCAD、Intellij IDEA、Node.js 16 などうまく動作しています。

Lovery Composer Snap Linux 版も良い感じです…! Linux でもレトロぴこぴこシンセの打ち込みを楽しめます。:D

デスクトップアクセサリーの MaCoPiX もソースコードからビルドして起動できました。

$ sudo apt install libgtk-3-dev
$ git clone https://github.com/chimari/MaCoPiX.git
$ cd MaCoPiX
$ ./configure
$ make -j8
$ src/macopix

Ubuntu 22.04 LTS は、Wayland セッションが前述の理由でまだ使えないのが寂しいですが、GNOME 系のアニメーションもスムーズになって良さそうな雰囲気です。Snap 版 Firefox も今の所、げ!というところはなさそうです…(今後あるかもですがw

LTS 版にて5年間(+5年延長)、引き続き Ubuntu にお世話になります。ちなみに、メインで使う OS を Ubuntu (8.04から) にしてから 14年くらい経つようです。ひー。

M5Stamp C3 用の開発向けボードを製作

M5Stack から発売されている ESP32-C3(RISC-V) が搭載されているマイコン、M5Stamp C3 用の開発向け基板を製作してみました!

Main Board

基板の特徴

  • JTAG デバッグのための外部 USB Type-C ポートの接続。
  • よく見かける KMR-1.8 とマークされた安価な LCD/SD の SPI 接続。
  • 電源入力の選択。M5Stamp 側か USB Type-C 側かの切り替えジャンパーピン。
  • ローダーモードに入れるための GPIO9 に接続されたタクトスイッチ(通常のスイッチとしても利用可能です)。
  • 利用可能な GPIO を外部に公開するピンヘッダーの接続。
  • 使われていない GPIO は GPIO 0(SPI CS を想定)と JTAG とは競合する GPIO18, 19(I2C 接続を想定)
  • 名刺サイズ(90x55mm)の基板です。

となっていて、手軽に RISC-V やマイコンプログラミングを楽しみやすいものを目指しました。

オープンソースハードウェア

基板のガーバーデータや部品表、サンプルのプログラムを次の GitHub リポジトリーにコミットしてあります。

https://github.com/h1romas4/m5stamp-c3dev

This is a development board for the M5Stamp C3 (RISC-V/FreeRTOS).

ソースコード、基板ガーバーデータ含め MIT License に設定しています。

ガーバーデータを元にご自身で PCB メーカーに製造発注可能です。なお、リポジトリに含まれている .zip は Fusion PCB 向けの設定になっています。(おそらく他でも大丈夫と思いますが、KiCad 6 形式のファイルも含めていますので、設定を変えることもできます)

基板頒布

また、BOOTH で完成品の基板(部品なし)の頒布も行っています。 2枚セット 130円で、匿名配送可能な BOOTH あんしんパック送料込みで 500 円になるように設定しています。(個人で製造発注しているため在庫がない場合が多々あります。入荷お知らせメールを設定していただければと思います)

FG06-C3DEV REV.B (2枚) – M5Stamp C3 向けの開発用基板 – 部品なし基板のみ

サンプルプログラム

GitHub にコミットしてあるサンプルプログラムには以下の実装が入っています。

  • 日本語 TrueType フォントの液晶への出力
  • SD カード内の PNG 画像の液晶への出力
  • WiFi 接続による NTP 同期
  • GPIO 0 の ADC 入力
  • M5Stamp C3 に付いている RGB LED の点灯
  • GPIO 18, 19 への I2C センサー接続テスト(UNIT ENV III の温度湿度気圧センサー)
  • AssemblyScript を使ったアナログ時計のサンプル(Wasm3 による WebAssembly の実行)
AssemblyScript and Wasm3
  • AssemblyScript を使った GPS GSV Viewer の実装(Wasm3 による WebAssembly の実行)

またその他の実装として、

  • TrueType フォントと .wasm バイナリーを格納している SPIFFS の使い方(parttool.pyspiffsgen.py ツール)
  • WiFi パスワードを格納している NVS(暗号化可能なキーバリューストア)の利用(nvs_partition_gen.py ツール)
  • esp-idf ビルドシステムを使ったライブラリーのビルド、依存関係の管理
  • Visual Studio Code の C/C++ Extention の設定と openocd と連携した JTAG デバッグ設定
  • AssembyScript をウェブブラウザーとマイコンで共有する手法

などなどがありますので、この基板に限らず ESP32-C3 や M5Stamp C3 を使う場合の参考になるかもしれません。 GitHub を眺めていただけたらと思います。

ビルドは Windows/Linux/macOS のそれぞれで正常に終了することを確認しています。

M5Stamp C3/ESP32-C3 は、メモリーの malloc もしやすく使いやすいマイコンだと感じました。 Wasm3 の末尾呼び出し最適化なども esp-idf の RISC-V コンパイラツールチェインでうまく動作するようです。

M5Stamp C3 への書き込みとデバッグブレイク方法

プログラムの upload と debug については以下の記事を参考にしてください。Windows WSL2 を使うと、設定も手軽で安定して動作させられます。


ここから下はご参考情報です。

M5Stack Core2 上での同サンプルの動作

Wasm3/AssemblyScript については、M5Stack Core 2 版も作成しています。

https://github.com/h1romas4/m5stack-core2-wasm3-as

M5Stack Core2 With Wasm3/AssemblyScript Demo

M5Stamp C3 版と同じ .wasm を動作させています。ウェブブラウザーからも動作を見ることができます。

https://h1romas4.github.io/m5stamp-c3dev/asclock/

AssemblyScript Analog Clock Sensor values are dummy.

良ければ遊んでみて下さい 😀

Main Board

関連

WebAssembly をウェブブラウザーで活用する(2)

この記事はゆるWeb勉強会@札幌 Advent Calendar 2021の 3日目の記事です。

去年のアドベントカレンダーより…

自分は、去年のゆるWebアドベントカレンダーで書きました…

WebAssembly をウェブブラウザーで活用する(1)

次の回では、C/C++ もしくは Rust でかかれたプログラムを WebAssembly に移植して動作させるデモをやってみたいと思います!(続く

次の回になるまで 1年かかりました…(すいませんw

というわけで、今年の記事はここ数ヶ月取り組んでいました C/C++/Rust のプログラムを WebAssembly で動作させた顛末を例に、Wasm(WebAssembly の略です) の周辺技術事情やキーワードを書いていきたいと思います。

WebAssembly とは

WebAssembly はバイナリーの実行コード形式です。C/C++/Rust/AssemblyScript をはじめとするさまざまな言語を .wasm 拡張子のバイトコードにコンパイルすることができ、それらの言語でかかれたプログラムを、ウェブブラウザーや WebAssembly ランタイム上で動作させることができます。

画像

特にウェブブラウザーは、これまでコンピュータ言語として JavaScript のみをネイティブでサポートしていましたが、WebAssembly の仕組みを使うことで、別の言語でかかれたソフトウェアやライブラリーを活用することができるようになりました。

中でも C/C++/Rust はシステムやミドルウェアよりのライブラリーの実装が多くありますので、画像・動画処理、文字列パーサー、仮想マシン、3D 処理、ファイル圧縮展開、そして今回取り上げる音声処理など従来 JavaScript で再実装が必要になっていた部分を、WebAssembly にビルドするという手順だけで手軽にウェブブラウザーに持ち込めます。

まずは、今年2021年に気になった WebAssembly の実装をいくつか紹介します。

⏩ Adobe Photoshop の WebAssembly による実装:

おそらく画像処理部分の C/C++ コードをクライアント版と共有していると思います。

Adobe PhotoshopにWebブラウザ版が登場。何ができる?

配信中では宇宙飛行士のヘルメットガラスの反射を修正ツールで取り除き、また色味を調整するなどの内容が披露。操作に伴うレスポンス遅延等もみられない、スムーズな編集を実現していることが示された。

ちなみに、Chromium 系のブラウザーの開発者ツールに、直接 C/C++ ソースのデバッグができる仕組み(と拡張)が追加されたのは、Web 版 Photoshop をつくっていたからという話がありました。

https://twitter.com/h1romas4/status/1348242121631830017

⏩ WebAssembly で動作可能な Rust でかかれた形態素解析 Goya:

日本語形態素解析がウェブブラウザー上で動作します。形態素解析系はビルドが大変だったりしますので、.wasm 版があるのは大変ありがたいです。

WebAssemblyの形態素解析器GoyaをRustで作った

Goyaという形態素解析器を Rust で作りました。本記事は利用者目線で Goya の紹介をします。技術的な詳細については別途記事を書きます。

⏩ Python の WebAssembly 版の Pyodide:

CPython が C/C++ で実装されていることを利用して、インタープリタ・ランタイムごと Wasm にビルドし、ウェブブラウザー上で Python を実行し、導入の操作なしに Python を使うことができます。

Try Pyodide (no installation needed)

Try Pyodide in a REPL directly in your browser. For further information, see the documentation.

⏩ PHP の WebAssembly 版:

Pyodide と同様に PHP のインタープリタも C/C++ ですので Wasm にビルドしてしまえば、あろうことか PHP がウェブブラウザーで動作します。 😀

PIB: PHP in Browser (and Node.js) aka php-wasm

https://seanmorris.github.io/php-wasm/

WebAssembly で実装されたシンセサイザー

今回の Wasm 実装例とするプログラムは WebAssembly にビルドされたシンセサイザーです。

次のリンクから動作を確認できます。(後述しますがマルチスレッド(SharedArrayBuffer) を使っている関係で iOS/Safari では現在動作しません)

https://chipstream.netlify.app/

画面をクリックするとサンプルの音楽が再生されたと思いますが、この音声波形生成(シンセサイズ)を C++/Rust でかかれた WebAssembly で行っています。

シンセサイザーとは “音” を電子機器を使って生成するハードウェア・ソフトウェアの総称です。

音を電子機器でつくる方式はいろいろあり、現在は PCM と呼ばれる録音した波形をコンピュータで変化させる方式が主流で、イメージとしてはピアノのラの音(440Hz)をマイクで収録し、それをコンピュータの演算で 880Hz にして高いラにして発音させるようなことをしています。(実際にはもっと複雑です)

ここで作成したシンセサイザーは FM 音源と呼ばれるシンセサイザーの方式で、サイン波(口で発声するのなら、”ポー”みたいな電子音)をサイン波で変調することで倍音を加え、デモのような電子音のような、そうでないような美しい不思議な音を発音させることができます。

画像

1980年代に非常に多く使われたシンセサイザーの方式で、日本で一番なじみがあるのが山手線のホームで流れる発車音のエレピの音だと思います。また 1990年台のゲーム基板や、2000年台初頭のガラケーにも搭載されていましたので、ゲームセンターや着メロで聞き覚えがある方もいらっしゃるかもしれません。

WebAssembly でできること

よくWebAssembly は計算しかできないと言われますが、まずはその通りで今回のシンセサイザーの例でも波形の計算を C++/Rust で行っています。

音声波形計算の単純な例をあげると、1秒を 44100(サンプリング周波数)で割った配列をつくり、16bit(量子化ビット数)の -32768 〜 32767 の値で 440Hz のサイン波をつくれば”ポー(ラー)”波形の計算となります。このシンセサイザーに、ラを0.5秒鳴らせといった演奏データ(シーケンス)を渡すことで音楽となる手はずです。

WebAssembly が計算しかできないと言われるゆえんは、WebAssembly からホストとなる(この場合はウェブブラウザー)の機能には直接アクセスできないことで(ユーザと対話できない)、今回の場合も計算された波形はブラウザーの JavaScript を経由して WebAudio API に渡して発音してもらうようなプログラムとなっています。

ソースコードを以下に公開していますので興味がある方は覗いてみてください。

実際には ymfm という C++ でかかれた YAMAHA FM 音源チップのエミュレーションライブラリーを、演奏データの制御やサウンドチップのサンプリングレートのコンバートを行う Rust のプログラムとリンクする形で動作しています。

https://github.com/h1romas4/libymfm.wasm

This repository is an experimental WebAssembly build of the [ymfm](https://github.com/aaronsgiles/ymfm) Yamaha FM sound cores library.

使わせてもらっている ymfm ライブラリーのソースコードは一切触れることなく、そのまま WebAssembly にビルドしています。Rust と C++ をリンクして動作する Wasm の例としても見ることができるかもしれません。

その他、リアルタイム音声処理に関しては処理の遅れが音切れという形で現実世界に悪影響を及ぼしますので、マルチスレッド(WebWorker)を使っていたり、同期するために SharedArrayBuffer を使っていたり、従来から使われている ScriptAudioProcesser ではなく AudioWorklet を使っているなど、 WebAssembly との組み合わせもあまり見ないサンプルになっていますので、JavaScript 的にも、もしかすると参考になるかもしれません。

なお、スレッド同期に使っている SharedArrayBuffer の iOS/Safari での実装が 2021年 12月現在テクニカルプレビュー中です。次のリリースあたりで使えるようになると思いますが、現在は Safari で動作しません。そのうちに動作し始めると思います。

ウェブブラウザーを超えて

さて、JavaScript がウェブブラウザーから飛び出し Node.js や Deno といった形で取り出されたように、WebAssembly にも同様なランタイムがあります。

いろいろな実装があり群雄割拠している状態ですが、自分が使っているものをいくつか紹介します。

wasmtime

Standalone JIT-style runtime for WebAssembly, using Cranelift

Wasmer

Run any code on any client. With WebAssembly and Wasmer.

Wasm3

The fastest WebAssembly interpreter, and the most universal runtime

wasmtime がリファレンス実装的な印象で、Wasmer は高速で各言語バインディングが充実、Wasm3 は JIT を使わないインタープリタ型で JIT 禁止の iOS 環境でも動作可能、また最小構成で Arduino などのマイコンでも動作といった特徴があります。

WebAssembly ランタイムはもちろん単体で .wasm を動作させることができますが、さまざまな言語をホストとして .wasm を実行をする仕組みが備わっています。

“wasmer-python” を利用して、この記事でウェブブラウザーで呼び出したシンセサイザーの .wasm ファイルとまったく同じものを Python から呼び出してサウンドプログラミングした動作例が次の動画となります。(ソースコード: https://github.com/h1romas4/libymfm.wasm/tree/main/examples/python

.wasm は OS を選びませんので、ランタイムと組み合わせることでウェブブラウザー(JavaScript)に限らずさまざまな言語から呼び出して活用することが可能です。

Wasmer の言語対応:

特に C/C++ でかかれたライブラリーのスクリプト言語からの呼び出しは、使われる範囲的にインターネット経由の入力が伴うことが多く、セキュリティーの面で気になる部分がでてきますが、Wasm をかぶせることでサンドボックスとなり安全性が高まり、また OS の依存もなくなりますので扱いが簡単です。 .wasm がひとつあればどこでも動作します。

PHP で画像処理したいと思ったら wasmer-php で Wasm ビルドした C/C++ ライブラリーを安全に使う…なんていうのもアイディアかもしれません。

最近ではソフトウェアのプラグインシステムとしても WebAssembly を活用し、そのソフトウェアがつくられた言語以外でプラグインをかけるようにしているしている例もみられるようになりました。

zellij

Zellij includes a layout system, and a plugin system allowing one to create plugins in any language that compiles to WebAssembly.

まとめ

  • WebAssembly はいろいろな言語でつくられたソフトウェア・ライブラリーを、ウェブブラウザーやランタイム上で OS を選ぶことなく動作させることができる。
  • WebAssembly のランタイムと各言語のバインディングを使うことで、言語を他の言語で拡張して使うこともできる。

WebAssembly の今後は「計算しかできない」を解決していく Interface Type や WASI といった仕様の策定・実装、GC やマルチスレッドの対応の強化が進み、活用範囲や対応言語も増え、目にする機会も増えるかなと思っています。クラウドの Lambda 的な部分での採用も増えていきそうです。

面白いことがあればぜひ教えてください。てなわけで、また来年(!?)…!

ツイッターやってます:

ゆるWeb勉強会

ゆるWeb勉強会とは札幌で開催している @tacck さん主催のWeb系勉強会で、現在はオンライン配信も行っていてどなたでも参加できます。いろんな方の発表を聴き、またわいわい質問もすることができますので、興味がある方は覗いてみてください!

ゆるWeb勉強会@札幌

主に「Web」というキーワードに関する、ゆるい勉強会です。 プログラムを始めたばかりの人も、仕事でバリバリやっている人も、どなたでも歓迎です!

「勉強し初めて、次に何をやればいいんだろう?」 「普段使っていない言語やフレームワーク、知っている人に導入部分を聞いてみたい。」 「いつもはバックエンドだけど、たまに触るフロントエンドの話も知りたい。」 「実際、みんな現場ではどうやって開発してるの?」

仕事・趣味を問わず、普段の仕事の内容も問わず、「Web系」に関することを、ゆるっとみんなで話してみたいです。

関連