Hatena::ブログ(Diary)

Chocolate Coding

2013-02-09

[][] 新しい信号処理の書籍が出版されました

2/1に新しい信号処理の書籍が出版されました。

サウンドプログラミング入門――音響合成の基本とC言語による実装 (Software Design plus)

サウンドプログラミング入門――音響合成の基本とC言語による実装 (Software Design plus)

北大の青木先生が執筆された本です。

C言語ではじめる音のプログラミング―サウンドエフェクトの信号処理

はエフェクト周りの内容でしたが、この本はシンセ周りの内容となっているようです。

読んだら感想を書こうと思います。

2012-09-29

[] TinyXML-2を使う

C++XMLをぐにぐにする必要が出てきたので、良い塩梅のXMLパーサを探す事にしました。

Boost.PropertyTreeのxml_parserを現行で使っていたのですが、XMLを構築する際にCDATAセクションに対応していなかったりするので、要件に合わない場合があります。

C++XMLパーサも一長一短でどこか不自由な箇所があるので、丁度いい具合のパーサって中々無いもんなんですね。


今回は特にパフォーマンスを考慮しないとして、TinyXML-2が候補として上がりました。

名前の通りヘッダ1個とソース1個で構成されるDOM方式のとても小さいXMLパーサです。

小さいながらも一通りの機能が揃っており(もちろんCDATAセクションもフラグで管理できる)、ライセンスもzlibなので安心です。*1

ただし、文字コードに関しては対応していないのでそこは自前で変換する必要が出てきます(道化師さんのbabelやmlang.dllを使えばいいと思います)


さて、ここではTinyXML-2の読み書きについて簡単なチュートリアル的なものを書き残しておきます。


導入

githubからcloneなりzipで落とすなりしてもってきましょう。

その中のtinyxml2.hとtinyxml2.cppを使いたいプロジェクトの中に直接放り込めば完了です。

面倒くさいリンク設定などは一切ありません。


チュートリアル

まず初めに既存のXMLを読み込む事から始めるのではなく、簡単な初期化方法からいきましょう。

ここで紹介する XMLDocument::NewDeclaration()は新たにXMLを一から構築する際に忘れがちです。

XMLDocument::NewDeclaration()を行うと、Prologueが構築されメモリプールが初期化されます。

既存のXMLをロードしてそれを操作する場合は必要ありません。

#include <iostream>
#include "tinyxml2.h"

