Perfume Global Site Project #001 From anno lab is Out!!!!!!!!!!

前回個人的に作ったやつ、実はanno labでも作ってました。

てまひまかけて一生懸命作りました、超自信作です。

是非見てやってください。

一目見ても訳がわからないと思うので、メイキングも用意しました。

ではどうぞ。

動画:Anno Perfume Global Site Project #001 on vimeo
http://vimeo.com/annolab/annoperfumeglobal/
メイキング:
http://annolab.com/annoperfumeglobal/

Perfume global official website
http://perfume-global.com/

となりの要素の表示状態を切り替える(+localStorageへ保存する)

開閉式メニューを実現するのに下記のようなコードをよく見かけるのですが

<a onclick="ChangeVisibleById('childId');">parent</a>
<div id="childId">child</div>

これだとchildIdが2箇所にあって嫌な感じです。

そこで、Visibilityを切り替える対象を隣の要素に限定して下記のようにしてみました。

<a onclick="ChangeVisibleNext(this);">parent</a>
<div>child</div>

こうすれば、どこへでもコピペ可能だしchildにidを書かなくて良いので可搬性バツグンです。

ちなみにChangeVisible~の実装はこんな感じです。

ついでにchild要素にidが指定されていたらVisibilityの値をlocalStorageに保存するようにしてみました。

var PREFIX = "visibility_";// 重複を防ぐためプレフィックスをつけとく(きやすめ)
var STORAGE_NAME="storage_name";// localStorageが使えない環境のためにLSTJSON(※)を使う場合
function ChangeVisible(obj)
{
	obj.style.display = (obj.style.display=="none")?"block":"none";
	if(obj.id) {
		localStorage[PREFIX+obj.id] = obj.style.display;
		LSTJSON.save(STORAGE_NAME);
	}
}
function ChangeVisibleById(id)
{
	var obj = document.getElementById(id);
	ChangeVisible(obj);
}
function ChangeVisibleNext(obj)
{
	do {
		obj = obj.nextSibling;
	} while(obj && obj.nodeType != 1);
	ChangeVisible(obj);
}
// localStorageからVisibilityを拾ってくる処理
function Load()
{
	LSTJSON.load(STORAGE_NAME);
	for(id in localStorage) {
		if(id.indexOf(PREFIX) == 0) {
			var obj = document.getElementById(id.substring(PREFIX.length));
			if(obj) {
				obj.style.display = localStorage[id];
			}
		}
	}
}

なお、htmlとhtaでnextSiblingの返すオブジェクトが違ったようなので、ChangeVisibleNextの実装にはこちらのサイトを参考にしました。
Finding HTML elements using Javascript nextSibling and previousSibling

(※)LSTJSONについてはこちら
htaでlocalStorageっぽいものを使えるようにしてみる

htaでlocalStorageっぽいものを使えるようにしてみる

localStorage超便利るんるんーって言ってたところで、htaではlocalStorageが使用できないことが判明(使えないよね?)

まぁhtaならファイル読み書き余裕ですしどっかローカルに保存しときゃ問題ないんですが

htaとhtmlとで違うコードを書かなきゃいけないのはいやだったので作りました。

localStorageが使えない環境だと自前で生成したlocalStorageを、localStorageが使える環境だと普通にlocalStorageを使用します。

■使用法

  1. localStorageを使用するより前(onloadあたり?)にLSTJSON.load(filename)を一度だけ呼んでおく
  2. 普通にlocalStorageにホイホイ代入
  3. 保存したいタイミング(onunloadあたり?)でLSTJSON.save(filename)を呼ぶ

※filenameはloadとsaveで対応がとれていれば適当で構いませんが、重複すると上書きされるので一意なものにすることをおすすめします。

※ファイルは環境変数%TMP%のフォルダに作られます。

■通常のlocalStorageと比べて良い点

・保存したファイルをhtaと一緒にパッケージとして配布できる(保存場所は工夫する必要あり?)

・ファイル単位で管理されるため、オリジン(プロトコル、ドメイン、ポート)をまたいで共有できる

■悪い点

・わざわざloadとsaveをする必要がある

・StorageクラスにあってArrayクラスにない機能が使えない

var LSTJSON = {};

