オブジェクト変換技!
バイナリーイメージの組み込み方法

バイナリ変換

画像や音声データなどのオブジェクトを組み込んで、画像表示させたり、音声を再生したりさせたい!なんて時が、たまにあったりしますよね?

でも、なかなかすんなり動作してくれなくて、いつもドはまりしていました。

ネットで調べてもあまり情報がなく、どうしたらいいんだーと嘆いていました。色々と試行錯誤して辿り着いた方法ですが、もっと効果的でスマートな方法はあるとは思いますが、そんな時のためにここで紹介するバイナリーオブジェクトの組込み方法を参照してください。

やはり、NXPファンなもんで、Kinetisマイコンで確認していきますね。

合わせて読みたい
バイナリファイルをARMオブジェクトファイルに変換した後のプロジェクトに組み込む方法はこちらを参考にしてください。

バイナリーファイルをプロジェクトに組み込む方法

 

やりたいこと

音声データのバイナリを組み込みたい。最終的には、I2SにPCMデータとして外部デバイスに音声出力したい。

今回は、オーディオデータを作成し、ARMバイナリイメージに変換し、プロジェクトに組み込むところまでを目指します。

ワークフロー

  1. 音声は、デモとしてサイン波を作成(フリーツールAudacityを使用)
  2. 作成したサイン波のバイナリーオブジェクトをARMバイナリーイメージに変換
  3. Cソースに組込む

要点

  • 音声の作成は、フリーソフトのAudacityで簡単に作成できる
  • 音声ファイルフォーマットはPCMが必要
  • 作成した音声ファイルをARM用バイナリーに変換が必要
  • 変換には、object copyを使う
  • 変換したバイナリーファイルのセクションの変更が必要
  • Cソースへの組込みには、配列として宣言し先頭アドレスへアクセスする

では、行ってみましょう!

音声データ作成

まず、何はともあれ、音声データが無いと始まりません。既に、使用するオブジェクトファイルがある場合は、この項目はスキップしてください。

音声データ作成には、私はフリーで使用できるAudacityを使っています。

音声の取り込みなどは、録音ボタン等で直感的に録音等が可能です。今回は、最終的には正しくI2Sに音声データが転送されるか確認したい(次回以降の記事で紹介)ので、サイン波を作成していきます。

Audacityのダウンロード

Audacityのダウンロードはこちらから↓

公式Audasityページ ダウンロード

Audasityの起動する

First view after starting Audacity

起動直後は、トラックが無い状態です。まずは、トラックを作成して音声を生成していきます。

トラックの作成

トラック作成

トラックの分離

サイン波を生成する前に、作成したステレオトラックを一旦分離しておきます。分離すると右、左のチャンネルにそれぞれ異なる周波数のサイン波を作成することができます。

 

参考

今後、右と左のチャンネルでそれぞれ正しく音声が出力、入力できているか確認する時に、それぞれ異なる周波数にしておくと便利です。

 

トラックボタン▼をクリックして、続いて”ステレオトラックを分離”をクリック。

トラックの分離

トラック分離後はこんな感じです。↓

 

トーン(サイン波)の生成

いよいよサイン波を生成します。ツールバーのジェネレータからトーンをクリックしてサイン波を選びます。440Hzで残りはままでOKをクリックします。440Hzは、音楽ではラの音ですね。

トーンの生成トーンの設定

両方のチャンネルに440Hzが設定されるので、今度は、右チャンネル側をクリックして選択しておき、同様にトーンをクリックして、異なる周波数に設定します。今回は、900Hzに設定します。

サイン波設定後

サンプリング周波数の設定

サンプリング周波数を設定します。通常44.1kHzで良いでしょう。

サンプリング周波数設定

ステレオトラックの統合

ステレオのトラックを統合して、ステレオトラックを作成します。

トラックを統合

フォーマット設定

PCMフォーマットを設定しておきます。今回は24ビットPCMを選択します。

オーディオフォーマットの指定

 

オーディオの書き出し

オーディオの書き出しは、ファイルのヘッダに色々情報が書き込まれるので、RAWデータを選択して書き出します。ファイル名の拡張子は、そのままでも問題ありません。出力後、.rawに自動的に保存されます。

オーディオ書き出し設定

後は、そのままOKをクリックして終了です。

 

ARMバイナリーフォーマットへ変換

ARMのバイナリーフォーマットは、32bitリトルエンディアンです。そのため、音声ファイルもこのバイナリーに変換してあげる必要があります。

その変換ツールは、open sourceのobjectcopyが使えます。MCUXpresso IDEをインストールしている場合は、既にobjectcopyがインストールされています。

objectcopyの場所

このobjectcopyは、様々なフォーマット間の変換をしてくれます。

例:

WAV file  ⇄ bin

ELF32  ⇄ bin

など

コマンド

objectcopy -I binary -B arm -O elf32-littlearm foo.bin foo.o

-I binary: –input-target 入力とするファイルのフォーマット(bfdname)を指定します。今回は、binaryと指定します。
-B arm: バイナリーのアーキテクチャを指定します。今回は、armと指定します。
-O elf32-littlearm : 出力ファイルのフォーマットを指定します。ARM Cortex-M向けには、elf32-littlearmが用意されています。

 

情報

セクションの変更

Cソースのプロジェクトに変換したバイナリを組み込むとデフォルトでは.dataセクションに配置されてしまいます。

.rodata(定数領域)にセクションを変更すると良いです。

オプション指定

–rename-section .data=.rodata,alloc,load,readonly,data,contents foo.bin foo.o

foo.binとfoo.oには任意のファイル名で指定します。

今回は、

foo.binに、sine-wave.aiff

foo.oに、sine-wave.o

と指定します。

 

objcopy実行

objcopy実行

出力されたオブジェクトファイルの確認

出力されたオブジェクトの中身を見てみると、、、

readelfを使って出力されたオブジェクトファイルを確認できます。

readelfコマンド

readelf foo.o -h -S

ヘッダ情報とセクション情報を表示します。

readelf実行

objdumpでシンボルテーブルを確認

objdump実行

シンボルテーブルを見ると、.rodataセクションは_binary_sine_wave_raw_start[]でアクセスできることが分かります。

Cソースでは、

extern char _binary_sine_wave_raw_start[];

extern char _binary_sine_wave_raw_size[];

const char *sine-wave = _binary_sine_wave_raw_start;

size_t sine-wave_size = _binary_sine_wave_raw_size;

でアクセスできます。配列の先頭アドレスやサイズでこのオブジェクトにアクセスできるところが重要です。

まとめ

サイン波を生成するには、Audacityが便利です。私は、何かと評価用の音源ソースを生成する時にはよく使用します。

バイナリイメージを変換するには、GNUのフリーツールが使用でき、MCUXpresso IDEをインストールすると付属してくるobjcopyが使用できます。

変換後は、セクション先頭アドレスに配列名でアクセスできます。

たまにバイナリーイメージを組み込みたい時は、参考にしてください。