{"id":885,"date":"2017-03-07T21:01:33","date_gmt":"2017-03-07T21:01:33","guid":{"rendered":"http:\/\/www.georg-hosoya.de\/wordpress\/?p=885"},"modified":"2017-03-07T21:19:29","modified_gmt":"2017-03-07T21:19:29","slug":"laurie-spiegels-algorithm","status":"publish","type":"post","link":"https:\/\/www.georg-hosoya.de\/wordpress\/?p=885","title":{"rendered":"Laurie Spiegel&#8217;s Algorithm"},"content":{"rendered":"<p>In her article <a href=\"http:\/\/retiary.org\/ls\/writings\/sonic_subsets.html\">Sonic Set Theory: A Tonal Music Theory for Computers<\/a>, Laurie Spiegel described a little algorithm, a chord sequence generator, to demonstrate principles of algorithmic composition. Curious of if it could be done in R and how it would sound I wrote a simple sine- and envelope generator and implemented the algorithm in R. Here it is:<\/p>\n<pre lang=\"rsplus\" line=\"1\">\r\nlibrary(\"audio\")\r\n\r\n# gen_sin(): generate sine signal\r\n#\r\n# sample rate=44100 Hz\r\n# f:    frquency in Hz\r\n# ms:   duration in milliseconds\r\ngen_sin<-function(f, ms)\r\n{\r\n  x<-NULL\r\n  k=44100\/(2*pi*f)\r\n  x<-sin(0:(44100*(ms\/1000))\/k)\r\n  return(x)\r\n}\r\n\r\n# Check\r\ngen_sin(440,10)\r\n\r\n# envelope(): generate simple linear AD envelope\r\n#\r\n# x:            signal returned by gen_sin\r\n# attack_ms:    attack time in milliseconds\r\n# decay:        decay time in milliseconds\r\n# max_vol:      maximum volume should not exceed 1 \r\n#               to avoid clipping\r\nenvelope<-function(x, attack_ms, decay_ms, max_vol)\r\n{\r\n  length=length(x)\r\n \r\n  attack_start=1\r\n  attack_end=44100*(attack_ms\/1000)\r\n  attack_slope=max_vol\/(attack_end-attack_start)\r\n\r\n  decay_end=length(x)\r\n  decay_start=decay_end-44100*(decay_ms\/1000)\r\n  decay_slope=max_vol\/(decay_end-decay_start)\r\n  \r\n  env<-rep(max_vol, length)\r\n  \r\n  volume_attack=0\r\n  for(i in attack_start:attack_end)\r\n  { \r\n    env[i]=volume_attack\r\n    volume_attack=volume_attack+attack_slope\r\n  }\r\n  volume_decay=max_vol\r\n  for(i in (decay_start):decay_end)\r\n  {\r\n    env[i]=volume_decay\r\n    volume_decay=volume_decay-decay_slope\r\n  }\r\n  return(env)  \r\n}\r\n\r\n# Checks\r\nx<-gen_sin(440,100)\r\nlength(x)\r\nplot(x)\r\nenv<-envelope(x,50,50,0.5)\r\nlength(env)\r\nplot(env)\r\n\r\n# gen note(): generate note\r\n#\r\n# f:          frequency in Hertz\r\n# ms:         duration in milliseconds\r\n# attack_ms:    attack time in milliseconds\r\n# decay:        decay time in milliseconds\r\n# max_vol:      maximum volume should not exceed 1 \r\n#               to avoid clipping\r\ngen_note<-function(f, ms, attack_ms, decay_ms, max_vol)\r\n{\r\n  x<-gen_sin(f,ms)\r\n  env<-envelope(x,attack_ms, decay_ms, max_vol)\r\n  env_signal<-x*env\r\n  return(env_signal)\r\n}\r\n\r\nx<-gen_note(440,1000,100,500,1)\r\nplay(x)\r\nplot(x)\r\n\r\n# gen_triad(): generate frequencies of a triad\r\n# note:        base note of triad\r\n# freq_scale:  scale frequencies\r\ngen_triad<-function(note, freq_scale)\r\n{\r\n  chord<-NULL\r\n  for(i in 1:3)\r\n  {\r\n    index=((note-1)%%16)+1 # R starts counting with 1\r\n    note=note+2\r\n    chord<-c(chord, gen_note(freq_scale[index], 400,40,200,0.8))\r\n  }\r\n    return(chord)\r\n}\r\n\r\n# Frequencies of the C major scale\r\nfreq_scale<-c(261.63, 293.66,  # C4 D4 \r\n              329.63, 349.23,  # E4 F4\r\n              392.00, 440.00,  # G4 A4\r\n              493.88, 523.25,  # B4 C5\r\n              587.33, 659.25,  # D5 E5\r\n              698.46, 783.99)  # F5 G5  \r\n\r\n# Check\r\nplot(freq_scale)\r\n# Play C Major chord\r\nx<-gen_triad(1, freq_scale)\r\nplay(x)\r\n\r\n### Generate piece ###\r\n# Source of the alogrithm:\r\n# Spiegel, L. (1982). Sonic Set Theory: A Tonal Music Theory for Computers. \r\n# In Proceedings of the Second Annual Symposium on Small Computers and the Arts.\r\n#     \r\nstages<-matrix(c(0, 0, 1, 0, 0, 0, 0,\r\n                 0.5, 0, 0, 0, 0, 0.5, 0,\r\n                 0, 0.5, 0, 0.5, 0, 0, 0,\r\n                 0, 0, 0, 0, 0.5, 0, 0.5,\r\n                 0.5, 0, 0, 0, 0, 0.5, 0), byrow=TRUE, ncol=7)\r\n\r\n# Base notes of chords\r\nbase_notes<-rep(1:7) \r\n\r\npiece<-NULL\r\ncycles=0\r\nstart=1\r\nmax_cycles=4\r\n\r\nwhile(cycles<max_cycles)\r\n{\r\n  for(i in start:5)\r\n  {\r\n    index<-sample(base_notes,1, p=stages[i,])    \r\n    piece<-c(piece, gen_triad(index, freq_scale))\r\n    cat(index)\r\n  }\r\n  start=sample(2:5,1)\r\n  cycles=cycles+1\r\n}\r\n\r\nplay(piece)\r\n<\/pre>\n<p>Hope I got it right. Read the article, play around with the probabilities and have fun! You do not have to use C major of course. Oh, and be careful with your speakers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In her article Sonic Set Theory: A Tonal Music Theory for Computers, Laurie Spiegel described a little algorithm, a chord sequence generator, to demonstrate principles of algorithmic composition. Curious of if it could be done in R and how it &hellip; <a href=\"https:\/\/www.georg-hosoya.de\/wordpress\/?p=885\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/885"}],"collection":[{"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=885"}],"version-history":[{"count":6,"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/885\/revisions"}],"predecessor-version":[{"id":892,"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/885\/revisions\/892"}],"wp:attachment":[{"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.georg-hosoya.de\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}