Skip to content

Instantly share code, notes, and snippets.

@Shinpeim
Last active August 29, 2015 14:19
Show Gist options
  • Save Shinpeim/65ec5dd8d31bbf3a2192 to your computer and use it in GitHub Desktop.
Save Shinpeim/65ec5dd8d31bbf3a2192 to your computer and use it in GitHub Desktop.
<?php
// chords テーブル
// id integer
// root varchar
// quality varchar
//
// rootには C, C#, D, D#, E....が入る
// quality テーブルにはm,Mが入る
// このテーブルには、12音 * 2つのqualityで24個のデータを最初から入れておく
// chord_progressions テーブル
// id integer
// key varchar
// from_chord_id integer
// to_chord_id integer
// count integer
//
// このテーブルには、コピーしたコード進行をねらさんが入れる。
// そのとき、曲の最初のコードのときはfrom_chord_idにnull,
// 最後のコードのときはto_chord_idにnullを入れる。
// たとえば、key:CMで C -> F -> G -> C で終わるような曲と、
// たとえば、key:CMで C -> Am -> Dm -> G -> C で終わるような曲の場合、
//
// I. 一曲目のデータを入れる
// 1. key:CM, from_chord_id:null
// to_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>を入れる
//
// 2. key:CM, from_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>
// to_chord_id:<chords テーブルでroot:Fでquality:Mなレコードのid>を入れる
//
// 3. key:CM, from_chord_id:<chords テーブルでroot:Fでquality:Mなレコードのid>
// to_chord_id:<chords テーブルでroot:Gでquality:Mなレコードのid>を入れる
//
// 4. key:CM, from_chord_id:<chords テーブルでroot:Gでquality:Mなレコードのid>
// to_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>を入れる
//
// 5. key:CM, from_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>
// to_chord_id:nullを入れる
//
// II. 二曲目のデータを入れる
// 1. key:CM, from_chord_id:null
// to_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>を入れる
//
// 2. key:CM, from_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>
// to_chord_id:<chords テーブルでroot:Aでquality:mなレコードのid>を入れる
//
// 3. key:CM, from_chord_id:<chords テーブルでroot:Aでquality:mなレコードのid>
// to_chord_id:<chords テーブルでroot:Dでquality:mなレコードのid>を入れる
//
// 4. key:CM, from_chord_id:<chords テーブルでroot:Dでquality:mなレコードのid>
// to_chord_id:<chords テーブルでroot:Gでquality:Mなレコードのid>を入れる
//
// 5. key:CM, from_chord_id:<chords テーブルでroot:Gでquality:Mなレコードのid>
// to_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>を入れる
//
// 6. key:CM, from_chord_id:<chords テーブルでroot:Cでquality:Mなレコードのid>
// to_chord_id:nullを入れる
// Cメイジャーのコード進行を提案するようなプログラム例
$chords = array();
$found_chord = /*"
SELECT to_chord_id
FROM chord_progressions
WHERE key = 'CM' AND from_chord_id IS NULL
ORDER BY RAND()
LIMIT 1
" // で取得できるto_chord_idのコード; */
$chords[] = $found_chord;// 最初のコードとして使えるコードを$chords配列の一番最初に突っ込む
while (true) {
$from_chord = $found_chord;
$found_chord = /*
SELECT to_chord_id
FROM chords
WHERE key = 'CM' AND from_chord_id = 'ここにfrom_chordのid'
ORDER BY RAND()
LIMIT 1
" // で取得できるto_chord_idのコード;*/
// SQLを読み解くと……
// 一回目のループでは
// もし今$from_chordにCが入っている。
// from_chord_idにCが入ってるレコードは
// from_chord_id: C, to_chord_id: F のものか、
// from_chord_id: C, to_chord_id: Am のものである
// その中からランダムにレコードを選ぶので、
// 結果として to_chord_id は F か Am になり、
// found_chord には F か Am が入る
// ここではFが入ったとする。
// 一回目のループでは、$found_chordにはFが入っているので
// nullではないのでここは無視される
if ($found_chord == null) {
break;
}
// Cの次のコードに F を入れる
$chords[] = $found_chord;
// この時点での chords == [C, F]
// 次のループへ
}
<?php
while (true) {
$from_chord = $found_chord;
$found_chord = /*
SELECT to_chord_id
FROM chord_progressions
WHERE key = 'CM' AND from_chord_id = 'ここにfrom_chordのid'
ORDER BY RAND()
LIMIT 1
" // で取得できるto_chord_idのコード;*/
// 3回目のループです。
// 今$from_chordにGが入っている。
// from_chord_idにGが入ってるレコードは
// from_chord_id: G, to_chord_id: C だけである
// その中からレコードを選ぶので、
// 結果として to_chord_id は C になり、
// found_chord には C が入る
// 2回目のループでは、$found_chordにはGが入っているので
// nullではないのでここは無視される
if ($found_chord == null) {
break;
}
// F の次のコードに G を入れる
$chords[] = $found_chord;
// この時点での chords == [C, F]
// 次のループへ
}
<?php
while (true) {
$from_chord = $found_chord;
$found_chord = /*
SELECT to_chord_id
FROM chord_progressions
WHERE key = 'CM' AND from_chord_id = 'ここにfrom_chordのid'
ORDER BY RAND()
LIMIT 1
" // で取得できるto_chord_idのコード;*/
// 3回目のループです。
// 今$from_chordにFが入っている。
// from_chord_idにFが入ってるレコードは
// from_chord_id: F, to_chord_id: G だけである
// その中からレコードを選ぶので、
// 結果として to_chord_id は G になり、
// found_chord には G が入る
// 3回目のループでは、$found_chordにはGが入っているので
// nullではないのでここは無視される
if ($found_chord == null) {
break;
}
// F の次のコードに G を入れる
$chords[] = $found_chord;
// 今は [C, F, G]
// 次のループへ
// 次のループは次のファイルで解説します
}
<?php
while (true) {
$from_chord = $found_chord;
$found_chord = /*
SELECT to_chord_id
FROM chord_progressions
WHERE key = 'CM' AND from_chord_id = 'ここにfrom_chordのid'
ORDER BY RAND()
LIMIT 1
" // で取得できるto_chord_idのコード;*/
// 4回目のループです。
// 今$from_chordにGが入っている。
// from_chord_idにGが入ってるレコードは
// from_chord_id: G, to_chord_id: C だけである
// その中からレコードを選ぶので、
// 結果として to_chord_id は C になり、
// found_chord には C が入る
// 4回目のループでは、$found_chordにはCが入っているので
// nullではないのでここは無視される
if ($found_chord == null) {
break;
}
// G の次のコードに C を入れる
$chords[] = $found_chord;
// 今は [C, F, G, C]
// 次のループへ
// 次のループは次のファイルで解説します
}
<?php
while (true) {
$from_chord = $found_chord;
$found_chord = /*
SELECT to_chord_id
FROM chord_progressions
WHERE key = 'CM' AND from_chord_id = 'ここにfrom_chordのid'
ORDER BY RAND()
LIMIT 1
" // で取得できるto_chord_idのコード;*/
// 5回目のループです。
// 今$from_chordにCが入っている。
// from_chord_idにCが入ってるレコードは
// from_chord_id: C, to_chord_id: null だけである
// その中からレコードを選ぶので、
// 結果として to_chord_id は null になり、
// found_chord には null が入る
// $found_chordにはnullが入っているのでここでループを抜ける
if ($found_chord == null) {
break;
}
$chords[] = $found_chord;
}
//$chords には [C, F, G, C]が入っている
// 要するに、「このキーでこのコードのとき、次に来れるコード」というのをデータベースにたくさんいれておいて、
// その中からランダムで次のコードを選ぶ、というのを繰り返して
// nullが来たら「曲が終わった」と解釈する、というスンポーです
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment