ルモーリン

バイナリデータを埋め込む

投稿:2013-02-07、更新:2013-03-22

プログラムがwavファイルを扱いたい時に、以前はwavファイルを16進ダンプしてcソースに変換、コンパイルしたけどスマートじゃありません。 バイナリファイルのままプロジェクトの1ファイルとしてプログラムに連結できないか挑戦してみました。
下記は実際に使っているソースです。 ソース中のmaguro.wavは、まぐろたべたい Copyright(C)さいたまにすと 2009,All rights reserved.
/*
 * maguro.c
 *
 *  Created on: 2013/01/02
 *      Author: ルモーリン
 */

// 音源データ(wavファイル)をこのオブジェクトに埋め込んで前後にラベルを追加

asm (
	"	.global wave_head\n"
	"	.global wave_tail\n"

	"	.section .rodata, \"a\"\n"
	"wave_head:\n"
	"	.incbin \"../src/maguro.wav\"\n"	//ファイル名 ※インクルードのパスから検索するから、incフォルダからの相対パスで指定すること
	"wave_tail:\n"
);
cソースの中でアセンブラソースを書いてその中でwavファイルをROMのデータセクションに取り込みます。 データを見たい処理で「extern const uint8_t wave_head[];」とか宣言すればバッチリ。 リンカの最適化でデータがプログラムから抜けません(参照してるからか?理由は不明)。 maguro.wavの更新をmakeで把握してるとは思えないので更新後はリビルド掛けといたほうが無難です。
2013.03.22 簡単に取り込めるようにマクロを作ってみました。
// ファイルをオブジェクトに埋め込んで前後にラベルを追加
// ラベルの種:label
// ファイル:file
// 先頭:label_head
// 末尾:label_tail
#define KSRK_INJECTION(label, file) \
asm (\
	"	.global "#label"_head		\n"\
	"	.global "#label"_tail		\n"\
	"	.section .rodata, \"a\"		\n"\
	#label"_head:					\n"\
	"	.incbin \"../src/"file"\"	\n"\
	#label"_tail:					\n"\
)
マクロを使う時はこう。
#include "ksrk.h"
KSRK_INJECTION(wave, "maguro.wav");
今回はソースなし。 maguro.wavは、さいたまにすと様の楽曲「まぐろたべたい」をモノラル、8ビット、7000Hzに変更していますので非公開です。