int main()
{
	using namespace tinyxml2;

	XMLDocument xml;
	XMLDeclaration* decl = xml.NewDeclaration();

	xml.InsertEndChild(decl);

	xml.Print();
	std::cout << "\n";

	// standalone等が必要になってPrologueを変更したい場合は自前で書くことも可能
	decl->SetValue("xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"");

	xml.Print();
	std::cout << "\n";

	return 0;
}

XMLを構築する(値を追加する)

TinyXML-2において大抵の要素はXMLNodeオブジェクト継承して作られたものです。

XMLを構築する際はそれらを使って入れ子状にしていきましょう。

// XMLElementが基本で、要素を作成出来ます
XMLElement* root = xml.NewElement("root");
// まずはrootを追加します(FirstにするとPrologueの上にきちゃいます)
xml.InsertEndChild(root);

// 次は追加したroot要素に対してテキストデータを入れたいのでXMLTextを作ります
XMLText* text = xml.NewText("Text");
// root要素に対して末尾にテキストを追加します
root->InsertEndChild(text);
// テキストなのでCDATAで囲みたいので、フラグをtrueにします
text->SetCData(true);

これを出力すると、

<?xml version="1.0" encoding="UTF-8"?>
<root><![CDATA[Text]]></root>

こうなります。

ちなみに、XMLElementやXMLTextのようにノードから派生するものを生成する時はXMLDocumentから生成する必要があります。

この例の場合は直接XMLDocumentを呼んでいますが、ノードにはGetDocument()メソッドが実装されているので、それを用いて所属するXMLDocumentオブジェクトを取得する事が出来ます。

XMLText text = root->GetDocument()->NewText();

こんなかんじですね。


XMLを構築する(属性を入れてみる)

追加したroot要素にAttributeを付けてみましょう

root->SetAttribute("name", "melponn");

これだけです。

<?xml version="1.0" encoding="UTF-8"?>
<root name="melponn"><![CDATA[Text]]></root>

XMLを構築する(連続した値)
<?xml version="1.0" encoding="UTF-8"?>
<root>
	<array>
		<value>hoge</value>
		<value>hoge</value>
	</array>
</root>

続いてこのようなデータを作ってみます。

XMLElement* array = root->GetDocument()->NewElement("array");
root->InsertEndChild(array);

for ( int i=0; i<2; ++i) {
	// valueを作ってarrayへ押し込めます
	XMLElement* value = xml.NewElement("value");
	array->InsertEndChild(value);

	// valueに対して値を追加します
	value->InsertEndChild(
		value->GetDocument()->NewText("hoge")
	);
}

簡単ですね。ちなみに値は全てテキストとして扱うので、文字列以外を入れたい場合はBoost.Lexical_CastやBoost.Formatとか使うと良いと思います。


XMLを読み込む(XMLのロード)

次は既存のXMLから読み込んでみます。先ほどのXMLをtest.xmlとして使用します。

<?xml version="1.0" encoding="UTF-8"?>
<root>
	<array>
		<value>hoge</value>
		<value>hoge</value>
	</array>
</root>

ファイルからの読み込みは超簡単です。XMLDocumentにLoadFileが用意されているので、それを使用します。

#include <iostream>
#include "tinyxml2.h"

int main()
{
	using namespace tinyxml2;

	XMLDocument		xml;
	xml.LoadFile("./test.xml");

	xml.Print();
	std::cout << "\n";

	return 0;
}

ファイルパスまたはANSI CスタイルのFILEポインタを渡す事が出来、ここでは相対パスを指定しています。

XMLを読み込む(各種要素を取り出す)

前項の出力結果通り、読み込むとその時点でXMLオブジェクトは構築されています。

それらを取り出す際は、FirstChildElement LastChildElement等を使用します。

XMLElement* root = xml.FirstChildElement("root");
XMLElement* array = root->FirstChildElement("array");
XMLElement* value = array->FirstChildElement("value");

std::cout << value->GetText() << "\n";

要素が取得できなかった場合はNULLが返ってきます。

XMLを読み込む(連続した要素を取り出す)

配列となっている要素に対しては以下のように行うとうまく取得できます

for(XMLElement* element= pt->FirstChildElement("element"); element!= NULL; element= element->NextSiblingElement("element") ) {
	...
}

NextSiblingElement()を使用することにより、次の要素を取得する事が出来ます。

続く要素がない場合、NULLを返すのでそれを判定してやればループで処理出来ますね。

とりあえずここまで。

*1:ただし、無印のTinyXMLはGPLなので注意

2012-03-06

[C++][VS11] range-based for loopが使えない?

先日VS11 betaがリリースされたのでWindows7 64bitに早速導入

range-based for loopを試してみました

適当に以下のようなコード

#include <iostream>

int main()
{
    int array[5] = {1,2,3,4,5};

    for (int& x : array ) {
        std::cout << x << std::endl;
    }
}

ずらずらーっとエラーが出力されます シンタックス周りのエラーですね

やっぱりWindows8環境(WinRT)じゃないと対応してないんですかねー…

What’s New for Visual C++ in Visual Studio 2012

2012-02-15

岡山探訪記

技術系以外はここに書かないつもりだったんですが、他に用意するのも面倒くさかったのでこっちで。

Boost.勉強会 #8 大阪の翌日、中3女子こと@さんの個展を見に行くべく岡山旅行をして参りました。

メンバーは、@さん、@さん、@さん、@さん、@さんと僕で、合計7人です。

詳しくはこちらのイベントで。

新大阪岡山

物心ついてから新幹線乗るのは初めてだったので内心はしゃいでましたね!

ずっと窓の外みてました

方谷駅

f:id:lapis0896:20120212103244j:image:medium f:id:lapis0896:20120212103153j:image:medium

あまりの大都会っぷりに唖然。良い景観です。

@さんとの待ち合わせ場所、方谷駅です。中3女子と待ち合わせと書くとなんとも言えませんが、現実は非情です。

画像にある『いくら』とはこの後行く井倉洞がある地名。僕がいくら丼と聞き間違えて凄く笑われました。ひどい!

井倉

f:id:lapis0896:20120212120611j:image:medium f:id:lapis0896:20120212115803j:image:medium f:id:lapis0896:20120212115515j:image:medium

当初の目的地である猪風来美術館へ行く前に、鍾乳洞を2ヶ所回ることに。

内部は1200mも続いており、高低差が激しいため体力がみるみる削られていきます。

しかしながら、鍾乳洞自体が初めてだったため非常に楽しめたと思います!

小休止

f:id:lapis0896:20120212135429j:image:medium f:id:lapis0896:20120212135305j:image:medium f:id:lapis0896:20120212135229j:image:medium

遊具で遊ぶ@氏と@氏。

新見のそば屋で腹ごしらえをした後、高台のある公園でちょこっと遊んでました。

満奇洞

f:id:lapis0896:20120212143656j:image:medium f:id:lapis0896:20120212143223j:image:medium f:id:lapis0896:20120212142744j:image:medium

2ヶ所目の鍾乳洞、満奇洞です。こちらは井倉洞と変わって、意外と整備されています。

色とりどりの光源が設置されており、演出にこだわってる感じでしたね。

どちらも素晴らしかったのですが、個人的には最初の井倉洞の方が天然っぽくて好きです。

猪風来美術館

岡山旅行のメイン、中3女子の本拠地です。残念ながら撮影はできませんでした。

元々あった小学校を美術館に改築?したようです。

縄文土器展だったのですが、非常に楽しめましたねー。繊細かつダイナミックな作品が多く、つい見入ってしまいました。

まさに、中3女子の原点ここにあり、といった感じです。

実際に土器を野焼きする写真なども展示されており、実際に野焼きに立ち会ってみたくなりましたね!

貴重な経験が出来て満足です。

焼肉

メインその2&〆、焼肉です。

この時始めて猪肉の焼肉を食べました。鍋はあれども焼肉はなかなかないですね!

臭みもあまりなく、やわらかい食感で美味しく頂けました。

野菜もおいしかったですね!


こんな感じの旅でした。貴重な経験を頂いた@さんに感謝です。

2012-02-13

[C++][Boost]Boost.勉強会 #8 大阪

人生2度目の大阪でした(ちなみに1回目は修学旅行です)

梅田は地獄ですね!

Boost.勉強会 #8 大阪

お昼休みの時間に僕は開催地である愛日会館付近についたわけですが、たまたま道化師さん達と道端で出くわしてそのままずるずるとお昼ごはんを食べる事に…

中々料理が来なくて、結局午後の部もやっぱり遅刻する事態となってしまいました

おのれカレー屋!


さて、肝心の勉強会の内容ですが、さすがAimingの本拠地とあってゲーム関連の話題も多かった気がします

ゲーム開発において使って欲しいという意思と問題意識がひしひしと伝わってきました…

特にaizen76さんのメモリ管理の話は本当に(ゲームを製作する上で)重要なので、気をつけて聞いていましたね


僕と同じ北海道から来たhotwatermorningさんのセッションもあったのですが、僕と同じようにぎりぎりまで資料製作をしていたにも関わらず分かりやすく解説していたのはすごいと思います


肝心の僕のセッションはというと、54つのBoostライブラリを紹介するという内容でした

一応ゲーム関係で使用するとちょっと良いライブラリを纏めたつもりです(おかげで、aizen76さんとは被ってしまいましたが)

何にも考えずに喋ってた*1ので何か非常に申し訳ないのですが、ニュアンスで各種ライブラリの良さを体感して頂けたら幸いです…

とりあえず何事も使ってみる事が大事なので、興味をもたれた方はどうか弄ってみて下さい(そしてもっと分かりやすくセッションして下さい!)

Boost.勉強会 #8 懇親会

前回とはまた違った方々と話せて楽しかったですねー

後半は結局ゲーム業界の面々で固まって話してた気がします*2

同じC++erが何十人も集まって腹を割って話す機会なんて年に数度しか無い訳ですから、一つ一つの懇親会も大切にしたいですね

おわりに

今回で恐らく今年の本州でのBoost.勉強会への参加は最後になるでしょう

僕は4月から社会人になってしまうので、生活が安定するまで数ヶ月間はじっとしていると思います


ちらほらご要望のあった今年の北海道でのBoost.勉強会は要検討ですねー

札幌C++勉強会の今後の大きな動きとしては、6月に開催される予定のオープンソースカンファレンスへの出展を予定しているぐらいです


後半戦の大都会岡山探訪記については別途記載します

*1:発表の構成を考えてなかったため

*2:半分ぐらいはrunicalpさんの話題でしたが