Sha256: 3d9def3e47334201be60add7b11127b2a7109a7420cabb8a2f9457d0348eb09b

Contents?: true

Size: 2 KB

Versions: 22

Compression:

Stored size: 2 KB

Contents

# frozen_string_literal: true

module Coltrane
  module Theory
    # It describes a set of notes
    class NoteSet
      extend Forwardable

      def_delegators :@notes, :first, :each, :size, :map, :reduce, :index,
                     :[], :index, :empty?, :permutation, :include?, :<<, :any?,
                     :count, :rotate

      attr_reader :notes

      alias root first
      alias all notes

      def self.[](*notes)
        new(notes)
      end

      def initialize(arg)
        @notes =
          case arg
          when NoteSet then arg.notes
          when Array   then arg.compact.map { |n| n.is_a?(PitchClass) ? n : Note[n] }.uniq
          else raise InvalidNotesError, arg
          end
      end

      def ==(other)
        (self & other).size == self.size
      end

      alias eql? ==

      def &(other)
        NoteSet[*(notes & other.notes)]
      end

      def degree(note)
        index(note) + 1
      end

      def +(other)
        case other
        when Note then NoteSet[*(notes + [other])]
        when NoteSet then NoteSet[*notes, *other.notes]
        when Interval then NoteSet[*notes.map { |n| n + other }]
        end
      end

      def -(other)
        case other
        when NoteSet then NoteSet[*(notes - other.notes)]
        when Interval then NoteSet[*notes.map { |n| n - other }]
        end
      end

      def pretty_names
        map(&:pretty_name)
      end

      def names
        map(&:name)
      end

      def hash
        integers.join.to_i
      end

      def integers
        map(&:integer)
      end

      def accidentals
        count(&:accidental?)
      end

      def sharps
        count(&:sharp?)
      end

      def flats
        count(&:flat?)
      end

      def alter(alteration)
        NoteSet[*map { |n| n.alter(alteration) }]
      end

      def alter_accidentals(alteration)
        NoteSet[*map { |n| n.alter(alteration) if n.accidental? }]
      end

      def interval_sequence
        IntervalSequence.new(notes: self)
      end
    end
  end
end

Version data entries

22 entries across 22 versions & 1 rubygems

Version Path
coltrane-4.1.2 lib/coltrane/theory/note_set.rb
coltrane-4.1.1 lib/coltrane/theory/note_set.rb
coltrane-4.1.0 lib/coltrane/theory/note_set.rb
coltrane-4.0.6 lib/coltrane/theory/note_set.rb
coltrane-4.0.5 lib/coltrane/theory/note_set.rb
coltrane-4.0.4 lib/coltrane/theory/note_set.rb
coltrane-4.0.3 lib/coltrane/theory/note_set.rb
coltrane-3.4.2 lib/coltrane/theory/note_set.rb
coltrane-3.4.1 lib/coltrane/theory/note_set.rb
coltrane-3.4.0 lib/coltrane/theory/note_set.rb
coltrane-3.3.3 lib/coltrane/theory/note_set.rb
coltrane-3.3.2 lib/coltrane/theory/note_set.rb
coltrane-3.3.1 lib/coltrane/theory/note_set.rb
coltrane-3.3.0 lib/coltrane/theory/note_set.rb
coltrane-3.2.0 lib/coltrane/theory/note_set.rb
coltrane-3.1.3 lib/coltrane/theory/note_set.rb
coltrane-3.1.2 lib/coltrane/theory/note_set.rb
coltrane-3.1.1 lib/coltrane/theory/note_set.rb
coltrane-3.1.0 lib/coltrane/theory/note_set.rb
coltrane-3.0.0 lib/coltrane/theory/note_set.rb