Loading [MathJax]/extensions/MathMenu.js

2016年1月6日水曜日

バイオモルフみたいに選ぶだけで音楽を作れるプログラム[Python]

1.バイオモルフ

昨日の続き。『心はプログラムできるか』にバイオモルフというプログラムが紹介されていた。
次のリンクはBiomorphで検索したら出てきたサイト。
バイオモルフというものを実際に実行できる。
・Biomorphs | Emergent Mind

表示されている9つの個体の中で,一番おもしろいと思うものをクリックしていく。
すると今度はクリックしたものと微妙に異なった新たな個体ができる。
それを繰り返していけば,とてもおもしろい形を作れるというハナシ。

本の中では「進化の力を借りてアートを創る試み」として紹介されていた。
評価関数をコンピュータの中ではなく,人間を用いるというのが非常に面白い着想で,「美しさ」みたいな抽象的なものでも作れる可能性があるということが面白いと思った。

2.ミュージックモルフ

作者の有田先生の研究室では顔モルフというものを作っていたらしい。
似顔絵をクリックするだけで作れるというもの。

この辺りから着想を得て良い音楽を選んでいくことで,だんだんと良い音楽に進化していくというプログラムを作ってみた。


残念ながらあまりいい出来とはいえないです……。音楽は5段階中3だったかな……。

2016/01/07 追記
この動画を見るとコードというものを使ってる……コードってなんぞ?プログラムのソースコードのことかの?どうやら音符の塊みたいなもののようだけれど……こういうのは音楽のトーシローができるもんじゃなさそうだ。


とりあえずソースコードを貼っておく。練習でGitHubでレポジトリを作ってみたのでそちらのリンクも貼っとく。
・TonyMooori/Music_Morph

ソースコード
# -*- coding: utf-8 -*-
import numpy as np
import pyaudio
import struct
import time
__author__ = "TonyMooori"
class MusicMorph:
def __init__(self,length = 8,n_child = 4,pulse = 0.25, mutation = 0.25):
"""
length: The length of a socre.(楽譜の長さ)
n_child: The number of the scores.(楽譜の数)
pulse: The length of a pulse(second).(拍の長さ[秒])
mutation: The percentage of mutation.(突然変異の確率)
"""
""" The frequency of each scales.(音程の周波数) """
self.scales = np.array([ 0.0, 261.63,293.66,329.63,349.23,392.00,440.00,493.88,523.25,])
self.length = length
self.n_child = n_child
self.pulse = pulse
self.mutation = mutation
""" Make scores.(楽譜を作る) """
self.refresh()
def createSineWave(self,freq,sec=1.0,rate = 44100.0):
"""
Return the sine wave.(サイン波を返します)
freq: The frequency of the sound.(音の周波数)
sec: The length of the sound(second).(音の時間[秒])
rate: The sampling rate of the sound.(サンプリング周波数)
"""
x = np.linspace( 0, 2 * np.pi * sec, num = int(rate * sec))
y = (32767.0 * np.sin( freq * x ) ).astype(np.int)
return struct.pack("h" * len(y), *y )
def play(self,indx):
"""
The function to play the score.(演奏を行う関数)
indx: The index of score.(楽譜番号)
"""
p = pyaudio.PyAudio()
stream = p.open(
rate=44100,
channels=1,
format=pyaudio.paFloat32,
output=True
)
""" Play each sound.(音ごとに演奏する) """
for indx,length in self.child_score[indx]:
sec = self.pulse * ( 2.0 ** length )
freq = self.scales[int(indx)]
stream.write(self.createSineWave(freq,sec))
stream.close()
p.terminate()
def random_sound(self,last_scale):
""" Return a random sound.(音をランダムに作る) """
sound = np.zeros(2)
n_scale = len(self.scales)
""" Decide a scale of the sound.(音程を決める) """
sound[0] = int(np.random.random_sample() * n_scale)
while last_scale == sound[0]:
sound[0] = int(np.random.random_sample() * n_scale)
""" Decide a length of the sound.(音の長さを決める) """
sound[1] = int(np.random.random_sample() * 4)
return sound
def random_score(self):
""" Return a random score.(ランダムな楽譜を返す) """
score = np.zeros((self.length,2))
last_scale = -1
for i in range(self.length):
score[i] = self.random_sound(last_scale)
last_scale = score[i,0]
return score
def make_children(self):
""" Remake all scores using the selected score.(選択した楽譜で全て作り直す) """
scores = np.zeros((self.n_child,self.length,2))
scores[0] = self.main_score
for i in range(1,self.n_child):
scores[i] = self.make_child()
return scores
def make_child(self):
""" Make a new score using a selected score.(類似した楽譜を作る) """
score = self.main_score.copy()
last_scale = -1
for i in range(len(score)):
if np.random.random_sample() < self.mutation:
score[i] = self.random_sound(last_scale)
last_scale = score[i,0]
return score
def select(self,indx):
"""
Select the best music.(選択を行うメソッド)
indx: The number of the score.(楽譜番号)
"""
self.main_score = self.child_score[indx]
self.child_score = self.make_children()
def refresh(self):
""" Refresh all the scores.(楽譜を一新するメソッド) """
self.main_score = self.random_score()
self.child_score = self.make_children()
print("Music Morph")
n_child = 4
mm = MusicMorph(n_child = n_child)
while True:
print("\n" + "*" * 40)
print("input command")
print("-3\t: exit")
print("-2\t: init scores")
print("-1\t: listen all")
for i in range(n_child):
print(str(i) + "\t: listen score no." + str(i))
for i in range(n_child):
print(str(i+n_child) + "\t: select score no." + str(i))
""" Input and parse to the integer.(入力してint型に変換) """
cmd = raw_input()
try:
cmd = int(cmd)
except:
cmd = -4
""" Branch.(分岐) """
if cmd == -3:
break
elif cmd == -2:
print("refreshed")
mm.refresh()
elif cmd == -1:
print("listen all")
for i in range(n_child):
print("playing no." + str(i) )
mm.play(i)
time.sleep(0.25)
elif 0 <= cmd <= n_child - 1:
print("playing no." + str(cmd))
mm.play( cmd )
elif n_child <= cmd <= 2 * n_child - 1:
print("selected no." + str(cmd%n_child))
mm.select(cmd % n_child)
else:
print("wrong input")
view raw MusicMorph.py hosted with ❤ by GitHub