// localStorageが使えない時のみ有効にする
if(!localStorage) {
	// json2を使うので読み込んどく。パスは適当に書き換えてください。
	// json2を持っていない方はこちらからDL→https://github.com/douglascrockford/JSON-js
	document.write('<script type="text/javascript" src="./js/json2.js"></sciprt>');

	var localStorage = new Array();

	LSTJSON.load = function(filename) {
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		// 作成済みなら%TMP%下にある
		var filepath = fso.BuildPath(fso.GetSpecialFolder(2).Path, filename+".json");
		// 空っぽだと困るので初期値を入れておく
		var str = "{}";
		if(fso.FileExists(filepath)) {
			var stream = fso.OpenTextFile(filepath);
			str = stream.ReadAll();
			stream.Close();
		}
		localStorage = JSON.parse(str);
	};

	LSTJSON.save = function(filename) {
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		// %TMP%下に作成
		var filepath = fso.BuildPath(fso.GetSpecialFolder(2).Path, filename+".json");
		var stream = fso.CreateTextFile(filepath);
		stream.Write(JSON.stringify(localStorage));
		stream.Close();
	};
}
// localStorageが使える時はloadとsaveを無視する
else {
	LSTJSON.load = function(){};
	LSTJSON.save = function(){};
}

GitHubに上げました。不便ところは多々あると思うのでご協力お願いします。

GitHub – WebStorageOnHTA

localStorageいいね!

Google Chromeはローカル環境でクッキーを作らないことに数時間気づけず打ちひしがれた心にオアシス。

localStorage。

個人的にはクッキーよりも簡潔に書けるので好きです。

LocalStorageがおもいのほか便利すぎたのでまとめ

ブラウザでストレージ? Web Storageを使いこなそう

が、現状では文字列しか保持できないらしいのでそこだけ注意ですね。

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

localStorage.value = true;
obj.checked = localStorage.value;
alert(obj.checked);

結果:なんの冗談かとおもいますよね。

Perfume Global Site Project #001

Perfume Global Site Project #001 でPerfumeのダンスモーションデータと曲データが公開されているので

一緒に公開されているサンプルコードを改造して動画を作ってみました。

Processingを使用してます。

気持ちいいディレイになると確信して作り始めたものの、まあやっぱ難しい。

こだわりだしたらきりがないので途中経過ということにしてアップ。

今後、曲の展開に合わせてパラメータを制御したりカメラをいじったり新しい処理を追加したり…

妄想はつきませんが、手の空いた時にゆっくりやろうかなといったところ。

BVHファイルのフレームレートを変更するperlスクリプト

どうやら巷ではここで配布されているBVHファイルを読み込むのが流行っているようです。

ただ、中には(ファイルに書いてあるはずの)フレームレートが無視されてしまうソフトに苦戦している方もいらっしゃるようですので

(把握してる限りだとCinema4Dがそうっぽい?)

BVHファイルのフレームレートを変更するコンバータを作成しました。

ご利用、再配布等々ご自由にどうぞ。

なお、何か悪いことが起きても責任は取りません。あしからず。

※要perl

conv_bvh_frame_rate.zip

フォルダ内にあるファイルのリストを作成するバッチ処理

ご無沙汰してます。

ちょろっと作ってみました。

make_file_list.bat

使い方:コマンドプロンプトで make_file_list.bat ルートフォルダ 出力ファイル名(フルパス) を実行してください。

フォルダ階層をカンマで区切ったファイル(csv形式)が生成されます。

※フルパスで指定しないと大変なことになります。

※ユーザビリティのことはあんまり考えてません…

※普通に dir /s /b すれば良いことには作ってから気付きました…

HITONE開発日誌-02.〜AudioQueueでサイン波の出力〜

HITONEではオーディオの出力に、AudioQueueを使用しています。(AudioToolBox/AudioQueue)

オーディオデバイスに送る波形を自前で作れるので、後々拡張しやすいだろうと思いまして。

今後も音を扱う作品を作っていくつもりですのでね。

さて、HITONEの音源はサイン波です。

今回はAudioQueueのコールバックを使ってスピーカからサイン波を出力してみます。

※iPhone/iPadでの開発ですが、Objective-CではなくC++を使っています。

Objective-C++の話は、どこかでちょこっと触れるかも。

NIAudioRenderer.h

#ifndef NI_AUDIO_RENDERER_H
#define NI_AUDIO_RENDERER_H

#include <AudioToolbox/AudioQueue.h>

#include “NIDef.h”
#include “NIAudioDef.h”

#define NUM_BUFFERS 3

typedef struct AQCallbackStruct {
AudioQueueRef queue;
NIUint32 frameCount;
AudioQueueBufferRef mBuffers[NUM_BUFFERS];
AudioStreamBasicDescription mDataFormat;
} AQCallbackStruct;

class NIAudioRenderer {
public:
static void Init();
static void Term();

private:
static void AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB);

private:
static AQCallbackStruct _in;
static AudioQueueRef _queue;
static NIUint32 _sampleIndex;
};

#endif // AUDIO_RENDERER_H

/* EOF */

NIAudioRenderer.cpp

#include <math.h>
#include “NIAudioRenderer.h”

AQCallbackStruct NIAudioRenderer::_in;
AudioQueueRef NIAudioRenderer::_queue;

