Sha256: 9cf619658e1a02ac15d925afe4ee7a4ff72d22d0f86622d01b75dcef9994ab56

Contents?: true

Size: 1.7 KB

Versions: 1

Compression:

Stored size: 1.7 KB

Contents

# frozen_string_literal: true

module Coltrane
  # 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)
      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 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

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
coltrane-2.2.1 lib/coltrane/note_set.rb