DNAから音楽を作る

はてなダイアリーに「メロディ再生機能」がついたそうな。MML (Music Macro Language)というらしい。
http://d.hatena.ne.jp/hatenadiary/20071011/1192086766

DNAから音楽を作る人がいるらしい。
http://ja.wikipedia.org/wiki/%E9%81%BA%E4%BC%9D%E5%AD%90%E9%9F%B3%E6%A5%BD

ということで早速作ってみた。ウニの遺伝子から作った音楽は悲しいと聞いたことがあったけど、本当に悲しい音楽になってしもた。たぶんウニに限ったことじゃないんだろうな。

バフンウニ (Hemicentrotus pulcherrimus)

http://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nuccore&id=157890094

t200 l8 @2 q14 o6
<D><E><E><G><G><F><F><G>BG<C><C><C><C>BB<E><E>B<E>BGAGAGG<C><C>GECFAEEEFEAEAEAEEAAGEEEFEAEEEEEA
AEEFAECDFFFEFAGEEAEAEECDCDFAG<C><C>BGECDAEFEEAEAAECDFEAEEEAGGEECD
<F><F><F><F><D><G>B<E>BGECFEFAEAECDDA<C>GEAEAAA<C>GGEAGEEAAEEEAA<C>BB<E><E><G><F><D>BBBGGEE
EECCAAGEFEAA<C><E>BB<E><E><G><D>BBB<E>BGECFEAEAGEEAAEEEAAGAGGA<C>B<E><E>BBB<E>BBB<E>B
EECAAAGEAGGEECAA<C>B<E><G><G><D><E>B<E><E><D><E>BBB<E>B<E><E>BBB<C>BB<C>G<C>GAAAAA<C>B<E><D><E>BB<C>B<C><E>
<D>B<C><E><E><E><D>B<E><E>BBB<E>BBGEECCFA<C>BBGEEAECAAEEEEA<C><E>BBBGAEAAAAEECDAAEAEE
FFEAGEAEAG<C><C>B<C><C><E>BBBBGAG<C>B<E><D><D><G><D>B<C><E>B<E><E>B<E>B<E>B<E><E><G><F><G><G><G>B<C>GGA<C><E><E><E><G><F>B<E>
<D>B<E>B<C>G<C><C><C>B<C><C>B<C>B<E><E>B<E><D><D>B<C>G<C>BBBBBBBBB<E><E><E><E>B<E><E><D>B<E>B<E><D>B<C>B<C>BB<C><C>BGA<C><E><G>
<F><G>B<E><D><E><G><G>BGEEAGECCDAAAGEEEEFEEFAEEEFCDDDCDAAEAA<C><E><G><F><F><F><F><F><F><F><D><E><E><D><E>
<D>BGAA<C><C><C><E><D><G><G><G><D><E>BBB<E><D>BB<C>B<E><E><E>B<C>BGA<C>BGAEA<C><E><E><D><E><G><D><E><E>B<E><E><E><E><E><D>BBB<E>B<E><E>
<E><E><D><G>BBB<E><E>BGGAGA<C>GG<C><E><D>B<C><C>B<E>BGEAEAG<C>B<E><E><E><G><F><G><G>BBB<E><E>BGA<C>BGAEAGAAAG
EAA<C>GGAGAAAEFCDFEFEAGAECDAGEAGAA<C><E>BGAEAGEFEAEECDAEFCDFFEAGAGA
EFAEFA<C><E><D><E>BB<C>B<E><E>BG<C><C><E>BBGAAAGEA<C>GEAEAEFAEFFCFAEEFEAAEAG<C><C>BG<C><C><C>
EECFFEEAGEFFAGAGEEAGGAGEFA<C>BBBBGEAEFFFEEFEECCDCAG<C><C><C>BB<C><C><E><E><G><F>B
<F><G><D><G><G><G>B<C>GEFCAAAAGAAAECCDCAECFAEFFEEAG<C><E><G><F><F><G><F><F><F><G><G><G><D>BBBGA<C><C>G<C><C><E>
<C>B<C><E>BGA<C>BGAAGAGGECFFFCDDAGGG<C><C>BBG<C><E><G><G><F><G>BBBBGAAAA<C><C>G<C>GEEAECA<C><E>
<D><G>BGG<C><C>GG<C>GAGEEAGEFAAGEEAGGECA<C><E>B<C><E><D><G>BGAA<C><E>BB<C>GEEAEFCDFFEAAAA
CFAEEEFFA<C>B<E>BB<C><E><D><G><G><F><F><G><G><G>B<E><D>B<C><C>GGAECCDAAECAEEFEFAGEA<C><E><E><D><E><G><D><E><D><D>
>B<FFA<C><E><E><G><D><E><G>BGG<C><E><D><E>BGEAAECA<C><E><D>B<C>B<C><E><D><E><E><E>B<C>G<C><E>BB<C>B<C><C>G<C><E><G><D><G>B<C>GEA<C>
CCFECDAAGEECDFCFAAEA<C><E><G><D>BGGECAA<C><E><E><E><D>BGGAEA<C>B<C><C>B<C>GG<C>BGGECDAAGE
DAEFCAA<C><E><D><E><E>B<E><D><E><D>BBB<C>B<E><D>BBGAEECAAGAEEECDAGGEEFCDCAAA<C>BGEA<C>BBG
DCAEFA<C>GAGEEEA<C><E><E><G><F>BGGEEA<C><E><D><E>BB<C>B<C><C><E><D><E><G><G><F>BB<C><C><E><E><G><F><F>BBBGEEAGA<C><E>
CDFCCAEAGEEFCAGGEFCFFFAGGGGEAGA<C>GA<C><E>B<C>G<C><C>G<C><C>GEFFAEFECCDA<C>GECA
<E><G><D><G><G><D><E><E><D><E><D><D><G><G>B<C>GEA<C><E><D><D><G><G>B<E><D><D><E>B<C><E><D><E><D><E>BGGEECCFCCCFFAGG<C>G<C><C><E><G><G><G>
<D>B<E><D><D><E>B<E><D><D><D><G><F>BG<C><E><D><D>BBB<E><D><D><D><D>B<E><D><D><E><G>B<E>BG<C><C>B<E><D><E><G><D><E><E><D><D><D><D><E>BGAEAGGEF
FEFFFFFCCAAECCDFCDCCAGEA<C>G<C><C><E><D><G>B<C><C><C><E><D><D><E><E><D><D><D><E><E><D><E><G><D><E><D><D><D><D><E>BGAA<C><C>
GEFCCCCDFFA<C><C>B