void NIAudioRenderer::AQBufferCallback(void *in, AudioQueueRef inQ, AudioQueueBufferRef outQB)
{
NIFloat floatVal;
NISint16 sampleValue; // -32767 bis +32767

AQCallbackStruct *inData = (AQCallbackStruct *)in;
NISint16 *coreAudioBuffer = (NISint16*) outQB->mAudioData;

if (inData->frameCount > 0) {
outQB->mAudioDataByteSize = 4*inData->frameCount;

for(int i=0; iframeCount*2; i=i+2) {
floatVal = sin(((NIFloat)_sampleIndex * 2 * M_PI * 440) / NI_AUDIO_SAMPLE_RATE);
sampleValue = (NISint16)(floatVal * 32767.0f);
coreAudioBuffer[i] = sampleValue;
coreAudioBuffer[i+1] = sampleValue;
_sampleIndex++;
}
AudioQueueEnqueueBuffer(inQ, outQB, 0, NULL);
} else {
AudioQueueStop(inData->queue, false);
}
}

void NIAudioRenderer::Init()
{
_in.mDataFormat.mSampleRate = NI_AUDIO_SAMPLE_RATE;
_in.mDataFormat.mFormatID = kAudioFormatLinearPCM;
_in.mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
_in.mDataFormat.mBytesPerPacket = 4;
_in.mDataFormat.mFramesPerPacket = 1;
_in.mDataFormat.mBytesPerFrame = 4;
_in.mDataFormat.mChannelsPerFrame = 2;
_in.mDataFormat.mBitsPerChannel = 16;
_in.frameCount = 1024;

_sampleIndex = 0;

AudioQueueNewOutput(&_in.mDataFormat, AQBufferCallback, &_in, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &_in.queue);

UInt32 bufferBytes = _in.frameCount * _in.mDataFormat.mBytesPerFrame;

for (int i=0; i< NUM_BUFFERS; i++) {
AudioQueueAllocateBuffer(_in.queue, bufferBytes, &_in.mBuffers[i]);
AQBufferCallback (&_in, _in.queue, _in.mBuffers[i]);
}
AudioQueueSetParameter(_in.queue, kAudioQueueParam_Volume, 1.0);
AudioQueueStart(_in.queue, NULL);
_queue = _in.queue;
}

void NIAudioRenderer::Term()
{
AudioQueueStop(_queue,true);
AudioQueueDispose(_queue, true);
}
/* EOF */

ちなみに、
NIAudioDef.hとNIDef.hには
NI_AUDIO_SAMPLE_RATE
NIUint32
NISint16
NIFloat
などが定義してあります。
使う際は、ご自分の環境に合わせて定義してください。

“NI”っていうのは、あれです、自分の開発用ライブラリの名前ですね。

気にしないでOKです。

で、使うところで

#include “NIAudioRenderer.h” して

NIAudioRenderer::Init(); すれば440Hzのサイン波が出力される、はず。

終了時にNIAudiorenderer::Term(); するのをお忘れなく。

参考にしたサイト
CSPhone Project -サイン波の出力-

HITONE過去記事
01-導入-

次回はサイン波を複数鳴らしてみます。

HITONE開発日誌-01.〜導入〜

お久しぶりに書きます。

ちょっとiPhone App.の開発から離れてたんですが、ちょっときっかけがあって再開しました。

前に途中まで作っていたTiLoopは少し置いておいて、今はHITONEというアプリを作っています。

もともとは大学の卒研で、Macで(Java+Processing+Max/MSP(OpenSoundControl))動くものを作ったんですが、

そもそもタッチスクリーンで動かしてなんぼなものなので、iPhone/iPad用にリメイクしてます。

(ソース見ながら移植も考えたんですが、思い出すのも嫌になるくらい汚いコーディングをしていたのでイチから書き直してます。。。いやーおはずかしい)

卒研のときのがこれで

HITONEHITONE

現在製作中のはこんな感じになってます。

これから数回に渡って、HITONEの制作状況を記事にしていこうと思ってます。

今回、サイン波を出力するのにAudioQueueを使用していますのでまずはそこの話からですかね。

日誌と書きつつ毎日更新は出来ないと思いますが(だって書くことがなくなってしまう)

乞うご期待。

春にはリリースしたいな!

1h Music 終了!

まとめは
コチラ
で!

出来上がった曲へのリンクもあります。

僕の曲には、1時間で作ったとは思えないクオリティの曲がつきました。感服。

楽しかった!

しかし、やはりというかなんというか

作詞の60分に比べて作曲の60分というのはかなり厳しい印象でした。

推敲の時間のなさや焦りを同じくらいのレベルにするなら

作詞を30分にするか、作曲を2時間にするかくらいしても良いのかな。

企画名が変わっちゃいそうですが。

当日の様子はコチラに録画がありますのでどうぞ。

俺も自分を録画しときゃよかった。