『心はプログラムできるか』を読んだ話

1.感想

実家に帰省した際,有田隆也先生の『心はプログラムできるか 人工生命で探る人類最後の謎』という本を読んだ。

今まで人工生命の研究が役に立つのか?と今まで疑問に思ったことがあったが,この本を読んで役に立つ場所をいくつか知ることができた。

例えば蟻の力を借りることで巡回セールスマン問題をある程度解くことができる蟻コロニー最適化
こういった突拍子もないアルゴリズムは,なかなか理解されにくい研究分野からポロッと出るのかもしれないと思った。

他にも似顔絵を作成することができる「顔モルフ」なるプログラムや遺伝的アルゴリズムによるロボットの形状・行動の学習などはとても面白いと感じた。

顔モルフに関しては,サポートサイトで実行することができるそうなのだが,30億のデバイスで走るJavaさんが奇跡的に動かなかった。

他のプログラムも実際に動く姿を見たいので,自分で実装できるぶんは実装したいと思う。
なのでこのページは関連リンク集にしたいと思う。

2.リンク

自分でやったこと
・バイオモルフみたいに選ぶだけで音楽を作れるプログラム[Python]
バイオモルフから着想を得て音楽でも似たようなことができないかやってみた。結果は……私の音楽の成績が低かったようで……。

・Processingでライフゲームを実装[Processing]
セル・オートマトンの一種。チューリング完全でライフゲームでライフゲームをやってる人をニコニコ動画で見たことがある。すごく面白い。

・ラングトンのアリを実装してみた[Python]
ラングトンのアリ。セル・オートマトンの一種。

・蟻コロニー最適化と遺伝的アルゴリズムで巡回セールスマン問題(TSP)を解いてみる
蟻コロニー最適化を実装した.

外部サイト
・Biomorphs | Emergent Mind
本で紹介されていたバイオモルフと呼ばれるプログラム。表示された9つの個体から,好きなモノをクリックしていくと,面白い個体が得られる。

・「心はプログラムできるか」のすべて! 公式サポートサイト(サイエンス・アイ新書)
サポートサイト。リンクをたどればバイオモルフの考え方を応用した顔モルフのプログラムが(運が良ければ)実行できる。

・人工生命ティエラ - 哲学的な何か、あと科学とか
ティエラの概要が書いてある。ティエラの話は同じく有田隆也先生の書かれた『人工生命』という専門書にものすごく詳しく書いてある。