AWS Lambda で読みがな変換関数を作成する

とある用途で日本語文字列→読みがなの変換処理が必要となったので、AWS Lambda で動作する関数を作成しました。ひらがなに変換する処理で MeCab を、ひらがなからローマ字に変換する処理で KAKASI を使います。KAKASI にもひらがな変換の機能は有りますが、今回の用途では MeCab の方が精度が良かったため、こういう構成となりました。

Python であれば mecab-python3 と pykakasi を使えばプログラムから呼び出せるので、Lambda レイヤーで mecab-python3, pykakasi の環境を作って Lambda 関数で呼び出すようにします。

mecab-python3, pykakasi がインストールされたディレクトリを zip ファイルにまとめてから Lambda コンソールにアップロードします。Lambda は内部的には Amazon Linux 2023 なので、一旦別の Amazon Linux 2023 環境で mecab-python3, pykakasi をインストールしてから zip ファイルを作ります。Amazon Linux 2023 を利用できる環境としては EC2, Docker イメージ, AWS Cloud9 などがありますが、今回は Docker イメージでやりました。
Lambda のランタイムとしては python3.12 も使えますが、Amazon Linux 2023 でパッケージインストールできる python3.11 を採用しました。

$ mkdir mecab-kakasi-python3.11
$ cd mecab-kakasi-python3.11
$ mkdir layers
$ vi Dockerfile
$ vi docker-compose.yml
$ vi laysers/requirements.txt

Dockerfile

FROM amazonlinux:2023

RUN dnf install -y zip python3.11
RUN dnf install -y python3.11-pip
RUN curl https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py
RUN python3 /tmp/get-pip.py

RUN pip3 install setuptools
RUN mkdir /home/layers
RUN mkdir /home/python

docker-compose.yml

version: '3'
services:
  aws-lambda-layers:
    build: .
    volumes:
      - './layers:/home/layers'
    working_dir: '/home/'
    command: sh -c "python3.11 -m pip install -r layers/requirements.txt -t python/ && zip -r layers/file.zip python/" 

requirements.txt

boto3==1.34.54
mecab-python3==1.0.8
ipadic==1.0.0
pykakasi==2.2.1

Docker コンテナ上で上記の設定ファイルを使って環境構築します。

$ sudo docker compose build
$ sudo docker compose up

layers/file.zip が作られたことを確認します。

$ unzip -l layers/file.zip |head
Archive:  layers/file.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2024-03-03 16:10   python/
        0  2024-03-03 16:10   python/boto3-1.34.54.dist-info/
    10174  2024-03-03 16:10   python/boto3-1.34.54.dist-info/LICENSE
     7546  2024-03-03 16:10   python/boto3-1.34.54.dist-info/RECORD
     6620  2024-03-03 16:10   python/boto3-1.34.54.dist-info/METADATA
        4  2024-03-03 16:10   python/boto3-1.34.54.dist-info/INSTALLER
       92  2024-03-03 16:10   python/boto3-1.34.54.dist-info/WHEEL

file.zip を S3 にアップロード(約30MBあって Lambda コンソールで直接アップロードできないため)してから Lambda レイヤーを作成します。
Lambda コンソール > レイヤー > レイヤーの作成

  • 名前: mecab-kakasi
  • Amazon S3 のリンク URL: アップロードした先の URL
  • ランタイム: python3.11

Lambda コンソール > Lambda 関数 > 関数の作成

  • 一から作成
  • 関数名: hiragana_roman
  • ランタイム: python3.11
  • アーキテクチャ: x86_64
import json
import MeCab
import ipadic
import pykakasi

def lambda_handler(event, context):
    mecab = MeCab.Tagger(f'-Oyomi {ipadic.MECAB_ARGS}')
    kks = pykakasi.kakasi()
    return {
        'statusCode': 200,
        'body': kks.convert(mecab.parse(event['src']).rstrip())
    }

テスト用のイベントJSONとテスト実行結果です。