ムラサキウニ (Anthocidaris crassispina)

http://www.ncbi.nlm.nih.gov/entrez/viewer.fcgi?db=nuccore&id=5689334

t200 l8 @2 q14 o6
GEFEECFA<C>BBB<C>BG<C>BB<C><C><C>BG<C><E><E>B<E><D><D><E><E><D><E><E><G>B<E><E><D><D><E><E><D><E><E><D>B<C><C><E><D><D><E>BG<C><E><G>B<C>
EA<C>B<C>GA<C>GAAAA<C>BBGG<C><C>GA<C><E>B<C>GA<C>GGGG<C><E><G><D><D><G>B<C>G<C><C><E><E><D><D><D><D><E>BGEAA<C>BGA<C>
<E><G>B<C><C>GECDFCCDDCDFEECDFEFEFEA<C>B<C>GA<C><C>B<C>GGEFAECAAGEEEEEFEA<C>BB<C>GE
CFEECA<C>B<C><C>GA<C>GAA<C>B<E><D>BB<C><E><G><D><D><G><D>B<C>GGEAGEFCDFEFA<C><E><E><G><F><D><G>B<C><E>B<C>GEEEF
<E><G><D>B<E><D><E><G><G><D>B<C>B<C><E><E><G><D>BB<C>GAGEFFCCFCDDDCDA<C>G<C><E><D><E><E><D><E><G><G>B<E><G><F><D><D>BGEFFCD
DFEAA<C>B<C><C>GEFECDFAGGG<C>BBB<C><E>B<C><C>GA<C><E><D><E>BB<E>BG<C><E>BG<C><C><C><E><G>BGECDDFFCAGA
<G><D><D><E><G><F><F><G>BGGEFFEFFFEECAA<C><C><C>GEEEFECAEEFFCCDFECA<C><C>GEFFCA<C>BGEEEEE
CDCAGGA<C><E><E><G><G><D><D>BGGEA<C>GAA<C><C>BGG<C><E><G><G><D>B<C>GEFA<C>BB<C>G<C><E><G><D>B<C>GG<C>GECDDCDD
FFEEEFAA<C><E><G><F><G><D>BB<E><E><E>BGG<C>G<C><C><E><E><G><D>B<E><D><G><F>BB<C><E><E>BGA<C>B<E><D><E><E><D><G><F><D><G><D><G><F><F><G><F><F>
FFAAAGA<C><E><D>BGA<C><E><E>BGGEFCA<C>GEEA<C><E><D>BGECFCCFEAEFFECFEAGEECFFAGGECA
<D><D><E>BB<C><E>BGEEFA<C>GECDDFFA<C><E>B<C>B<E><D><D><D>B<C>B<C><C><C><E><G>B<C>GG<C><E><E><D><G>B<E><G>B<C>GEFECAAA
>B<FFCAGEAEA<C>GEEFCCAA<C>B<C><C><E><D><D><E>BBGA<C>GEA<C>B<C><E>BGEEECFEFCAGEECA<C><C><E><E><D><E>
EEFEEAAEEFAG<C><C>GECCCCDAGECFFAECAAG<C>G<C><C><E><E><D><D><E><E><D><G><D><D><G><D><D>BB<C><C><E><G><G><D><D><D>B
<F>B<C><C><E><G><D><D><G><G><F><G>B<C><C>B<C>GEAGECCA<C><E><E><G><F><G><F><F><F><D><G><F><G><D><E><E><E><E><E><D>BGEEEEECFAG<C>B<C><E><G>
>B<FAECCDCDAGEA<C>B<C>BGECFA<C><E><E><G>B<E>BB<C>BG<C>BG<C><E>BBGA<C>GA<C>BGGA<C>GG<C><E><E><E>B<C><E><G>
<F><G><G><D><D>B<C>G<C><E><G><G><G><F><G><F>BGEFEAAA<C>GGA<C><E><G><D><D><G>BGECCDFFEAGEA<C><E><E><E>BB<C>B<C><C>BGEE
<D><D><E><E><G><D><E><E><E><G>BGEFCDFA<C>BGEEFCDCCFEFEFAAEA<C><C>B<E><D><G><D><G><F><D><E>B<C><C><C><C><E><D>B<E><D><D><E><E>
<D><D><G><G><F><G>B<C><E>B<C><C><E><E><G>B<C>GA<C>GECCFFFA<C>GA<C>BB<E><D><D><G><D><D><E><D><E><E><E><E><G><F><F><D>BB<C>GAA<C>B<C>GA
CCAEECCDDDCCDFCAG<C><E>BBBBBBBBBBB<C>GEAGEEAG<C><C>GECDDCCCDCFEFAAGG<C><E><D>
FECDDAGEECAAG<C>B<E><E>BBBBB<E>B<E><E>BB<E>BBGEECDFECFEAG<C>B<E>B<E><E><G><D><E>BGEEEFAGA
GECFEAECDCAECFFEEEAEEEECCDCDCCAECAG<C><E><E><E><E>

