summaryrefslogtreecommitdiff
path: root/examp.rb
diff options
context:
space:
mode:
authorAlessio Treglia <quadrispro@ubuntu.com>2009-12-03 13:03:13 +0100
committerAlessio Treglia <quadrispro@ubuntu.com>2009-12-03 13:03:13 +0100
commit8b022ab680a3f5e374a44f2c05c1671cfb2bc799 (patch)
treeaf20b9a16eeca697a1d30a554d8d1b31ae9c1e4f /examp.rb
parent5cd66eecc95be11cacc5aaf4db8c67a499bb2d4d (diff)
Imported Upstream version 11.1
Diffstat (limited to 'examp.rb')
-rw-r--r--examp.rb2967
1 files changed, 6 insertions, 2961 deletions
diff --git a/examp.rb b/examp.rb
index 5584248..a951f94 100644
--- a/examp.rb
+++ b/examp.rb
@@ -2,307 +2,8 @@
# Translator/Author: Michael Scholz <mi-scholz@users.sourceforge.net>
# Created: Wed Sep 04 18:34:00 CEST 2002
-# Changed: Wed Oct 14 04:45:55 CEST 2009
+# Changed: Thu Nov 26 19:34:47 CET 2009
-# Commentary:
-#
-# Extensions to Ruby:
-#
-# provided?(feature)
-# provide(feature)
-# features(all)
-#
-# array?(obj) alias list?(obj)
-# hash?(obj)
-# string?(obj)
-# regexp?(obj)
-# symbol?(obj)
-# number?(obj)
-# integer?(obj)
-# float?(obj)
-# rational?(obj)
-# complex?(obj)
-# boolean?(obj)
-# proc?(obj)
-# thunk?(obj)
-# method?(obj)
-# func?(obj)
-# mus?(obj)
-# get_func_name(n)
-# assert_type(condition, obj, pos, msg)
-# identity(arg)
-# ignore(*rest)
-# enum(*names)
-#
-# class Object
-# null?
-# function?(obj)
-# snd_func(name, *rest, &body)
-# set_snd_func(name, val, *rest, &body)
-# snd_apropos(str_or_sym)
-#
-# NilClass(arg)
-# Fixnum(arg)
-#
-# class NilClass
-# each
-# apply(func, *rest, &body)
-# empty?
-# zero?
-# nonzero?
-# to_vct
-# to_vector
-# to_poly
-# +(other)
-# -(other)
-# *(other)
-#
-# backward compatibility methods:
-# String#to_sym, Symbol#to_sym
-# make_array(len, init, &body)
-# Array#insert
-# Float#step
-# Range#step
-# Enumerable#each_index
-# Enumerable#zip
-#
-# class Array
-# to_pairs
-# each_pair do |x, y| ... end
-# to_string(len)
-# first=(val)
-# last=(val)
-# pick
-# rand
-# rand!
-# add(other)
-# add!(other)
-# subtract(other)
-# subtract!(other)
-# multiply(other)
-# multiply!(other)
-# offset(scl)
-# offset!(scl)
-# scale(scl)
-# scale!(scl)
-# to_vector
-# car
-# car=
-# cadr
-# cadr=
-# caddr
-# caddr=
-# cadddr
-# cadddr=
-# caddddr
-# caddddr=
-# cdr
-# step(n)
-# apply(func, *rest, &body)
-#
-# class Vec < Array
-# Vec[]
-# initialize(len, init, &body)
-# inspect
-# to_s
-# to_vector
-# +(other)
-# -(other)
-# *(other)
-#
-# Vec(obj)
-# make_vector(len, init, &body)
-# vector?(obj)
-# vector(*args)
-#
-# class String
-# to_vector
-# to_vct
-#
-# Vct(obj)
-# make_vct!(len, init) do |i| ... end
-#
-# class Vct
-# Vct[]
-# name
-# to_sound_data(sd, chn)
-# to_vct
-# to_vector
-# apply(func, *rest, &body)
-# +(other) handles self.offset (Numeric) and self.add (Array, Vec, Vct)
-# -(other) handles self.offset (Numeric) and self.subtract (Array, Vec, Vct)
-# *(other) handles self.scale (Numeric) and self.multiply (Array, Vec, Vct)
-# step(n)
-# [](idx, size)
-#
-# class Fixnum
-# +(other) handles other.offset on Vct, Array, and Vec
-# *(other) handles other.scale on Vct, Array, and Vec
-#
-# class Float
-# +(other) handles other.offset on Vct, Array, and Vec
-# *(other) handles other.scale on Vct, Array, and Vec
-#
-# SoundData(ary) can be used to reread evaled output from sound_data2string
-# sound_data2string(sd) produces a string which can be evaled and reread with SoundData
-#
-# class SoundData
-# name
-# to_vct(chn)
-# to_a
-# length
-# scale!(scl)
-# fill!(val)
-# each(chn)
-# each_with_index(chn)
-# map(chn)
-# map!(chn)
-#
-# mus_a0(gen)
-# set_mus_a0(gen, val)
-# mus_a1(gen)
-# set_mus_a1(gen, val)
-# mus_a2(gen)
-# set_mus_a2(gen, val)
-# mus_b1(gen)
-# set_mus_b1(gen, val)
-# mus_b2(gen)
-# set_mus_b2(gen, val)
-#
-# class Mus
-# run(arg1, arg2)
-# apply(*rest)
-# inspect
-# close
-# xcoeff=(index, val)
-# ycoeff=(index, val)
-# a0 a0=(val)
-# a1 a1=(val)
-# a2 a2=(val)
-# b1 b1=(val)
-# b2 b2=(val)
-#
-# class Musgen base class for generators written in Ruby
-# initialize
-# inspect
-# to_s
-# run(val1, val2)
-# apply(*rest)
-# eql?(other)
-# reset
-#
-# class Numeric
-# positive?
-# negative?
-#
-# class Integer
-# even?
-# odd?
-# prime?
-#
-# module Enumerable
-# map_with_index do |x, i| ... end
-# map_with_index! do |x, i| ... end
-# clm_cycle
-# clm_cycle=(val)
-#
-# as_one_edit_rb(*origin, &body)
-# map_channel_rb(beg, dur, snd, chn, edpos, edname, &body)
-# map_chan_rb(beg, dur, edpos, snd, chn, &body)
-#
-# with_silence(exception) do |old_verbose, old_debug| ... end
-#
-# module Info
-# description=(text)
-# description
-#
-# class Proc
-# to_method(name, klass)
-# to_str
-# to_body
-# source
-# source=
-#
-# make_proc2method(name, prc)
-# make_proc_with_setter(name, getter, setter)
-# make_proc_with_source(string, bind)
-# proc_source(prc) set_proc_source(prc, val)
-#
-# Multi-line input to the Snd listener and Emacs/inf-snd.el
-#
-# $emacs_eval_hook.call(line)
-# run_emacs_eval_hook(line)
-#
-# class Snd_eval
-# Snd_eval.count_level(line)
-#
-# class Snd_prompt
-# initialize(level)
-# inspect
-# update(level)
-# reset
-#
-# start_emacs_eval(file)
-# start_listener_eval(file)
-# stop_emacs_eval
-# stop_listener_eval
-#
-# Debugging resp. inspecting local variables
-#
-# debug_properties(name) set_debug_properties(name, val)
-# debug_property(key, name) set_debug_property(key, val, name)
-# debug_binding(name) set_debug_binding(bind, name)
-# display_all_variables(name)
-# each_variables(&body)
-#
-# let(*rest) do |*rest| ... end
-#
-# Utilities:
-#
-# close_sound_extend(snd)
-# times2samples(start, dur)
-# random(n)
-# logn(r, b)
-# car(v), cadr(v), caddr(v), cdr(v)
-# warning(*args), die(*args), error(*args)
-# clm_message(*args), message(*args), debug(*args), debug_trace(*args)
-#
-# class Snd
-# Snd.add_sound_path(path)
-# Snd.open_from_path(fname)
-# Snd.find_from_path(fname)
-# Snd.fullname(fname)
-# Snd.load_path
-# Snd.message(*args)
-# Snd.display(*args)
-# Snd.warning(*args)
-# Snd.die(*args)
-# Snd.error(*args)
-# Snd.debug(*args)
-# Snd.debug_trace(*args)
-# Snd.sounds
-# Snd.regions
-# Snd.marks(snd, chn)
-# Snd.snd(snd)
-# Snd.chn(chn)
-# Snd.catch(tag, retval)
-# Snd.throw(tag, *rest)
-# Snd.raise(tag, *rest)
-#
-# snd_catch(tag, retval)
-# snd_throw(tag, *rest)
-# snd_raise(tag, *rest)
-#
-# gloop(*args) do |args| ... end
-# get_args(args, key, default)
-# get_shift_args(args, key, default)
-# get_class_or_key(args, klass, key, default)
-# optkey(args, *rest)
-# load_init_file(file)
-#
-# edit_list_proc_counter
-# set_edit_list_proc_counter
-#
# module Examp (examp.scm)
# selection_rms
# region_rms(n)
@@ -452,2665 +153,7 @@
#
# Code:
-unless defined? $LOADED_FEATURES then alias $LOADED_FEATURES $" end
-
-# Ruby 1.9.x moved Continuation to 'continuation'!
-# (See ruby/ChangeLog Tue Jan 20 16:17:12 2009.)
-unless defined? Kernel.callcc then require 'continuation' end
-
-def provided?(feature)
- assert_type((symbol?(feature) or string?(feature)), feature, 0, "a symbol or a string")
- $LOADED_FEATURES.map do |f| File.basename(f) end.member?(feature.to_s.tr("_", "-"))
-end
-
-def provide(feature)
- assert_type((symbol?(feature) or string?(feature)), feature, 0, "a symbol or a string")
- $LOADED_FEATURES.push(feature.to_s)
-end
-
-def features(all = nil)
- if all
- $LOADED_FEATURES.map do |f| File.basename(f) end
- else
- $LOADED_FEATURES.map do |f|
- next if f.include?("/") or f.include?(".")
- f
- end.compact
- end
-end
-
-def make_polar(r, theta)
- Complex(cos(theta) * r, sin(theta) * r)
-end
-
-def make_rectangular(re, im = 1.0)
- Complex(re, im)
-end
-
-def array?(obj)
- obj.kind_of?(Array)
-end
-alias list? array?
-
-def hash?(obj)
- obj.kind_of?(Hash)
-end
-
-def string?(obj)
- obj.kind_of?(String)
-end
-
-def regexp?(obj)
- obj.kind_of?(Regexp)
-end
-
-def symbol?(obj)
- obj.kind_of?(Symbol)
-end
-
-def number?(obj)
- obj.kind_of?(Numeric)
-end
-
-def integer?(obj)
- obj.kind_of?(Fixnum)
-end
-
-def float?(obj)
- obj.kind_of?(Float)
-end
-
-def rational?(obj)
- obj.kind_of?(Rational)
-end
-
-def complex?(obj)
- obj.kind_of?(Complex)
-end
-
-def boolean?(obj)
- obj.kind_of?(TrueClass) or obj.kind_of?(FalseClass)
-end
-
-def proc?(obj)
- obj.kind_of?(Proc)
-end
-
-def thunk?(obj)
- obj.kind_of?(Proc) and obj.arity.zero?
-end
-
-def method?(obj)
- obj.kind_of?(Method)
-end
-
-def func?(obj)
- obj.kind_of?(String) or obj.kind_of?(Symbol)
-end
-
-def mus?(obj)
- obj.kind_of?(Mus)
-end
-
-def binding?(obj)
- obj.kind_of?(Binding)
-end
-
-def get_func_name(n = 1)
- if ca = caller(n)[0].scan(/^.*:in `(.*)'/).first
- ca.first
- else
- "top_level"
- end
-end
-
-def assert_type(condition, obj, pos, msg)
- condition or Kernel.raise(TypeError,
- format("%s: wrong type arg %d, %s, wanted %s",
- get_func_name(2), pos, obj.inspect, msg))
-end
-
-def identity(arg)
- arg
-end
-
-def ignore(*rest)
- nil
-end
-
-# backward compatibility aliases and constants (mostly from snd7.scm)
-# alias new old
-if provided? :snd
- alias save_options save_state
- alias delete_samples_with_origin delete_samples
- alias default_output_type default_output_header_type
- alias default_output_format default_output_data_format
- alias previous_files_sort view_files_sort
- alias preload_directory add_directory_to_view_files_list
- alias preload_file add_file_to_view_files_list
- alias $previous_files_select_hook $view_files_select_hook
- Sort_files_by_name = 0
- Sort_files_by_date = 2
- Sort_files_by_size = 4
- Sort_files_by_entry = -1
- alias mus_audio_sun_outputs mus_sun_set_outputs
- alias set_oss_buffers mus_oss_set_buffers
- alias mus_audio_set_oss_buffers mus_oss_set_buffers
- unless defined? mus_file_data_clipped
- alias mus_file_data_clipped mus_clipping
- alias set_mus_file_data_clipped set_mus_clipping
- end
- alias mus_data_clipped mus_clipping
- alias set_mus_data_clipped set_mus_clipping
- alias dac_is_running playing
- # backwards compatibility for snd 8
- alias make_ppolar make_two_pole
- alias make_zpolar make_two_zero
- alias make_average make_moving_average
- alias average moving_average
- alias average? moving_average?
- # *windowed_maxamp -> dsp.rb
- def samples2sound_data(beg = 0,
- num = false,
- snd = false,
- chn = false,
- obj = false,
- pos = false,
- sd_chan = 0)
- len = (num or frames(snd, chn))
- gen = (obj or make_sound_data(1, len))
- vct2sound_data(channel2vct(beg, len, snd, chn, pos), gen, sd_chan)
- end
-
- def open_sound_file(*args)
- mus_sound_open_output(get_args(args, :file, (little_endian ? "test.wav" : "test.snd")),
- get_args(args, :srate, 22050),
- get_args(args, :channels, 1),
- (little_endian ? Mus_lfloat : Mus_bfloat),
- get_args(args, :header_type, (little_endian ? Mus_riff : Mus_next)),
- get_args(args, :comment, ""))
- end
-
- alias close_sound_file mus_sound_close_output
-
- def vct2sound_file(fd, v, samps)
- mus_sound_write(fd, 0, samps - 1, 1, vct2sound_data(v))
- end
-
- # snd10.scm
- def make_sum_of_sines(*args)
- sines, frequency, initial_phase = nil
- optkey(args, binding,
- [:sines, 1],
- [:frequency, 0.0],
- [:initial_phase, 0.0])
- gen = make_nsin(:frequency, frequency, :n, sines)
- gen.phase = initial_phase
- gen
- end
- alias sum_of_sines nsin
- alias sum_of_sines? nsin?
-
- def make_sum_of_cosines(*args)
- cosines, frequency, initial_phase = nil
- optkey(args, binding,
- [:cosines, 1],
- [:frequency, 0.0],
- [:initial_phase, 0.0])
- gen = make_ncos(:frequency, frequency, :n, cosines)
- gen.phase = initial_phase
- gen
- end
- alias sum_of_cosines ncos
- alias sum_of_cosines? ncos?
-
- def make_sine_summation(*args)
- frequency, initial_phase, n, a, ratio = nil
- optkey(args, binding,
- [:frequency, 0.0],
- [:initial_phase, 0.0],
- [:n, 1],
- [:a, 0.5],
- [:ratio, 1.0])
- gen = make_nrxysin(:frequency, frequency, :ratio, ratio, :n, n, :r, a)
- gen.phase = initial_phase
- gen
- end
- alias sine_summation nrxysin
- alias sine_summation? nrxysin?
-end
-
-# enum("foo", :bar, "FOO_BAR")
-# produces three constants
-# Foo == 0
-# Bar == 1
-# FOO_BAR == 2
-def enum(*names)
- names.flatten.map_with_index do |name, i|
- const_name = name.to_s
- if const_name[0].between?(?a, ?z)
- const_name[0] += ?A - ?a
- end
- Object.const_set(const_name, i)
- const_name
- end
-end
-
-class Object
- def null?
- self.nil? or
- (self.respond_to?(:zero?) and self.zero?) or
- (self.respond_to?(:empty?) and self.empty?) or
- (self.respond_to?(:length) and self.length.zero?)
- end
-
- def function?(obj)
- func?(obj) and Snd.catch(:all, false) do self.method(obj) end.first
- rescue
- false
- end
-
- # Float(nil) ==> 0.0 like Integer(nil) ==> 0
- alias old_Float Float
- def new_Float(numb)
- if numb.kind_of?(NilClass)
- 0.0
- else
- old_Float(numb)
- end
- end
- alias Float new_Float
-
- def snd_func(name, *rest, &body)
- assert_type(func?(name), name, 0, "a string or symbol")
- send(name.to_s, *rest, &body)
- end
-
- def set_snd_func(name, val, *rest, &body)
- assert_type(func?(name), name, 0, "a string or symbol")
- send(format("set_%s", name.to_s), val, *rest, &body)
- end
-
-# snd_apropos(str_or_sym)
-# if `str_or_sym' is a symbol, returns snd_help result,
-# if `str_or_sym' is a string or regexp it looks in
-# self.public_methods,
-# self.protected_methods,
-# self.private_methods,
-# Object.constants, and
-# Kernel.global_variables and returns an array of strings or nil.
-#
-# [].snd_apropos(/^apply/) ==> ["apply", "apply_controls"]
-# vct(0).snd_apropos("subseq") ==> ["subseq", "vct_subseq"]
-# snd_apropos(/^mus_sound/) ==> ["mus_sound_...", ...]
- def snd_apropos(str_or_sym)
- case str_or_sym
- when Symbol
- snd_help(str_or_sym)
- when String, Regexp
- res = []
- [self.public_methods,
- self.protected_methods,
- self.private_methods,
- Object.constants,
- Kernel.global_variables].each do |m| res += m.grep(/#{str_or_sym}/) end
- res
- else
- nil
- end
- end
-end
-
-def NilClass(arg)
- nil
-end
-
-alias Fixnum Integer
-
-class NilClass
- # FIXME (dangerous)
- # def method_missing(id, *args, &body)
- # nil
- # end
-
- def each
- nil
- end
-
- def apply(func, *rest, &body)
- nil
- end
-
- def empty?
- true
- end
-
- # Integer(nil) ==> 0
- def zero?
- true
- end
-
- def nonzero?
- false
- end
-
- def to_vct
- vector2vct([])
- end
-
- def to_vector
- vector()
- end
-
- def to_poly
- poly()
- end
-
- def +(other)
- other
- end
-
- def -(other)
- other
- end
-
- def *(other)
- snd_func(other.class.name, nil)
- end
-end
-
-# If $DEBUG = true, on older Ruby versions warnings occur about
-# missing NilClass#to_str and Symbol#to_str
-if $DEBUG and RUBY_VERSION < "1.8.0"
- class Object
- def method_missing(id, *args)
- if id == :to_str
- self.class.class_eval do define_method(id, lambda do | | self.to_s end) end
- id.id2name
- else
- Kernel.raise(NameError,
- format("[version %s] undefined method `%s'", RUBY_VERSION, id.id2name))
- end
- end
- end
-end
-
-class String
- def to_sym
- self.intern
- end unless defined? "a".to_sym
-end
-
-class Symbol
- def to_sym
- self
- end unless defined? :a.to_sym
-end
-
-alias object_id __id__ unless defined? object_id
-
-# with_silence(exception) do |old_verbose, old_debug| ... end
-#
-# subpress debug messages (mostly on older Ruby versions)
-#
-# with_silence do $global_var ||= value end
-# with_silence(LoadError) do require("nonexistent.file") end
-def with_silence(exception = StandardError)
- old_verbose = $VERBOSE
- old_debug = $DEBUG
- $VERBOSE = false
- $DEBUG = false
- ret = if block_given?
- begin
- yield(old_verbose, old_debug)
- rescue exception
- false
- end
- else
- false
- end
- $VERBOSE = old_verbose
- $DEBUG = old_debug
- ret
-end
-
-# Provides descriptions of instances of classes, see nb.rb,
-# xm-enved.rb, etc.
-#
-# m = lambda do |*args| puts args end
-# m.info = "my description"
-# puts m.info
-module Info
- def description=(val)
- @description = val.to_s
- end
- alias info= description=
-
- def description
- if defined?(@description) and string?(@description) and (not @description.empty?)
- @description
- else
- "no description available"
- end
- end
- alias info description
-end
-
-require "ws"
-alias snd_help get_help unless defined? snd_help
-
-$array_print_length = 10
-
-def print_length
- $array_print_length
-end unless defined? print_length
-
-def set_print_length(val)
- $array_print_length = val
-end unless defined? set_print_length
-
-module Enumerable
- def map_with_index
- i = -1
- self.map do |x| yield(x, i += 1) end
- end
-
- def map_with_index!
- i = -1
- self.map! do |x| yield(x, i += 1) end
- end
-
- def clm_cycle
- unless defined? @clm_cycle_index then @clm_cycle_index = 0 end
- val = self[@clm_cycle_index % self.length]
- @clm_cycle_index += 1
- if @clm_cycle_index == self.length then @clm_cycle_index = 0 end
- val
- end
-
- def clm_cycle=(val)
- unless defined? @clm_cycle_index then @clm_cycle_index = 0 end
- self[@clm_cycle_index % self.length] = val
- @clm_cycle_index += 1
- if @clm_cycle_index == self.length then @clm_cycle_index = 0 end
- val
- end
- attr_accessor :clm_cycle_index
-
- # backward compatibility methods
- def each_index
- self.each_with_index do |val, i| yield(i) end
- end unless vct(0).respond_to?(:each_index)
-
- # Enumerable#zip, new in ruby core since 19-Nov-2002.
- # a = [4, 5, 6]
- # b = [7, 8, 9]
- # [1, 2, 3].zip(a, b) --> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
- # [1, 2].zip(a, b) --> [[1, 4, 7], [2, 5, 8]]
- # a.zip([1, 2],[8]) --> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
- def clm_zip(*objs)
- args = objs.map do |obj| obj.to_a end
- res = self.to_a
- res.each_with_index do |val, i|
- ary = [val]
- args.each do |obj| ary.push(obj[i]) end
- if block_given?
- yield(*ary)
- else
- res[i] = ary
- end
- end
- res
- end
- alias zip clm_zip unless [].respond_to?(:zip)
-end
-
-# Older Ruby versions lack Array.new(10) do |i| ... end
-# make_array
-# make_array(10)
-# make_array(10, 1.0)
-# make_array(10) do |i| ... end
-def make_array(len = 0, init = nil)
- assert_type((number?(len) and len >= 0), len, 0, "a number")
- len = Integer(len)
- if block_given?
- Array.new(len, init).map_with_index do |x, i| yield(i) end
- else
- Array.new(len, init)
- end
-end
-
-class Array
- def insert(pos, *args)
- unless args.empty?
- if pos < 0
- pos = self.length - (pos.abs - 1)
- end
- tmp = self.dup
- self[pos, args.length] = args
- self[pos + args.length..-1] = tmp[pos..-1]
- end
- self
- end unless defined? [].insert
-
- # [0.0, 0.0, 0.5, 0.2, 1.0, 1.0].to_pairs --> [[0.0, 0.0], [0.5, 0.2], [1.0, 1.0]]
- def to_pairs
- ary = []
- self.step(2) do |a, b| ary.push([a, b]) end
- ary
- end
-
- # [0.0, 0.0, 0.5, 0.2, 1.0, 1.0].each_pair do |x, y| print x, " ", y, "\n" end
- # --> 0.0 0.0
- # 0.5 0.2
- # 1.0 1.0
- def each_pair
- ary = []
- self.step(2) do |a, b| ary.push(yield(a, b)) end
- ary
- end
-
- # prints flat float array more prettily
- def to_string(len = print_length)
- ary = self.flatten
- str = "["
- ary.each_with_index do |val, i|
- if i < len
- str += "%1.3f, " % val.to_f
- else
- break
- end
- end
- if ary.length > len
- str += "..."
- else
- str.chop!.chop!
- end
- str += "]"
- end
-
- alias old_to_s to_s
- alias to_s inspect
-
- def first=(val)
- self[0] = val
- end
-
- def last=(val)
- self[-1] = val
- end
-
- # ary.pick ==> random value
- # ary.pick(3) ==> [x, y, z]
- # ary.pick(true) ==> whole ary randomized
- def array_pick(n = 1)
- n = self.length if n == true
- if n == 1
- self[kernel_rand(self.length)]
- else
- (0...n).map do |i| self[kernel_rand(self.length)] end
- end
- end
- alias pick array_pick
-
- def array_rand
- tmp = self.dup
- tmp.each_index do |i|
- r = kernel_rand(tmp.length)
- tmp[r], tmp[i] = tmp[i], tmp[r]
- end
- tmp
- end
- alias rand array_rand
-
- def array_rand!
- self.each_index do |i|
- r = kernel_rand(self.length)
- self[r], self[i] = self[i], self[r]
- end
- self
- end
- alias rand! array_rand!
-
- def add(other)
- assert_type((array?(other) or vct?(other)), 0, other, "an array, a vector or a vct")
- new_ary = self.dup
- [self.length, other.length].min.times do |i| new_ary[i] += other[i] end
- new_ary
- end
-
- def add!(other)
- assert_type((array?(other) or vct?(other)), 0, other, "an array, a vector or a vct")
- [self.length, other.length].min.times do |i| self[i] += other[i] end
- self
- end
-
- def subtract(other)
- assert_type((array?(other) or vct?(other)), 0, other, "an array, a vector or a vct")
- new_ary = self.dup
- [self.length, other.length].min.times do |i| new_ary[i] -= other[i] end
- new_ary
- end
-
- def subtract!(other)
- assert_type((array?(other) or vct?(other)), 0, other, "an array, a vector or a vct")
- [self.length, other.length].min.times do |i| self[i] -= other[i] end
- self
- end
-
- def multiply(other)
- assert_type((array?(other) or vct?(other)), 0, other, "an array, a vector or a vct")
- new_ary = self.dup
- [self.length, other.length].min.times do |i| new_ary[i] *= other[i] end
- new_ary
- end
-
- def multiply!(other)
- assert_type((array?(other) or vct?(other)), 0, other, "an array, a vector or a vct")
- [self.length, other.length].min.times do |i| self[i] *= other[i] end
- self
- end
-
- def offset(scl)
- assert_type(number?(scl), 0, scl, "a number")
- scl = Float(scl)
- self.class.new(self.length) do |i| self[i] + scl end
- end
-
- def offset!(scl)
- assert_type(number?(scl), 0, scl, "a number")
- scl = Float(scl)
- self.map! do |val| val += scl end
- end
-
- def scale(scl)
- assert_type(number?(scl), 0, scl, "a number")
- scl = Float(scl)
- self.class.new(self.length) do |i| self[i] * scl end
- end
-
- def scale!(scl)
- assert_type(number?(scl), 0, scl, "a number")
- scl = Float(scl)
- self.map! do |val| val *= scl end
- end
-
- def to_vector
- Vec.new(self.length) do |i| Float(self[i]) end
- end
-
- def car
- self[0]
- end
-
- def car=(val)
- self[0] = val
- end
-
- def cadr
- self[1]
- end
-
- def cadr=(val)
- self[1] = val
- end
-
- def caddr
- self[2]
- end
-
- def caddr=(val)
- self[2] = val
- end
-
- def cadddr
- self[3]
- end
- def cadddr=(val)
- self[3] = val
- end
-
- def caddddr
- self[4]
- end
-
- def caddddr=(val)
- self[4] = val
- end
-
- def cdr
- self[1..-1]
- end
-
- def step(n = 1)
- 0.step(self.length - n, n) do |i| yield(*self[i, n]) end
- self
- end
-
- add_help(:apply,
- "Array#apply([:func,] *rest, &body)
-applies function or procedure with possible rest args \
-to each element of Array or subclasses of Array.
- [0, 1, 2].apply(\"a: %d\\n\") do |fmt, a| printf(fmt, a) end
- [0, 1, 2].apply(:printf, \"a: %d\\n\")
-both produce
-a: 0
-a: 1
-a: 2
- [1, 2, 3, 4].apply(:+) # ==> 10
- %w(snd sndplay with_sound).apply(:length) # ==> [3, 7, 10]
- [[1, 2, 3, 4], [1, 2, 3], [1, 2]].apply(:max) # ==> [4, 3, 2]
-[vct(0.1, 0.2, 0.3), vct(-0.1, -0.2, -0.3)].apply(:peak) # ==> [0.3, 0.3]
- sounds.apply(:map) do |s| puts s end
- sounds.apply(:close_sound)")
- def apply(func, *rest, &body)
- if block_given? and (not symbol?(func))
- rest.unshift(func)
- self.map do |item| yield(*rest + [item]) end
- else
- assert_type((func?(func) or proc?(func) or method?(func)),
- func, 0, "a function (string or symbol), a method or a proc")
- case func
- when Proc, Method
- self.map do |item| func.call(*rest + [item]) end
- when Symbol, String
- meths = self.methods
- if body and (meths.member?(func.to_s) or meths.member?(func.to_sym))
- # map, each, ...
- self.send(func, *rest, &body)
- else
- receiver = self.compact.first
- meths = receiver.methods
- if receiver and (meths.member?(func.to_s) or meths.member?(func.to_sym))
- # methods
- case func.to_sym
- when :+, :-, :*
- res = receiver
- self[1..-1].compact.map do |item| res = res.send(func, *rest + [item]) end
- res
- else
- len = rest.length + ((array?(receiver) and receiver.length) or 1)
- if receiver.method(func).arity.abs == len
- # remove_file (String(WS) in ws.rb)
- self.map do |item| send(func, *rest + [item]) end
- else
- # length, max, min, ...
- self.map do |item| item.send(func, *rest) end
- end
- end
- else
- # functions
- self.map do |item| send(func, *rest + [item]) end
- end
- end
- end
- end
- end
-
- # original operands +, -, and * can now handle nil and numberic (offset, multiply)
- #
- # [].+(ary) concatenate arrays
- # [].+(number) [].add(number)
- unless defined? [].ary_plus
- alias old_ary_plus +
- def ary_plus(other)
- case other
- when Numeric
- self.offset(other)
- when NilClass
- self
- else
- self.old_ary_plus(other)
- end
- end
- alias + ary_plus
- end
-
- # [].-(ary) intersection
- # [1, 2, 3, 4] - [2, 3] ==> [1, 4]
- # [] - number [].offset
- unless defined? [].ary_minus
- alias old_ary_minus -
- def ary_minus(other)
- case other
- when Numeric
- self.offset(-other)
- when NilClass
- self
- else
- self.old_ary_minus(other)
- end
- end
- alias - ary_minus
- end
-
- # [].*(n) repetition or [].join(n)
- # [5] * 3 ==> [5, 5, 5]
- # ["foo", "bar"] * "-" ==> "foo-bar"
- unless defined? [].ary_times
- alias old_ary_times *
- def ary_times(other)
- case other
- when NilClass
- nil.to_a
- else
- self.old_ary_times(other)
- end
- end
- alias * ary_times
- end
-end
-
-# name Vector is in use (lib/ruby/1.9/matrix.rb)
-class Vec < Array
- def self.[](*ary)
- self.new(ary.length) do |i| ary[i] end
- end
-
- def initialize(len, init = 0.0, &body)
- assert_type((number?(len) and len >= 0), len, 0, "a number")
- @name = "vector"
- len = Integer(len)
- if block_given?
- super(len, &body)
- else
- super(len, init)
- end
- test = self.detect do |x| (not number?(x)) end
- assert_type((not test), test, 0, "only numeric elements")
- end
-
- def inspect
- str = "%s(" % @name
- self.each do |val| str += "%s, " % val end
- if self.length > 0 then str.chop!.chop! end
- str += ")"
- str
- end
-
- def to_s
- if self.length > 0
- vals = ":"
- self.map do |val| vals += " %s" % val end
- else
- vals = ""
- end
- format("#<%s[%d]%s>", self.class, self.length, vals)
- end
-
- def +(other)
- case other
- when Numeric
- self.offset(other).to_vector
- when Array, Vec, Vct
- self.add(other.to_vector)
- when NilClass
- self
- end
- end
-
- def -(other)
- case other
- when Numeric
- self.offset(-other).to_vector
- when Array, Vec, Vct
- self.subtract(other.to_vector)
- when NilClass
- self
- end
- end
-
- def *(other)
- case other
- when Numeric
- self.scale(other).to_vector
- when Array, Vec, Vct
- self.multiply(other.to_vector)
- when NilClass
- nil.to_vector
- end
- end
-end
-
-def Vec(obj)
- if obj.nil? then obj = [] end
- assert_type(obj.respond_to?(:to_vector), obj, 0,
- "an object containing method 'to_vector' (Vct, String, Array and subclasses)")
- obj.to_vector
-end
-
-def make_vector(len, init = 0.0, &body)
- Vec.new(len, init, &body)
-end
-
-def vector?(obj)
- obj.kind_of?(Vec)
-end
-
-def vector(*args)
- args.to_vector
-end
-
-class String
- def to_vector
- if self.scan(/^vector\([-+,.)\d\s]+/).null?
- nil
- else
- eval(self)
- end
- end
-
- def to_vct
- if self.scan(/^vct\([-+,.)\d\s]+/).null?
- nil
- else
- eval(self)
- end
- end
-end
-
-def Vct(obj)
- if obj.nil? then obj = [] end
- assert_type(obj.respond_to?(:to_vct), obj, 0,
- "an object containing method 'to_vct' (Vct, String, Array and subclasses)")
- obj.to_vct
-end
-
-def make_vct!(len, init = 0.0, &body)
- if block_given?
- Vct.new(len, &body)
- else
- Vct.new(len, init)
- end
-end
-
-class Vct
- def self.[](*ary)
- self.new(ary.length) do |i| ary[i] end
- end
-
- def name
- self.class.to_s.downcase
- end
-
- def to_sound_data(sd = nil, chn = 0)
- if sound_data?(sd)
- vct2sound_data(self, sd, chn)
- else
- vct2sound_data(self)
- end
- end
-
- def to_vct(chn = 0) # CHN for compatibility with sound-data
- self
- end
-
- def to_vector
- Vec.new(self.length) do |i| self[i] end
- end
-
- def apply(*rest, &body)
- self.to_a.apply(*rest, &body)
- end
-
- def +(other)
- assert_type((number?(other) or vct?(other) or array?(other) or other.nil?), other, 0,
- "a number, an array, a vector or a vct")
- case other
- when Numeric
- self.offset(other)
- when Array, Vec, Vct
- self.add(other.to_vct)
- when NilClass
- self
- end
- end
-
- def -(other)
- assert_type((number?(other) or vct?(other) or array?(other) or other.nil?), other, 0,
- "a number, an array, a vector or a vct")
- case other
- when Numeric
- self.offset(-other)
- when Array, Vec, Vct
- self.subtract(other.to_vct)
- when NilClass
- self
- end
- end
-
- def *(other)
- assert_type((number?(other) or vct?(other) or array?(other) or other.nil?), other, 0,
- "a number, an array, a vector or a vct")
- case other
- when Numeric
- self.scale(other)
- when Array, Vec, Vct
- self.multiply(other.to_vct)
- when NilClass
- nil.to_vct
- end
- end
-
- def step(n = 1, &body)
- self.to_a.step(n, &body)
- end
-
- # v = vct(0, 1, 2, 3, 4)
- # v[2..4] ==> vct(2.000, 3.000, 4.000)
- # v[2...4] ==> vct(2.000, 3.000)
- # v[3, 4] ==> vct(3.000, 4.000)
- # v[-1] ==> 4.0
- def vct_ref_extend(idx, size = nil)
- case idx
- when Fixnum
- if idx < 0 then idx += self.length end
- if idx < 0 then Snd.raise(:out_of_range, "index < 0", idx) end
- if integer?(size)
- size += idx - 1
- if size >= self.length then size = self.length - 1 end
- if size.between?(0, self.length - 1) and size >= idx
- self.subseq(idx, size)
- else
- nil.to_vct # i.e. false
- end
- else
- vct_ref(self, idx)
- end
- when Range
- beg = idx.first
- len = idx.last
- if beg < 0 then beg += self.length end
- if len < 0 then len += self.length end
- if len >= self.length then len = self.length - 1 end
- # exclude_end?: (1..2) ==> false
- # (1...2) ==> true
- if idx.exclude_end? then len -= 1 end
- if beg.between?(0, self.length - 1) and len >= beg
- self.subseq(beg, len)
- else
- nil.to_vct # i.e. false
- end
- end
- end
- # alias [] vct_ref_extend
-
- # This is required since Ruby 1.9.
- alias zip clm_zip if [].respond_to?(:zip)
-end
-
-class Fixnum
- # no reloading (load "examp.rb")
- unless defined? 0.new_int_plus
- alias int_plus +
- def new_int_plus(other)
- case other
- when Vct, Array, Vec
- other.offset(Float(self))
- when NilClass
- self
- else
- self.int_plus(other)
- end
- end
- alias + new_int_plus
- end
-
- unless defined? 0.new_int_times
- alias int_times *
- def new_int_times(other)
- case other
- when Vct, Array, Vec
- other.scale(self)
- when NilClass
- 0
- else
- self.int_times(other)
- end
- end
- alias * new_int_times
- end
-end
-
-class Float
- # no reloading (load "examp.rb")
- unless defined? 0.0.new_float_plus
- alias float_plus +
- def new_float_plus(other)
- case other
- when Vct, Array, Vec
- other.offset(self)
- when NilClass
- self
- else
- self.float_plus(other)
- end
- end
- alias + new_float_plus
- end
-
- unless defined? 0.0.new_float_times
- alias float_times *
- def new_float_times(other)
- case other
- when Vct, Array, Vec
- other.scale(self)
- when NilClass
- 0.0
- else
- self.float_times(other)
- end
- end
- alias * new_float_times
- end
-
- unless defined? 0.0.imag
- def imag
- 0.0
- end
- alias image imag
- end
-end
-
-def SoundData(ary)
- assert_type((array?(ary) and vct?(ary.first)), ary, 0, "an array of vcts")
- sd = SoundData.new(ary.length, ary.first.length)
- ary.each_with_index do |v, chn| vct2sound_data(v, sd, chn) end
- sd
-end
-
-def sound_data2string(sd)
- sd.to_a.to_s
-end
-
-class SoundData
- def name
- "sound-data"
- end
-
- def to_vct(chn = 0)
- sound_data2vct(self, chn)
- end
-
- # returns an array of sd.chans vcts
- def to_a
- sound_data2vector(self)
- end
-
- alias sd_length length
- def length
- self.size / self.chans
- end
-
- def fill!(val)
- sound_data_fill!(self, val)
- end
-
- alias sd_each each
- def each(chn = nil)
- if chn
- self.length.times do |i| yield(self[chn, i]) end
- else
- self.sd_each do |val| yield(val) end
- end
- end
-
- def each_with_index(chn = nil)
- if chn
- self.length.times do |i| yield(self[chn, i], i) end
- else
- self.length.times do |i|
- self.chans.times do |j| yield(self[j, i], i) end
- end
- end
- end
-
- def map(chn = nil)
- sd = nil
- if chn
- sd = self.dup
- self.each_with_index(chn) do |val, i| sd[chn, i] = yield(val) end
- else
- sd = SoundData.new(self.chans, self.length)
- self.chans.times do |j|
- self.each_with_index(j) do |val, i| sd[j, i] = yield(val) end
- end
- end
- sd
- end
-
- def map!(chn = nil)
- if chn
- self.each_with_index(chn) do |val, i| self[chn, i] = yield(val) end
- else
- self.chans.times do |j|
- self.each_with_index(j) do |val, i| self[j, i] = yield(val) end
- end
- end
- self
- end
-end
-
-def mus_a0(gen)
- mus_xcoeff(gen, 0)
-end
-
-def set_mus_a0(gen, val)
- set_mus_xcoeff(gen, 0, val)
-end
-
-def mus_a1(gen)
- mus_xcoeff(gen, 1)
-end
-
-def set_mus_a1(gen, val)
- set_mus_xcoeff(gen, 1, val)
-end
-
-def mus_a2(gen)
- mus_xcoeff(gen, 2)
-end
-
-def set_mus_a2(gen, val)
- set_mus_xcoeff(gen, 2, val)
-end
-
-def mus_b1(gen)
- mus_ycoeff(gen, 1)
-end
-
-def set_mus_b1(gen, val)
- set_mus_ycoeff(gen, 1, val)
-end
-
-def mus_b2(gen)
- mus_ycoeff(gen, 2)
-end
-
-def set_mus_b2(gen, val)
- set_mus_ycoeff(gen, 2, val)
-end
-
-class Mus
- # clm_gen.call(a1, a2) requires 2 arguments but clm_gen.run([a1, [a2]])
- # 0, 1 or 2.
- #
- # clm_gen.run([arg1, [arg2]])
- def run(arg1 = 0.0, arg2 = 0.0)
- mus_run(self, arg1, arg2)
- end
-
- def apply(*rest)
- mus_apply(self, *rest)
- end
-
- alias mus_inspect inspect
- def inspect
- "#<" + mus_describe(self) + ">"
- end
-
- def close
- mus_close(self)
- end
-
- # gen.xcoeff = 0, 0.4
- # set_mus_xcoeff(gen, index, val)
- def xcoeff=(args)
- set_mus_xcoeff(self, *args.flatten[0, 2])
- end
-
- # gen.ycoeff = 0, 0.4
- # set_mus_ycoeff(gen, index, val)
- def ycoeff=(args)
- set_mus_ycoeff(self, *args.flatten[0, 2])
- end
-
- def a0
- mus_xcoeff(self, 0)
- end
-
- def a0=(val)
- set_mus_xcoeff(self, 0, val)
- end
-
- def a1
- mus_xcoeff(self, 1)
- end
-
- def a1=(val)
- set_mus_xcoeff(self, 1, val)
- end
-
- def a2
- mus_xcoeff(self, 2)
- end
-
- def a2=(val)
- set_mus_xcoeff(self, 2, val)
- end
-
- def b1
- mus_ycoeff(self, 1)
- end
-
- def b1=(val)
- set_mus_ycoeff(self, 1, val)
- end
-
- def b2
- mus_ycoeff(self, 2)
- end
-
- def b2=(val)
- set_mus_ycoeff(self, 2, val)
- end
-end
-
-# base class for generators written in Ruby
-class Musgen
- def initialize
- @frequency = $clm_default_frequency
- @phase = 0.0
- @scaler = 1.0
- @length = 0
- @data = nil
- @increment = 0
- @interp_type = -1
- @file_name = ""
- end
- attr_accessor :frequency
- attr_accessor :phase
- attr_accessor :scaler
- attr_accessor :increment
- attr_reader :length
- attr_reader :data
- attr_reader :interp_type
- attr_reader :file_name
-
- def inspect
- format("%s.new()", self.class)
- end
-
- def to_s
- format("#<%s>", self.class)
- end
-
- def run(val1 = 0.0, val2 = 0.0)
- self.run_func(val1, val2)
- end
- alias call run
-
- def apply(*rest)
- self.run_func(*rest)
- end
-
- def eql?(other)
- self == other
- end
-
- def reset
- @frequency = $clm_default_frequency
- @phase = 0.0
- @scaler = 1.0
- @increment = 0
- self
- end
-end
-
-class Numeric
- def positive?
- self > 0
- end
-
- def negative?
- self < 0
- end
-end
-
-class Integer
- def even?
- self.modulo(2) == 0
- end unless defined? 1.even?
-
- def odd?
- self.modulo(2) != 0
- end unless defined? 1.odd?
-
- def prime?
- (self == 2) or
- (self.odd? and 3.step(sqrt(self), 2) do |i| return false if self.modulo(i) == 0 end)
- end
-end
-
-class Float
- # step accepts floats as arguments (still implemented in newer versions)
- def step(upto, step)
- counter = self
- while counter < upto
- yield(counter)
- counter += step
- end
- counter
- end unless 1.1.respond_to?(:step)
-end
-
-class Range
- def step(n = 1, &body)
- self.to_a.step(n, &body)
- end unless defined? Range.new(0, 1).step
-end
-
-def as_one_edit_rb(*origin, &body)
- # ruby compatibility:
- # ruby pre 1.9: lambda do end.arity != lambda do | | end.arity
- # ruby 1.9: they are even (0)
- as_one_edit(lambda do | | body.call end, origin.empty? ? "" : format(*origin))
-end
-
-def map_channel_rb(beg = 0, dur = false,
- snd = false, chn = false, edpos = false, edname = false, &func)
- map_channel(func, beg, dur, snd, chn, edpos, edname)
-end
-
-add_help(:map_chan_rb,
- "map_chan(func,[start=0,[end=false,[edname=false,[snd=false,[chn=false,[edpos=false]]]]]])\
- map_chan applies func to samples in the specified channel.\
- It is the old (\"irregular\") version of map_channel.")
-def map_chan_rb(beg = 0, dur = false, ednam = false, snd = false, chn = false, edpos = false, &func)
- map_chan(func, beg, dur, ednam, snd, chn, edpos)
-end
-
-class Proc
- include Info
- alias run call
-
- add_help(:to_method,
- "Proc#to_method(name, [klass=Object]) \
-converts a Proc to a Method 'name' in the given class, default Object. \
-'name' can be a string or a symbol.
-
-m = lambda do |*args| p args end
-m.to_method(:func)
-func(1, 2, 3) ==> [1, 2, 3]
-
-lambda do |x| p x end.to_method(:foo); foo(\"text1\") ==> \"text1\"
-lambda do |x| p x end.to_method(\"bar\"); bar(\"text2\") ==> \"text2\"")
- def to_method(name, klass = Object)
- assert_type((symbol?(name) or string?(name)), name, 0, "a symbol or a string")
- assert_type((klass.kind_of?(Class) and klass.class == Class), name, 1, "a class, e.g. Object")
- name = case name
- when String
- name.intern
- when Symbol
- name
- end
- body = self
- klass.class_eval do define_method(name, body) end
- end
-
- # Important:
- # The following works only with newer ruby versions (I assume >=
- # 1.8.x). Proc#inspect must return #<Proc:0x80c96a0@xxx:x> to
- # locate the source file of the procedure, not only #<Proc:0x80c96a0>!
-
- # Functions to_str and to_body try to search the procedure source
- # code in a file determined by to_s. It is only a simple scanner
- # which doesn't look for the whole Ruby syntax. ;-)
- #
- # It doesn't work if no source file exists, i.e, if the code is
- # eval'ed by the Snd listener (or in Emacs). You must load the file
- # instead.
- #
- # with_sound(:notehook, lambda do |name| snd_print(name) if name =~ /viol/ end) do
- # fm_violin(0, 1, 440, 0.3)
- # end
- #
- # $clm_notehook = lambda do |name| clm_print(name) if name =~ /viol/ end
- #
- # with_sound do
- # fm_violin(0, 1, 440, 0.3)
- # end
- #
- # with_sound(:save_body, true) do
- # ...
- # end
-
- # returns something like 'lambda do ... end'
- def to_str
- if body = self.source
- return body
- end
- file, line = self.to_s.sub(/>/, "").split(/@/).last.split(/:/)
- if file[0] == ?( and file[-1] == ?)
- if $VERBOSE
- warning("%s#%s: no file found for procedure %s", self.class, get_func_name, self.inspect)
- end
- body = ""
- elsif (not File.exist?(file))
- if $VERBOSE
- warning("%s#%s: Sorry, you need a higher ruby version to use Proc#to_str.
-It works only with newer ruby versions (I assume >= 1.8.x).
-Proc#inspect must return #<Proc:0x01234567@xxx:x> not only %s!",
- self.class, get_func_name, self.inspect)
- end
- body = ""
- else
- lineno = line.to_i
- body = ""
- blck = i = 0
- first_line = true
- File.foreach(file) do |ln|
- i += 1
- next if i < lineno
- body << ln
- if first_line
- if (ln.scan(/\s*do\b|\{/).length - ln.scan(/\s*end\b|\}/).length).zero? and
- (ln.scan(/\(/).length - ln.scan(/\)/).length).zero?
- break
- else
- first_line = false
- blck = 1
- next
- end
- end
- next if /\s*\S+\s*(if|unless|while|until)+/ =~ ln
- break if (blck += Snd_eval.count_level(ln)).zero?
- break if blck.negative?
- end
- end
- unless self.source then self.source = body end
- body
- end
-
- # returns the inner body without 'lambda do end'
- def to_body
- if (body = self.to_str).null?
- ""
- elsif body.split(/\n/).length == 1
- body.chomp.sub(/^(?:\s*\w+(?:\(.*\))??\s*(?:do\s+|\{\s*))(.*)\s*(?:end|\})$/, '\1').strip
- else
- body.split(/\n/)[1..-2].join("\n")
- end
- end
-
- # property set in g_edit_list_to_function (snd-edits.c)
- def source
- property(self.object_id, :proc_source)
- end
-
- def source=(val)
- set_property(self.object_id, :proc_source, val)
- end
-end
-
-def make_proc2method(name, prc)
- assert_type(func?(name), name, 0, "a symbol or a string")
- assert_type(proc?(prc), prc, 1, "a proc")
- prc.to_method(name)
-end
-
-# produces two new functions: NAME and SET_NAME
-# val = 10
-# make_proc_with_setter(:foo, lambda { puts val }, lambda { |a| val = a })
-# foo ==> 10
-# set_foo(12)
-# foo ==> 12
-def make_proc_with_setter(name, getter, setter)
- make_proc2method(name, getter)
- make_proc2method(format("set_%s", name).intern, setter)
-end
-
-# prc = make_proc_with_source(%(lambda do |a, b, c| puts a, b, c end))
-# prc.call(1, 2, 3)
-# prc.source ==> "lambda do |a, b, c| puts a, b, c end"
-#
-# With the second argument BIND one can use local variables known in
-# the current (or other) environment in the proc body:
-#
-# os = make_oscil(:frequency, 330)
-# prc = make_proc_with_source(%(lambda do | | 10.times do |i| p os.run end end), binding)
-# puts prc.source ==> lambda do | | 10.times do |i| p os.run end end
-# prc.call ==> ..., 0.748837699712728
-# puts
-# prc.call ==> ..., 0.97679449812022
-def make_proc_with_source(string, bind = binding)
- assert_type(string?(string), string, 0, "a string")
- assert_type(binding?(bind), bind, 1, "a binding object")
- if proc?(prc = (res = Snd.catch(:all) do eval(string, bind) end).first)
- prc.source = string
- prc
- else
- Snd.raise(:runtime_error, res, prc, string)
- end
-end
-
-make_proc_with_setter(:proc_source,
- lambda { |prc|
- assert_type(proc?(prc), prc, 0, "a proc")
- prc.source
- },
- lambda { |prc, val|
- assert_type(proc?(prc), prc, 0, "a proc")
- assert_type(string?(val), val, 1, "a string")
- prc.source = val
- })
-
-# Multi-line input to the Snd listener and Emacs/inf-snd.el.
-# A simple parser collects multi-line input, e.g.
-#
-# with_sound do
-# fm_violin(0.0, 0.1, 330, 0.1)
-# fm_violin(0.1, 0.1, 660, 0.1)
-# end
-#
-# and evals it.
-#
-# ~/.snd
-# set_listener_prompt("snd> ") # optional
-# start_listener_eval # installs read-hook for snd-listener input
-# start_emacs_eval # installs emacs-eval-hook
-
-make_hook("$emacs_eval_hook", 1, "\
-emacs_eval_hook(line): called each time inf-snd.el sends a line to the Snd process. \
-The hook functions may do their best to deal with multi-line input; \
-they can collect multi-line input and eval it by itself. \
-One example is install_eval_hooks(file, retval, input, hook, &reset_cursor) in examp.rb.")
-
-# inf-snd.el calls this function each time a line was sent to the
-# emacs buffer.
-def run_emacs_eval_hook(line)
- if $emacs_eval_hook.empty?
- # without emacs-eval-hook only single line eval
- file = "(emacs-eval-hook)"
- set_snd_input(:emacs)
- begin
- Snd.display(eval(line, TOPLEVEL_BINDING, file, 1).inspect)
- rescue Interrupt, ScriptError, NameError, StandardError
- Snd.display(verbose_message_string(true, "# ", file))
- end
- set_snd_input(:snd)
- nil
- else
- $emacs_eval_hook.call(line)
- end
-end
-
-class Snd_eval
- class << Snd_eval
- Open_token = %w(class module def do { while until if unless case begin for)
- Close_token = %w(end })
-
- def count_level(line)
- eval_level = 0
- # skip strings and symbols which may contain reserved words
- line.gsub(/(:\w+|".+")/, "").split(/\b/).each do |s|
- case s
- when *Open_token
- eval_level += 1
- when *Close_token
- eval_level -= 1
- end
- end
- eval_level
- end
- end
-end
-
-class Snd_prompt
- # level number inserted into original prompt
- # ">" --> "(0)>"
- # "snd> " --> "snd(0)> "
- def initialize(level)
- @listener_prompt = listener_prompt
- @base_prompt = listener_prompt.split(/(\(\d+\))?(>)?\s*$/).car.to_s
- @rest_prompt = listener_prompt.scan(/>\s*$/).car.to_s
- update(level)
- end
-
- def inspect
- format("#<%s %s(0)%s>", self.class, @base_prompt, @rest_prompt)
- end
-
- def update(level)
- set_listener_prompt(format("%s(%d)%s", @base_prompt, level, @rest_prompt))
- end
-
- def reset
- set_listener_prompt(@listener_prompt)
- end
-end
-
-def install_eval_hooks(file, retval, input, hook, &reset_cursor)
- eval_level = 0
- eval_line = ""
- prompt = Snd_prompt.new(eval_level)
- reset_cursor.nil? or reset_cursor.call
- $exit_hook.add_hook!(file) do | | prompt.reset end
- hook.add_hook!(file) do |line|
- eval_line << line << "\n"
- eval_level += Snd_eval.count_level(line)
- if eval_level.negative?
- eval_level = 0
- eval_line = ""
- end
- if eval_level.zero?
- set_snd_input(input)
- begin
- Snd.display(eval(eval_line, TOPLEVEL_BINDING, file, 1).inspect)
- rescue Interrupt, ScriptError, NameError, StandardError
- Snd.display(verbose_message_string(true, "# ", file))
- ensure
- eval_line = ""
- end
- end
- prompt.update(eval_level)
- reset_cursor.nil? or reset_cursor.call
- retval
- end
-end
-
-# installs the emacs-eval-hook
-def start_emacs_eval(name = "(emacs)")
- install_eval_hooks(name, nil, :emacs, $emacs_eval_hook) do
- $stdout.print(listener_prompt)
- $stdout.flush
- end
-end
-
-# installs the read-hook
-def start_listener_eval(name = "(snd)")
- set_show_listener(true)
- install_eval_hooks(name, true, :snd, $read_hook)
-end
-
-def stop_emacs_eval(name = "(emacs)")
- $emacs_eval_hook.remove_hook!(name)
- $exit_hook.run_hook_by_name(name)
- $exit_hook.remove_hook!(name)
-end
-
-def stop_listener_eval(name = "(snd)")
- $read_hook.remove_hook!(name)
- $exit_hook.run_hook_by_name(name)
- $exit_hook.remove_hook!(name)
- reset_listener_cursor
- clm_print("\n%s", listener_prompt)
-end
-
-# Debugging resp. inspecting local variables
-
-make_proc_with_setter(:debug_properties,
- lambda { |name|
- property(name, :debug_property)
- },
- lambda { |name, val|
- set_property(name, :debug_property, val)
- })
-
-make_proc_with_setter(:debug_property,
- lambda { |key, name|
- hash?(h = debug_properties(name)) and h[key]
- },
- lambda { |key, val, name|
- unless hash?(h = debug_properties(name)) and h.store(key, [val] + h[key])
- unless array?(a = property(:debug, :names)) and a.push(name)
- set_property(:debug, :names, [name])
- end
- set_debug_properties(name, {key => [val]})
- end
- })
-
-make_proc_with_setter(:debug_binding,
- lambda { |name|
- debug_property(:binding, name)
- },
- lambda { |bind, *name|
- assert_type(binding?(bind), bind, 0, "a binding object")
- name = (name.car or get_func_name(3))
- set_debug_property(:binding, bind, name)
- })
-
-# shows all local variables of functions prepared by set_debug_binding(binding)
-#
-# def function1
-# [...]
-# set_debug_binding(binding)
-# end
-#
-# def function2
-# [...]
-# set_debug_binding(binding)
-# end
-# [...]
-#
-# display_all_variables
-def display_all_variables(name = nil)
- if name
- [name]
- else
- (property(:debug, :names) or [])
- end.each do |nm|
- debug_binding(nm).each do |bind|
- Snd.message("=== %s ===", nm)
- Snd.message()
- eval("local_variables", bind).each do |var|
- Snd.message("%s = %s", var, eval(var, bind).inspect)
- end
- Snd.message()
- end
- end
-end
-
-# each_variables provides all local variable names and their values in
-# the given proc context
-#
-# def function
-# [...]
-# each_variables do |k, v|
-# Snd.display("%s = %s", k, v)
-# end
-# end
-def each_variables(&prc)
- eval("local_variables", prc).each do |var| yield(var, eval(var, prc)) end
-end
-
-# let(8, :foo, "bar") do |a, b, c|
-# printf("a: %d, b: %s, c: %s\n", a, b, c)
-# end
-#
-# Simulates a save local variable environment and restores old
-# variables to their original values.
-#
-# EVAL doesn't take any longer a proc for a binding. The date is a
-# guess.
-if RUBY_RELEASE_DATE > "2006-12-21"
- def let(*args, &prc)
- prc.call(*args)
- rescue Interrupt, ScriptError, NameError, StandardError
- Kernel.raise
- end
-else
- def let(*args, &prc)
- locals = Hash.new
- eval("local_variables", prc).each do |name| locals[name] = eval(name, prc) end
- # yield(*args)
- # See ruby/ChangeLog: Tue Jul 18 16:52:29 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
- prc.call(*args)
- rescue Interrupt, ScriptError, NameError, StandardError
- Kernel.raise
- ensure
- @locals = locals
- locals.each_key do |name| eval("#{name} = @locals[#{name.inspect}]", prc) end
- remove_instance_variable("@locals")
- end
-end
-
-include Math
-
-TWO_PI = PI * 2.0 unless defined? TWO_PI
-HALF_PI = PI * 0.5 unless defined? HALF_PI
-
-# for irb (rgb.rb)
-def make_color(r, g, b)
- [:Pixel, 0]
-end unless defined? make_color
-
-def doc(*rest)
- # dummy for old Kernel.doc
-end
-
-require "env"
-require "dsp"
-require "rgb"
-
-##
-## Utilities
-##
-
-if provided? :snd_nogui
- alias close_sound_extend close_sound
-else
- def close_sound_extend(snd)
- # 5 == Notebook
- if main_widgets[5]
- idx = Snd.sounds.index(snd)
- if idx.nil? then idx = 0 end
- close_sound(snd)
- snds = sounds() and set_selected_sound(snds[idx < snds.length ? idx : -1])
- else
- close_sound(snd)
- end
- end
-end
-
-add_help(:times2samples,
- "times2samples(start, dur) \
-START and DUR are in seconds; returns array [beg, end] in samples.")
-def times2samples(start, dur)
- beg = seconds2samples(start)
- [beg, beg + seconds2samples(dur)]
-end
-
-def random(val)
- if val.zero?
- val
- else
- case val
- when Fixnum
- kernel_rand(val)
- when Float
- val.negative? ? -mus_random(val).abs : mus_random(val).abs
- end
- end
-end
-
-def logn(r, b = 10)
- if r <= 0 then Snd.raise(:ruby_error, r, "r must be > 0") end
- if b <= 0 or b == 1 then Snd.raise(:ruby_error, b, "b must be > 0 and != 1") end
- log(r) / log(b)
-end
-
-def car(v)
- v[0]
-end
-
-def cadr(v)
- v[1]
-end
-
-def caddr(v)
- v[2]
-end
-
-def cdr(v)
- v[1..-1]
-end
-
-def verbose_message_string(stack_p, remark, *args)
- fmt_remark = format("\n%s", remark)
- args.to_a.car = String(args.to_a.car)
- str = if args.length < 2
- args.car
- else
- format(*args)
- end
- str = if str.split(/\n/).length > 1
- str.split(/\n/).join(fmt_remark)
- else
- format("%s%s", remark, args.car)
- end
- if $!
- str += format("[%s] %s (%s)", rb_error_to_mus_tag.inspect, snd_error_to_message, $!.class)
- if stack_p then str += format("\n%s%s", remark, $!.backtrace.join(fmt_remark)) end
- else
- if stack_p and caller(2) then str += format("\n%s%s", remark, caller(2).join(fmt_remark)) end
- end
- str
-end
-
-def warning(*args)
- str = "Warning: " << verbose_message_string($VERBOSE, nil, *args)
- if provided? :snd
- snd_warning(str)
- nil
- else
- clm_message(str)
- end
-end
-
-def die(*args)
- message(verbose_message_string(true, nil, *args))
- exit(1) unless provided? :snd
-end
-
-def error(*args)
- Snd.raise(:runtime_error, verbose_message_string(true, nil, *args))
-end
-
-make_proc_with_setter(:snd_input,
- lambda { property(:snd_input, :snd_listener) },
- lambda { |val| set_property(:snd_input, :snd_listener, val) })
-
-# like clm_print(fmt, *args)
-
-def clm_message(*args)
- msg = if args.null?
- ""
- elsif args.length == 1
- String(args.car)
- else
- format(*args)
- end
- if provided?(:snd)
- clm_print("\n%s", msg)
- unless provided?(:snd_nogui)
- $stdout.print(msg, "\n")
- end
- else
- $stdout.print(msg, "\n")
- end
-end
-
-# like clm_print(*args), in emacs it prepends msg with a comment sign
-
-def message(*args)
- msg = if args.null?
- ""
- elsif args.length == 1
- String(args.car)
- else
- format(*args)
- end
- clm_message(verbose_message_string(false, "# ", msg))
-end
-
-# debug(var1, var2) --> #<DEBUG: ClassName: value1, ClassName: value2>
-
-def debug(*args)
- fmt = ""
- args.each do |arg|
- fmt += format("%s: %s", arg.class, arg.inspect)
- fmt += ", "
- end
- message("#<DEBUG: %s>", fmt.chomp(", "))
-end
-
-def debug_trace(*args)
- debug(*args)
- clm_message(verbose_message_string(true, "# "))
-end
-
-if provided? :snd then set_snd_input(:snd) end
-
-class Snd
- class << Snd
- Snd_path = Array.new
-
- if provided? :snd
- def add_sound_path(path)
- Snd_path.push(path)
- add_directory_to_view_files_list(path)
- end
-
- def open_from_path(fname)
- snd_file = Snd.fullname(fname)
- find_sound(snd_file) or open_sound(snd_file)
- end
-
- def find_from_path(fname)
- find_sound(Snd.fullname(fname))
- end
- else
- def add_sound_path(path)
- Snd_path.push(path)
- end
- end
-
- def fullname(fname)
- if File.exist?(fname)
- fname
- else
- f = File.basename(fname)
- Snd_path.each do |path|
- if File.exist?(path + "/" + f)
- return path + "/" + f
- end
- end
- Snd.raise(:no_such_file, fname)
- end
- end
-
- def load_path
- Snd_path
- end
-
- def message(*args)
- msg = if args.null?
- ""
- elsif args.length == 1
- String(args.car)
- else
- format(*args)
- end
- clm_message(verbose_message_string(false, "# ", msg))
- end
-
- def display(*args)
- args[0] = String(args[0])
- msg = format(*args)
- if snd_input == :snd
- snd_print("\n" + msg)
- if $VERBOSE then $stdout.print(msg, "\n") end
- nil
- else
- $stdout.print(msg, "\n")
- end
- end
-
- def warning(*args)
- if provided? :snd
- snd_warning(verbose_message_string($VERBOSE, nil, *args))
- nil
- else
- args[0] = "Warning: " + String(args[0])
- Snd.display(verbose_message_string($VERBOSE, "# ", *args))
- end
- end
-
- def die(*args)
- Snd.display(verbose_message_string(true, nil, *args))
- exit(1) unless provided? :snd
- end
-
- def error(*args)
- Snd.raise(:runtime_error, verbose_message_string(true, nil, *args))
- end
-
- def debug(*args)
- fmt = ""
- args.each do |arg|
- fmt += format("%s: %s", arg.class, arg.inspect)
- fmt += ", "
- end
- Snd.message("#<DEBUG: %s>", fmt.chomp(", "))
- end
-
- def debug_trace(*args)
- Snd.debug(*args)
- Snd.display(verbose_message_string(true, "# "))
- end
-
- def sounds
- (Kernel.sounds or []).reverse
- end
-
- def regions
- (Kernel.regions or []).reverse
- end
-
- def marks(snd = false, chn = false)
- (Kernel.marks(snd, chn) or [])
- end
-
- def snd(sn = false)
- sn or selected_sound or Snd.sounds.car
- end
-
- def chn(ch = false)
- ch or selected_channel or 0
- end
-
- def catch(tag = :all, retval = :undefined)
- old_debug = $DEBUG
- $DEBUG = false
- val = Kernel.catch(tag) do yield end
- # catch/throw part
- if array?(val) and val.car == :snd_throw # [:snd_throw, tag, get_func_name(2), *rest]
- if retval != :undefined
- if proc?(retval)
- retval.call(val.cdr)
- else
- [retval]
- end
- else
- val.cdr
- end
- else
- [val]
- end
- # ruby1.9/ChangeLog
- # Thu Feb 2 16:01:24 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
- # * error.c (Init_Exception): change NameError to direct subclass of
- # Exception so that default rescue do not handle it silently.
- rescue Interrupt, ScriptError, NameError, StandardError
- mus_tag = rb_error_to_mus_tag
- # raise part
- if (tag == mus_tag) or (tag == :all)
- if retval != :undefined
- if proc?(retval)
- retval.call(mus_tag, snd_error_to_message)
- else
- [retval]
- end
- else
- [mus_tag, snd_error_to_message]
- end
- else
- Kernel.raise
- end
- ensure
- $DEBUG = old_debug
- end
-
- def throw(tag, *rest)
- Kernel.throw(tag, [:snd_throw, tag, get_func_name(2), *rest])
- end
-
- def raise(tag, *rest)
- msg = format("%s: %s:", get_func_name(2), tag)
- rest.each do |s| msg += format(" %s,", s) end
- msg.chomp!(",")
- exception = case tag
- when :out_of_range
- RangeError
- when :wrong_type_arg
- TypeError
- when *Snd_error_tags
- StandardError
- else
- Ruby_exceptions[tag] or RuntimeError
- end
- Kernel.raise(exception, msg, caller(1))
- end
- end
-end
-
-# almost all StandardError
-Snd_error_tags = [# clm2xen.c
- :mus_error,
- :no_such_method,
- :wrong_type_arg, # TypeError
- # snd-0.h
- :no_such_envelope,
- :no_such_sample,
- :no_such_edit,
- :cannot_save,
- :cant_update_file,
- # snd-chn.c
- :cant_open_file,
- # snd-dac.c
- :bad_format,
- :no_such_player,
- :arg_error,
- # snd-draw.c
- :no_such_widget,
- :no_such_graphics_context,
- :no_such_axis,
- :bad_length,
- # snd-edits.c
- :no_such_direction,
- :no_such_region,
- :no_such_auto_delete_choice,
- # snd-env.c
- :env_error,
- # snd-error.c
- :snd_error,
- # snd-gxcolormaps.c
- :no_such_colormap,
- :colormap_error,
- # snd-key.c
- :no_such_key,
- # snd-ladspa.c
- :no_such_plugin,
- :plugin_error,
- # snd-marks.c
- :no_such_mark,
- # snd-menu.c
- :no_such_menu,
- # snd-mix.c
- :no_such_mix,
- # snd-print.c
- :cannot_print,
- # snd-region.c
- :io_error,
- # run.c
- :wrong_number_of_args,
- :cannot_parse,
- # snd-snd.c
- :no_such_sound,
- :not_a_sound_file,
- :cannot_apply_controls,
- :bad_size,
- :snd_internal_error,
- # snd-xen.c
- :no_active_selection,
- :bad_arity,
- # snd-xmain.c
- :xt_error,
- # snd-xchn.c
- :no_such_color,
- # snd.c
- :snd_top_level,
- :gsl_error,
- # sndlib2xen.h
- :out_of_range,
- :no_such_channel,
- :no_such_file,
- :bad_type,
- :no_data,
- :bad_header,
- # xm.c
- :no_such_resource]
-
-def rb_error_to_mus_tag
- # to_s and string error-names intended here
- # otherwise e.g. NameError goes to case StandardError!
- case $!.class.to_s
- # case 1
- # No_such_file: file->array /baddy/hiho No such file or directory
- # case 2
- # insert_region: No_such_region: 1004
- # case 3 (mus_error)
- # mus_ycoeff__invalid_index_123__order___3?: Mus_error
- # can't translate /usr/gnu/sound/sf1/oboe.g721 to /usr/gnu/sound/sf1/oboe.g721.snd:
- # : Mus_error>
- when "StandardError"
- err = $!.message.split(/\n/).first.downcase.split(/:/).map do |e| e.strip.chomp(">") end
- # err = $!.message.delete("\n").downcase.split(/:/).compact.map do |e| e.strip.chomp(">") end
- Snd_error_tags.detect do |tag| err.member?(tag.to_s) end or :standard_error
- when "RangeError"
- :out_of_range
- when "TypeError"
- :wrong_type_arg
- when "ArgumentError"
- :wrong_number_of_args
- else
- # converts ruby exceptions to symbols: NoMethodError --> :no_method_error
- $!.class.to_s.gsub(/([A-Z])/) do |c| "_" + c.tr("A-Z", "a-z") end[1..-1].intern
- end
-end
-
-def snd_error_to_message
- err = $!.message.split(/:/).map do |e| e.strip.chomp("\n") end
- str = err.join(": ")
- if err.length > 1 and (len = str.scan(/~A/).length).positive?
- str.gsub!(/~A/, "%s")
- str = if $!.class == RangeError
- format(str.strip, if string?(s = err.cadr.split(/,/)[1..-2].join(","))
- eval(s)
- else
- 0
- end)
- else
- format(str.strip, *if string?(s = str.slice!(str.index("[")..str.index("]")))
- eval(s)
- else
- [0] * len
- end)
- end
- end
- str.gsub(rb_error_to_mus_tag.to_s.capitalize + ": ", "")
-rescue Interrupt, ScriptError, NameError, StandardError
- if $DEBUG
- $stderr.printf("# Warning (%s)\n", get_func_name)
- each_variables do |k, v| $stderr.printf("# %s = %s\n", k, v.inspect) end
- end
- str
-end
-
-add_help(:snd_catch,
- "snd_catch([tag=:all, [retval=:undefined]]) \
-catchs snd_throw and exceptions and \
-returns body's last value wrapped in an array if all goes well. \
-If a snd_throw tag meets snd_catch's, returns an array with the tag name, \
-the function name from where was thrown and optional arguments given to snd_throw. \
-If an exception was risen and the exception name meets tag name, \
-returns an array with tag name and the exception message, otherwise reraises exception. \
-If retval is given and tag matches exception or snd_throw tag, returns retval. \
-If retval is a procedure, calls retval with tag name and message.
-
-res = snd_catch do 10 + 2 end
-puts res ==> [12]
-
-res = Snd.catch(:no_such_file) do
- open_sound(\"unknown-file.snd\")
-end
-puts res ==> [:no_such_file,
- \"open_sound: no_such_file: Unknown_file.snd No such file or directory\"]
-
-res = Snd.catch(:finish) do
- 10.times do |i|
- if i == 8 then snd_throw(:finish, i) end
- end
-end
-puts res ==> [:finish, \"top_level\", 8]
-
-res = Snd.catch(:all, lambda do |tag, msg| Snd.display([tag, msg]) end) do
- set_listener_prompt(17)
-end
-==> [:wrong_type_arg, \"set_listener-prompt: wrong type arg 0, 17, wanted a string\"]
-puts res ==> nil
-
-The lambda function handles the error in the last case.")
-def snd_catch(tag = :all, retval = :undefined, &body)
- Snd.catch(tag, retval, &body)
-end
-
-add_help(:snd_throw,
- "snd_throw(tag, *rest) \
-jumps to the corresponding snd_catch('tag') and returns an array \
-with tag, function name and possible *rest strings or values.")
-def snd_throw(tag, *rest)
- Snd.throw(tag, *rest)
-end
-
-class Break < StandardError
-end
-
-Ruby_exceptions = {
- :script_error => ScriptError,
- :load_error => LoadError,
- :name_error => NameError,
- :not_implemented_error => NotImplementedError,
- :syntax_error => SyntaxError,
- :interrupt => Interrupt,
- :system_exit => SystemExit,
- :standard_error => StandardError,
- :arg_error => ArgumentError,
- :float_domain_error => FloatDomainError,
- :index_error => IndexError,
- :io_error => IOError,
- :eof_error => EOFError,
- :local_jump_error => LocalJumpError,
- :no_memory_error => NoMemoryError,
- :range_error => RangeError,
- :regexp_error => RegexpError,
- :runtime_error => RuntimeError,
- :security_error => SecurityError,
- :system_call_error => SystemCallError,
- :system_stack_error => SystemStackError,
- :thread_error => ThreadError,
- :type_error => TypeError,
- :zero_division_error => ZeroDivisionError,
- :break => Break}
-
-add_help(:snd_raise,
- "snd_raise(tag, *rest) \
-raises an exception 'tag' with an error message \
-containing function name, tag and possible *rest strings or values. \
-'tag' is a symbol, \
-a Ruby exception looks like :local_jump_error instead of LocalJumpError, \
-a Snd error tag looks like :no_such_sound.")
-def snd_raise(tag, *rest)
- Snd.raise(tag, *rest)
-end
-
-# for irb
-def c_g?
- false
-end unless defined? c_g?
-
-def srate
- mus_srate
-end unless defined? srate
-
-# general purpose loop
-
-add_help(:gloop,
- "gloop(*args) { |args| ... }
- :step = 1
- :before = nil (thunk)
- :after = nil (thunk)
-
-args[0]: Range (each)
- Hash(s) (each)
- Array(s) (each_with_index) [args.last == Fixnum --> step]
- Fixnum (times)
- Fixnum [args[1] == :step --> step]
-
-A general purpose loop, handling Range, Hash, Array, Vec, Vct, Fixnum,
-with optional step. Returns the result of body as array like map.
-
-Examples:
- Range
- gloop(0..3) do |i| puts i end
- Hash (loops over all Hashs consecutively)
- gloop({1 => :a, 2 => :b}, {11 => :aa => 22 => :bb}) do |k, v|
- print('key: ', k, ' value: ', v)
- puts
- end
- Array, Vec, Vct
- gloop([0, 1]) do |x, i|
- print(i, ': ', x)
- puts end
- Arrays with step (mixes all Arrays)
- gloop([0, 1, 2, 3], [:a, :b, :c, :d], [55, 66, 77, 88, 99], 2) do |x, i|
- print(i, ': ', x.inspect)
- puts
- end
- Numeric (like Integer#times)
- gloop(3) do |i| puts i end
- Numeric with step (like Integer#step)
- gloop(6, 2) do |i| puts i end
- a simple body call
- gloop do puts 'empty' end")
-def gloop(*args, &body)
- step = get_shift_args(args, :step, 1)
- before = get_shift_args(args, :before)
- after = get_shift_args(args, :after)
- do_extra = lambda do |thunk| thunk?(thunk) ? thunk.call : snd_func(thunk) end
- result = []
- case args[0]
- when Range
- args[0].step(step) do |i|
- do_extra.call(before) if before
- result << body.call(i)
- do_extra.call(after) if after
- end
- when Array, Vec, Vct
- lmax = args.map do |x| x.length end.max
- 0.step(lmax - 1, step.round) do |i|
- do_extra.call(before) if before
- result << body.call(*args.map do |x| x[i] end << i)
- do_extra.call(after) if after
- end
- when Hash
- args.each do |x| x.each do |k, v|
- do_extra.call(before) if before
- result << body.call(k, v)
- do_extra.call(after) if after
- end
- end
- when Numeric
- 0.step(args[0], number?(args[1]) ? args[1] : step) do |i|
- do_extra.call(before) if before
- result << body.call(i)
- do_extra.call(after) if after
- end
- else
- do_extra.call(before) if before
- result << body.call
- do_extra.call(after) if after
- end
- result
-end
-
-# get_args(args, key, default = nil)
-#
-# returns value, whether DEFAULT or value of KEY found in ARGS
-
-def get_args(args, key, default = nil)
- if args.member?(key)
- arg = args[args.index(key) + 1]
- default = arg.nil? ? default : arg
- end
- default
-end
-
-def get_shift_args(args, key, default = nil)
- default = get_args(args, key, default)
- if args.member?(key)
- i = args.index(key)
- 2.times do args.delete_at(i) end
- end
- default
-end
-
-# var = get_class_or_key(args, Klass, :key, default = nil)
-
-def get_class_or_key(args, klass, key, default = nil)
- if (not symbol?(args.first)) and args.first.kind_of?(klass)
- args.shift
- else
- get_shift_args(args, key, default)
- end
-end
-
-# var1, var2, var3, var4 = optkey(args, [:key, default],
-# [:number, 1],
-# [Array, :list, [0, 1, 2, 3]],
-# :var_w/o_default_value)
-#
-# Key-default pairs must be included in brackets while keys alone can
-# be included in brackets or not, see last key
-# ":var_w/o_default_value" above. If no default value is specified,
-# nil is used.
-
-def optkey(args, *rest)
- args_1 = args.dup
- bind = binding?(rest.car) ? rest.shift : nil
- @locals = nil
- vals = rest.map do |keys|
- val = if array?(keys)
- case keys.length
- when 1
- name = keys.car.to_s
- get_class_or_key(args_1, Object, keys.car, nil)
- when 2
- name = keys.car.to_s
- get_class_or_key(args_1, keys.cadr.class, *keys)
- when 3
- name = keys.cadr.to_s
- get_class_or_key(args_1, *keys)
- else
- assert_type(keys.length.between?(1, 3), keys, 1,
- "an array of one to three elements [class, :key, default]")
- end
- else
- name = keys.to_s
- get_class_or_key(args_1, Object, keys, nil)
- end
- @locals = val
- eval("#{name} = @locals", bind)
- val
- end
- remove_instance_variable("@locals")
- if vals.length == 1
- vals.first
- else
- vals
- end
-end
-
-add_help(:load_init_file,
- "load_init_file(file) \
-Returns false if file doesn't exist, otherwise loads it. \
-File may reside in current working dir or in $HOME dir.")
-def load_init_file(file)
- if File.exist?(file)
- Snd.catch do load(file) end
- elsif File.exist?(f = ENV["HOME"] + "/" + file)
- Snd.catch do load(f) end
- else
- false
- end
-end
-
-let(-1) do |count|
- # see rotate_phase(func, snd, chn) in dsp.rb
- # it's necessary to produce a uniq method name
- make_proc_with_setter(:edit_list_proc_counter, lambda { count }, lambda { count += 1 })
-end
+require "clm"
module Examp
# (ext)snd.html examples made harder to break
@@ -3319,7 +362,9 @@ end")
def superimpose_ffts(snd, chn, y0, y1)
maxsync = Snd.sounds.map do |s| sync(s) end.max
if sync(snd) > 0 and
- snd == Snd.sounds.map do |s| sync(snd) == sync(s) ? s : maxsync + 1 end.min
+ snd == Snd.sounds.map do |s|
+ sync(snd) == sync(s) ? sound2integer(s) : (maxsync + 1)
+ end.min
ls = left_sample(snd, chn)
rs = right_sample(snd, chn)
pow2 = (log(rs - ls) / log(2)).ceil
@@ -4939,7 +1984,7 @@ region_play_list([[0.0, 0], [0.5, 1], [1.0, 2], [1.0, 0]])")
(data or []).each do |tm, rg|
tm = (1000.0 * tm).floor
if region?(rg)
- call_in(tm, lambda do | | play_region(rg) end)
+ call_in(tm, lambda do | | play(rg) end)
end
end
end