Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

2848 linhas
64KB

  1. # clm.rb -- Ruby extension
  2. # Author: Michael Scholz <mi-scholz@users.sourceforge.net>
  3. # Created: 09/10/14 23:02:57
  4. # Changed: 16/01/05 22:49:21
  5. # Ruby extensions:
  6. #
  7. # array?(obj) alias list?(obj)
  8. # hash?(obj)
  9. # string?(obj)
  10. # regexp?(obj)
  11. # symbol?(obj)
  12. # number?(obj)
  13. # integer?(obj)
  14. # float?(obj)
  15. # rational?(obj)
  16. # complex?(obj)
  17. # boolean?(obj)
  18. # proc?(obj)
  19. # thunk?(obj)
  20. # method?(obj)
  21. # func?(obj)
  22. # mus?(obj)
  23. # get_func_name(n)
  24. # assert_type(condition, obj, pos, msg)
  25. # identity(arg)
  26. # ignore(*rest)
  27. # with_silence(exception) do |old_verbose, old_debug| ... end
  28. #
  29. # provided?(feature)
  30. # provide(feature)
  31. # features(all)
  32. #
  33. # Backward compatibility aliases and constants (from sndXX.scm)
  34. #
  35. # enum(*names)
  36. #
  37. # class Object
  38. # null?
  39. # function?(obj)
  40. # snd_func(name, *rest, &body)
  41. # set_snd_func(name, val, *rest, &body)
  42. # snd_apropos(str_or_sym)
  43. #
  44. # NilClass(arg)
  45. # Fixnum(arg)
  46. #
  47. # class NilClass
  48. # each
  49. # apply(func, *rest, &body)
  50. # empty?
  51. # zero?
  52. # nonzero?
  53. # to_vct
  54. # to_vector
  55. # to_poly
  56. # +(other)
  57. # -(other)
  58. # *(other)
  59. #
  60. # backward compatibility methods:
  61. # String#to_sym, Symbol#to_sym
  62. # make_array(len, init, &body)
  63. # Array#insert
  64. # Float#step
  65. # Numeric#to_c
  66. # Range#step
  67. # Enumerable#each_index
  68. # Enumerable#zip
  69. #
  70. # class Array
  71. # to_pairs
  72. # each_pair do |x, y| ... end
  73. # to_string(len)
  74. # first=(val)
  75. # last=(val)
  76. # pick
  77. # rand
  78. # rand!
  79. # add(other)
  80. # add!(other)
  81. # subtract(other)
  82. # subtract!(other)
  83. # multiply(other)
  84. # multiply!(other)
  85. # offset(scl)
  86. # offset!(scl)
  87. # scale(scl)
  88. # scale!(scl)
  89. # to_vector
  90. # car
  91. # car=
  92. # cadr
  93. # cadr=
  94. # caddr
  95. # caddr=
  96. # cadddr
  97. # cadddr=
  98. # caddddr
  99. # caddddr=
  100. # cdr
  101. # step(n)
  102. # apply(func, *rest, &body)
  103. #
  104. # class Vec < Array
  105. # Vec[]
  106. # initialize(len, init, &body)
  107. # inspect
  108. # to_s
  109. # to_vector
  110. # +(other)
  111. # -(other)
  112. # *(other)
  113. #
  114. # Vec(obj)
  115. # make_vector(len, init, &body)
  116. # vector?(obj)
  117. # vector(*args)
  118. #
  119. # class String
  120. # to_vector
  121. # to_vct
  122. #
  123. # Vct(obj)
  124. # make_vct!(len, init) do |i| ... end
  125. #
  126. # class Vct
  127. # Vct[]
  128. # name
  129. # to_vct
  130. # to_vector
  131. # apply(func, *rest, &body)
  132. # +(other) handles self.offset (Numeric) and self.add (Array, Vec, Vct)
  133. # -(other) handles self.offset (Numeric) and self.subtract (Array, Vec, Vct)
  134. # *(other) handles self.scale (Numeric) and self.multiply (Array, Vec, Vct)
  135. # step(n)
  136. # [](idx, size)
  137. #
  138. # class Fixnum
  139. # +(other) handles other.offset on Vct, Array, and Vec
  140. # *(other) handles other.scale on Vct, Array, and Vec
  141. #
  142. # class Float
  143. # +(other) handles other.offset on Vct, Array, and Vec
  144. # *(other) handles other.scale on Vct, Array, and Vec
  145. #
  146. # mus_a0(gen)
  147. # set_mus_a0(gen, val)
  148. # mus_a1(gen)
  149. # set_mus_a1(gen, val)
  150. # mus_a2(gen)
  151. # set_mus_a2(gen, val)
  152. # mus_b1(gen)
  153. # set_mus_b1(gen, val)
  154. # mus_b2(gen)
  155. # set_mus_b2(gen, val)
  156. #
  157. # class Mus
  158. # run(arg1, arg2)
  159. # apply(*rest)
  160. # inspect
  161. # close
  162. # xcoeff=(index, val)
  163. # ycoeff=(index, val)
  164. # a0 a0=(val)
  165. # a1 a1=(val)
  166. # a2 a2=(val)
  167. # b1 b1=(val)
  168. # b2 b2=(val)
  169. #
  170. # class Musgen base class for generators written in Ruby
  171. # initialize
  172. # inspect
  173. # to_s
  174. # run(val1, val2)
  175. # apply(*rest)
  176. # eql?(other)
  177. # reset
  178. #
  179. # class Numeric
  180. # positive?
  181. # negative?
  182. #
  183. # class Integer
  184. # even?
  185. # odd?
  186. # prime?
  187. #
  188. # module Enumerable
  189. # map_with_index do |x, i| ... end
  190. # map_with_index! do |x, i| ... end
  191. # clm_cycle
  192. # clm_cycle=(val)
  193. #
  194. # as_one_edit_rb(*origin, &body)
  195. # map_channel_rb(beg, dur, snd, chn, edpos, edname, &body)
  196. # map_chan_rb(beg, dur, edpos, snd, chn, &body)
  197. #
  198. # module Info
  199. # description=(text)
  200. # description
  201. #
  202. # class Proc
  203. # to_method(name, klass)
  204. # to_str
  205. # to_body
  206. # source
  207. # source=
  208. #
  209. # make_proc2method(name, prc)
  210. # make_proc_with_setter(name, getter, setter)
  211. # make_proc_with_source(string, bind)
  212. # proc_source(prc) set_proc_source(prc, val)
  213. #
  214. # Multi-line input to the Snd listener and Emacs/inf-snd.el
  215. #
  216. # $emacs_eval_hook.call(line)
  217. # run_emacs_eval_hook(line)
  218. #
  219. # class Snd_eval
  220. # Snd_eval.count_level(line)
  221. #
  222. # class Snd_prompt
  223. # initialize(level)
  224. # inspect
  225. # update(level)
  226. # reset
  227. #
  228. # start_emacs_eval(file)
  229. # start_listener_eval(file)
  230. # stop_emacs_eval
  231. # stop_listener_eval
  232. #
  233. # Debugging resp. inspecting local variables
  234. #
  235. # debug_properties(name) set_debug_properties(name, val)
  236. # debug_property(key, name) set_debug_property(key, val, name)
  237. # debug_binding(name) set_debug_binding(bind, name)
  238. # display_all_variables(name)
  239. # each_variables(bind, &body)
  240. #
  241. # let(*rest) do |*rest| ... end
  242. #
  243. # Utilities:
  244. #
  245. # close_sound_extend(snd)
  246. # times2samples(start, dur)
  247. # random(n)
  248. # logn(r, b)
  249. # car(v), cadr(v), caddr(v), cdr(v)
  250. # warning(*args), die(*args), error(*args)
  251. # clm_message(*args), message(*args), debug(*args), debug_trace(*args)
  252. #
  253. # class Snd
  254. # Snd.add_sound_path(path)
  255. # Snd.open_from_path(fname)
  256. # Snd.find_from_path(fname)
  257. # Snd.fullname(fname)
  258. # Snd.load_path
  259. # Snd.message(*args)
  260. # Snd.display(*args)
  261. # Snd.warning(*args)
  262. # Snd.die(*args)
  263. # Snd.error(*args)
  264. # Snd.debug(*args)
  265. # Snd.debug_trace(*args)
  266. # Snd.sounds
  267. # Snd.regions
  268. # Snd.marks(snd, chn)
  269. # Snd.snd(snd)
  270. # Snd.chn(chn)
  271. # Snd.catch(tag, retval)
  272. # Snd.throw(tag, *rest)
  273. # Snd.raise(tag, *rest)
  274. #
  275. # snd_catch(tag, retval)
  276. # snd_throw(tag, *rest)
  277. # snd_raise(tag, *rest)
  278. #
  279. # gloop(*args) do |args| ... end
  280. # get_args(args, key, default)
  281. # get_shift_args(args, key, default)
  282. # get_class_or_key(args, klass, key, default)
  283. # optkey(args, *rest)
  284. # load_init_file(file)
  285. #
  286. # edit_list_proc_counter
  287. # set_edit_list_proc_counter
  288. def make_polar(r, theta)
  289. Complex(cos(theta) * r, sin(theta) * r)
  290. end
  291. def make_rectangular(re, im = 1.0)
  292. Complex(re, im)
  293. end
  294. def array?(obj)
  295. obj.kind_of?(Array)
  296. end
  297. alias list? array?
  298. def hash?(obj)
  299. obj.kind_of?(Hash)
  300. end
  301. def string?(obj)
  302. obj.kind_of?(String)
  303. end
  304. def regexp?(obj)
  305. obj.kind_of?(Regexp)
  306. end
  307. def symbol?(obj)
  308. obj.kind_of?(Symbol)
  309. end
  310. def number?(obj)
  311. obj.kind_of?(Numeric)
  312. end
  313. def integer?(obj)
  314. obj.kind_of?(Fixnum)
  315. end
  316. def float?(obj)
  317. obj.kind_of?(Float)
  318. end
  319. def rational?(obj)
  320. obj.kind_of?(Rational)
  321. end
  322. def complex?(obj)
  323. obj.kind_of?(Complex)
  324. end
  325. def boolean?(obj)
  326. obj.kind_of?(TrueClass) or obj.kind_of?(FalseClass)
  327. end
  328. def proc?(obj)
  329. obj.kind_of?(Proc)
  330. end
  331. def thunk?(obj)
  332. obj.kind_of?(Proc) and obj.arity.zero?
  333. end
  334. def method?(obj)
  335. obj.kind_of?(Method)
  336. end
  337. def func?(obj)
  338. obj.kind_of?(String) or obj.kind_of?(Symbol)
  339. end
  340. def mus?(obj)
  341. obj.kind_of?(Mus)
  342. end
  343. def binding?(obj)
  344. obj.kind_of?(Binding)
  345. end
  346. def get_func_name(n = 1)
  347. if ca = caller(n)[0].scan(/^.*:in `(.*)'/).first
  348. ca.first
  349. else
  350. "top_level"
  351. end
  352. end
  353. def assert_type(condition, obj, pos, msg)
  354. condition or Kernel.raise(TypeError,
  355. format("%s: wrong type arg %d, %p, wanted %s",
  356. get_func_name(2), pos, obj, msg))
  357. end
  358. def identity(arg)
  359. arg
  360. end
  361. def ignore(*rest)
  362. nil
  363. end
  364. unless defined? $LOADED_FEATURES
  365. alias $LOADED_FEATURES $"
  366. end
  367. def provided?(feature)
  368. $LOADED_FEATURES.map do |f|
  369. File.basename(f)
  370. end.member?(feature.to_s.tr("_", "-"))
  371. end
  372. def provide(feature)
  373. $LOADED_FEATURES.push(feature.to_s)
  374. end
  375. def features(all = nil)
  376. if all
  377. $LOADED_FEATURES.map do |f| File.basename(f) end
  378. else
  379. $LOADED_FEATURES.map do |f|
  380. next if f.include?("/") or f.include?(".")
  381. f
  382. end.compact
  383. end
  384. end
  385. # with_silence(exception) do |old_verbose, old_debug| ... end
  386. #
  387. # subpress debug messages (mostly on older Ruby versions)
  388. #
  389. # with_silence do $global_var ||= value end
  390. # with_silence(LoadError) do require("nonexistent.file") end
  391. def with_silence(exception = StandardError)
  392. old_verbose = $VERBOSE
  393. old_debug = $DEBUG
  394. $VERBOSE = false
  395. $DEBUG = false
  396. ret = if block_given?
  397. begin
  398. yield(old_verbose, old_debug)
  399. rescue exception
  400. false
  401. end
  402. else
  403. false
  404. end
  405. $VERBOSE = old_verbose
  406. $DEBUG = old_debug
  407. ret
  408. end
  409. # ruby19 moved complex.rb and rational.rb to C
  410. # (See ruby/Changelog Sun Mar 16 08:51:41 2008.)
  411. if defined? Complex
  412. require "cmath"
  413. include CMath
  414. else
  415. with_silence do
  416. # lib/complex.rb is deprecated
  417. require "complex"
  418. end
  419. include Math
  420. end
  421. unless defined? Rational
  422. with_silence do
  423. # lib/rational.rb is deprecated
  424. require "rational"
  425. end
  426. end
  427. unless provided?(:sndlib)
  428. with_silence do
  429. # warning: method redefined; discarding old rand
  430. require "sndlib"
  431. end
  432. end
  433. TWO_PI = PI * 2.0 unless defined? TWO_PI
  434. HALF_PI = PI * 0.5 unless defined? HALF_PI
  435. #
  436. # Backward compatibility aliases and constants (from sndXX.scm)
  437. #
  438. # alias new old
  439. if provided? :snd
  440. alias save_options save_state
  441. alias delete_samples_with_origin delete_samples
  442. alias default_output_type default_output_header_type
  443. alias default_output_format default_output_sample_type
  444. alias mus_audio_set_oss_buffers mus_oss_set_buffers
  445. unless defined? mus_file_data_clipped
  446. alias mus_file_data_clipped mus_clipping
  447. alias set_mus_file_data_clipped set_mus_clipping
  448. end
  449. alias mus_data_clipped mus_clipping
  450. alias set_mus_data_clipped set_mus_clipping
  451. alias dac_is_running playing
  452. # backwards compatibility for snd 8
  453. alias make_ppolar make_two_pole
  454. alias make_zpolar make_two_zero
  455. alias make_average make_moving_average
  456. alias average moving_average
  457. alias average? moving_average?
  458. # snd10.scm
  459. def make_sum_of_sines(*args)
  460. sines, frequency, initial_phase = nil
  461. optkey(args, binding,
  462. [:sines, 1],
  463. [:frequency, 0.0],
  464. [:initial_phase, 0.0])
  465. gen = make_nsin(:frequency, frequency, :n, sines)
  466. gen.phase = initial_phase
  467. gen
  468. end
  469. alias sum_of_sines nsin
  470. alias sum_of_sines? nsin?
  471. def make_sum_of_cosines(*args)
  472. cosines, frequency, initial_phase = nil
  473. optkey(args, binding,
  474. [:cosines, 1],
  475. [:frequency, 0.0],
  476. [:initial_phase, 0.0])
  477. gen = make_ncos(:frequency, frequency, :n, cosines)
  478. gen.phase = initial_phase
  479. gen
  480. end
  481. alias sum_of_cosines ncos
  482. alias sum_of_cosines? ncos?
  483. def make_sine_summation(*args)
  484. frequency, initial_phase, n, a, ratio = nil
  485. optkey(args, binding,
  486. [:frequency, 0.0],
  487. [:initial_phase, 0.0],
  488. [:n, 1],
  489. [:a, 0.5],
  490. [:ratio, 1.0])
  491. gen = make_nrxysin(:frequency, frequency, :ratio, ratio, :n, n, :r, a)
  492. gen.phase = initial_phase
  493. gen
  494. end
  495. alias sine_summation nrxysin
  496. alias sine_summation? nrxysin?
  497. # snd13.scm
  498. def clm_print(fmt, *args)
  499. snd_print(format(fmt, *args))
  500. end unless defined? clm_print
  501. end
  502. # enum("foo", :bar, "FOO_BAR")
  503. # produces three constants
  504. # Foo == 0
  505. # Bar == 1
  506. # FOO_BAR == 2
  507. if ?a.kind_of?(String)
  508. def enum(*names)
  509. names.map_with_index do |name, i|
  510. const_name = name.to_s
  511. const_name[0] = const_name[0].capitalize
  512. Object.const_set(const_name, i)
  513. const_name
  514. end
  515. end
  516. else
  517. def enum(*names)
  518. cap_alpha = ?A.kind_of?(String) ? ?A.sum : ?A
  519. lit_alpha = ?a.kind_of?(String) ? ?a.sum : ?a
  520. letter_diff = cap_alpha - lit_alpha
  521. names.map_with_index do |name, i|
  522. const_name = name.to_s
  523. if const_name[0].between?(?a, ?z)
  524. const_name[0] += letter_diff
  525. end
  526. Object.const_set(const_name, i)
  527. const_name
  528. end
  529. end
  530. end
  531. class Object
  532. def null?
  533. self.nil? or
  534. (self.respond_to?(:zero?) and self.zero?) or
  535. (self.respond_to?(:empty?) and self.empty?) or
  536. (self.respond_to?(:length) and self.length.zero?)
  537. end
  538. def function?(obj)
  539. func?(obj) and Snd.catch(:all, false) do self.method(obj) end.first
  540. rescue
  541. false
  542. end
  543. # Float(nil) ==> 0.0 like Integer(nil) ==> 0
  544. alias old_Float Float
  545. def new_Float(numb)
  546. if numb.kind_of?(NilClass)
  547. 0.0
  548. else
  549. old_Float(numb)
  550. end
  551. end
  552. alias Float new_Float
  553. def snd_func(name, *rest, &body)
  554. send(name.to_s, *rest, &body)
  555. end
  556. def set_snd_func(name, val, *rest, &body)
  557. send(format("set_%s", name.to_s), val, *rest, &body)
  558. end
  559. # snd_apropos(str_or_sym)
  560. # if `str_or_sym' is a symbol, returns snd_help result,
  561. # if `str_or_sym' is a string or regexp it looks in
  562. # self.public_methods,
  563. # self.protected_methods,
  564. # self.private_methods,
  565. # Object.constants, and
  566. # Kernel.global_variables and returns an array of strings or nil.
  567. #
  568. # [].snd_apropos(/^apply/) ==> ["apply", "apply_controls"]
  569. # vct(0).snd_apropos("subseq") ==> ["subseq", "vct_subseq"]
  570. # snd_apropos(/^mus_sound/) ==> ["mus_sound_...", ...]
  571. def snd_apropos(str_or_sym)
  572. case str_or_sym
  573. when Symbol
  574. snd_help(str_or_sym)
  575. when String, Regexp
  576. res = []
  577. [self.public_methods,
  578. self.protected_methods,
  579. self.private_methods,
  580. Object.constants,
  581. Kernel.global_variables].each do |m| res += m.grep(/#{str_or_sym}/) end
  582. res
  583. else
  584. nil
  585. end
  586. end
  587. end
  588. def NilClass(arg)
  589. nil
  590. end
  591. alias Fixnum Integer
  592. class NilClass
  593. def each
  594. nil
  595. end
  596. def apply(func, *rest, &body)
  597. nil
  598. end
  599. def empty?
  600. true
  601. end
  602. # Integer(nil) ==> 0
  603. def zero?
  604. true
  605. end
  606. def nonzero?
  607. false
  608. end
  609. def to_vct
  610. vector2vct([])
  611. end
  612. def to_vector
  613. vector()
  614. end
  615. def to_poly
  616. poly()
  617. end
  618. def +(other)
  619. other
  620. end
  621. def -(other)
  622. other
  623. end
  624. def *(other)
  625. snd_func(other.class.name, nil)
  626. end
  627. end
  628. # If $DEBUG = true, on older Ruby versions warnings occur about
  629. # missing NilClass#to_str and Symbol#to_str
  630. if $DEBUG and RUBY_VERSION < "1.8.0"
  631. class Object
  632. def method_missing(id, *args)
  633. if id == :to_str
  634. self.class.class_eval do
  635. define_method(id, lambda do | | self.to_s end)
  636. end
  637. id.id2name
  638. else
  639. Kernel.raise(NameError,
  640. format("[version %s] undefined method `%s'",
  641. RUBY_VERSION, id.id2name))
  642. end
  643. end
  644. end
  645. end
  646. class String
  647. def to_sym
  648. self.intern
  649. end unless defined? "a".to_sym
  650. end
  651. class Symbol
  652. def to_sym
  653. self
  654. end unless defined? :a.to_sym
  655. end
  656. alias object_id __id__ unless defined? object_id
  657. # Provides descriptions of instances of classes, see nb.rb,
  658. # xm-enved.rb, etc.
  659. #
  660. # m = lambda do |*args| puts args end
  661. # m.info = "my description"
  662. # puts m.info
  663. module Info
  664. def description=(val)
  665. @description = val.to_s
  666. end
  667. alias info= description=
  668. def description
  669. if defined?(@description) and
  670. string?(@description) and (not @description.empty?)
  671. @description
  672. else
  673. "no description available"
  674. end
  675. end
  676. alias info description
  677. end
  678. unless defined? snd_help
  679. alias snd_help get_help
  680. end
  681. $array_print_length = 10
  682. def print_length
  683. $array_print_length
  684. end unless defined? print_length
  685. def set_print_length(val)
  686. $array_print_length = val
  687. end unless defined? set_print_length
  688. module Enumerable
  689. def map_with_index
  690. i = -1
  691. self.map do |x| yield(x, i += 1) end
  692. end
  693. def map_with_index!
  694. i = -1
  695. self.map! do |x| yield(x, i += 1) end
  696. end
  697. def clm_cycle
  698. unless defined? @clm_cycle_index then @clm_cycle_index = 0 end
  699. val = self[@clm_cycle_index % self.length]
  700. @clm_cycle_index += 1
  701. if @clm_cycle_index == self.length then @clm_cycle_index = 0 end
  702. val
  703. end
  704. def clm_cycle=(val)
  705. unless defined? @clm_cycle_index then @clm_cycle_index = 0 end
  706. self[@clm_cycle_index % self.length] = val
  707. @clm_cycle_index += 1
  708. if @clm_cycle_index == self.length then @clm_cycle_index = 0 end
  709. val
  710. end
  711. attr_accessor :clm_cycle_index
  712. # backward compatibility methods
  713. def each_index
  714. self.each_with_index do |val, i| yield(i) end
  715. end unless vct(0).respond_to?(:each_index)
  716. # Enumerable#zip, new in ruby core since 19-Nov-2002.
  717. # a = [4, 5, 6]
  718. # b = [7, 8, 9]
  719. # [1, 2, 3].zip(a, b) ==> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
  720. # [1, 2].zip(a, b) ==> [[1, 4, 7], [2, 5, 8]]
  721. # a.zip([1, 2],[8]) ==> [[4, 1, 8], [5, 2, nil], [6, nil, nil]]
  722. def clm_zip(*objs)
  723. args = objs.map do |obj| obj.to_a end
  724. res = self.to_a
  725. res.each_with_index do |val, i|
  726. ary = [val]
  727. args.each do |obj| ary.push(obj[i]) end
  728. if block_given?
  729. yield(*ary)
  730. else
  731. res[i] = ary
  732. end
  733. end
  734. res
  735. end
  736. alias zip clm_zip unless [].respond_to?(:zip)
  737. end
  738. # Older Ruby versions lack Array.new(10) do |i| ... end
  739. # make_array
  740. # make_array(10)
  741. # make_array(10, 1.0)
  742. # make_array(10) do |i| ... end
  743. def make_array(len = 0, init = nil)
  744. if len >= 0
  745. if block_given?
  746. Array.new(len, init).map_with_index do |x, i| yield(i) end
  747. else
  748. Array.new(len, init)
  749. end
  750. else
  751. Kernel.raise(TypeError, format("array length < 0 (%p)?", len))
  752. end
  753. end
  754. class Array
  755. def insert(pos, *args)
  756. unless args.empty?
  757. if pos < 0
  758. pos = self.length - (pos.abs - 1)
  759. end
  760. tmp = self.dup
  761. self[pos, args.length] = args
  762. self[pos + args.length..-1] = tmp[pos..-1]
  763. end
  764. self
  765. end unless defined? [].insert
  766. # [0.0, 0.0, 0.5, 0.2, 1.0, 1.0].to_pairs
  767. # ==> [[0.0, 0.0], [0.5, 0.2], [1.0, 1.0]]
  768. def to_pairs
  769. ary = []
  770. self.step(2) do |a, b| ary.push([a, b]) end
  771. ary
  772. end
  773. # [0.0, 0.0, 0.5, 0.2, 1.0, 1.0].each_pair do |x, y|
  774. # print x, " ", y, "\n"
  775. # end ==> 0.0 0.0
  776. # 0.5 0.2
  777. # 1.0 1.0
  778. def each_pair
  779. ary = []
  780. self.step(2) do |a, b| ary.push(yield(a, b)) end
  781. ary
  782. end
  783. # prints flat float array more prettily
  784. def to_string(len = print_length)
  785. ary = self.flatten
  786. str = "["
  787. ary.each_with_index do |val, i|
  788. if i < len
  789. str = str + "%1.3f, " % val.to_f
  790. else
  791. break
  792. end
  793. end
  794. if ary.length > len
  795. str += "..."
  796. else
  797. str.chop!.chop!
  798. end
  799. str += "]"
  800. end
  801. alias old_to_s to_s
  802. alias to_s inspect
  803. def first=(val)
  804. self[0] = val
  805. end
  806. def last=(val)
  807. self[-1] = val
  808. end
  809. # ary.pick ==> random value
  810. # ary.pick(3) ==> [x, y, z]
  811. # ary.pick(true) ==> whole ary randomized
  812. def array_pick(n = 1)
  813. n = self.length if n == true
  814. if n == 1
  815. self[kernel_rand(self.length)]
  816. else
  817. (0...n).map do |i| self[kernel_rand(self.length)] end
  818. end
  819. end
  820. alias pick array_pick
  821. def array_rand
  822. tmp = self.dup
  823. tmp.each_index do |i|
  824. r = kernel_rand(tmp.length)
  825. tmp[r], tmp[i] = tmp[i], tmp[r]
  826. end
  827. tmp
  828. end
  829. alias rand array_rand
  830. def array_rand!
  831. self.each_index do |i|
  832. r = kernel_rand(self.length)
  833. self[r], self[i] = self[i], self[r]
  834. end
  835. self
  836. end
  837. alias rand! array_rand!
  838. def add(other)
  839. new_ary = self.dup
  840. [self.length, other.length].min.times do |i| new_ary[i] += other[i] end
  841. new_ary
  842. end
  843. def add!(other)
  844. [self.length, other.length].min.times do |i| self[i] += other[i] end
  845. self
  846. end
  847. def subtract(other)
  848. new_ary = self.dup
  849. [self.length, other.length].min.times do |i| new_ary[i] -= other[i] end
  850. new_ary
  851. end
  852. def subtract!(other)
  853. [self.length, other.length].min.times do |i| self[i] -= other[i] end
  854. self
  855. end
  856. def multiply(other)
  857. new_ary = self.dup
  858. [self.length, other.length].min.times do |i| new_ary[i] *= other[i] end
  859. new_ary
  860. end
  861. def multiply!(other)
  862. [self.length, other.length].min.times do |i| self[i] *= other[i] end
  863. self
  864. end
  865. def offset(scl)
  866. scl = Float(scl)
  867. self.class.new(self.length) do |i| self[i] + scl end
  868. end
  869. def offset!(scl)
  870. scl = Float(scl)
  871. self.map! do |val| val += scl end
  872. end
  873. def scale(scl)
  874. scl = Float(scl)
  875. self.class.new(self.length) do |i| self[i] * scl end
  876. end
  877. def scale!(scl)
  878. scl = Float(scl)
  879. self.map! do |val| val *= scl end
  880. end
  881. def to_vector
  882. Vec.new(self.length) do |i| Float(self[i]) end
  883. end
  884. def car
  885. self[0]
  886. end
  887. def car=(val)
  888. self[0] = val
  889. end
  890. def cadr
  891. self[1]
  892. end
  893. def cadr=(val)
  894. self[1] = val
  895. end
  896. def caddr
  897. self[2]
  898. end
  899. def caddr=(val)
  900. self[2] = val
  901. end
  902. def cadddr
  903. self[3]
  904. end
  905. def cadddr=(val)
  906. self[3] = val
  907. end
  908. def caddddr
  909. self[4]
  910. end
  911. def caddddr=(val)
  912. self[4] = val
  913. end
  914. def cdr
  915. self[1..-1]
  916. end
  917. def step(n = 1)
  918. 0.step(self.length - n, n) do |i| yield(*self[i, n]) end
  919. self
  920. end
  921. add_help(:apply,
  922. "Array#apply([:func,] *rest, &body) \
  923. Applies function or procedure with possible rest args \
  924. to each element of Array or subclasses of Array.
  925. [0, 1, 2].apply(\"a: %d\\n\") do |fmt, a| printf(fmt, a) end
  926. [0, 1, 2].apply(:printf, \"a: %d\\n\")
  927. both produce
  928. a: 0
  929. a: 1
  930. a: 2
  931. [1, 2, 3, 4].apply(:+) # ==> 10
  932. %w(snd sndplay with_sound).apply(:length) # ==> [3, 7, 10]
  933. [[1, 2, 3, 4], [1, 2, 3], [1, 2]].apply(:max) # ==> [4, 3, 2]
  934. [vct(0.1, 0.2, 0.3), vct(-0.1, -0.2, -0.3)].apply(:peak) # ==> [0.3, 0.3]
  935. sounds.apply(:map) do |s| puts s end
  936. sounds.apply(:close_sound)")
  937. def apply(func, *rest, &body)
  938. if block_given? and (not symbol?(func))
  939. rest.unshift(func)
  940. self.map do |item| body.call(*rest + [item]) end
  941. else
  942. case func
  943. when Proc, Method
  944. self.map do |item| func.call(*rest + [item]) end
  945. when Symbol, String
  946. meths = self.methods
  947. if body and (meths.member?(func.to_s) or meths.member?(func.to_sym))
  948. # map, each, ...
  949. self.send(func, *rest, &body)
  950. else
  951. receiver = self.compact.first
  952. meths = receiver.methods
  953. if receiver and
  954. (meths.member?(func.to_s) or meths.member?(func.to_sym))
  955. # methods
  956. case func.to_sym
  957. when :+, :-, :*
  958. res = receiver
  959. self[1..-1].compact.map do |item|
  960. res = res.send(func, *rest + [item])
  961. end
  962. res
  963. else
  964. len = rest.length + ((array?(receiver) and receiver.length) or 1)
  965. if receiver.method(func).arity.abs == len
  966. # remove_file (String(WS) in ws.rb)
  967. self.map do |item| send(func, *rest + [item]) end
  968. else
  969. # length, max, min, ...
  970. self.map do |item| item.send(func, *rest) end
  971. end
  972. end
  973. else
  974. # functions
  975. self.map do |item| send(func, *rest + [item]) end
  976. end
  977. end
  978. end
  979. end
  980. end
  981. # original operands +, -, and * can now handle nil and numberic
  982. # (offset, multiply)
  983. #
  984. # [].+(ary) concatenate arrays
  985. # [].+(number) [].add(number)
  986. unless defined? [].ary_plus
  987. alias old_ary_plus +
  988. def ary_plus(other)
  989. case other
  990. when Numeric
  991. self.offset(other)
  992. when NilClass
  993. self
  994. else
  995. self.old_ary_plus(other)
  996. end
  997. end
  998. alias + ary_plus
  999. end
  1000. # [].-(ary) intersection
  1001. # [1, 2, 3, 4] - [2, 3] ==> [1, 4]
  1002. # [] - number [].offset
  1003. unless defined? [].ary_minus
  1004. alias old_ary_minus -
  1005. def ary_minus(other)
  1006. case other
  1007. when Numeric
  1008. self.offset(-other)
  1009. when NilClass
  1010. self
  1011. else
  1012. self.old_ary_minus(other)
  1013. end
  1014. end
  1015. alias - ary_minus
  1016. end
  1017. # [].*(n) repetition or [].join(n)
  1018. # [5] * 3 ==> [5, 5, 5]
  1019. # ["foo", "bar"] * "-" ==> "foo-bar"
  1020. unless defined? [].ary_times
  1021. alias old_ary_times *
  1022. def ary_times(other)
  1023. case other
  1024. when NilClass
  1025. nil.to_a
  1026. else
  1027. self.old_ary_times(other)
  1028. end
  1029. end
  1030. alias * ary_times
  1031. end
  1032. end
  1033. # name Vector is in use (lib/ruby/1.9/matrix.rb)
  1034. class Vec < Array
  1035. def self.[](*ary)
  1036. self.new(ary.length) do |i| ary[i] end
  1037. end
  1038. def initialize(len, init = 0.0, &body)
  1039. @name = "vector"
  1040. if len >= 0
  1041. if block_given?
  1042. super(len, &body)
  1043. else
  1044. super(len, init)
  1045. end
  1046. else
  1047. Kernel.raise(TypeError, format("array length < 0 (%p)?", len))
  1048. end
  1049. if test = self.detect do |x| (not number?(x)) end
  1050. Kernel.raise(TypeError,
  1051. format("only numeric elements (%p)?", test))
  1052. end
  1053. end
  1054. def inspect
  1055. str = "%s(" % @name
  1056. self.each do |val| str = str + "%s, " % val end
  1057. if self.length > 0 then str.chop!.chop! end
  1058. str += ")"
  1059. str
  1060. end
  1061. def to_s
  1062. if self.length > 0
  1063. vals = ":"
  1064. self.map do |val| vals = vals + " %s" % val end
  1065. else
  1066. vals = ""
  1067. end
  1068. format("#<%s[%d]%s>", self.class, self.length, vals)
  1069. end
  1070. def +(other)
  1071. case other
  1072. when Numeric
  1073. self.offset(other).to_vector
  1074. when Array, Vec, Vct
  1075. self.add(other.to_vector)
  1076. when NilClass
  1077. self
  1078. end
  1079. end
  1080. def -(other)
  1081. case other
  1082. when Numeric
  1083. self.offset(-other).to_vector
  1084. when Array, Vec, Vct
  1085. self.subtract(other.to_vector)
  1086. when NilClass
  1087. self
  1088. end
  1089. end
  1090. def *(other)
  1091. case other
  1092. when Numeric
  1093. self.scale(other).to_vector
  1094. when Array, Vec, Vct
  1095. self.multiply(other.to_vector)
  1096. when NilClass
  1097. nil.to_vector
  1098. end
  1099. end
  1100. end
  1101. def Vec(obj)
  1102. if obj.nil? then obj = [] end
  1103. assert_type(obj.respond_to?(:to_vector), obj, 0,
  1104. "an object containing method \
  1105. 'to_vector' (Vct, String, Array and subclasses)")
  1106. obj.to_vector
  1107. end
  1108. def make_vector(len, init = 0.0, &body)
  1109. Vec.new(len, init, &body)
  1110. end
  1111. def vector?(obj)
  1112. obj.kind_of?(Vec)
  1113. end
  1114. def vector(*args)
  1115. args.to_vector
  1116. end
  1117. class String
  1118. def to_vector
  1119. if self.scan(/^vector\([-+,.)\d\s]+/).null?
  1120. nil
  1121. else
  1122. eval(self)
  1123. end
  1124. end
  1125. def to_vct
  1126. if self.scan(/^vct\([-+,.)\d\s]+/).null?
  1127. nil
  1128. else
  1129. eval(self)
  1130. end
  1131. end
  1132. end
  1133. def Vct(obj)
  1134. if obj.nil? then obj = [] end
  1135. assert_type(obj.respond_to?(:to_vct), obj, 0,
  1136. "an object containing method \
  1137. 'to_vct' (Vct, String, Array and subclasses)")
  1138. obj.to_vct
  1139. end
  1140. def make_vct!(len, init = 0.0, &body)
  1141. if block_given?
  1142. Vct.new(len, &body)
  1143. else
  1144. Vct.new(len, init)
  1145. end
  1146. end
  1147. class Vct
  1148. def self.[](*ary)
  1149. self.new(ary.length) do |i| ary[i] end
  1150. end
  1151. def name
  1152. self.class.to_s.downcase
  1153. end
  1154. def to_vct
  1155. self
  1156. end
  1157. def to_vector
  1158. Vec.new(self.length) do |i| self[i] end
  1159. end
  1160. def apply(*rest, &body)
  1161. self.to_a.apply(*rest, &body)
  1162. end
  1163. def +(other)
  1164. case other
  1165. when Numeric
  1166. self.offset(other)
  1167. when Array, Vec, Vct
  1168. self.add(other.to_vct)
  1169. when NilClass
  1170. self
  1171. end
  1172. end
  1173. def -(other)
  1174. case other
  1175. when Numeric
  1176. self.offset(-other)
  1177. when Array, Vec, Vct
  1178. self.subtract(other.to_vct)
  1179. when NilClass
  1180. self
  1181. end
  1182. end
  1183. def *(other)
  1184. case other
  1185. when Numeric
  1186. self.scale(other)
  1187. when Array, Vec, Vct
  1188. self.multiply(other.to_vct)
  1189. when NilClass
  1190. nil.to_vct
  1191. end
  1192. end
  1193. def step(n = 1, &body)
  1194. self.to_a.step(n, &body)
  1195. end
  1196. # v = vct(0, 1, 2, 3, 4)
  1197. # v[2..4] ==> vct(2.000, 3.000, 4.000)
  1198. # v[2...4] ==> vct(2.000, 3.000)
  1199. # v[3, 4] ==> vct(3.000, 4.000)
  1200. # v[-1] ==> 4.0
  1201. def vct_ref_extend(idx, size = nil)
  1202. case idx
  1203. when Fixnum
  1204. if idx < 0 then idx += self.length end
  1205. if idx < 0 then Snd.raise(:out_of_range, "index < 0", idx) end
  1206. if integer?(size)
  1207. size += idx - 1
  1208. if size >= self.length then size = self.length - 1 end
  1209. if size.between?(0, self.length - 1) and size >= idx
  1210. self.subseq(idx, size)
  1211. else
  1212. nil.to_vct # i.e. false
  1213. end
  1214. else
  1215. vct_ref(self, idx)
  1216. end
  1217. when Range
  1218. beg = idx.first
  1219. len = idx.last
  1220. if beg < 0 then beg += self.length end
  1221. if len < 0 then len += self.length end
  1222. if len >= self.length then len = self.length - 1 end
  1223. # exclude_end?: (1..2) ==> false
  1224. # (1...2) ==> true
  1225. if idx.exclude_end? then len -= 1 end
  1226. if beg.between?(0, self.length - 1) and len >= beg
  1227. self.subseq(beg, len)
  1228. else
  1229. nil.to_vct # i.e. false
  1230. end
  1231. end
  1232. end
  1233. # alias [] vct_ref_extend
  1234. # This is required since Ruby 1.9.
  1235. alias zip clm_zip if [].respond_to?(:zip)
  1236. end
  1237. class Fixnum
  1238. # no reloading (load "clm.rb")
  1239. unless defined? 0.new_int_plus
  1240. alias int_plus +
  1241. def new_int_plus(other)
  1242. case other
  1243. when Vct, Array, Vec
  1244. other.offset(Float(self))
  1245. when NilClass
  1246. self
  1247. else
  1248. self.int_plus(other)
  1249. end
  1250. end
  1251. alias + new_int_plus
  1252. end
  1253. unless defined? 0.new_int_times
  1254. alias int_times *
  1255. def new_int_times(other)
  1256. case other
  1257. when Vct, Array, Vec
  1258. other.scale(self)
  1259. when NilClass
  1260. 0
  1261. else
  1262. self.int_times(other)
  1263. end
  1264. end
  1265. alias * new_int_times
  1266. end
  1267. end
  1268. class Float
  1269. # no reloading (load "clm.rb")
  1270. unless defined? 0.0.new_float_plus
  1271. alias float_plus +
  1272. def new_float_plus(other)
  1273. case other
  1274. when Vct, Array, Vec
  1275. other.offset(self)
  1276. when NilClass
  1277. self
  1278. else
  1279. self.float_plus(other)
  1280. end
  1281. end
  1282. alias + new_float_plus
  1283. end
  1284. unless defined? 0.0.new_float_times
  1285. alias float_times *
  1286. def new_float_times(other)
  1287. case other
  1288. when Vct, Array, Vec
  1289. other.scale(self)
  1290. when NilClass
  1291. 0.0
  1292. else
  1293. self.float_times(other)
  1294. end
  1295. end
  1296. alias * new_float_times
  1297. end
  1298. unless defined? 0.0.imag
  1299. def imag
  1300. 0.0
  1301. end
  1302. alias image imag
  1303. end
  1304. end
  1305. def mus_a0(gen)
  1306. mus_xcoeff(gen, 0)
  1307. end
  1308. def set_mus_a0(gen, val)
  1309. set_mus_xcoeff(gen, 0, val)
  1310. end
  1311. def mus_a1(gen)
  1312. mus_xcoeff(gen, 1)
  1313. end
  1314. def set_mus_a1(gen, val)
  1315. set_mus_xcoeff(gen, 1, val)
  1316. end
  1317. def mus_a2(gen)
  1318. mus_xcoeff(gen, 2)
  1319. end
  1320. def set_mus_a2(gen, val)
  1321. set_mus_xcoeff(gen, 2, val)
  1322. end
  1323. def mus_b1(gen)
  1324. mus_ycoeff(gen, 1)
  1325. end
  1326. def set_mus_b1(gen, val)
  1327. set_mus_ycoeff(gen, 1, val)
  1328. end
  1329. def mus_b2(gen)
  1330. mus_ycoeff(gen, 2)
  1331. end
  1332. def set_mus_b2(gen, val)
  1333. set_mus_ycoeff(gen, 2, val)
  1334. end
  1335. class Mus
  1336. # clm_gen.call(a1, a2) requires 2 arguments but clm_gen.run([a1, [a2]])
  1337. # 0, 1 or 2.
  1338. #
  1339. # clm_gen.run([arg1, [arg2]])
  1340. def run(arg1 = 0.0, arg2 = 0.0)
  1341. mus_run(self, arg1, arg2)
  1342. end
  1343. def apply(*rest)
  1344. mus_apply(self, *rest)
  1345. end
  1346. alias mus_inspect inspect
  1347. def inspect
  1348. "#<" + mus_describe(self) + ">"
  1349. end
  1350. def close
  1351. mus_close(self)
  1352. end
  1353. # gen.xcoeff = 0, 0.4
  1354. # set_mus_xcoeff(gen, index, val)
  1355. def xcoeff=(args)
  1356. set_mus_xcoeff(self, *args.flatten[0, 2])
  1357. end
  1358. # gen.ycoeff = 0, 0.4
  1359. # set_mus_ycoeff(gen, index, val)
  1360. def ycoeff=(args)
  1361. set_mus_ycoeff(self, *args.flatten[0, 2])
  1362. end
  1363. def a0
  1364. mus_xcoeff(self, 0)
  1365. end
  1366. def a0=(val)
  1367. set_mus_xcoeff(self, 0, val)
  1368. end
  1369. def a1
  1370. mus_xcoeff(self, 1)
  1371. end
  1372. def a1=(val)
  1373. set_mus_xcoeff(self, 1, val)
  1374. end
  1375. def a2
  1376. mus_xcoeff(self, 2)
  1377. end
  1378. def a2=(val)
  1379. set_mus_xcoeff(self, 2, val)
  1380. end
  1381. def b1
  1382. mus_ycoeff(self, 1)
  1383. end
  1384. def b1=(val)
  1385. set_mus_ycoeff(self, 1, val)
  1386. end
  1387. def b2
  1388. mus_ycoeff(self, 2)
  1389. end
  1390. def b2=(val)
  1391. set_mus_ycoeff(self, 2, val)
  1392. end
  1393. end
  1394. # base class for generators written in Ruby
  1395. class Musgen
  1396. def initialize
  1397. @frequency = $clm_default_frequency
  1398. @phase = 0.0
  1399. @scaler = 1.0
  1400. @length = 0
  1401. @data = nil
  1402. @increment = 0
  1403. @interp_type = -1
  1404. @file_name = ""
  1405. end
  1406. attr_accessor :frequency
  1407. attr_accessor :phase
  1408. attr_accessor :scaler
  1409. attr_accessor :increment
  1410. attr_reader :length
  1411. attr_reader :data
  1412. attr_reader :interp_type
  1413. attr_reader :file_name
  1414. def inspect
  1415. format("%s.new()", self.class)
  1416. end
  1417. def to_s
  1418. format("#<%s>", self.class)
  1419. end
  1420. def run(val1 = 0.0, val2 = 0.0)
  1421. self.run_func(val1, val2)
  1422. end
  1423. alias call run
  1424. def apply(*rest)
  1425. self.run_func(*rest)
  1426. end
  1427. def eql?(other)
  1428. self == other
  1429. end
  1430. def reset
  1431. @frequency = $clm_default_frequency
  1432. @phase = 0.0
  1433. @scaler = 1.0
  1434. @increment = 0
  1435. self
  1436. end
  1437. end
  1438. class Numeric
  1439. def positive?
  1440. self > 0
  1441. end unless defined? 1.positive?
  1442. def negative?
  1443. self < 0
  1444. end unless defined? 1.negative?
  1445. # According to Ruby's ChangeLog-2.0.0:
  1446. # Wed Nov 21 21:53:29 2012 Tadayoshi Funaba <tadf@dotrb.org>
  1447. # * complex.c (nucomp_to_c): added.
  1448. def to_c
  1449. Complex(self)
  1450. end unless defined? 1.to_c
  1451. end
  1452. class Integer
  1453. def even?
  1454. self.modulo(2) == 0
  1455. end unless defined? 1.even?
  1456. def odd?
  1457. self.modulo(2) != 0
  1458. end unless defined? 1.odd?
  1459. def prime?
  1460. (self == 2) or
  1461. (self.odd? and
  1462. 3.step(sqrt(self), 2) do |i| return false if self.modulo(i) == 0 end)
  1463. end
  1464. end
  1465. class Float
  1466. # step accepts floats as arguments (implemented in newer versions)
  1467. def step(upto, step)
  1468. counter = self
  1469. while counter < upto
  1470. yield(counter)
  1471. counter += step
  1472. end
  1473. counter
  1474. end unless 1.1.respond_to?(:step)
  1475. end
  1476. class Range
  1477. def step(n = 1, &body)
  1478. self.to_a.step(n, &body)
  1479. end unless defined? Range.new(0, 1).step
  1480. end
  1481. def as_one_edit_rb(*origin, &body)
  1482. # ruby compatibility:
  1483. # ruby pre 1.9: lambda do end.arity != lambda do | | end.arity
  1484. # ruby 1.9: they are even (0)
  1485. as_one_edit(lambda do | | body.call end, origin.empty? ? "" : format(*origin))
  1486. end
  1487. def map_channel_rb(beg = 0, dur = false,
  1488. snd = false, chn = false,
  1489. edpos = false, edname = false, &func)
  1490. map_channel(func, beg, dur, snd, chn, edpos, edname)
  1491. end
  1492. add_help(:map_chan_rb,
  1493. "map_chan(func, start=0, end=false, edname=false, \
  1494. snd=false, chn=false, edpos=false) \
  1495. Applies FUNC to samples in the specified channel. \
  1496. It is the old (\"irregular\") version of map_channel.")
  1497. def map_chan_rb(beg = 0, dur = false, ednam = false,
  1498. snd = false, chn = false, edpos = false, &func)
  1499. map_chan(func, beg, dur, ednam, snd, chn, edpos)
  1500. end
  1501. class Proc
  1502. include Info
  1503. alias run call
  1504. add_help(:to_method,
  1505. "Proc#to_method(name, klass=Object) \
  1506. Converts a Proc to a Method 'name' in the given class, default Object. \
  1507. NAME can be a string or a symbol.
  1508. m = lambda do |*args| p args end
  1509. m.to_method(:func)
  1510. func(1, 2, 3) ==> [1, 2, 3]
  1511. lambda do |x| p x end.to_method(:foo); foo(\"text1\") ==> \"text1\"
  1512. lambda do |x| p x end.to_method(\"bar\"); bar(\"text2\") ==> \"text2\"")
  1513. def to_method(name, klass = Object)
  1514. name = case name
  1515. when String
  1516. name.intern
  1517. when Symbol
  1518. name
  1519. end
  1520. body = self
  1521. klass.class_eval do define_method(name, body) end
  1522. end
  1523. # Important:
  1524. # The following works only with newer ruby versions (I assume >=
  1525. # 1.8.x). Proc#inspect must return #<Proc:0x80c96a0@xxx:x> to
  1526. # locate the source file of the procedure, not only #<Proc:0x80c96a0>!
  1527. # Functions to_str and to_body try to search the procedure source
  1528. # code in a file determined by to_s. It is only a simple scanner
  1529. # which doesn't look for the whole Ruby syntax. ;-)
  1530. #
  1531. # It doesn't work if no source file exists, i.e, if the code is
  1532. # eval'ed by the Snd listener (or in Emacs). You must load the file
  1533. # instead.
  1534. #
  1535. # with_sound(:notehook,
  1536. # lambda do |name| snd_print(name) if name =~ /viol/ end) do
  1537. # fm_violin(0, 1, 440, 0.3)
  1538. # end
  1539. #
  1540. # $clm_notehook = lambda do |name| clm_print(name) if name =~ /viol/ end
  1541. #
  1542. # with_sound do
  1543. # fm_violin(0, 1, 440, 0.3)
  1544. # end
  1545. #
  1546. # with_sound(:save_body, true) do
  1547. # ...
  1548. # end
  1549. # returns something like 'lambda do ... end'
  1550. def to_str
  1551. if body = self.source
  1552. return body
  1553. end
  1554. file, line = self.to_s.sub(/>/, "").split(/@/).last.split(/:/)
  1555. if file[0] == ?( and file[-1] == ?)
  1556. if $VERBOSE
  1557. warning("%s#%s: no file found for procedure %p",
  1558. self.class, get_func_name, self)
  1559. end
  1560. body = ""
  1561. elsif (not File.exist?(file))
  1562. if $VERBOSE
  1563. warning("%s#%s: \
  1564. Sorry, you need a higher ruby version to use Proc#to_str.
  1565. It works only with newer ruby versions (I assume >= 1.8.x).
  1566. Proc#inspect must return #<Proc:0x01234567@xxx:x> not only %p!",
  1567. self.class, get_func_name, self)
  1568. end
  1569. body = ""
  1570. else
  1571. lineno = line.to_i
  1572. body = ""
  1573. blck = i = 0
  1574. first_line = true
  1575. File.foreach(file) do |ln|
  1576. i += 1
  1577. next if i < lineno
  1578. body << ln
  1579. if first_line
  1580. if (ln.scan(/\s*do\b|\{/).length -
  1581. ln.scan(/\s*end\b|\}/).length).zero? and
  1582. (ln.scan(/\(/).length - ln.scan(/\)/).length).zero?
  1583. break
  1584. else
  1585. first_line = false
  1586. blck = 1
  1587. next
  1588. end
  1589. end
  1590. next if /\s*\S+\s*(if|unless|while|until)+/ =~ ln
  1591. break if (blck += Snd_eval.count_level(ln)).zero?
  1592. break if blck.negative?
  1593. end
  1594. end
  1595. unless self.source then self.source = body end
  1596. body
  1597. end
  1598. # returns the inner body without 'lambda do end'
  1599. def to_body
  1600. if (body = self.to_str).null?
  1601. ""
  1602. elsif body.split(/\n/).length == 1
  1603. body.chomp.sub(/^(?:\s*\w+(?:\(.*\))??\s*(?:do\s+|\{\s*))(.*)\s*(?:end|\})$/, '\1').strip
  1604. else
  1605. body.split(/\n/)[1..-2].join("\n")
  1606. end
  1607. end
  1608. # property set in g_edit_list_to_function (snd-edits.c)
  1609. def source
  1610. property(self.object_id, :proc_source)
  1611. end
  1612. def source=(val)
  1613. set_property(self.object_id, :proc_source, val)
  1614. end
  1615. end
  1616. def make_proc2method(name, prc)
  1617. prc.to_method(name)
  1618. end
  1619. # produces two new functions: NAME and SET_NAME
  1620. # val = 10
  1621. # make_proc_with_setter(:foo, lambda { puts val }, lambda { |a| val = a })
  1622. # foo ==> 10
  1623. # set_foo(12)
  1624. # foo ==> 12
  1625. def make_proc_with_setter(name, getter, setter)
  1626. make_proc2method(name, getter)
  1627. make_proc2method(format("set_%s", name).intern, setter)
  1628. end
  1629. # prc = make_proc_with_source(%(lambda do |a, b, c| puts a, b, c end))
  1630. # prc.call(1, 2, 3)
  1631. # prc.source ==> "lambda do |a, b, c| puts a, b, c end"
  1632. #
  1633. # With the second argument BIND one can use local variables known in
  1634. # the current (or other) environment in the proc body:
  1635. #
  1636. # os = make_oscil(:frequency, 330)
  1637. # prc = make_proc_with_source(%(lambda do | |
  1638. # 10.times do |i| p os.run end
  1639. # end), binding)
  1640. # puts prc.source ==> lambda do | | 10.times do |i| p os.run end end
  1641. # prc.call ==> ..., 0.748837699712728
  1642. # puts
  1643. # prc.call ==> ..., 0.97679449812022
  1644. def make_proc_with_source(string, bind = binding)
  1645. if proc?(prc = (res = Snd.catch(:all) do eval(string, bind) end).first)
  1646. prc.source = string
  1647. prc
  1648. else
  1649. Snd.raise(:runtime_error, res, prc, string)
  1650. end
  1651. end
  1652. make_proc_with_setter(:proc_source,
  1653. lambda do |prc| prc.source end,
  1654. lambda do |prc, val| prc.source = val end)
  1655. # Multi-line input to the Snd listener and Emacs/inf-snd.el.
  1656. # A simple parser collects multi-line input, e.g.
  1657. #
  1658. # with_sound do
  1659. # fm_violin(0.0, 0.1, 330, 0.1)
  1660. # fm_violin(0.1, 0.1, 660, 0.1)
  1661. # end
  1662. #
  1663. # and evals it.
  1664. #
  1665. # ~/.snd
  1666. # set_listener_prompt("snd> ") # optional
  1667. # start_listener_eval # installs read-hook for snd-listener input
  1668. # start_emacs_eval # installs emacs-eval-hook
  1669. make_hook("$emacs_eval_hook", 1, "\
  1670. emacs_eval_hook(line): \
  1671. called each time inf-snd.el sends a line to the Snd process. \
  1672. The hook functions may do their best to deal with multi-line input; \
  1673. they can collect multi-line input and eval it by itself. \
  1674. One example is install_eval_hooks(file, retval, input, hook, &reset_cursor) \
  1675. in clm.rb.")
  1676. # inf-snd.el calls this function each time a line was sent to the
  1677. # emacs buffer.
  1678. def run_emacs_eval_hook(line)
  1679. if $emacs_eval_hook.empty?
  1680. # without emacs-eval-hook only single line eval
  1681. file = "(emacs-eval-hook)"
  1682. set_snd_input(:emacs)
  1683. begin
  1684. Snd.display(eval(line, TOPLEVEL_BINDING, file, 1).inspect)
  1685. rescue Interrupt, ScriptError, NameError, StandardError
  1686. Snd.display(verbose_message_string(true, "# ", file))
  1687. end
  1688. set_snd_input(:snd)
  1689. nil
  1690. else
  1691. $emacs_eval_hook.call(line)
  1692. end
  1693. end
  1694. class Snd_eval
  1695. class << Snd_eval
  1696. Open_token = %w(class module def do { while until if unless case begin for)
  1697. Close_token = %w(end })
  1698. def count_level(line)
  1699. eval_level = 0
  1700. # skip strings and symbols which may contain reserved words
  1701. line.gsub(/(:\w+|".+")/, "").split(/\b/).each do |s|
  1702. case s
  1703. when *Open_token
  1704. eval_level += 1
  1705. when *Close_token
  1706. eval_level -= 1
  1707. end
  1708. end
  1709. eval_level
  1710. end
  1711. end
  1712. end
  1713. class Snd_prompt
  1714. # level number inserted into original prompt
  1715. # ">" ==> "(0)>"
  1716. # "snd> " ==> "snd(0)> "
  1717. def initialize(level)
  1718. @listener_prompt = listener_prompt
  1719. @base_prompt = listener_prompt.split(/(\(\d+\))?(>)?\s*$/).car.to_s
  1720. @rest_prompt = listener_prompt.scan(/>\s*$/).car.to_s
  1721. update(level)
  1722. end
  1723. def inspect
  1724. format("#<%s %s(0)%s>", self.class, @base_prompt, @rest_prompt)
  1725. end
  1726. def update(level)
  1727. set_listener_prompt(format("%s(%d)%s", @base_prompt, level, @rest_prompt))
  1728. end
  1729. def reset
  1730. set_listener_prompt(@listener_prompt)
  1731. end
  1732. end
  1733. def install_eval_hooks(file, retval, input, hook, &reset_cursor)
  1734. eval_level = 0
  1735. eval_line = ""
  1736. prompt = Snd_prompt.new(eval_level)
  1737. reset_cursor.nil? or reset_cursor.call
  1738. $exit_hook.add_hook!(file) do | | prompt.reset end
  1739. hook.add_hook!(file) do |line|
  1740. eval_line = eval_line + line + "\n"
  1741. eval_level += Snd_eval.count_level(line)
  1742. if eval_level.negative?
  1743. eval_level = 0
  1744. eval_line = ""
  1745. end
  1746. if eval_level.zero?
  1747. set_snd_input(input)
  1748. begin
  1749. Snd.display(eval(eval_line, TOPLEVEL_BINDING, file, 1).inspect)
  1750. rescue Interrupt, ScriptError, NameError, StandardError
  1751. Snd.display(verbose_message_string(true, "# ", file))
  1752. ensure
  1753. eval_line = ""
  1754. end
  1755. end
  1756. prompt.update(eval_level)
  1757. reset_cursor.nil? or reset_cursor.call
  1758. retval
  1759. end
  1760. end
  1761. # installs the emacs-eval-hook
  1762. def start_emacs_eval(name = "(emacs)")
  1763. install_eval_hooks(name, nil, :emacs, $emacs_eval_hook) do
  1764. $stdout.print(listener_prompt)
  1765. $stdout.flush
  1766. end
  1767. end
  1768. # installs the read-hook
  1769. def start_listener_eval(name = "(snd)")
  1770. set_show_listener(true)
  1771. install_eval_hooks(name, true, :snd, $read_hook)
  1772. end
  1773. def stop_emacs_eval(name = "(emacs)")
  1774. $emacs_eval_hook.remove_hook!(name)
  1775. $exit_hook.run_hook_by_name(name)
  1776. $exit_hook.remove_hook!(name)
  1777. end
  1778. def stop_listener_eval(name = "(snd)")
  1779. $read_hook.remove_hook!(name)
  1780. $exit_hook.run_hook_by_name(name)
  1781. $exit_hook.remove_hook!(name)
  1782. reset_listener_cursor
  1783. clm_print("\n%s", listener_prompt)
  1784. end
  1785. # Debugging resp. inspecting local variables
  1786. make_proc_with_setter(:debug_properties,
  1787. lambda do |name|
  1788. property(name, :debug_property)
  1789. end,
  1790. lambda do |name, val|
  1791. set_property(name, :debug_property, val)
  1792. end)
  1793. make_proc_with_setter(:debug_property,
  1794. lambda do |key, name|
  1795. hash?(h = debug_properties(name)) and h[key]
  1796. end,
  1797. lambda do |key, val, name|
  1798. h = debug_properties(name)
  1799. unless hash?(h) and h.store(key, [val] + h[key])
  1800. a = property(:debug, :names)
  1801. unless array?(a) and a.push(name)
  1802. set_property(:debug, :names, [name])
  1803. end
  1804. set_debug_properties(name, {key => [val]})
  1805. end
  1806. end)
  1807. make_proc_with_setter(:debug_binding,
  1808. lambda do |name|
  1809. debug_property(:binding, name)
  1810. end,
  1811. lambda do |bind, *name|
  1812. set_debug_property(:binding, bind,
  1813. (name[0] or get_func_name(3)))
  1814. end)
  1815. # Shows all local variables of last call of functions prepared with
  1816. # set_debug_binding(binding)
  1817. #
  1818. # def function1
  1819. # [...]
  1820. # set_debug_binding(binding)
  1821. # end
  1822. # def function2
  1823. # [...]
  1824. # set_debug_binding(binding)
  1825. # end
  1826. # [...]
  1827. # function1
  1828. # function2
  1829. # [...]
  1830. #
  1831. # display_all_variables
  1832. def display_all_variables(name = nil)
  1833. if name
  1834. [name]
  1835. else
  1836. (property(:debug, :names) or [])
  1837. end.each do |nm|
  1838. debug_binding(nm).each do |bind|
  1839. Snd.message("=== %s ===", nm)
  1840. Snd.message()
  1841. each_variables(bind) do |var, val|
  1842. Snd.message("%s = %s", var, val.inspect)
  1843. end
  1844. Snd.message()
  1845. end
  1846. end
  1847. end
  1848. # each_variables provides all local variable names and their values in
  1849. # the given proc context
  1850. #
  1851. # def function
  1852. # [...]
  1853. # each_variables do |k, v|
  1854. # Snd.display("%s = %s", k, v)
  1855. # end
  1856. # end
  1857. def each_variables(bind = binding, &prc)
  1858. eval("local_variables", bind).each do |name|
  1859. name = name.to_s
  1860. prc.call(name, eval(name, bind))
  1861. end
  1862. end
  1863. # let(8, :foo, "bar") do |a, b, c|
  1864. # printf("a: %d, b: %s, c: %s\n", a, b, c)
  1865. # end
  1866. #
  1867. # Simulates a save local variable environment and restores old
  1868. # variables to their original values.
  1869. def let(*args, &prc)
  1870. locals = Hash.new
  1871. bind = prc.binding
  1872. each_variables(bind) do |var, val|
  1873. locals[var] = val
  1874. end
  1875. prc.call(*args)
  1876. rescue Interrupt, ScriptError, NameError, StandardError
  1877. Kernel.raise
  1878. ensure
  1879. @locals = locals
  1880. locals.each_key do |name|
  1881. eval("#{name} = @locals[#{name.inspect}]", bind)
  1882. end
  1883. remove_instance_variable("@locals")
  1884. end
  1885. # for irb (rgb.rb)
  1886. def make_color(r, g, b)
  1887. [:Pixel, 0]
  1888. end unless defined? make_color
  1889. def doc(*rest)
  1890. # dummy for old Kernel.doc
  1891. end
  1892. ##
  1893. ## Utilities
  1894. ##
  1895. if provided? :snd_nogui
  1896. alias close_sound_extend close_sound
  1897. else
  1898. def close_sound_extend(snd)
  1899. # 5 == Notebook
  1900. if main_widgets[5]
  1901. idx = Snd.sounds.index(snd)
  1902. if idx.nil? then idx = 0 end
  1903. close_sound(snd)
  1904. snds = sounds() and set_selected_sound(snds[idx < snds.length ? idx : -1])
  1905. else
  1906. close_sound(snd)
  1907. end
  1908. end
  1909. end
  1910. add_help(:times2samples,
  1911. "times2samples(start, dur) \
  1912. START and DUR are in seconds; returns array [beg, end] in samples.")
  1913. def times2samples(start, dur)
  1914. beg = seconds2samples(start)
  1915. [beg, beg + seconds2samples(dur)]
  1916. end
  1917. def random(val)
  1918. if val.zero?
  1919. val
  1920. else
  1921. case val
  1922. when Fixnum
  1923. kernel_rand(val)
  1924. when Float
  1925. val.negative? ? -mus_random(val).abs : mus_random(val).abs
  1926. end
  1927. end
  1928. end
  1929. def logn(r, b = 10)
  1930. if r <= 0
  1931. Snd.raise(:ruby_error, r, "r must be > 0")
  1932. end
  1933. if b <= 0 or b == 1
  1934. Snd.raise(:ruby_error, b, "b must be > 0 and != 1")
  1935. end
  1936. log(r) / log(b)
  1937. end
  1938. def car(v)
  1939. v[0]
  1940. end
  1941. def cadr(v)
  1942. v[1]
  1943. end
  1944. def caddr(v)
  1945. v[2]
  1946. end
  1947. def cdr(v)
  1948. v[1..-1]
  1949. end
  1950. def verbose_message_string(stack_p, remark, *args)
  1951. fmt_remark = format("\n%s", remark)
  1952. str = if args.null?
  1953. ""
  1954. elsif args.length == 1
  1955. String(args.car)
  1956. else
  1957. format(*args)
  1958. end
  1959. str = if str.split(/\n/).length > 1
  1960. str.split(/\n/).join(fmt_remark)
  1961. else
  1962. format("%s%s", remark, str)
  1963. end
  1964. if $!
  1965. str += format("[%p] %s (%s)",
  1966. rb_error_to_mus_tag, snd_error_to_message, $!.class)
  1967. if stack_p
  1968. str += format("\n%s%s", remark, $!.backtrace.join(fmt_remark))
  1969. end
  1970. else
  1971. if stack_p and caller(2)
  1972. str += format("\n%s%s", remark, caller(2).join(fmt_remark))
  1973. end
  1974. end
  1975. str
  1976. end
  1977. def warning(*args)
  1978. str = "Warning: " << verbose_message_string($VERBOSE, nil, *args)
  1979. if provided? :snd
  1980. snd_warning(str)
  1981. else
  1982. clm_message(str)
  1983. end
  1984. nil
  1985. end
  1986. def die(*args)
  1987. message(verbose_message_string(true, nil, *args))
  1988. exit(1) unless provided? :snd
  1989. end
  1990. def error(*args)
  1991. Snd.raise(:runtime_error, verbose_message_string(true, nil, *args))
  1992. end
  1993. make_proc_with_setter(:snd_input,
  1994. lambda do property(:snd_input, :snd_listener) end,
  1995. lambda do |val|
  1996. set_property(:snd_input, :snd_listener, val)
  1997. end)
  1998. # like clm_print(fmt, *args)
  1999. def clm_message(*args)
  2000. msg = if args.null?
  2001. ""
  2002. elsif args.length == 1
  2003. String(args.car)
  2004. else
  2005. format(*args)
  2006. end
  2007. if provided? :snd
  2008. if provided? :snd_nogui
  2009. clm_print("%s\n", msg)
  2010. else
  2011. clm_print("\n%s", msg)
  2012. end
  2013. nil
  2014. else
  2015. $stdout.print(msg, "\n")
  2016. end
  2017. nil
  2018. end
  2019. # like clm_print(*args), in emacs it prepends msg with a comment sign
  2020. def message(*args)
  2021. clm_message(verbose_message_string(false, "# ", *args))
  2022. end
  2023. # debug(var1, var2) ==> #<DEBUG: ClassName: value1, ClassName: value2>
  2024. def debug(*args)
  2025. fmt = ""
  2026. args.each do |arg|
  2027. fmt += format("%s: %p", arg.class, arg)
  2028. fmt += ", "
  2029. end
  2030. message("#<DEBUG: %s>", fmt.chomp(", "))
  2031. end
  2032. def debug_trace(*args)
  2033. debug(*args)
  2034. clm_message(verbose_message_string(true, "# "))
  2035. end
  2036. if provided?(:snd) then set_snd_input(:snd) end
  2037. class Snd
  2038. class << Snd
  2039. Snd_path = Array.new
  2040. if provided? :snd_motif
  2041. def add_sound_path(path)
  2042. Snd_path.push(path)
  2043. add_directory_to_view_files_list(path)
  2044. end
  2045. else
  2046. def add_sound_path(path)
  2047. Snd_path.push(path)
  2048. end
  2049. end
  2050. def fullname(fname)
  2051. if File.exist?(fname)
  2052. fname
  2053. else
  2054. f = File.basename(fname)
  2055. Snd_path.each do |path|
  2056. if File.exist?(path + "/" + f)
  2057. return path + "/" + f
  2058. end
  2059. end
  2060. Snd.raise(:no_such_file, fname)
  2061. end
  2062. end
  2063. def open_from_path(fname)
  2064. snd_file = Snd.fullname(fname)
  2065. find_sound(snd_file) or open_sound(snd_file)
  2066. end
  2067. def find_from_path(fname)
  2068. find_sound(Snd.fullname(fname))
  2069. end
  2070. def load_path
  2071. Snd_path
  2072. end
  2073. def message(*args)
  2074. clm_message(verbose_message_string(false, "# ", *args))
  2075. end
  2076. def display(*args)
  2077. msg = if args.null?
  2078. ""
  2079. elsif args.length == 1
  2080. String(args.car)
  2081. else
  2082. format(*args)
  2083. end
  2084. if snd_input == :snd
  2085. if provided? :snd_nogui
  2086. clm_print("%s\n", msg)
  2087. else
  2088. clm_print("\n%s", msg)
  2089. end
  2090. else
  2091. $stdout.print(msg, "\n")
  2092. end
  2093. nil
  2094. end
  2095. def warning(*args)
  2096. if provided? :snd
  2097. snd_warning(verbose_message_string($VERBOSE, nil, *args))
  2098. else
  2099. args[0] = "Warning: " + String(args[0])
  2100. Snd.display(verbose_message_string($VERBOSE, "# ", *args))
  2101. end
  2102. nil
  2103. end
  2104. def die(*args)
  2105. Snd.display(verbose_message_string(true, nil, *args))
  2106. exit(1) unless provided? :snd
  2107. end
  2108. def error(*args)
  2109. Snd.raise(:runtime_error, verbose_message_string(true, nil, *args))
  2110. end
  2111. def debug(*args)
  2112. if args.null?
  2113. Snd.message("#<DEBUG>")
  2114. elsif args.length == 1
  2115. Snd.message("#<DEBUG: %s>", String(args.car))
  2116. else
  2117. Snd.message("#<DEBUG: %s>", format(*args))
  2118. end
  2119. end
  2120. def debug_trace(*args)
  2121. Snd.debug(*args)
  2122. Snd.display(verbose_message_string(true, "# "))
  2123. end
  2124. def sounds
  2125. (Kernel.sounds or []).reverse
  2126. end
  2127. def regions
  2128. (Kernel.regions or []).reverse
  2129. end
  2130. def marks(snd = false, chn = false)
  2131. (Kernel.marks(snd, chn) or [])
  2132. end
  2133. def snd(sn = false)
  2134. sn or selected_sound or Snd.sounds.car
  2135. end
  2136. def chn(ch = false)
  2137. ch or selected_channel or 0
  2138. end
  2139. def catch(tag = :all, retval = :undefined)
  2140. old_debug = $DEBUG
  2141. $DEBUG = false
  2142. val = Kernel.catch(tag) do yield end
  2143. # catch/throw part
  2144. # [:snd_throw, tag, get_func_name(2), *rest]
  2145. if array?(val) and val.car == :snd_throw
  2146. if retval != :undefined
  2147. if proc?(retval)
  2148. retval.call(val.cdr)
  2149. else
  2150. [retval]
  2151. end
  2152. else
  2153. val.cdr
  2154. end
  2155. else
  2156. [val]
  2157. end
  2158. # ruby1.9/ChangeLog
  2159. # Thu Feb 2 16:01:24 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
  2160. # * error.c (Init_Exception): change NameError to direct subclass of
  2161. # Exception so that default rescue do not handle it silently.
  2162. rescue Interrupt, ScriptError, NameError, StandardError
  2163. mus_tag = rb_error_to_mus_tag
  2164. # raise part
  2165. if (tag == mus_tag) or (tag == :all)
  2166. if retval != :undefined
  2167. if proc?(retval)
  2168. retval.call(mus_tag, snd_error_to_message)
  2169. else
  2170. [retval]
  2171. end
  2172. else
  2173. [mus_tag, snd_error_to_message]
  2174. end
  2175. else
  2176. Kernel.raise
  2177. end
  2178. ensure
  2179. $DEBUG = old_debug
  2180. end
  2181. def throw(tag, *rest)
  2182. Kernel.throw(tag, [:snd_throw, tag, get_func_name(2), *rest])
  2183. end
  2184. def raise(tag, *rest)
  2185. msg = format("%s in %s:", tag, get_func_name(2))
  2186. rest.each do |s| msg += format(" %s,", s) end
  2187. msg.chomp!(",")
  2188. exception = case tag
  2189. when :out_of_range
  2190. RangeError
  2191. when :wrong_type_arg
  2192. TypeError
  2193. when *Snd_error_tags
  2194. StandardError
  2195. else
  2196. Ruby_exceptions[tag] or RuntimeError
  2197. end
  2198. Kernel.raise(exception, msg, caller(1))
  2199. end
  2200. end
  2201. end
  2202. # almost all StandardError
  2203. Snd_error_tags = [# clm2xen.c
  2204. :mus_error,
  2205. :no_such_method,
  2206. :wrong_type_arg, # TypeError
  2207. # snd-0.h
  2208. :no_such_envelope,
  2209. :no_such_sample,
  2210. :no_such_edit,
  2211. :cannot_save,
  2212. :cant_update_file,
  2213. # snd-chn.c
  2214. :cant_open_file,
  2215. # snd-dac.c
  2216. :bad_format,
  2217. :no_such_player,
  2218. :arg_error,
  2219. # snd-draw.c
  2220. :no_such_widget,
  2221. :no_such_graphics_context,
  2222. :no_such_axis,
  2223. :bad_length,
  2224. # snd-edits.c
  2225. :no_such_direction,
  2226. :no_such_region,
  2227. :no_such_auto_delete_choice,
  2228. # snd-env.c
  2229. :env_error,
  2230. # snd-error.c
  2231. :snd_error,
  2232. # snd-gxcolormaps.c
  2233. :no_such_colormap,
  2234. :colormap_error,
  2235. # snd-key.c
  2236. :no_such_key,
  2237. # snd-ladspa.c
  2238. :no_such_plugin,
  2239. :plugin_error,
  2240. # snd-marks.c
  2241. :no_such_mark,
  2242. # snd-menu.c
  2243. :no_such_menu,
  2244. # snd-mix.c
  2245. :no_such_mix,
  2246. # snd-print.c
  2247. :cannot_print,
  2248. # snd-region.c
  2249. :io_error,
  2250. # run.c
  2251. :wrong_number_of_args,
  2252. :cannot_parse,
  2253. # snd-snd.c
  2254. :no_such_sound,
  2255. :not_a_sound_file,
  2256. :cannot_apply_controls,
  2257. :bad_size,
  2258. :snd_internal_error,
  2259. # snd-xen.c
  2260. :no_active_selection,
  2261. :bad_arity,
  2262. # snd-xmain.c
  2263. :xt_error,
  2264. # snd-xchn.c
  2265. :no_such_color,
  2266. # snd.c
  2267. :snd_top_level,
  2268. :gsl_error,
  2269. # sndlib2xen.h
  2270. :out_of_range,
  2271. :no_such_channel,
  2272. :no_such_file,
  2273. :bad_type,
  2274. :no_data,
  2275. :bad_header,
  2276. # xm.c
  2277. :no_such_resource]
  2278. def rb_error_to_mus_tag
  2279. # to_s and string error-names intentional here
  2280. # otherwise e.g. NameError goes to case StandardError!
  2281. case $!.class.to_s
  2282. when "StandardError"
  2283. $!.message.split(/[: ]/).first.downcase.intern
  2284. when "RangeError"
  2285. :out_of_range
  2286. when "TypeError"
  2287. :wrong_type_arg
  2288. when "ArgumentError"
  2289. :wrong_number_of_args
  2290. else
  2291. # converts ruby exceptions to symbols: NoMethodError ==> :no_method_error
  2292. $!.class.to_s.gsub(/([A-Z])/) do |c|
  2293. "_" + c.tr("A-Z", "a-z")
  2294. end[1..-1].intern
  2295. end
  2296. end
  2297. def snd_error_to_message
  2298. $!.message.split(/\n/).first.sub(/^.*: /, "")
  2299. end
  2300. add_help(:snd_catch,
  2301. "snd_catch(tag=:all, retval=:undefined]) \
  2302. Catchs snd_throw and exceptions and \
  2303. returns body's last value wrapped in an array if all goes well. \
  2304. If a snd_throw tag meets snd_catch's, returns an array with the tag name, \
  2305. the function name from where was thrown \
  2306. and optional arguments given to snd_throw. \
  2307. If an exception was risen and the exception name meets tag name, \
  2308. returns an array with tag name and the exception message, \
  2309. otherwise reraises exception. \
  2310. If retval is given and tag matches exception or snd_throw tag, \
  2311. returns retval. \
  2312. If retval is a procedure, calls retval with tag name and message.
  2313. res = snd_catch do 10 + 2 end
  2314. puts res ==> [12]
  2315. res = Snd.catch(:no_such_file) do
  2316. open_sound(\"unknown-file.snd\")
  2317. end
  2318. puts res ==> [:no_such_file, \
  2319. \"open_sound: no_such_file: Unknown_file.snd No such file or directory\"]
  2320. res = Snd.catch(:finish) do
  2321. 10.times do |i|
  2322. if i == 8 then snd_throw(:finish, i) end
  2323. end
  2324. end
  2325. puts res ==> [:finish, \"top_level\", 8]
  2326. res = Snd.catch(:all, lambda do |tag, msg| Snd.display([tag, msg]) end) do
  2327. set_listener_prompt(17)
  2328. end
  2329. ==> [:wrong_type_arg, \
  2330. \"set_listener-prompt: wrong type arg 0, 17, wanted a string\"]
  2331. puts res ==> nil
  2332. The lambda function handles the error in the last case.")
  2333. def snd_catch(tag = :all, retval = :undefined, &body)
  2334. Snd.catch(tag, retval, &body)
  2335. end
  2336. add_help(:snd_throw,
  2337. "snd_throw(tag, *rest) \
  2338. Jumps to the corresponding snd_catch(TAG) and returns an array \
  2339. with TAG, function name and possible *REST strings or values.")
  2340. def snd_throw(tag, *rest)
  2341. Snd.throw(tag, *rest)
  2342. end
  2343. class Break < StandardError
  2344. end
  2345. Ruby_exceptions = {
  2346. :script_error => ScriptError,
  2347. :load_error => LoadError,
  2348. :name_error => NameError,
  2349. :not_implemented_error => NotImplementedError,
  2350. :syntax_error => SyntaxError,
  2351. :interrupt => Interrupt,
  2352. :system_exit => SystemExit,
  2353. :standard_error => StandardError,
  2354. :arg_error => ArgumentError,
  2355. :float_domain_error => FloatDomainError,
  2356. :index_error => IndexError,
  2357. :io_error => IOError,
  2358. :eof_error => EOFError,
  2359. :local_jump_error => LocalJumpError,
  2360. :no_memory_error => NoMemoryError,
  2361. :range_error => RangeError,
  2362. :regexp_error => RegexpError,
  2363. :runtime_error => RuntimeError,
  2364. :security_error => SecurityError,
  2365. :system_call_error => SystemCallError,
  2366. :system_stack_error => SystemStackError,
  2367. :thread_error => ThreadError,
  2368. :type_error => TypeError,
  2369. :zero_division_error => ZeroDivisionError,
  2370. :break => Break}
  2371. add_help(:snd_raise,
  2372. "snd_raise(tag, *rest) \
  2373. Raises an exception TAG with an error message \
  2374. containing function name, TAG and possible *REST strings or values. \
  2375. TAG is a symbol, \
  2376. a Ruby exception looks like :local_jump_error instead of LocalJumpError, \
  2377. a Snd error tag looks like :no_such_sound.")
  2378. def snd_raise(tag, *rest)
  2379. Snd.raise(tag, *rest)
  2380. end
  2381. def srate
  2382. mus_srate
  2383. end unless defined? srate
  2384. # general purpose loop
  2385. add_help(:gloop,
  2386. "gloop(*args) { |args| ... }
  2387. :step = 1
  2388. :before = nil (thunk)
  2389. :after = nil (thunk)
  2390. args[0]: Range (each)
  2391. Hash(s) (each)
  2392. Array(s) (each_with_index) [args.last == Fixnum ==> step]
  2393. Fixnum (times)
  2394. Fixnum [args[1] == :step ==> step]
  2395. A general purpose loop, handling Range, Hash, Array, Vec, Vct, Fixnum,
  2396. with optional step. Returns the result of body as array like map.
  2397. Examples:
  2398. Range
  2399. gloop(0..3) do |i| puts i end
  2400. Hash (loops over all Hashs consecutively)
  2401. gloop({1 => :a, 2 => :b}, {11 => :aa => 22 => :bb}) do |k, v|
  2402. print('key: ', k, ' value: ', v)
  2403. puts
  2404. end
  2405. Array, Vec, Vct
  2406. gloop([0, 1]) do |x, i|
  2407. print(i, ': ', x)
  2408. puts end
  2409. Arrays with step (mixes all Arrays)
  2410. gloop([0, 1, 2, 3], [:a, :b, :c, :d], [55, 66, 77, 88, 99], 2) do |x, i|
  2411. print(i, ': ', x.inspect)
  2412. puts
  2413. end
  2414. Numeric (like Integer#times)
  2415. gloop(3) do |i| puts i end
  2416. Numeric with step (like Integer#step)
  2417. gloop(6, 2) do |i| puts i end
  2418. a simple body call
  2419. gloop do puts 'empty' end")
  2420. def gloop(*args, &body)
  2421. step = get_shift_args(args, :step, 1)
  2422. before = get_shift_args(args, :before)
  2423. after = get_shift_args(args, :after)
  2424. do_extra = lambda do |thunk| thunk?(thunk) ? thunk.call : snd_func(thunk) end
  2425. result = []
  2426. case args[0]
  2427. when Range
  2428. args[0].step(step) do |i|
  2429. do_extra.call(before) if before
  2430. result << body.call(i)
  2431. do_extra.call(after) if after
  2432. end
  2433. when Array, Vec, Vct
  2434. lmax = args.map do |x| x.length end.max
  2435. 0.step(lmax - 1, step.round) do |i|
  2436. do_extra.call(before) if before
  2437. result << body.call(*args.map do |x| x[i] end << i)
  2438. do_extra.call(after) if after
  2439. end
  2440. when Hash
  2441. args.each do |x| x.each do |k, v|
  2442. do_extra.call(before) if before
  2443. result << body.call(k, v)
  2444. do_extra.call(after) if after
  2445. end
  2446. end
  2447. when Numeric
  2448. 0.step(args[0], number?(args[1]) ? args[1] : step) do |i|
  2449. do_extra.call(before) if before
  2450. result << body.call(i)
  2451. do_extra.call(after) if after
  2452. end
  2453. else
  2454. do_extra.call(before) if before
  2455. result << body.call
  2456. do_extra.call(after) if after
  2457. end
  2458. result
  2459. end
  2460. # get_args(args, key, default = nil)
  2461. #
  2462. # returns value, whether DEFAULT or value of KEY found in ARGS
  2463. def get_args(args, key, default = nil)
  2464. if args.member?(key)
  2465. arg = args[args.index(key) + 1]
  2466. default = arg.nil? ? default : arg
  2467. end
  2468. default
  2469. end
  2470. def get_shift_args(args, key, default = nil)
  2471. default = get_args(args, key, default)
  2472. if args.member?(key)
  2473. i = args.index(key)
  2474. 2.times do args.delete_at(i) end
  2475. end
  2476. default
  2477. end
  2478. # var = get_class_or_key(args, Klass, :key, default = nil)
  2479. def get_class_or_key(args, klass, key, default = nil)
  2480. if (not symbol?(args.first)) and args.first.kind_of?(klass)
  2481. args.shift
  2482. else
  2483. get_shift_args(args, key, default)
  2484. end
  2485. end
  2486. # var1, var2, var3, var4 = optkey(args, [:key, default],
  2487. # [:number, 1],
  2488. # [Array, :list, [0, 1, 2, 3]],
  2489. # :var_w/o_default_value)
  2490. #
  2491. # Key-default pairs must be included in brackets while keys alone can
  2492. # be included in brackets or not, see last key
  2493. # ":var_w/o_default_value" above. If no default value is specified,
  2494. # nil is used.
  2495. def optkey(args, *rest)
  2496. args_1 = args.dup
  2497. bind = binding?(rest.car) ? rest.shift : nil
  2498. @locals = nil
  2499. vals = rest.map do |keys|
  2500. val = if array?(keys)
  2501. case keys.length
  2502. when 1
  2503. name = keys.car.to_s
  2504. get_class_or_key(args_1, Object, keys.car, nil)
  2505. when 2
  2506. name = keys.car.to_s
  2507. get_class_or_key(args_1, keys.cadr.class, *keys)
  2508. when 3
  2509. name = keys.cadr.to_s
  2510. get_class_or_key(args_1, *keys)
  2511. else
  2512. assert_type(keys.length.between?(1, 3), keys, 1,
  2513. "an array of one to three \
  2514. elements [class, :key, default]")
  2515. end
  2516. else
  2517. name = keys.to_s
  2518. get_class_or_key(args_1, Object, keys, nil)
  2519. end
  2520. @locals = val
  2521. eval("#{name} = @locals", bind)
  2522. val
  2523. end
  2524. remove_instance_variable("@locals")
  2525. if vals.length == 1
  2526. vals.first
  2527. else
  2528. vals
  2529. end
  2530. end
  2531. add_help(:load_init_file,
  2532. "load_init_file(file) \
  2533. Returns false if FILE doesn't exist, otherwise loads it. \
  2534. FILE may reside in current working dir or in $HOME dir.")
  2535. def load_init_file(file)
  2536. if File.exist?(file)
  2537. Snd.catch do load(file) end
  2538. elsif File.exist?(f = ENV["HOME"] + "/" + file)
  2539. Snd.catch do load(f) end
  2540. else
  2541. false
  2542. end
  2543. end
  2544. let(-1) do |count|
  2545. # see rotate_phase(func, snd, chn) in dsp.rb
  2546. # it's necessary to produce a uniq method name
  2547. make_proc_with_setter(:edit_list_proc_counter,
  2548. lambda do count end,
  2549. lambda do count += 1 end)
  2550. end
  2551. # clm.rb ends here