生成コード

require 'enumerator'

module Enumerable
  def min_by
     min {|a,b| yield(a) <=> yield(b) }
  end
end

HEMICENTROTUS_PULCHERRIMUS_AB331417 = %w(
aaggaagtgccccttaatatgtgtggccgacgtaaagatatataattgaaagataaaaat
aagtacagggagtgaatataacacagtgcctgacatagaatattacagataaatggaaca
aaacgtatgacgagtatacaatcgatatttcggatgaattaaattcttaagactttggaa
accttgagattcattaagctttatgacgatatgaattaaattgtggtctaatttatttat
actttgatggaacttctaggcataacatttataatttcttcgcgtttttctacattctca
tcaaactaatttattgaaccgtcttgaatacttaaaatcatttgtattttaacattataa
gatgatatgcctccattttgtgctaccgctcataatatataagagggtcggtcaaagata
tatcgccctcctctaatacctcgctttttttttaaaataactatactctcttcctgtcag
gtacaggtgaatgaccatttgaaaagaagtaaagcaaacattattcagaaaaaaacaaca
tgttcccacgggcatttacttctaaatctgtctgtatcaacagcaataaaaactttataa
acgtttaatggtgtcggcactcctatgatatgctaaagaggtttaatgtctgtatgtttg
ttcggtgtttagcagagatgtacatgatgttcatgtatgagataacatagcaggatgtgt
gtagtcacattctaatgccattgtttgatcgatatagtaggcgtaagattatgcctgccc
acggaatgaggtgtgaatggtgagtcttttgatagggaagaaccactgcccttccaagat
gcgggtcgagcttttgtttaccactacgtaggaatgcagaagaaagggctttgtccgcca
tcatgtctgttgtggacgggcaatgggccttgcaggagttttgttttccgcgaatactca
gtggccggcgtgaatgagttgaatggactcatcacgtgttcattcgaatagcaggatttt
gtaaaggtctattcacggaagggtactccggtaccattactaagagtgatcaacagcacc
ggtcaagcagtggcacatgattactcactctcacaaatcgcattctccgcagcgtcgatc
cgacattgaacagcgttatcagctggacttcaaactggtatctcctcggctggacattga
tagcttcacaatacactttctacttgtaacttgtaaacatggaagcactttctgatcttg
ctagtcgtgaaatcaagatggaatcacattctccacaggattccaagaatttgaatgtca
agcctatgaagctggagcgggtggggatgtcgtcatcgccgccgaggtagaccatcgact
gcggcaacaccggtcgatcaccggtaccatcacacatggaaccgcccggtggcgccaggg
taccatacccgatgcacctttacccctaccagtatgcctacagcaaccccatgtatggag
agggggccttaccagcacctgatcgccacgtcccaccaacccaacagcaccccatgttcc
agccccaggtcct
)

