bonar note

京都のエンジニア bonar の技術的なことや技術的でない日常のブログです。

音楽配信の次にくるもの

「リミックス」だと思う今日この頃。これから少しずつプロじゃない人たちの音源を簡単に入手できるようになってくると、それをリミックスしてかっこいい感じに出来る人がモテモテになるような。m-floみたいな感じで。


とてもチェックしきれない数の音楽であふれかえって、全体のクオリティは下がるけれども、そこから素晴らしい音楽を探せる人がスタープレイヤーになると思う。


今は音楽の配布形態がmp3なのでなかなか再編集が難しいのですが、GarageBandの形式で配布するのがはやったり、昔でいうmodみたいな形式の音楽がはやりだすと、もうリミックス自体の到来の予感。友達が作った音楽や恥ずかしい歌とかにそれっぽいストリングとリズムを重ねてみたり、すきなミュージシャンの曲をみんなでアレンジして競い合ってみたり。すごく楽しそうじゃないですか?


そういう時がきたら、主役はGarageBandSONARの用なサウンドアグリゲーションツールであって、ユーザに必要になるのはかっ>こいいドラムループとコード進行の知識だと思う。音楽の「部品」を自由に作れるようになると楽しいかなあと。


そんなことを考えながら、コードからそれを構成する和音を取得するスクリプトを書いてみました。

#!/usr/bin/perl

use strict;
use Switch;

use constant {
    CODE_REGEXP => '^(C|D|E|F|G|A|B)(m|M7|m7|7)?$',

    HOP_MAJOR => [0, 4, 7],
    HOP_MINOR => [0, 3, 7],
    HOP_M7    => [0, 4, 7, 11],
    HOP_m7    => [0, 3, 7, 10],
    HOP_7     => [0, 4, 7, 10],

    CODE_2_NOTE => {
        'C'  => 0,
        'C#' => 1,
        'D'  => 2,
        'D#' => 3,
        'E'  => 4,
        'F'  => 5,
        'F#' => 6,
        'G'  => 7,
        'G#' => 8,
        'A'  => 9,
        'A#' => 10,
        'B'  => 11,
    },
};

# make mapping
my $code_note = CODE_2_NOTE;
my %NOTE_TO_NUM = %{ $code_note };
my %NUM_TO_NOTE = reverse %{ $code_note };

sub fix_overflow_note {
    my ($num) = @_;

    $num -= 12 if $num >= 12;
    return $num;
}

sub push_incr {
    my ($target_aref, $basenum, $incre_aref) = @_;

    return if ref($incre_aref)  ne 'ARRAY';
    return if ref($target_aref) ne 'ARRAY';

    foreach my $incre (@$incre_aref) {
        push @$target_aref, fix_overflow_note($basenum + $incre);
    }
}

sub get_notes_from_code {
    my ($code) = @_;

    my $code_regexp = CODE_REGEXP;
    if ($code !~ /$code_regexp/) {
        die "invalid code string [$code]";
    }
    my ($code_base_num, $code_class) = ($1, $2);

    # base note
    if (!exists $NOTE_TO_NUM{$code_base_num}) {
        die "no such base code [$code_base_num]";
    }
    my $base_num = $NOTE_TO_NUM{$code_base_num};
    my (@notes);

    switch ($code_class) {
        case ""   { push_incr(?@notes, $base_num, HOP_MAJOR); }
        case 'm'  { push_incr(?@notes, $base_num, HOP_MINOR); }
        case 'M7' { push_incr(?@notes, $base_num, HOP_M7); }
        case 'm7' { push_incr(?@notes, $base_num, HOP_m7); }
        case '7'  { push_incr(?@notes, $base_num, HOP_7); }

        else { die "unknown code class [$code_class]"; }
    }

    return map { $NUM_TO_NOTE{$_} } @notes;
}

# get args
my $codes = $ARGV[0];
my @codes = split /?-/, $codes;

foreach my $code (@codes) {
    my @notes = get_notes_from_code($code);
    my $note_str = join " ", @notes;
    print "[ $note_str ]?n";
}

こんな感じで使ってみたり。

bonar$ perl get_notes.pl C-G-Am-Em-F-C-F-G-G-GM7-G7-E
[ C E G ]
[ G B D ]
[ A C E ]
[ E G B ]
[ F A C ]
[ C E G ]
[ F A C ]
[ G B D ]
[ G B D ]
[ G B D F# ]
[ G B D F ]
[ E G# B ]

だから何?って感じですか(笑

実際はこの出力を少しシャッフルしたり他の音をちょこっとまぜたりしてpmml等のmidiパーサにつっこんだりして遊びます。それだけだと本当にただの和音ファイルなのですが、GarageBandに放り込んでリバーブとかエコーみたいな効果をかけると意外と奇麗になったりするんです。


Mac OS XでPMMLを使う
http://www.mgsoft.org/jikanbae/untitled/computer/pmml/


この結果をうまくこねこねして曲のパーツになるようなものを生成するツールを作りたい。素敵なGUIを付けたい。Objective-Cがわからない。


あーもうだめだ。ひどいエントリーだ。