2009 年 1 月 のアーカイブ

DelayLamaをつなげる ~「あの楽器」で DelayLama~

2009 年 1 月 30 日 金曜日

ちょっと お遊びで、Applet に DelayLamaをつなげてみた。

DelayLamaは、最近(ってもう古いか(笑))はやりの、僧侶が歌うっていう VSTiプラグイン。坊歌ロイドとか言われてたりする。

準備するもの。

DelayLama:->http://www.audionerdz.com/ のダウンロードページからWindows用のファイルを落としてください。落としたファイルを適当なディレクトリに展開。

VSTHOST->DelayLama に MIDI IN をつけるためのソフト http://www.forest.impress.co.jp/article/2006/11/08/vsthost.html http://www.hermannseib.com/english/vsthost.htm Synth1 っていうフリーのシンセサイザを使おうと思って入れたソフト。適当なディレクトリに展開。

MIDIYork:->VSTHOSTだけじゃ同じマシン上のシーケンサのMIDIOutを受け取ってくれないので、パイプ役をするソフト。http://www.midiox.com/index.htm?http://www.midiox.com/myoke.htm。ダウンロードして Install。再起動が必要です。

まず、VHOSTを起動して、メニューのFile -> NewPlugin をクリックして、展開したDelayLamaのディレクトリの下にある、Delay Lama.dll を指定して OK すると、ちっさい窓ができます。その窓のつまみのアイコン(PluginEdit)をクリックすると僧侶の絵が出ます。

Deviceメニュー -> MIDI から、InputDevice に MIDIYork 1 を選んでください。

これで 準備完了です。

ここを開いて、左上すみをクリックして、出力デバイスに MIDIYork1を選んでください。それで、ピアノロールをクリックしてドラッグしてみてください。

この方法を使うと、有料のシーケンスソフトでなくても、VSTプラグインが使えます。

これで今日からあなたも僧侶ーズ(笑)

音出し その3 和音

2009 年 1 月 29 日 木曜日

和音に挑戦。

