#!/usr/bin/env ruby # agn.rb -- Bill Schottstaedt's agn.cl # (see clm-2/clm-example.clm and clm-2/bess5.cl) # Translator/Author: Michael Scholz # Created: Sat May 24 20:35:03 CEST 2003 # Changed: Sat Jul 28 00:37:44 CEST 2012 # Type do_agn # or start the script in a shell. $clm_c_version = true require "sndlib" if $clm_c_version require "sndins" else require "v" # fm_violin_rb, jc_reverb_rb require "clm-ins" # nrev_rb class Instrument alias fm_violin fm_violin_rb alias jc_reverb jc_reverb_rb alias nrev nrev_rb end end require "clm" require "ws" require "env" $clm_play = true $clm_statistics = true $clm_verbose = true $clm_srate = 44100 $clm_channels = 2 $clm_reverb = :jc_reverb $clm_reverb_data = [:volume, 0.8] $clm_reverb_channels = 2 $clm_delete_reverb = true class Agn include Math include Env Limit = 256 Time = 60 def initialize mode = [0, 0, 2, 4, 11, 11, 5, 6, 7, 0, 0, 0, 0] @octs = make_array(Limit) do |i| (4 + 2 * rbell(random(1.0))).floor end @pits = make_array(Limit) do |i| mode[(12 * random(1.0)).floor] end @rhys = make_array(Limit) do |i| (4 + 6 * random(1.0)).floor end @amps = make_array(Limit) do |i| (1 + 8 * rbell(random(1.0))).floor end end def tune(x) [1.0, 256.0 / 243, 9.0 / 8, 32.0 / 27, 81.0 / 64, 4.0 / 3, 1024.0 / 729, 3.0 / 2, 128.0 / 81, 27.0 / 16, 16.0 / 9, 243.0 / 128, 2.0].at(x % 12) * 2 ** x.divmod(12).first end def rbell(x) envelope_interp(x * 100, [0, 0, 10, 0.25, 90, 1.0, 100, 1.0]) end def agn(file) File.open(file, "w") do |f| f << "# from agn.cl (see clm-2/clm-example.clm and clm-2/bess5.cl)\n" f << "#\n" f << make_default_comment() << "\n\n" wins = [[0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 60, 0.1, 80, 0.2, 90, 0.4, 95, 1, 100, 0], [0, 0, 10, 1, 16, 0, 32, 0.1, 50, 1, 56, 0, 60, 0, 90, 0.3,100,0], [0, 0, 30, 1, 56, 0, 60, 0, 90, 0.3, 100, 0], [0, 0, 50, 1, 80, 0.3, 100, 0], [0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 40, 0.1, 60, 0.2, 75, 0.4, 82, 1, 90, 1, 100, 0], [0, 0, 10, 1, 32, 0.1, 50, 1, 90, 0.3, 100, 0], [0, 0, 60, 0.1, 80, 0.3, 95, 1, 100, 0], [0, 0, 80, 0.1, 90, 1, 100, 0]] (1..3).each do |i| cellbeg, cellsiz, cellctr = 0, 4, 0 whichway, base, mi, winnum, mytempo = 1, i, i - 1, 0, 0.2 nextbeg = revamt = ranamt = beg = dur = freq = ampl = ind = 0.0 while beg < Time and cellctr < Limit beg += nextbeg nextbeg = dur = [0.25, mytempo * (0.9 + 0.2 * random(1.0)) * @rhys[cellctr]].max freq = (16.352 / 2 ** mi) * tune(@pits[cellctr]) * 2 ** @octs[cellctr] dur += dur if freq < 100 ampl = [0.003, @amps[cellctr] * (1.0 / (60 * base))].max ind = random(1.0) * 2 * base revamt = base * 0.1 winnum = (10 * (beg - beg.floor)).floor ranamt = 0.00001 * (logn(freq, 2.0) - 4) ** 4 f << format("\ fm_violin(%f, %f, %f, %f, :fm_index, %f, :amp_env, %s, :reverb_amount, %f, :noise_amount, %f)\n", beg, dur, freq, ampl, ind, wins[winnum].inspect, revamt, ranamt) cellctr += 1 if cellctr > (cellsiz + cellbeg) cellbeg += 1 if random(1.0) > 0.5 cellsiz += whichway end if cellsiz > 16 and random(1.0) > 0.99 whichway = -2 if cellsiz > 12 and random(1.0) > 0.999 whichway = -1 if cellsiz < 4 whichway = 1 end end end cellbeg += 3 cellctr = cellbeg end end end f << "\n# " + file + " ends here\n" end file end end def do_agn(file = "agn.rbm") sndfile = File.basename(file, ".*") + ".snd" message("Writing %s", file.inspect) Agn.new.agn(file) clm_load(file, :clm, true, :output, sndfile) end unless provided?(:snd) do_agn((ARGV[0] or "agn.rbm")) end # agn.rb ends here