{ "src": "SPLOUT株式会社" }
{
  "statusCode": 200,
  "mecab": "SPLOUT カブシキガイシャ\n",
  "body": [
    {
      "orig": "SPLOUT",
      "hira": "SPLOUT",
      "kana": "SPLOUT",
      "hepburn": "SPLOUT",
      "kunrei": "SPLOUT",
      "passport": "SPLOUT"
    },
    {
      "orig": "カブシキガイシャ",
      "hira": "かぶしきがいしゃ",
      "kana": "カブシキガイシャ",
      "hepburn": "kabushikigaisha",
      "kunrei": "kabusikigaisya",
      "passport": "kabushikigaisha"
    }
}

Androidアプリでバーコードリーダーから値を受け取る

先日、Android タブレットにUSBでバーコードリーダーを繋いでアプリで読み取る実装を経験しました。基本的にUSB接続のバーコードリーダーはキーボードと同じです。読み取った文字列のキーコードを1文字ずつ送りつけてエンターで終わります。

Android アプリでは setOnKeyListener の onKey でキーイベントを拾って1文字ずつ処理します。プログラムの流れとしては、ループで1文字ずつ繋げてエンターキーを受け取ったら繋げた文字列を処理用の関数に渡す、となっています。コードはこんな感じです。

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View rootView = binding.getRoot();
        rootView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View view, int i, KeyEvent keyEvent) {
                if (keyEvent.getAction() != KeyEvent.ACTION_UP) { // キーが押されたときが ACTION_DOWN, 離されたときが ACTION_UP
                    return false;
                }
                int keyCode = keyEvent.getKeyCode();
                if (keyCode == KeyEvent.KEYCODE_ENTER) {  // エンターキーが押されたら終了。ここまで繋げてきた数字の列を処理する。
                    processValue(scannedDigits); 
                    scannedDigits = "";
                    return false;
                } else if (keyCode < KeyEvent.KEYCODE_0 || KeyEvent.KEYCODE_9 < keyCode) { // 数字以外の文字は無視する
                    return false;
                }
                scannedDigits += (char) (keyCode + 41); // ASCII コードに変換
                return false;
            }
        });

        return rootView;
    }

上記は数値をバーコード化したものを読み取る処理です。 KeyEvent.KEYCODE_0とKeyEvent.KEYCODE_9でキーコードの範囲を限定しています。

最初はバーコードリーダーという自分にとっての未知のデバイスを前に身構えていたものの、PCに接続して読み取った文字列をエディタに反映させたりブラウザのフォームを埋めたりしているうちにキーボードと同じという実感を得ていく作業は大変楽しいものでした。

AIで音楽を作ってみました

こんにちは。開発担当のマットです。
このあいだ、友達を家に招いたら、楽器を持ってきました。
持ってきたものは、ディジュリドゥでした。

ディジュリドゥが母国のオーストラリアの先住民が使う吹奏楽器です。
子供の頃、叔父の家に一つあったのでちょっとだけ使ったことがありますが、
不慣れのディジュリドゥを吹いてみるとすぐに息が切れて、中々演奏できませんでした。

楽器を使って、音楽を作れたらカッコいいな〜と思ったら…

パソコンならできる?

実際の楽器なら演奏できる能力がない。
ただし、パソコンなら、ソフトウェアを使って、何かを作曲できそう!

と思ってみて、GarageBand という音楽制作ソフトを開いてみて、やってみたら・・・

なんじゃこれ・・・・完全に駄目ですね。真剣にやってみます。
GarageBand の使い方をなんとか勉強して、20分掛けてみたら、以下の曲を作れました。

なにこれ・・・w

壁が見えてきました

まず、GarageBand の音楽作成ソフトの使い方を覚えないといけない壁が一つ。
つぎ、音楽論など、音楽を作成する時に必要な最低限の知識を覚えないといけないので、壁が二つ。
そして、元々センスがない自分がなんとか、センスを付けないといけない壁が三つもあります。

難しいですね。

今どきの壁を破るAI

音楽なら、AIが作れますよね〜

ネットで探してみたら、多数の音楽生成のAIを見つけましたけど、自分が求めているものを見つけられませんでした。ほとんどのサービスが決められているテーマや楽器の組み合わせを使って、音楽を作れる便利なサービスですが、僕は求めていたのはクリエイティビティ。

・「背景を和太鼓にする」
・「テンポをちょっと落とす」
・「途中でバイオリンのソロを入れる」

など・・・このようなことをお願いしたら、やってくれるAIが欲しかったです。

話し相手を求めるなら・・・ChatGPT

このような人間の言葉を理解してくれるのは ChatGPT でしょう。
ChatGPT で完全に思う通りの音楽を作ってみることにしました。

まず、簡単な MIDI ファイルを作ってくれるようお願いしてみたら、以下の返答をもらいました。

「よかった!簡単にできる!」と思ったら、ChatGPT が嘘をついていました。
ファイルに保存して、.midi の拡張子を付けても、使い物になりませんでした。
よくよく調べてみたら、参考となった別のプロジェクトを見つけました。

全く別の形式なものを ChatGPT に作ってもらって、
それを pythonのライブラリーで変換しなければならない。

python で変換…(大変になってきた)

かなり、大変なことになってしまいましたが、Google Colab で python のスクリプトをコピーして、
ChatGPT に、新たな曲をその形式で求めて実行してみます。

ChatGPTのテキストをMIDIに変換するpython コード

ChatGPT に「複数な楽器を同時に演奏する曲」をお願いしてみました。
何度も何度も繰り返してみました。時には、フォーマットが不正な回答だった。
時には、複数の楽器の演奏があったけど、同時演奏ではなかったなど。

何度も頑張ってやったら、やっと、一つの曲をなんとか作れました。

フルートはかなりの耳障りですが・・・・ChatGPT に音楽を作ってもらったことでなんとか嬉しい気持ちです。

AIの未来

