musa-dsl 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/Gemfile +0 -1
  4. data/README.md +15 -1
  5. data/docs/README.md +1 -0
  6. data/docs/subsystems/datasets.md +75 -0
  7. data/docs/subsystems/generative.md +92 -6
  8. data/docs/subsystems/music.md +349 -19
  9. data/docs/subsystems/transport.md +26 -0
  10. data/lib/musa-dsl/datasets/dataset.rb +2 -0
  11. data/lib/musa-dsl/datasets/gdv.rb +3 -3
  12. data/lib/musa-dsl/datasets/p.rb +1 -1
  13. data/lib/musa-dsl/datasets/score/to-mxml/process-time.rb +4 -2
  14. data/lib/musa-dsl/datasets/score.rb +3 -1
  15. data/lib/musa-dsl/generative/darwin.rb +36 -1
  16. data/lib/musa-dsl/generative/generative-grammar.rb +31 -1
  17. data/lib/musa-dsl/generative/markov.rb +3 -1
  18. data/lib/musa-dsl/generative/rules.rb +54 -0
  19. data/lib/musa-dsl/generative/variatio.rb +69 -0
  20. data/lib/musa-dsl/midi/midi-recorder.rb +4 -0
  21. data/lib/musa-dsl/midi/midi-voices.rb +13 -1
  22. data/lib/musa-dsl/music/chord-definition.rb +7 -5
  23. data/lib/musa-dsl/music/chord-definitions.rb +37 -0
  24. data/lib/musa-dsl/music/chords.rb +88 -21
  25. data/lib/musa-dsl/music/equally-tempered-12-tone-scale-system.rb +70 -521
  26. data/lib/musa-dsl/music/scale_kinds/bebop/bebop_dominant_scale_kind.rb +110 -0
  27. data/lib/musa-dsl/music/scale_kinds/bebop/bebop_major_scale_kind.rb +110 -0
  28. data/lib/musa-dsl/music/scale_kinds/bebop/bebop_minor_scale_kind.rb +110 -0
  29. data/lib/musa-dsl/music/scale_kinds/blues/blues_major_scale_kind.rb +100 -0
  30. data/lib/musa-dsl/music/scale_kinds/blues/blues_scale_kind.rb +99 -0
  31. data/lib/musa-dsl/music/scale_kinds/chromatic_scale_kind.rb +79 -0
  32. data/lib/musa-dsl/music/scale_kinds/ethnic/double_harmonic_scale_kind.rb +102 -0
  33. data/lib/musa-dsl/music/scale_kinds/ethnic/hungarian_minor_scale_kind.rb +102 -0
  34. data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_major_scale_kind.rb +102 -0
  35. data/lib/musa-dsl/music/scale_kinds/ethnic/neapolitan_minor_scale_kind.rb +101 -0
  36. data/lib/musa-dsl/music/scale_kinds/ethnic/phrygian_dominant_scale_kind.rb +103 -0
  37. data/lib/musa-dsl/music/scale_kinds/harmonic_major/harmonic_major_scale_kind.rb +104 -0
  38. data/lib/musa-dsl/music/scale_kinds/major_scale_kind.rb +110 -0
  39. data/lib/musa-dsl/music/scale_kinds/melodic_minor/altered_scale_kind.rb +106 -0
  40. data/lib/musa-dsl/music/scale_kinds/melodic_minor/dorian_b2_scale_kind.rb +104 -0
  41. data/lib/musa-dsl/music/scale_kinds/melodic_minor/locrian_sharp2_scale_kind.rb +103 -0
  42. data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_augmented_scale_kind.rb +103 -0
  43. data/lib/musa-dsl/music/scale_kinds/melodic_minor/lydian_dominant_scale_kind.rb +106 -0
  44. data/lib/musa-dsl/music/scale_kinds/melodic_minor/melodic_minor_scale_kind.rb +104 -0
  45. data/lib/musa-dsl/music/scale_kinds/melodic_minor/mixolydian_b6_scale_kind.rb +103 -0
  46. data/lib/musa-dsl/music/scale_kinds/minor_harmonic_scale_kind.rb +125 -0
  47. data/lib/musa-dsl/music/scale_kinds/minor_natural_scale_kind.rb +123 -0
  48. data/lib/musa-dsl/music/scale_kinds/modes/dorian_scale_kind.rb +111 -0
  49. data/lib/musa-dsl/music/scale_kinds/modes/locrian_scale_kind.rb +114 -0
  50. data/lib/musa-dsl/music/scale_kinds/modes/lydian_scale_kind.rb +111 -0
  51. data/lib/musa-dsl/music/scale_kinds/modes/mixolydian_scale_kind.rb +111 -0
  52. data/lib/musa-dsl/music/scale_kinds/modes/phrygian_scale_kind.rb +111 -0
  53. data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_major_scale_kind.rb +93 -0
  54. data/lib/musa-dsl/music/scale_kinds/pentatonic/pentatonic_minor_scale_kind.rb +99 -0
  55. data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_hw_scale_kind.rb +110 -0
  56. data/lib/musa-dsl/music/scale_kinds/symmetric/diminished_wh_scale_kind.rb +110 -0
  57. data/lib/musa-dsl/music/scale_kinds/symmetric/whole_tone_scale_kind.rb +99 -0
  58. data/lib/musa-dsl/music/scale_systems/equally_tempered_12_tone_scale_system.rb +80 -0
  59. data/lib/musa-dsl/music/scale_systems/twelve_semitones_scale_system.rb +60 -0
  60. data/lib/musa-dsl/music/scales.rb +606 -67
  61. data/lib/musa-dsl/musicxml/builder/note.rb +31 -92
  62. data/lib/musa-dsl/musicxml/builder/pitched-note.rb +33 -94
  63. data/lib/musa-dsl/musicxml/builder/rest.rb +30 -91
  64. data/lib/musa-dsl/musicxml/builder/unpitched-note.rb +31 -91
  65. data/lib/musa-dsl/neumas/array-to-neumas.rb +1 -1
  66. data/lib/musa-dsl/neumas/neuma-gdv-decoder.rb +2 -2
  67. data/lib/musa-dsl/sequencer/sequencer-dsl.rb +367 -3
  68. data/lib/musa-dsl/series/base-series.rb +250 -240
  69. data/lib/musa-dsl/series/buffer-serie.rb +16 -5
  70. data/lib/musa-dsl/series/hash-or-array-serie-splitter.rb +29 -3
  71. data/lib/musa-dsl/series/main-serie-constructors.rb +19 -15
  72. data/lib/musa-dsl/series/main-serie-operations.rb +74 -29
  73. data/lib/musa-dsl/series/proxy-serie.rb +5 -1
  74. data/lib/musa-dsl/series/quantizer-serie.rb +16 -2
  75. data/lib/musa-dsl/series/queue-serie.rb +15 -1
  76. data/lib/musa-dsl/series/series-composer.rb +5 -2
  77. data/lib/musa-dsl/series/timed-serie.rb +8 -4
  78. data/lib/musa-dsl/transport/timer-clock.rb +4 -2
  79. data/lib/musa-dsl/transport/timer.rb +27 -4
  80. data/lib/musa-dsl/version.rb +1 -1
  81. data/musa-dsl.gemspec +18 -15
  82. metadata +85 -22
