こんにちは。電子的な音に妙にワクワクしてしまうイシイです。今回は、音声を使ってデータのやりとりを行うことができるChirpというものを使ってみます。

Chirpとは

ロンドンに拠点を置く『Chirp』は、特殊な音声を介してデータをやりとりすることができるテクノロジーで、2012年くらいからiOS/Androidでアプリを提供していたようなのですが、最近SDKをデベロッパー向けに開放したことで、また改めて注目されるようになったようです。

サクッとどんなものかを試してみたい場合には、AppStoreまたはGooglePlayからアプリをインストールして、Exampleのページで流れる音声をアプリに読み込ませることで試すことができます。

音声データを介してやりとりをする方法としては、人には聞こえない周波数帯に、解析できる音声信号を音源に埋め込んでやりとりをする「音透かし」が最近の主流ですが、Chirpでは0-9とa-vで構成される合計32文字のシリアル化されたデータを音声トーンに変換してやりとりをするという手法のようです。

SDKを使うには

SDK自体は現在は無料のようなのですが、まだプライベートベータのため、コンタクトフォームからリクエストを送る必要があります。今回このSDKを使ってみようと登録して待つこと3週間、ようやく連絡がきて使えるようになりました。登録後はデベロッパー用のページからログインし、自分のKEYなどを確認することができます。ちなみにAPIの利用は5,000回までのようです。 登録完了後

今回やってみること

iOS/Androidアプリはストアからダウンロードできるものを使ってそのまますぐに試せてしまうので、今回はArduinoとの連携を試してみようと思います。Chirpから提供しているArduinoとの連携機能をまとめてChirpino(Chirp+Arduino)と呼んでいるようで、ChirpinoのサンプルがGithubにいくつか挙がっています。ここではもっともシンプルに、 Arduinoから音を出してスマホアプリで受信するという形を取ってみたいので、ChirpinoSing for Arduinosを使ってみます。

Arduinoの準備

今回はArduino UNOを使用しました。音を出すために圧電スピーカー を準備し、ジャンパーワイヤでつなぎます。ジャンパーワイヤはDigital 3ピンとGNDにつなぎ、USBをPCとつなぎます。 接続イメージ

次に、ArduinoにChirpinoライブラリをインストールします。今回はChirpinoSing for Arduinosを使うので、ChirpinoSing

 ~/Documents/Arduino/libraries/

に設置します。

Arduinoを立ち上げ、メニューからFile > Examples > ChirpinoSing > Simpleを選択すると、サンプルが読み込まれますので、Arduinoにアップロードします。エラーが出てしまう場合には、メニューのTools > Portから、正しくUSBが選択されているかを確認します。アップロードが完了すると、圧電スピーカーから音が出始めるので、ストアからダウンロードしておいたアプリで取得できるか試してみます。

ChirpinoSingのサンプルを試してみた結果

ExampleのSimpleに組み込まれていたコードが使えなくなっているのか、音声データ受け取り側のアプリ内で解析の波形は動くのですが、データを取得することができませんでした(2015/08/18時点)。そのため、別のExamplesのVariationからコードを持ってきて、再度試してみました。結果としては、波形読み取りとして有効だったのは、Variationの中の5つのコードのうち、2番目と5番目のみ、解析ができました。さらに別のExamplesのCustomBeakの方にもVariationと同じコードが書かれていて、有効だったコードも同じだったので、他のコードは現在使えなくなっているのかもしれませんが、詳しくは調べていません。

自分で設定したものが送れるか試してみる

ひとまずサンプルのコードは動いたので、今度は自分で設定したものが送れるかを試してみます。 サンプルの中に記述されているコードは18桁なので、この18桁のコードを準備しなければならないのですが、ChirpからWEB上で提供されているCode生成ツールで試してみても、URLには10桁のshortcodeしか表示されていません。もう少しソースなどを覗いてみると、音声を流すボタンのところに18桁のlongcodeもあったのですが、これをArduinoに設定してもやはり認識しません。entitiesというプロパティのところに、"Android & iOS"と書いてあったり、"embeddable"のプロパティの値がfalseであったりするため、ここで生成したものはArduinoでは動かないのもかも知れません。

もう少し調べてみると、ChirpinoのAPI Examplesに記載されているコマンドから作成できそうに見えるのですが、curlの追加ヘッダーオプションに記載されている"X-chirp-hummingbird-key"が24桁のHummingbird API keyを設定せよとなっているのに対し、SDK登録後に取得したApplication KEYは25桁で、これもどうも違うようです。

そこで色々見ていたところ、SDKのダウンロードページのところに、

