懐かしの昭和シェル芸…で電話番号を押さずに電話をかけたり演奏したり(DTMF)


DTMFというものを知っていますか？
細かい話は置いておき、以下のシェル芸で数字(+ ABCD#*)を変換し、DTMFの音を再生できます。

```bash
echo "0123456789#"|xargs -I@ bash -c 'gen -t raw -d "@" $0|aplay --rate 22050 --format S16_LE $0' `mktemp -ut XXX.raw`
```
このシェル芸を持って1996年あたりにタイムスリップすればもしかすればモテる[^1][^7]かも……[^2]
プッシュ音(DTMF)だけ、演奏できることで有名なメリーさんのひつじを鳴らすのに利用できたりもします。

```bash
echo "3212333222399321233322321"|xargs -I@ bash -c 'gen -t raw -d "@" $0|aplay --rate 22050 --format S16_LE $0' `mktemp -ut XXX.raw`
```

https://x.com/amanoese/status/1730996498991870148?s=20

2023年現在でも、一部の電話機ではこのシェル芸を使って電話をかけることができます。。。たぶん。


もしかしたら、Twilioや自動応答サービスのテストを行うのに役に立つかもですね。

## Dependency

利用しているコマンドとインストール先は以下になります。
 - gen -> [multimon](https://packages.ubuntu.com/jammy/multimon) 
 - play -> [sox](https://packages.ubuntu.com/jammy/sox)
 - aplay -> [alsa-utils](https://packages.ubuntu.com/jammy/alsa-utils)

```bash
apt-get install multimon sox alsa-utils 
```

## コマンドの解説

DTMFで利用できる数字(+ ABCD#*)を、音声ファイルに変換できる[multimonというパッケージ](https://packages.ubuntu.com/jammy/multimon)に含まれるgenというコマンドがあります。
少しクセの強い[^4]コマンドですが、一応以下のようにすると利用できます。

```bash
$ gen -t raw -d 0123456789 ./output.raw 
gen - (C) 1997 by Tom Sailer HB9JNX/AE4WA
```
genコマンドには -t で指定できる拡張子がrawのみというバグがあります。[^5] [^6]
そのため再生するのが若干難しいです。

生成したDTMFは、aplayコマンドやplayコマンドで再生できます。
```bash
$ aplay -r 22050 -f S16_LE output.raw
再生中 raw データ 'output.raw' : Signed 16 bit Little Endian, レート 22050 Hz, モノラル
$ play -b16 -r22050 -c1 -e signed-integer output.raw
```
aplayの方が若干指定するパラメータ少なめで再生できるぽいです。

このgenコマンドとaplayコマンドを利用して、電話番号をDTMFに変換し即座に再生したくなりますが、genコマンドは出力がファイルになっており、またファイルに/dev/stdinも指定できません。
```bash
## すでにファイルがある場合
gen -t raw -d 0123456789 ./output.raw 
gen - (C) 1997 by Tom Sailer HB9JNX/AE4WA
open: File exists

## 標準出力に出したい場合
gen -t raw -d 0123456789 /dev/stdin 
gen - (C) 1997 by Tom Sailer HB9JNX/AE4WA
open: File exists
```

仕方ないのでmktempで一時ファイルを作成して、再生します。
```bash
mktemp -ut XXX.raw|xargs -I@ bash -c 'gen -t raw -d 0123456789 @|aplay --rate 22050 --format S16_LE @'
再生中 raw データ '/tmp/Xtm.raw' : Signed 16 bit Little Endian, レート 22050 Hz, モノラル
```
しかし、このコードだとDTMFに変換したい数字がワンライナーの中間に入ってしまっていて番号の指定が面倒なので、bashをうまく使って数字が前に来るように修正します。

```bash
echo "0123456789"|xargs -I@ bash -c 'gen -t raw -d "@" $0|aplay --rate 22050 --format S16_LE $0' `mktemp -ut XXX.raw`
```
完璧ですね？

## 余談

スマホが普及した今では、電話番号を入力することは少なく、また音声電話自体が利用されることも減ってきたかもしれませんが、DTMFは今でも電話での自動音声サービスやアマチュア無線では利用されている…のはずです。

ちなみに私は、暗号を学んでいる過程で知った、ポケベル暗号が面白く、その背景や技術[^3]を知りたくてDTMFとそれを利用するためのコマンドを知りました。

さらにこの記事のタイトルにある昭和の文字ですが、ポケベルの全盛期は1996年らしいので、どちらかというと昭和シェル芸ではなく平成シェル芸かもです。。。

この記事が誰かの役に立てば幸いです。

[^1]: 当時電話から番号を入力することで、電話先のポケベルに数字を送ることができたようです。数字だけで送るメッセージはポケベル暗号と俗称され、2タッチ入力[^3]が出た後も、公衆電話から10円の通話時間内に相手にメッセージを送れるはかなり重要で、当時の若者でプッシュ正確かつ早い人は一目置かれる存在だったという噂ですが……当時の正確な資料は見つからず真偽はわからないです。

[^2]: ポケベル全盛期は1996年？のようですが、Linuxの歴史は1991年からになります。また、利用しているコマンドやライブラリのリリース日を見る限りではこのシェル芸が当時使えるかは怪しく……他の技術を学ぶのが良いかもしれません。

[^3]: 2タッチ入力では任意のアルファベット/数字/かな文字を送信できるようになりました。良い技術なのですが、ポケベル暗号の文化の方が個人的に好みでした。

[^7]: このシェル芸の機能と似た機能で、当時製品化されていたトーンダイヤラーはとても高価だったらしいです。

[^4]: manに書かれているEXAMPLEのコマンド例が実行できなかったり、作成したファイルの再生方法の記載がなかったり、コマンド実行のたびに作者名が表示されたり、メンテナスも絶望的かもです。

[^5]: ちなみにmultimonにあるgenコマンドは内部でSOXを利用して音声ファイルを作成しているのですが、
そのSOXコマンドをファイルタイプのパラメータ指定の方法が古いため発生しています。

[^6]: さらに後継のプロジェクトぽいmultilon-ngでは、バグ[^4]の問題は修正されていますが、修正されたgenコマンドがbuildに含まれてないため修正されたgenを利用できない悲しみがあったりします。。。