和音の並び、画面構成は @きよし 様 作成  MIDI Chord Helper参考にしました。 パクリました(^^;

とりあえず試したいかたはこちら

使い方:

  1. 上のコード表を クリックすると和音が出ます。sus4欄は 下のコード+sus4 です。
  2. コード表のコードは適当に並んでいるわけではありません。
  3. shiftキーで7th、ctrlキーでM7th、altキーで6th になります。(ウソかもしれない)
  4. コード生成方法が適当です。本来は上に並んでる b#の数(キー(調))によって、音をオクターブ移動したりしないといけないはずなんですが、してません。(誰かルール教えて(´・ω・`))
  5. ピアノロールは、そのままクリックすると単音が出ます。Shiftキーと一緒にクリックすると、メジャー和音が出ます。
  6. 左上デバイスの変更、音色(Program)の変更は今まで通りですが、音色は番号だけじゃなくて名前を表示するようにしました。右ボタンで逆順に変化します。
  7. Effect は、緑の画面エフェクトのOn/Off です。Onにすると、背景が黒くなり、例のエフェクトが出ます。
  8. Octave はオクターブの移動です。ピアノロールのC の位置にオクターブ表示があります。左クリックで オクターブが上がり、右クリックで下がります。

あくまで、和音は適当なので、ご注意ください。

※このアプレットのソースコードの公開予定はありません。


以前、ニコニコ技術部で、@きよし さん の「あの楽器?でInnocenceをコード演奏してみた」を見たときから、これは すごいと思っていて、「あの楽器」を作るときは絶対このやりかたを使おうと心に決めていました。
<a href=”http://www.nicovideo.jp/watch/sm5733724″ mce_href=”http://www.nicovideo.jp/watch/sm5733724″>【ニコニコ動画】あの楽器?でInnocenceをコード演奏してみた</a>
で、実際にproce55ingで作ってみたのが こちらです。

しかし、音楽理論がさっぱりわからん。今回、実際に実装したコードの生成方法は次の通り、

3和音のトニック、ドミナント、サブドミナントの生成方法。

  • トニック:ベース音コード名の音(C ならド)。
  • ドミナント:トニックの3度上の音(MIDI Pitch で トニック+4)
  • サブドミナント:トニックの5度上の音(MIDI Pitch で トニック+7)
  • マイナーの場合、ドミナントを MIDI Pitch で -1
  • sus4 の場合、ドミナントをMIDI Pitchで +1

さらに、7th等の生成

  • 7thは、3和音に、短7度上の音を加える。(MIDI Pitch で トニック+10)
  • M7thは、3和音に、長7度上の音を加える。(MIDI Pitch で トニック+11)
  • 6thは、3和音に、短6度上の音を加える。(MIDI Pitch で トニック+9)

という非常に簡単な方法で 行っています。

コードはこんな感じ

int[] makeCode(int base, int mFlg, int numFlg, int shpNum ){
int[] pitches= new int[4];
// 基本3和音
pitches[0] = base;
pitches[1] = base+4;
pitches[2] = base+7;
pitches[3] = -1;
// マイナー
if( mFlg == 1 ){
pitches[1] = pitches[1] -1;
}
// sus4
if( mFlg == 2 ){
pitches[1] = pitches[1] +1;
}
// add
if( numFlg == 6 ){  // 6th
pitches[3] = base+9;
}
if( numFlg == 7 ){  // 7th
pitches[3] = base+10;
}
if( numFlg == 8 ){  // M7th
pitches[3] = base+11;
}
if( numFlg == 9 ){  // 9th
pitches[3] = base+14;
}
return pitches;
}

ほんとうは、サブドミナント音を オクターブ下にもっていったり4和音目を オクターブ下にもっていったり しなきゃいけないはずなんだけど、さっぱりわからん。

このへんは、音楽の詳しいひとに教わりたいなぁ。誰か教えてください。

音出しその2 PitchBend

2009 年 1 月 27 日 火曜日

PitchBend 解決。お試しはこちら。横ドラッグで、PitchBend。

PitchBend できないのかなぁ と 色々さぐってたら。

私 大きな勘違いしてたようです。PitchBendは エクスクルーシブメッセージじゃなくて、イベントメッセージじゃないですかっ! ControllChange なんかより上のレベルでした。なんか変だと思った。

NoteOnとか、ControllChangeとかと同じレベルに実装されてなきゃいけないものでした。ということは、ない。PitchBendがない。MidiOutput クラスに、sendPtichBendとかいうメソッドが実装されてないといけないはず。

ないものは作ってしまえというわけで、rwmidi ライブラリに手を入れました。

MidiEvent.java   に、PitchBend イベントを追加

public static final int PROGRAM_CHANGE = 0xC0;
public static final int PITCH_BEND = 0xE0;

PitchBend イベントの イベントコードは 0xE0

MidiOutput.java に sendPitchBend メソッドを追加。

/**
* Send a Pitch Bend on this output
* @param channel Channel on which to send the message
* @param value Program Change value
* @return 1 on success, 0 on error
*/
public int sendPitchBend(int channel, int value) {
ShortMessage msg = new ShortMessage();
try {
int bb = value & 0×7f;
int ub = value >> 7;
msg.setMessage(MidiEvent.PITCH_BEND, channel, bb, ub);
receiver.send(msg, -1);
return 1;
} catch (InvalidMidiDataException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return 0;
}
}

これで 0~16383 の範囲の数字で 正常動作するはず。

processingの mouseDragged イベントにコード追加。

void mouseDragged() {
// Xdrag で Bent
print( “mouse dragged ” );
int bend = (mouseX - org_mouseX)*8+8192;
if( bend<0 ){ bend=0; }
if( bend>16383 ){ bend=16383; }
println( bend );
output.sendPitchBend( ch_s, bend );

これで 実行。 をぉ いい感じ。横ドラッグで、PitchBendがかかってる~。

ただ、これも NoteOn 時に リセットしてやらないと ダメな感じ。

それも実装。

mousePressedイベント

output.sendPitchBend( ch_s, 8192 );
output.sendController( ch_s, 11, vel_s );
output.sendNoteOn( ch_s, pit_s, vel_s);

8192 と マジックナンバー書いてしまったけど、まぁ いいかな。8192が センターだし、これでよしとしよう。

お試しは、こちら。 はぁ、よかったよかった。

rwmidi <たろう>Patch の バイナリ(jarファイル)は こちら。ソースはこちら。いずれも、解凍して 使ってください。

音出し

2009 年 1 月 27 日 火曜日

あの楽器の画面エフェクトが とりあえず終わった(?)ので次は音出しの実装。

とりあえず試したいひとは こちら

  • 縦にドラッグすると音量が変化します。Windowsの方は、ボリュームの画面で SWシンセサイザのボリュームを最大にしておいてください。
  • 左上のメッセージは、上の段が、MIDIOUTのデバイス名、下の段がプログラム番号(音色)です。それぞれの文字の 左端をクリックすると デバイス名、プログラム番号が変化します。

音出しはMidiOutに依存する。さっそく processing用のMIDIライブラリをグーグル様に問い合わせると、ありました proMIDI。sampleがついてたので色々ためす。おお音が出る。いいぞいいぞ。。。。

あれ sendNote はあるけど、NoteOn NoteOff が 送信できないじゃないですか。これはいけません。ピアノみたいに 音が減衰するやつはいいけど、オルガンみたいな鳴りっぱなしの音を人の操作で止める方法がない。それに和音の実装ができないですなこれじゃ。和音はNoteOnをまとめて送って、NoteOff するって実装になるはず。ありゃ、これは使えないです。

どうやら、これはMIDI Inでイベントを取るのを主目的にしたライブラリの模様。このライブラリの利用は断念。

では 次はと、グーグル様に問い合わせると、RWMidiいいよ とのこと、ダウンロードはこちら。これには NoteOn NoteOff があるのを確認。でも sample、ドキュメントがいまいち不親切と感じた。

ともあれ 実装開始。

import rwmidi.*;
MidiOutput output;
int ch_s = 0;
int pit_s = 60;
int vel_s = 100;

int program_s;
int device_s;

NoteOff へ NoteOn時の情報を渡すための変数を 設定。なんか初期化してあるけど、気にしない(笑) プログラムナンバー、デバイスナンバーもとりあえず保存する。将来、切り替えられるようにね(^^

void setup() {
size( 800,380 );
device_s = 0;
program_s = 0;
output = RWMidi.getOutputDevices()[device_s].createOutput();
output.sendProgramChange(program_s);
println( output.getName() );
}

画面、デバイスNo,プログラムNo とか初期値設定して MidiOutputを作成して、プログラムNoを送っておく。

音出しするだけなら、draw は 何もかかなくて OK。実際は、前回のEffectテストに追加して書いてます。

Mouseのクリックで 音出し開始。とりあえず Volmeの変化はなしの方向で。

void mousePressed() {
// mouseX, mouseY
println( “mouse pressed” );

org_mouseX = mouseX;
org_mouseY = mouseY;
// Midi Out
int iw;
iw = int( width / 24 );
pit_s = 60 + int( mouseX/iw );
//
output.sendNoteOn( ch_s, pit_s, vel_s);
}

mousePressed イベントに記述。org_mouseX,org_mouseY は将来ドラッグして ベロシティの変化とか、ピッチベントに使うので、保存しておく。

まずは、画面の幅を24(2オクターブ幅)で割って、mouseXの位置からPitch(音階)を生成。チャンネル、ベロシティはデフォ値そのまま。で NoteOn!

次はNoteOffを送信。

void mouseReleased() {
println( “mouse released” );
output.sendNoteOff( ch_s, pit_s, vel_s);
}

mouseRelase イベントで NoteOffを送信。 それだけ。

これで 音出しテスト。おお 結構いけてるよこれ。ソース上で プログラムNoを書き換えて音を変更してみる。 OkOk いい感じ。和音もいけるかテスト、3つのNoteOnを書いて、NoteOffを送信。いけてるーー。和音はひとまず外してっと。

こうなると、音量、ピッチベンド つけたくなるよねえ。

※以下のPitchBendの項目勘違いしてます。次の記事参照。

マウスドラッグのイベントで 変更するメッセージ流せばいいんじゃね?

Midiシーケンサ(Cherry)立ち上げて、PitchBendの番号を調べる。153 ね。データの範囲は-8192 ~ +8191 ねぇ。なんか 広いなぁ。

で、とりあえず。Mouseドラッグに 適当に実装。

void mouseDragged() {
// Xdrag で Bent
print( “mouse dragged ” );
println( (mouseX - org_mouseX)*8 );
output.sendController( ch_s, 153, (mouseX - org_mouseX)*8 );
}

まだ、テスト段階だから、適当にマジックナンバー割り当てと。ほい実行。わっ思いっきりエラーだ。なになに、153 が値を超えてる?なんじゃこりゃ と思って調べてみると、

  1. sendoControllerメソッドで扱えるのは 127 までの#CC(コントロールコードの略らしい)
  2. それを越えると、sendSysExメソッドで エクスクルーシブメッセージを自分で作らないといけないらしい。
  3. MIDIのサイトをいくつかめぐってみたが、メッセージの作り方がよくわからん。0xF0で始まって0xF7 で終わるメッセージらしいんだけど、間にメーカーコードとか 入れないといけないようだ。わからんorz。
  4. よさげなサンプルがないかと さぐってみたけどまだ見つけられない。
  5. JavaMIDIのサンプルをさぐってみたほうがいいかもしれない。

ピッチベンドは後回し決定。

※このPitchBendの項目勘違いしてます。次の記事参照。

じゃあ 縦ドラッグで、Volume変更だ。というわけで イベント書いてみた。

void mouseDragged() {

// Ydrag で Volume…
int v = vel_s - ( org_mouseY-mouseY );
if( 0 <= v && v<128 ){
output.sendController( ch_s, 7, v );
}
}

あれ だめじゃん。次のNoteOnのVolumeまで影響してるよ。

調べてみると、ふつう、NoteOn中の音量調整は、11.Expressionでやるらしい。なるほど。で sendController の 7を11 にして 実行。 あれ やっぱりVolume変更の情報残ってるよ(´・ω・`)

じゃ NoteOnの直前に 11.Expression 戻してみるか。

というわけで、実際の実装

mousePressed

output.sendController( ch_s, 11, vel_s );
output.sendNoteOn( ch_s, pit_s, vel_s);

sendNoteOn の前に Expression を リセット

mouseDragged

// Ydrag で Volume…
v = vel_s - int(( org_mouseY-mouseY )/4);
if( v < 0 ){ v=0; }
if( v > 127 ){ v=127; }
output.sendController( ch_s, 11, v );

}

変化の範囲を 1/4 にして、ドラッグの範囲を広げた、値が Expressionの範囲を越えたら 最大値、最小値にする。(ドラッグ処理落ちの対応)

なんとなく いい感じじゃない? これは採用。

で、デバイスの変更と、プログラム(音色)の変更を実装。

mousePressed

if( mouseX<100 && mouseY<40 ){
if( mouseY<20 ){
output.closeMidi();
device_s = device_s+1;
if( device_s >= RWMidi.getOutputDevices().length ){
device_s=0;
}
output = RWMidi.getOutputDevices()[device_s].createOutput();
println( output.getName() );
int retx = output.sendProgramChange(program_s);
} else {
program_s = program_s+1;
int retx = output.sendProgramChange(program_s);
}
} else {

左上 100*40 の範囲は コントロール用。上のクリックで デバイスを変更。注意点は、変更する場合は、一旦閉じないといけないということ。 output.closeMidi()を忘れないでね。getOutPutDevices で デバイスの配列がとれます。クリックが配列数をオーバーしないように処理しています。プログラムNoは、チェックしてないです。127 越えたら 0 にするような処理が必要ですね。Applet には 実装。

あとは、演奏中のデバイス名と、プログラムNoを表示するようにして完成。

※このへんは ソース見てください。Applet画面に ソースへのリンクがあります。

単音 音出し、完了。試してみたい方はここ

  1. エフェクト作成。
  2. (今ここ→)音出し作成。(単音、和音)
  3. 音階ボタン作成。
  4. 音階ボタンから音生成。
  5. 筐体作成。
  6. 完成。

画面エフェクト

2009 年 1 月 27 日 火曜日

まずは、processing で 画面エフェクト。

とりあえず試してみたい方はこちらから。黒いとこをクリックしてみて。

  1. エフェクトの種類はとりあえず、直線、○、△、□。将来的に、任意の絵を表示できるように。
  2. クリックポイントを中心に 各図形が回転しながら大きくなって暗くなって消えていく。
  3. 直線はクリックポイントを通るランダムな角度の直線。
  4. processingの座標変換機能を最大限利用。サイズの変化は描画で、角度の変化は座標変換で。
  5. 画面エフェクトは、Class化しておく。
  6. メソッドは、start と display。コンストラクタは何もしない。

processingでのListの実装がわからん。エフェクトオブジェクトをクリックされるたび、生成して、暗くなっ て消えたら デストラクタして、、と考えたんだけど、配列しか無くて、可変できないみたい。む~、美しくないけど、固定配列に start() で 生成して順番に使って行く形式にする。

というわけで ささっと作ったのがこれ。

class Effect {
int px;
int py;

int dBright = 10;
boolean drawFlg = false;
int cR = 0;
int cG = 240;
int cB = 96;
float angle=0;
int objType = 0;

int strokeW = 20;

float rAngle;
float dAngle = 20;
int rSize;
int dSize = 20;

Effect() {
}

void startObj(int x,int y ) {
this.px = x;
this.py = y;
this.drawFlg = true;
this.angle = random(0, 360 );
cR = 0;
cG = 240;
cB = 96;
objType = int(random(0,4));
rAngle = angle;
rSize = strokeW;
noFill();
}

void display() {
if( drawFlg ){
// 座標形の変更
strokeWeight(strokeW);
stroke( cR, cG, cB );
cR = cR - dBright; if( cR<0 ){ cR=0; }
cG = cG - dBright; if( cG<0 ){ cG=0; }
cB = cB - dBright; if( cB<0 ){ cB=0; }
if( cR==0 && cG==0 && cB==0 ){
drawFlg = false;
}
pushMatrix();
translate( px,py );
rotate( radians( angle ) );

if( objType==0 ){
// 線
strokeWeight(strokeW*2);
line( 1024,0, -1024,0 );
} else if( objType == 1 ){
// ○
ellipse( 0,0, rSize, rSize );
ellipse( 0,0, rSize+50, rSize+50 );
rSize = rSize + dSize;
} else if( objType == 2 ){
// □
rectMode( CENTER );
rotate( radians( rAngle ) );
rect( 0, 0, rSize, rSize );
rSize = rSize + dSize;
rAngle = rAngle + dAngle;
} else if( objType == 3 ){
// △
// dx = sin( 60 );
float dx,dy;
dx = rSize * cos( radians( 60 ) );
dy = rSize * sin( radians( 60 ) );
rotate( radians( rAngle ) );
triangle( 0, int(dy*2/3), int(dx), int(-dy/3), int(-dx), int(-dy/3) );
rSize = rSize + dSize;
rAngle = rAngle + dAngle;
}

popMatrix();
}
}

}

で、メイン側の処理

import processing.opengl.*;

Effect[] efs = new Effect[10];
int efCnt = 0;

void setup() {
size( 1024,380 );

for(int i=0; i<efs.length; i++ ){
efs[i] = new Effect();
}
}

void draw() {
background( 0 );
//
for(int i=0; i<efs.length; i++ ){
efs[i].display();
}
}

void mousePressed() {
// mouseX, mouseY
println( “mouse pressed” );
// 絵を描き始め
efs[efCnt].startObj( mouseX, mouseY );
efCnt++;
if( efCnt == efs.length ){ efCnt=0; }
}

変数の説明とかは 後で、このソースに書き足しておきます。

※たしか、processingは 簡単に JavaApplet にできたと思ったんだけどな。

まぁ後でやっておこう。

簡単だった(笑) アプレット化 黒いとこを クリックしてみてねぃ(^^

※問題点

  1. エフェクトの数が10個しか用意されてないので それを越えると古い画像が消えるように見えるかも。(まだ、足りなくなったことはない)
  2. 画面サイズを大きくすると、描画がとろい、というか画面のリセットがとろいのだなこれは。Effectクラスの描画パラメータをいじってみる。
  3. 書き方の順番が オブジェクトの0からになってるので、重なりの描画が変(これはプログラムのせい。いつか直そう)。重なったら、なんかするべきだろ>processing
  4. 重なりの描画は なんか 考える必要があるな。。背景が黒ってのがまずいような気がする。Alphaチャンネルを扱えるのはいいのだけど、どうも考えてる仕様とはちがうな。

とりあえず。Effectの描画は これで オーケーってことにしておこう(笑)。

  1. (今ここ→)エフェクト作成。
  2. 音出し作成。(単音、和音)
  3. 音階ボタン作成。
  4. 音階ボタンから音生成。
  5. 筐体作成。
  6. 完成。

「あの楽器」作成手順

2009 年 1 月 27 日 火曜日

液晶画面タッチパネルは 今使ってるノートパソコンを使うとして、、、

音源はMIDI outを使うように作る。遅延とか気になるけど、まぁ、今はプロトタイプの段階だし、遅延が気になるようになった時点で俺の作業は終わりってことにしよう。 FPGAなり、CPLDなり軽いものに置き換えるのはもっと技術力のある人におまかせ。

音階入力は gainer経由のボタンから行う予定。

形状は、Innocenseの画像よりずんぐりむっくりになる。いいのだ プロトタイプなんだから。

プログラミング言語は proce55ing。processing が正式なんだけど、processingでぐぐると、ゴミがですぎるので、proce55ing。興味のあるひとはぐぐってみてね。gnainerのライブラリがあったのが、主な採用理由なんだけど、これ、中身はJavaでJavaライブラリが使えるらしい。Javaには MIDIライブラリもあるし、いい選択のようだ。

大体の スケジュール。というか作成手順。

  1. エフェクト作成。
  2. 音出し作成。(単音、和音)
  3. 音階ボタン作成。
  4. 音階ボタンから音生成。
  5. 筐体作成。
  6. 完成。

メモ

音のNoteONは画面タッチで、NoteOffは音階キーのリリースで。おまけとして(というか実験として)カオシレータのようにタッチ位置から音階を拾う機能をつける。

音のエフェクトは、エクスクルーシブ(ベロシティ)、ピッチベンドは実装したい。

というわけで 作ってみる。開始。

「あの楽器」に挑戦

2009 年 1 月 27 日 火曜日

ニコニコ技術部で大流行(?)の「あの楽器」。

挑戦って わけで、作成経過 Blogを 造ってみた。

まずは「あの楽器」名古屋ミーティング 2009/1/11 で なんか発表。

nico Tech あの楽器配布ちらしano.pdf
nico Tech あの楽器発表資料Ano_project.pdf

今 見てみると、結構適当だな(笑) なんてたって 一晩で作り上げた資料だものなあ(笑)