ANTHOCIDARIS_CRASSISPINA_AB024732 = %w(
agaacgtctttctgcttccctgcaataccaacaagtaaccaacaactccaccatgcagtc
tctcgtcgttttcttggccgtcatcgtcggggcagccgtcgccaaccccatgattctgtc
gtccgacagccaacagaacagagagatctcgtcctcggagtacttgaaaaagatcttcga
gaactctccgtcgttctacttcagccgctcggatgagcagagtcaagacgtcatcgaaag
gctacaggctctcaagcttcgtgaggccgcaaacatcgcacaacaggtagacctgaggca
gattctccgagacagtgggctttcatccgtcacattatgcatgcccagtgacaaggctgt
ccagaagtggaggagggaacttcccgaaagactaaggccagactccgaggctctgaaaaa
actggtcaaggcctggatcgttcctggcaggctcgagtcttcgcagctcggcgacaacaa
gaaagttcagagcttaaatggcgccaagctacgattcaatgtctacaacgacgcgaagaa
gtttgtcactgtcaatggagctcgaatcactgacgccgataggacgatgaacggtggact
cattcatgaagtcgacaaggtcatctaccctctcccagtcggcaacgtagtcgagacttt
ggctgatatcgaagccttctccaccattgtcgatctcatgaaacgagctgaactccaaca
agaattaagtgccgaccccatgacggtacttgcgccaaccaacgccgccttccaggccct
tccagccggagtcctcgatgacctcaagagaaacgagcaaaaactgaaaaacgtgctcag
gtaccacatgatctctgacgtcaagtattctgctgcattgtcgtctggtcggcaaatcag
ggcctcgcagggagatgagatttcggtcagccgtgaccaggatgatcaaattctcctgaa
caagcaaagtgagcagtctgaagcaccgagagttatcctacgcgacatccccactaccaa
cggagtcatccaagtcgtcgaccgggtcgtcttaccgccacaaaagaacttcgttctcgt
ctaaccaaaccagctgcatttttttttttcgatgaatgccgacaacccacgagttggcac
acaatgaacttgctaatttttataattattgaacagacgatgctataagcatgaaagtgt
acgatacactacggaaataaaaccacacctactgcaaaa
)

class DNAMusic
   DNA2SCALE = {
      ?c => [0, 1, 8, 9],
      ?a => [2, 3, 10, 11],
      ?g => [4, 5, 12, 13],
      ?t => [6, 7],
   }

   SCALE = %w(>B< C D E F G A B <C> <D> <E> <F> <G> <H>)

   def initialize(data)
      @tempo = 200
      @data = data
   end

   def dna2scales(w)
      w.enum_for(:each_byte).inject([(rand*13).to_i]) do |r, s|
         r + [DNA2SCALE[s].min_by {|e| (e - r[-1]).abs}]
      end.collect do |e|
         SCALE[e]
      end.to_s
   end

   def to_s
      [
         ">|mml|",
         "t#{@tempo} l8 @2 q14 o6",
         @data.collect {|w| dna2scales(w)},
         "||<"
      ].join("\n")
   end
end

puts DNAMusic.new(ANTHOCIDARIS_CRASSISPINA_AB024732)