あなたの天然記念物
ホーム更新雑談Perl鉄ゲタランドナーコースガイド自転車Linuxリンク経歴連絡先

バイナリデータを埋め込む (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に変更していますので非公開です。 元動画はこちら。