Please note that to use Chirp on an embedded device, you need a Hummingbird API key. To obtain one, please contact us.

と書いてありました。どうやら問い合わせをして、Hummingbird API keyというものをもらわないとダメなようなので、ChirpのDeveloper Teamにメールでコンタクトを取ってみることにします。きっと世界は優しさに包まれているはずなので、多少の英文間違いなどは気にせずに勢いでメールしてみます(上記で取得したSDKのKEYやSecretは、今回のエントリーでは使わないのですが、ここでメールを送る際に、すでにSDK登録を済ませている旨を伝えました)。メールは翌日には返信がきたので、わりとすぐにHummingbird API keyを取得することができました。

Arduino用のコードを取得

Example内のChirpinoLinkなどを参考に、Arduino自身でコードの取得から行ってしまうようなプログラムも組めそうですが、今回はとにかくシンプルに試したかったので、コードはターミナルから下記のようなコマンドを叩いて事前取得します。「YOUR-24-CHAR-HUMMINGBIRD-KEY」のところには、問い合わせメールから取得したHummingbird API keyを設定します。

curl -X POST -d '{ "body": "Hello World!", "title": "Hello", "mimetype": "text/plain" }' -H "X-chirp-hummingbird-key: YOUR-24-CHAR-HUMMINGBIRD-KEY" http://hummingbird.chirp.io:1254/chirp

戻ってきた値は下記のようなJSONデータです。

{"now": "07:05:06", "code": "uhpjmdadmgmp6dfob3"}

この「code」の値をArduinoのプログラムに設定します。

Arduinoにアップロードするプログラム

コード生成のパターンとして、テキスト・URL・画像のパターンがあったので、これら複数の取得コードをまとめて動作させてしまいたいので、複数コードを配列に入れて動作させているサンプルになっているVariationをベースに作成してみます。なお、出力音声にはシンプルに音声トーンを出すBeakと、小鳥が鳴いているような音声トーンのPortamentoBeakの2パターンが用意されているので、今回は後者のPortamentoBeakを使用しました。

/*
    CHIRPINO SING version 1.0
    This software is provided by ASIO Ltd trading as Chirp

        http://chirp.io

    and is distributed freely and without warranty under the Creative Commons licence CC BY-NC 3.0

        https://creativecommons.org/licenses/by-nc/3.0/

    Have fun
*/

#include <ChirpinoSing.h>

const char *chirpCodes[] = {
    "uhpjmdadmgmp6dfob3",//Hello,World text
    "mecjnle0uef2q1cemo",//4009 URL
    "q0j6vdhgotqtbfjl19",//4009 Artistic image
    NULL
};

PortamentoBeak portaBeak;

const char *nextChirpString() {
    // static so value retained between calls
    static const char **chirpStringAt = chirpCodes;

    // reset pointer if it's pointing at the end NULL
    if( ! *chirpStringAt) {
        chirpStringAt = chirpCodes;
    }

    return *chirpStringAt++;
}

void setup() {
}

void loop() {

    const char *chirpString = nextChirpString();

    portaBeak.chirp(chirpString);
    delay(6000);

}

動作テスト

上記プログラムを使って、iOSアプリ+Chirpinoで動作させてみた感じは下記のような動画になりました。せっかく音声データでのやりとりなので、受信側は複数台用意して試してみています。

初めて取得するデータについては、音声解析後にネットワークを介してデータを取りに行くのですが、一度取得したものについてはローカルからデータが呼ばれるようです。また、取得したデータをさらに再配布することもできます。

考察

Bluetoothのようなペアリングが不要なため、気軽に音声データのやりとりを行える点は優れているのですが、音声解析をして把握できるのはあくまで実データを保持しているネットワークサーバーへのシリアルキーであり、データそのもの自体はサーバーへ取得しに行かなければならないため、ネットワーク環境が必須です。この辺りが改善され、オフラインでのデータ送受信ができるようになるのであれば、もうちょっと広がりが出てきそうな気がしますが、Chirpも今後の方向性としてそういった機能も検討しているようです。また、今回はノイズ環境では試していませんが、音声トーンを解析する以上、ノイズ耐性も気になるところですし、現状ではバックグラウンドでは動きません。そのため、メリット・デメリットの観点だけから捉えると、今のところ音透かしやビーコンの方が使い勝手は良さそうです。ただ、Iot分野が加速し、例えばスマートハウス化が進んだりすると、この特徴的な音声が賑やかしとして映えてくる場合もあると思いますので、その辺りをうまく差別化しながら進めていくのかもしれません。