ChatGPT は言語専用のAIですが、実は Google の MusicFX も見つかりました。
日本では使えないツールですが、オーストラリアからアクセスしてみたら、ログインができて、使うことができました。

このツールを使えば、言葉だけで音楽を生成することができます。

まずは、
1)「Caribbean relaxing music with snare drums」(スネアドラムを使ったカリブ海風のくつろげる音楽)

次は、
2) 「Opera with Electric Guitars」(エレキギターを使ったオペラ)

最後は、もともと作りたかったもの
3) 「Rock and Roll with a Didgeridoo」(ディジュリドゥを使ったロックンロール)

まとめ

MusicFXの結果がかなり優れていて、びっくりはしましたけど、その反面、簡単な MIDI ファイルを作るだけでも大苦労でした。

今後、AIが進化するに連れ、このようなツールが数多くなって、力強くなると思います。
いずれ、僕のような音楽の初心者でも、完全にいいものを作曲できる日を楽しみにしています。

時計はなぜ「12」から始まるの?

時計を眺めていた時、ふと時計の表記は12進数を使ってるけど 12 から始まるのは変だなぁと思いました。

目覚まし時計のイラスト

時計は「12」を頂点に右回りに1から11までの文字が並んでいますが時間の表記が12進数をつかっている理由と12が頂点になっていることについて調べてみました。

n進数について

n進数とはn種類の数を用いて数を表現するやりかたで
例えば、10進法は0,1,2,3,4,5,6,7,8,9の10種類の数を用いており
9のつぎは桁が繰り上がり10となります
2進法は0,1の2種類の数を用いており
1の次は桁が繰り上がり10となります

以上のことより二つの法則がわかります
・0から始まる
・nの数で繰り上がる

このn進数を使うことで膨大な数を表したり数を一定のまとまりで把握することができます
これを先ほどの時間に当てはめると

午前午後にわけて12等分した数で表せる為、
0 ~ 11の12進数で構成されています

しかし時計は「12」が頂点になっており「0」は表記されていません
なぜでしょうか

時計が「0」の表記がない理由

諸説ありますが時間と数学の歴史が時間的にズレているの起因だと言われております。時間の概念が生まれたのは紀元前15世紀頃のバビロニア人だと言われております。
バビロニアの人々は太陽の日の出の際見え始めから完全に見えるまでの時間を基本単位と定め、太陽が沈むまでにこの基本単位がどれくらい繰り返すか数え720回で太陽が沈むことに気づきました。そこから様々な方法をつかい、年と日を12進数法で時間と分を60進法で表すようにしました。

次に「0」が発見された時期ですが8世紀のインドだと言われております。
つまり「0」が発見される前から時間の概念は存在しておりさらに時計も存在していました。「0」の代わりに「12」を使っていたとのことです。
その時点で浸透した為、修正せず現代まで受け継いでいるのが理由とのことです。

時計が紀元前から存在していたこととこれだけの時代をたっても形が変わっていないこと
なんかロマンを感じますね

Amazonセールでゲット!意外とよかったアレクサ

毎年11月、Amazonは「Amazonブラックフライデー」というセールを開催しており、このセール期間中、Amazon自社製品が特にお得な価格で提供されます。私はこれまでアレクサにあまり興味がありませんでしたが、アレクサデバイスの1つ「Echo Pop」が1,980円(定価5,980円)というお手頃な価格で販売されているのを見て、購入してみました。

初めは、「アレクサ、本当に役立つのかな?」と少し疑問に思っていましたが、実際に使ってみると、その便利さに驚かされました。特に注目したいのは、アレクサとスマートリモコン(別売り機器)を組み合わせることで、家電を音声で操作できるようになる点です。これまでは電気やエアコンをそれぞれのリモコンで操作していましたが、「アレクサ、電気とエアコンをつけて」と一言で両方を操作できるようになりました。家事の最中など手が塞がってるときに声で操作できるのは非常に便利です。

またアレクサには、特定のフレーズを呼びかけてアレクサに実行してほしい動作を登録する「定型アクション」という機能があります。
これを使うと友人のプライベートな情報、例えば「アレクサ、太郎君について教えて」という音声指示に対し、「太郎君は大阪市在住で三人兄弟の末っ子、遅刻癖があり時間にルーズです」というような返答を設定すると、太郎君が訪れた際に、「え、なんでこんなことまで知ってるの??」とアレクサを使ってちょっとしたサプライズができるのも面白いです。

さらに、アレクサにはオリジナルソングが多数存在します。「アレクサ、歌って」と呼びかけることでいろんな曲を披露してくれたり、「アレクサ、大好き」と伝えると、「大好きって言ってくれてありがとう」と感謝のラブソングを歌ってくれるのも、とても可愛らしく感じます。相手は機械なのに愛着が湧いてくるのがアレクサの良いとこです。

まとめると、単に音楽を聴くだけではなく、アレクサは実用性に加えてエンタメ要素もあるので想像以上に多くのシーンで活用できます。Amazonのセール時には特にお得に手に入るので、興味がある方は是非試してみてください。