@@ -166,6 +166,8 @@ module Musa
166
166
  #
167
167
  # @param content [Object] element content
168
168
  # @param attributes [Hash, nil] element attributes
169
+ #
170
+ # @return [void]
169
171
  def initialize(content, attributes = nil)
170
172
  @content = content
171
173
  @attributes = attributes || {}
@@ -367,10 +369,12 @@ module Musa
367
369
  # @param index [Integer] option index
368
370
  #
369
371
  # @return [Node] option converted to node
370
- def [](index)
372
+ def get(index)
371
373
  options[index].to_serie.to_node
372
374
  end
373
375
 
376
+ alias_method :[], :get
377
+
374
378
  # Converts options to series.
375
379
  #
376
380
  # Generates options and converts them to a {Musa::Series::Serie}.
@@ -406,6 +410,14 @@ module Musa
406
410
 
407
411
  protected
408
412
 
413
+ # Generates condition block from simplified arguments.
414
+ #
415
+ # @param attribute [Symbol, nil] attribute to check
416
+ # @param after_collect_operation [Symbol, nil] operation on collected values
417
+ # @param comparison_method [Symbol, nil] comparison method to apply
418
+ # @param comparison_value [Object, nil] value to compare against
419
+ #
420
+ # @return [Proc, nil] condition block or nil if arguments incomplete
409
421
  def generate_simple_condition_block(attribute = nil,
410
422
  after_collect_operation = nil,
411
423
  comparison_method = nil,
@@ -451,6 +463,9 @@ module Musa
451
463
 
452
464
  # @param content [Object] node content
453
465
  # @param attributes [Hash] node attributes
466
+ #
467
+ # @return [void]
468
+ #
454
469
  # @api private
455
470
  def initialize(content, attributes)
456
471
  super()
@@ -482,6 +497,9 @@ module Musa
482
497
  class BlockNode < Node
483
498
  # @param attributes [Hash] node attributes
484
499
  # @yield [parent, attributes] block to generate content
500
+ #
501
+ # @return [void]
502
+ #
485
503
  # @api private
486
504
  def initialize(attributes, &block)
487
505
  @attributes = attributes
@@ -516,6 +534,9 @@ module Musa
516
534
  class ConditionNode < Node
517
535
  # @param node [Node] node to filter
518
536
  # @yield [option] condition block
537
+ #
538
+ # @return [void]
539
+ #
519
540
  # @api private
520
541
  def initialize(node, &block)
521
542
  @node = node
@@ -545,6 +566,9 @@ module Musa
545
566
  class OrNode < Node
546
567
  # @param node1 [Node] first alternative
547
568
  # @param node2 [Node] second alternative
569
+ #
570
+ # @return [void]
571
+ #
548
572
  # @api private
549
573
  def initialize(node1, node2)
550
574
  @node1 = node1
@@ -579,6 +603,9 @@ module Musa
579
603
  class NextNode < Node
580
604
  # @param node [Node] first node in sequence
581
605
  # @param after [Node] node to follow
606
+ #
607
+ # @return [void]
608
+ #
582
609
  # @api private
583
610
  def initialize(node, after)
584
611
  @node = node
@@ -609,6 +636,9 @@ module Musa
609
636
  class RepeatNode < Node
610
637
  # @param node [Node] node to repeat
611
638
  # @param max [Integer, nil] maximum repetitions (nil = infinite)
639
+ #
640
+ # @return [void]
641
+ #
612
642
  # @api private
613
643
  def initialize(node, max = nil)
614
644
  @node = node
@@ -97,7 +97,7 @@ module Musa
97
97
  # Implements {Musa::Series::Serie} interface for integration with series operations.
98
98
  class Markov
99
99
  # TODO: adapt to series prototyping
100
- include Musa::Series::Serie.base
100
+ include Musa::Series::Serie::Base
101
101
 
102
102
  # Creates Markov chain generator.
103
103
  #
@@ -113,6 +113,8 @@ module Musa
113
113
  # start: :a,
114
114
  # finish: :x
115
115
  # )
116
+ #
117
+ # @return [void]
116
118
  def initialize(transitions:, start:, finish: nil, random: nil)
117
119
  @transitions = transitions.clone.freeze
118
120
 
@@ -149,6 +149,8 @@ module Musa
149
149
  # cut 'validate' { |obj| prune if invalid?(obj) }
150
150
  # ended_when { |obj| complete?(obj) }
151
151
  # end
152
+ #
153
+ # @return [void]
152
154
  def initialize(&block)
153
155
  @dsl = RulesEvalContext.new(&block)
154
156
  end
@@ -257,6 +259,7 @@ module Musa
257
259
  # @return [Array<CutRule>] cut rules
258
260
  attr_reader :_grow_rules, :_ended_when, :_cut_rules
259
261
 
262
+ # @return [void]
260
263
  # @api private
261
264
  def initialize(&block)
262
265
  @_grow_rules = []
@@ -296,10 +299,24 @@ module Musa
296
299
  self
297
300
  end
298
301
 
302
+ # Checks if end condition is defined.
303
+ #
304
+ # @return [Boolean] true if ended_when was called
305
+ #
306
+ # @api private
299
307
  def _has_ending?
300
308
  !@_ended_when.nil?
301
309
  end
302
310
 
311
+ # Evaluates end condition for object.
312
+ #
313
+ # @param object [Object] object to check
314
+ # @param history [Array] object history
315
+ # @param parameters [Hash] additional parameters
316
+ #
317
+ # @return [Boolean] true if object should end
318
+ #
319
+ # @api private
303
320
  def _ended?(object, history, **parameters)
304
321
  if @_ended_when
305
322
  with object, history, **parameters, &@_ended_when
@@ -311,11 +328,21 @@ module Musa
311
328
  class GrowRule
312
329
  attr_reader :name
313
330
 
331
+ # @param name [String] rule name
332
+ #
333
+ # @return [void]
314
334
  def initialize(name, &block)
315
335
  @name = name
316
336
  @block = block
317
337
  end
318
338
 
339
+ # Generates possible branched objects.
340
+ #
341
+ # @param object [Object] object to branch
342
+ # @param history [Array] object history
343
+ # @param parameters [Hash] additional parameters
344
+ #
345
+ # @return [Array<Object>] branched objects
319
346
  def generate_possibilities(object, history, **parameters)
320
347
  # TODO: optimize context using only one instance for all genereate_possibilities calls
321
348
  context = GrowRuleEvalContext.new
@@ -329,10 +356,16 @@ module Musa
329
356
 
330
357
  attr_reader :_branches
331
358
 
359
+ # @return [void]
332
360
  def initialize
333
361
  @_branches = []
334
362
  end
335
363
 
364
+ # Records a branched object.
365
+ #
366
+ # @param object [Object] branched object
367
+ #
368
+ # @return [self]
336
369
  def branch(object)
337
370
  @_branches << object
338
371
  self
@@ -347,11 +380,21 @@ module Musa
347
380
  class CutRule
348
381
  attr_reader :reason
349
382
 
383
+ # @param reason [String] rejection reason
384
+ #
385
+ # @return [void]
350
386
  def initialize(reason, &block)
351
387
  @reason = reason
352
388
  @block = block
353
389
  end
354
390
 
391
+ # Checks if object should be rejected.
392
+ #
393
+ # @param object [Object] object to check
394
+ # @param history [Array] object history
395
+ # @param parameters [Hash] additional parameters
396
+ #
397
+ # @return [Array<String>, nil] rejection reasons or nil if not rejected
355
398
  def rejects?(object, history, **parameters)
356
399
  # TODO: optimize context using only one instance for all rejects? checks
357
400
  context = CutRuleEvalContext.new
@@ -367,10 +410,16 @@ module Musa
367
410
 
368
411
  attr_reader :_secondary_reasons
369
412
 
413
+ # @return [void]
370
414
  def initialize
371
415
  @_secondary_reasons = []
372
416
  end
373
417
 
418
+ # Marks object for pruning.
419
+ #
420
+ # @param secondary_reason [String, nil] additional reason detail
421
+ #
422
+ # @return [self]
374
423
  def prune(secondary_reason = nil)
375
424
  @_secondary_reasons << secondary_reason
376
425
  self
@@ -399,6 +448,11 @@ module Musa
399
448
  class Node
400
449
  attr_reader :parent, :children, :object, :rejected
401
450
 
451
+ # @param object [Object, nil] node object
452
+ # @param parent [Node, nil] parent node
453
+ #
454
+ # @return [void]
455
+ #
402
456
  # @api private
403
457
  def initialize(object = nil, parent = nil)
404
458
  @parent = parent
@@ -143,6 +143,8 @@ module Musa
143
143
  # field :y, [:a, :b]
144
144
  # constructor { |x:, y:| { x: x, y: y } }
145
145
  # end
146
+ #
147
+ # @return [void]
146
148
  def initialize(instance_name, &block)
147
149
  raise ArgumentError, 'instance_name should be a symbol' unless instance_name.is_a?(Symbol)
148
150
  raise ArgumentError, 'block is needed' unless block
@@ -259,6 +261,11 @@ module Musa
259
261
 
260
262
  private
261
263
 
264
+ # Generates evaluation tree for parameter calculation.
265
+ #
266
+ # @param fieldset [Fieldset] fieldset to process
267
+ #
268
+ # @return [A, nil] root node of evaluation tree
262
269
  def generate_eval_tree_A(fieldset)
263
270
  root = nil
264
271
  current = nil
@@ -279,6 +286,11 @@ module Musa
279
286
  root
280
287
  end
281
288
 
289
+ # Generates evaluation tree for attribute application.
290
+ #
291
+ # @param fieldset [Fieldset] fieldset to process
292
+ #
293
+ # @return [B] root node of attribute tree
282
294
  def generate_eval_tree_B(fieldset)
283
295
  affected_field_names = []
284
296
  inner = []
@@ -298,12 +310,19 @@ module Musa
298
310
  attr_reader :parameter_name, :options
299
311
  attr_accessor :inner
300
312
 
313
+ # @param parameter_name [Symbol] parameter name
314
+ # @param options [Array] option values
315
+ #
316
+ # @return [void]
301
317
  def initialize(parameter_name, options)
302
318
  @parameter_name = parameter_name
303
319
  @options = options
304
320
  @inner = nil
305
321
  end
306
322
 
323
+ # Calculates all parameter combinations.
324
+ #
325
+ # @return [Array<Hash>] parameter combination hashes
307
326
  def calc_parameters
308
327
  unless @calc_parameters
309
328
  if inner
@@ -320,16 +339,19 @@ module Musa
320
339
  private_constant :A
321
340
 
322
341
  class A1 < A
342
+ # @return [void]
323
343
  def initialize(parameter_name, options)
324
344
  super parameter_name, options
325
345
 
326
346
  @own_parameters = @options.collect { |option| { @parameter_name => option } }
327
347
  end
328
348
 
349
+ # @return [Array<Hash>] own parameter combinations
329
350
  def calc_own_parameters
330
351
  @own_parameters
331
352
  end
332
353
 
354
+ # @return [String] string representation
333
355
  def inspect
334
356
  "A1 name: #{@parameter_name}, options: #{@options}, inner: #{@inner || 'nil'}"
335
357
  end
@@ -340,6 +362,11 @@ module Musa
340
362
  private_constant :A1
341
363
 
342
364
  class A2 < A
365
+ # @param parameter_name [Symbol] parameter name
366
+ # @param options [Array] option values
367
+ # @param subcomponent [A] nested tree
368
+ #
369
+ # @return [void]
343
370
  def initialize(parameter_name, options, subcomponent)
344
371
  super parameter_name, options
345
372
 
@@ -361,10 +388,12 @@ module Musa
361
388
  @own_parameters = result
362
389
  end
363
390
 
391
+ # @return [Array<Hash>] own parameter combinations
364
392
  def calc_own_parameters
365
393
  @own_parameters
366
394
  end
367
395
 
396
+ # @return [String] string representation
368
397
  def inspect
369
398
  "A2 name: #{@parameter_name}, options: #{@options}, subcomponent: #{@subcomponent}, inner: #{@inner || 'nil'}"
370
399
  end
@@ -383,6 +412,13 @@ module Musa
383
412
  class B
384
413
  attr_reader :parameter_name, :options, :affected_field_names, :blocks, :inner
385
414
 
415
+ # @param parameter_name [Symbol] parameter name
416
+ # @param options [Array] option values
417
+ # @param affected_field_names [Array<Symbol>] field names affected
418
+ # @param inner [Array<B>] nested B nodes
419
+ # @param blocks [Array<Proc>] with_attributes blocks
420
+ #
421
+ # @return [void]
386
422
  def initialize(parameter_name, options, affected_field_names, inner, blocks)
387
423
  @parameter_name = parameter_name
388
424
  @options = options
@@ -392,6 +428,12 @@ module Musa
392
428
  @procedures = blocks.collect { |proc| Musa::Extension::SmartProcBinder::SmartProcBinder.new proc }
393
429
  end
394
430
 
431
+ # Runs attribute application for this node.
432
+ #
433
+ # @param parameters_with_depth [Hash] parameters with nesting depth
434
+ # @param parent_parameters [Hash, nil] parent context parameters
435
+ #
436
+ # @return [void]
395
437
  def run(parameters_with_depth, parent_parameters = nil)
396
438
  parent_parameters ||= {}
397
439
 
@@ -417,6 +459,7 @@ module Musa
417
459
  end
418
460
  end
419
461
 
462
+ # @return [String] string representation
420
463
  def inspect
421
464
  "B name: #{@parameter_name}, options: #{@options}, affected_field_names: #{@affected_field_names}, blocks_size: #{@blocks.size}, inner: #{@inner}"
422
465
  end
@@ -435,6 +478,10 @@ module Musa
435
478
  # @return [Fieldset] defined fieldset
436
479
  attr_reader :_fieldset
437
480
 
481
+ # @param name [Symbol] fieldset name
482
+ # @param options [Array, Range, nil] fieldset options
483
+ #
484
+ # @return [void]
438
485
  # @api private
439
486
  def initialize(name, options = nil, &block)
440
487
  @_fieldset = Fieldset.new name, options.arrayfy.explode_ranges
@@ -446,6 +493,8 @@ module Musa
446
493
  #
447
494
  # @param name [Symbol] field name
448
495
  # @param options [Array, Range, nil] field option values
496
+ #
497
+ # @return [void]
449
498
  # @api private
450
499
  def field(name, options = nil)
451
500
  @_fieldset.components << Field.new(name, options.arrayfy.explode_ranges)
@@ -455,7 +504,10 @@ module Musa
455
504
  #
456
505
  # @param name [Symbol] fieldset name
457
506
  # @param options [Array, Range, nil] fieldset option values
507
+ #
458
508
  # @yield fieldset DSL block
509
+ #
510
+ # @return [void]
459
511
  # @api private
460
512
  def fieldset(name, options = nil, &block)
461
513
  fieldset_context = FieldsetContext.new name, options, &block
@@ -465,6 +517,8 @@ module Musa
465
517
  # Adds attribute modification block.
466
518
  #
467
519
  # @yield attribute modification block
520
+ #
521
+ # @return [void]
468
522
  # @api private
469
523
  def with_attributes(&block)
470
524
  @_fieldset.with_attributes << block
@@ -481,6 +535,7 @@ module Musa
481
535
  # @return [Proc, nil] finalize block
482
536
  attr_reader :_constructor, :_finalize
483
537
 
538
+ # @return [void]
484
539
  # @api private
485
540
  def initialize(&block)
486
541
  @_constructor = nil
@@ -492,6 +547,8 @@ module Musa
492
547
  # Defines object constructor.
493
548
  #
494
549
  # @yield constructor block receiving field values
550
+ #
551
+ # @return [void]
495
552
  # @api private
496
553
  def constructor(&block)
497
554
  @_constructor = block
@@ -500,6 +557,8 @@ module Musa
500
557
  # Defines finalize block.
501
558
  #
502
559
  # @yield finalize block receiving completed object
560
+ #
561
+ # @return [void]
503
562
  # @api private
504
563
  def finalize(&block)
505
564
  @_finalize = block
@@ -512,6 +571,7 @@ module Musa
512
571
  attr_reader :name
513
572
  attr_accessor :options
514
573
 
574
+ # @return [String] string representation
515
575
  def inspect
516
576
  "Field #{@name} options: #{@options}"
517
577
  end
@@ -520,6 +580,10 @@ module Musa
520
580
 
521
581
  private
522
582
 
583
+ # @param name [Symbol] field name
584
+ # @param options [Array] option values
585
+ #
586
+ # @return [void]
523
587
  def initialize(name, options)
524
588
  @name = name
525
589
  @options = options
@@ -532,6 +596,7 @@ module Musa
532
596
  attr_reader :name, :with_attributes, :components
533
597
  attr_accessor :options
534
598
 
599
+ # @return [String] string representation
535
600
  def inspect
536
601
  "Fieldset #{@name} options: #{@options} components: #{@components}"
537
602
  end
@@ -540,6 +605,10 @@ module Musa
540
605
 
541
606
  private
542
607
 
608
+ # @param name [Symbol] fieldset name
609
+ # @param options [Array, nil] option values
610
+ #
611
+ # @return [void]
543
612
  def initialize(name, options)
544
613
  @name = name
545
614
  @options = options || [nil]
@@ -79,6 +79,8 @@ module Musa
79
79
  # @see https://github.com/javier-sy/midi-events MIDIEvents documentation
80
80
  class MIDIRecorder
81
81
  # @param sequencer [Musa::Sequencer::Sequencer] provides the musical position for each recorded message.
82
+ #
83
+ # @return [void]
82
84
  def initialize(sequencer)
83
85
  @sequencer = sequencer
84
86
  @midi_parser = MIDIParser.new
@@ -179,6 +181,8 @@ module Musa
179
181
  #
180
182
  # @param position [Rational] sequencer position when captured.
181
183
  # @param message [MIDIEvents::Event] parsed MIDI event.
184
+ #
185
+ # @return [void]
182
186
  def initialize(position, message)
183
187
  @position = position
184
188
  @message = message
@@ -97,6 +97,8 @@ module Musa
97
97
  # @param output [#puts, nil] anything responding to `puts` that accepts `MIDIEvents::Event`s (typically a MIDICommunications output).
98
98
  # @param channels [Array<Numeric>, Range, Numeric] list of MIDI channels to control. Ranges are expanded automatically.
99
99
  # @param do_log [Boolean] enables info level logs per emitted message.
100
+ #
101
+ # @return [void]
100
102
  def initialize(sequencer:, output:, channels:, do_log: nil)
101
103
  do_log ||= false
102
104
 
@@ -200,6 +202,8 @@ module Musa
200
202
  # @param output [#puts, nil]
201
203
  # @param channel [Integer] MIDI channel number (0-15).
202
204
  # @param name [String, nil] human friendly identifier.
205
+ #
206
+ # @return [void]
203
207
  def initialize(sequencer:, output:, channel:, name: nil, do_log: nil)
204
208
  do_log ||= false
205
209
 
@@ -337,6 +341,8 @@ module Musa
337
341
  class ControllersControl
338
342
  # @param output [#puts] MIDI output.
339
343
  # @param channel [Integer] MIDI channel number.
344
+ #
345
+ # @return [void]
340
346
  def initialize(output, channel)
341
347
  @output = output
342
348
  @channel = channel
@@ -368,6 +374,8 @@ module Musa
368
374
  #
369
375
  # @param controller_number_or_symbol [Integer, Symbol] CC number or well-known alias (see +@controller_map+).
370
376
  # @param value [Integer] byte value that will be clamped to 0-127.
377
+ #
378
+ # @return [Integer] clamped value
371
379
  def []=(controller_number_or_symbol, value)
372
380
  number = number_of(controller_number_or_symbol)
373
381
  value ||= 0
@@ -377,10 +385,12 @@ module Musa
377
385
  end
378
386
 
379
387
  # @return [Integer, nil] last value assigned to the controller.
380
- def [](controller_number_or_symbol)
388
+ def get(controller_number_or_symbol)
381
389
  @controller[number_of(controller_number_or_symbol)]
382
390
  end
383
391
 
392
+ alias_method :[], :get
393
+
384
394
  # Resolves a controller reference to its MIDI CC number.
385
395
  #
386
396
  # @param controller_number_or_symbol [Integer, Symbol] CC number or alias.
@@ -429,6 +439,8 @@ module Musa
429
439
  # @param velocity [Numeric, Array<Numeric>] on velocity (can be per-note).
430
440
  # @param duration [Numeric, nil] duration in bars or nil for infinite.
431
441
  # @param velocity_off [Numeric, Array<Numeric>] release velocity.
442
+ #
443
+ # @return [void]
432
444
  def initialize(voice, pitch:, velocity: nil, duration: nil, velocity_off: nil)
433
445
  raise ArgumentError, "MIDIVoice: note duration should be nil or Numeric: #{duration} (#{duration.class})" unless duration.nil? || duration.is_a?(Numeric)
434
446
 
@@ -1,5 +1,3 @@
1
- require 'set'
2
-
3
1
  module Musa
4
2
  # Chord construction and manipulation framework.
5
3
  #
@@ -115,10 +113,14 @@ module Musa
115
113
  # @example
116
114
  # ChordDefinition[:maj] # => <ChordDefinition :maj>
117
115
  # ChordDefinition[:min7] # => <ChordDefinition :min7>
118
- def self.[](name)
116
+ def self.get(name)
119
117
  @definitions[name]
120
118
  end
121
119
 
120
+ class << self
121
+ alias_method :[], :get
122
+ end
123
+
122
124
  # Registers a new chord definition.
123
125
  #
124
126
  # Creates and registers a chord definition with specified intervals and features.
@@ -150,7 +152,7 @@ module Musa
150
152
  definition.features.each { |k, v| @features_by_value[v] = k }
151
153
 
152
154
  @feature_keys ||= Set[]
153
- features.keys.each { |feature_name| @feature_keys << feature_name }
155
+ features.each_key { |feature_name| @feature_keys << feature_name }
154
156
 
155
157
  self
156
158
  end
@@ -267,7 +269,7 @@ module Musa
267
269
 
268
270
  # Checks if chord fits within a scale.
269
271
  #
270
- # @param scale [Scale] scale to check against
272
+ # @param scale [Scales::Scale] scale to check against
271
273
  # @param chord_root_pitch [Integer] chord root pitch
272
274
  # @return [Boolean] true if all chord notes are in scale
273
275
  #
@@ -1,5 +1,42 @@
1
1
  require_relative 'chord-definition'
2
2
 
3
+ # Standard chord definitions for Western harmony.
4
+ #
5
+ # This file registers the common chord types used in Western music theory,
6
+ # organized by size (number of notes) and quality (major, minor, etc.).
7
+ #
8
+ # ## Chord Categories
9
+ #
10
+ # ### Triads (3 notes)
11
+ # - **Major** (:maj) - Root, major 3rd, perfect 5th (0-4-7)
12
+ # - **Minor** (:min) - Root, minor 3rd, perfect 5th (0-3-7)
13
+ # - **Diminished** (:dim) - Root, minor 3rd, diminished 5th (0-3-6)
14
+ # - **Augmented** (:aug) - Root, major 3rd, augmented 5th (0-4-8)
15
+ #
16
+ # ### Seventh Chords (4 notes)
17
+ # - **Major 7th** (:maj7) - Major triad + major 7th (0-4-7-11)
18
+ # - **Minor 7th** (:min7) - Minor triad + minor 7th (0-3-7-10)
19
+ # - **Dominant 7th** (:dom7) - Major triad + minor 7th (0-4-7-10)
20
+ #
21
+ # ### Extended Chords (5+ notes)
22
+ # - **9th chords**: :maj9, :min9, :dom9
23
+ # - **11th chords**: :maj11, :min11
24
+ # - **13th chords**: :maj13, :min13
25
+ #
26
+ # ## Usage
27
+ #
28
+ # Chords are accessed via scale notes using the {Musa::Scales::NoteInScale#chord} method:
29
+ #
30
+ # scale = Scales.et12[440.0].major[60]
31
+ # scale.tonic.chord # Major triad (default)
32
+ # scale.tonic.chord :seventh # Major 7th
33
+ # scale.dominant.chord :seventh # Dominant 7th
34
+ # scale.tonic.chord quality: :minor # Minor triad
35
+ #
36
+ # @see Musa::Chords::ChordDefinition.register How chords are registered
37
+ # @see Musa::Chords::Chord How to build and use chords
38
+ # @see Musa::Scales::NoteInScale#chord Building chords from scale notes
39
+
3
40
  # TODO trasladar los acordes de https://en.wikipedia.org/wiki/Chord_notation
4
41
 
5
42
  # TRIADS