<commit_before>
module Music
	module Utils
		def self.included(base)
			base.send(:include, InstanceMethods)
		end

		module InstanceMethods
			include Music::Constants

			# Looks up a scale pattern. You can also use Arrays or Hashes
			# directly.
			def find_scale_pattern(pattern)
				case pattern
					when Symbol, String
						if SCALE_PATTERNS[pattern.to_sym]
							SCALE_PATTERNS[pattern.to_sym][:pattern]
						else
							raise BadScalePattern.new(pattern)
						end
					when Hash
						pattern[:pattern]
					when Array
						pattern
				end
			end


			# Looks up a chord type. You can also use Arrays or Hashes
			# directly.
			def find_chord_type(t)
				case t
					when Symbol, String
						if CHORD_TYPES[t.to_sym]
							CHORD_TYPES[t.to_sym][:intervals]
						else
							raise BadChordType.new(t)
						end
					when Hash
						t[:intervals]
					when Array
						t
				end
			end


			# Figure out the actual notes in the scale.
			#
			# * key is one of the notes from notes
			# * pattern is a pattern from SCALE_PATTERNS or an Array
			#   representing a pattern.
			def find_scale_notes(key, pattern)
				start = find_note_from_char(key)
				key_notes = [ key ]

				find_scale_pattern(pattern).each do |v|
					start += case v
						when 'h'
							1
						when 'w'
							2
						when 'wh'
							3
						when 'ww'
							4
						else
							raise BadScalePattern.new(v)
					end
					key_notes << find_note_from_index(start)
				end

				# This is good... a proper scale... otherwise, we should popup
				# a warning that this scale isn't all that great, as it doesn't
				# end in the same note it starts from...
				if (key_notes.first == key_notes.last)
					key_notes.pop
				else
					raise BadScalePattern.new("scale doesn't end on same note as key!!")
				end

				return key_notes
			end


			# Translate a series of 'h', 'w', 'wh' and 'ww' strings to their
			# respective number of half steps.
			def find_scale_intervals(pattern)
				n = 0
				[ 0 ] + find_scale_pattern(pattern).collect do |offset|
					n += case offset
						when 'h'
							1
						when 'w'
							2
						when 'wh'
							3
						when 'ww'
							4
					end
				end
			end


			# Returns the index to NOTES for the note c.
			def find_note_from_char(c)
				NOTES.index(c) or
					raise BadNote.new(c)
			end


			# Returns the value from NOTES for the index i.
			def find_note_from_index(i)
				NOTES[((i.to_i).modulo(NOTES.length))] or
					raise BadNote.new(i)
			end

			# Figure out what notes are in a chord based on the key and the
			# chord type.
			#
			# * key is one of the notes from NOTES
			# * type is a chord type from CHORD_TYPES or an Array of integers
			#   representing intervals.
			def find_chord_notes(key, type)
				start = find_note_from_char(key)

				find_chord_type(type).collect do |v|
					find_note_from_index(start + v.to_i)
				end
			end


			# Used by some interval lookup methods to possibly convert string
			# notes to intervals where necessary.
			def interval_or_note_to_interval(key, interval)
				key = find_note_from_char(key) if key.is_a?(String)

				case interval
					when String
						(NOTES.index(interval) - key).modulo(NOTES.length)
					when Fixnum
						interval
					else
						raise BadNote.new(v)
				end
			end


			# Find intervals between notes in a chord or on a scale. Returns an
			# Array of Arrays where the internal Arrays are set up as
			# [ note, interval name ] in order starting with the tonic.
			#
			# * root is the tonic, a note from NOTES
			# * notes is an Array of notes
			def find_intervals(root, notes = NOTES)
				start = find_note_from_char(root)
				retval = Array.new
				Array(notes).each do |v|
					n = interval_or_note_to_interval(start, v)
					name = case n
						when 0
							'tonic'
						when 1
							'minor second'
						when 2
							'major second'
						when 3
							'minor third'
						when 4
							'major third'
						when 5<commit_msg>Code clean up.<commit_after>
module Music
	module Utils
		def self.included(base)
			base.send(:include, InstanceMethods)
		end

		module InstanceMethods
			include Music::Constants

			# Looks up a scale pattern. You can also use Arrays or Hashes
			# directly.
			def find_scale_pattern(pattern)
				case pattern
					when Symbol, String
						SCALE_PATTERNS[pattern.to_sym][:pattern] rescue raise BadScalePattern.new(pattern)
					when Hash
						pattern[:pattern]
					when Array
						pattern
				end
			end


			# Looks up a chord type. You can also use Arrays or Hashes
			# directly.
			def find_chord_type(t)
				case t
					when Symbol, String
						CHORD_TYPES[t.to_sym][:intervals] rescue raise BadChordType.new(t)
					when Hash
						t[:intervals]
					when Array
						t
				end
			end


			# Figure out the actual notes in the scale.
			#
			# * key is one of the notes from notes
			# * pattern is a pattern from SCALE_PATTERNS or an Array
			#   representing a pattern.
			def find_scale_notes(key, pattern)
				start = find_note_from_char(key)
				key_notes = [ key ]

				find_scale_pattern(pattern).each do |v|
					start += case v
						when 'h'
							1
						when 'w'
							2
						when 'wh'
							3
						when 'ww'
							4
						else
							raise BadScalePattern.new(v)
					end
					key_notes << find_note_from_index(start)
				end

				# This is good... a proper scale... otherwise, we should popup
				# a warning that this scale isn't all that great, as it doesn't
				# end in the same note it starts from...
				if (key_notes.first == key_notes.last)
					key_notes.pop
				else
					raise BadScalePattern.new("scale doesn't end on same note as key!!")
				end

				return key_notes
			end


			# Translate a series of 'h', 'w', 'wh' and 'ww' strings to their
			# respective number of half steps.
			def find_scale_intervals(pattern)
				n = 0
				[ 0 ] + find_scale_pattern(pattern).collect do |offset|
					n += case offset
						when 'h'
							1
						when 'w'
							2
						when 'wh'
							3
						when 'ww'
							4
					end
				end
			end


			# Returns the index to NOTES for the note c.
			def find_note_from_char(c)
				NOTES.index(c) or
					raise BadNote.new(c)
			end


			# Returns the value from NOTES for the index i.
			def find_note_from_index(i)
				NOTES[((i.to_i).modulo(NOTES.length))] or
					raise BadNote.new(i)
			end

			# Figure out what notes are in a chord based on the key and the
			# chord type.
			#
			# * key is one of the notes from NOTES
			# * type is a chord type from CHORD_TYPES or an Array of integers
			#   representing intervals.
			def find_chord_notes(key, type)
				start = find_note_from_char(key)

				find_chord_type(type).collect do |v|
					find_note_from_index(start + v)
				end
			end


			# Used by some interval lookup methods to possibly convert string
			# notes to intervals where necessary.
			def interval_or_note_to_interval(key, interval)
				key = find_note_from_char(key) if key.is_a?(String)

				case interval
					when String
						(NOTES.index(interval) - key).modulo(NOTES.length)
					when Fixnum
						interval
					else
						raise BadNote.new(interval)
				end
			end


			# Find intervals between notes in a chord or on a scale. Returns an
			# Array of Arrays where the internal Arrays are set up as
			# [ note, interval name ] in order starting with the tonic.
			#
			# * root is the tonic, a note from NOTES
			# * notes is an Array of notes
			def find_intervals(root, notes = NOTES)
				start = find_note_from_char(root)
				retval = Array.new
				Array(notes).each do |v|
					n = interval_or_note_to_interval(start, v)
					name = case n
						when 0
							'tonic'
						when 1
							'minor second'
						when 2
							'major second'
						when 3
							'minor third'
						when 4
							'major third'
						when 5
{'fraction_non_alphanumeric': 0.07212525667351129, 'fraction_numerical': 0.004106776180698152, 'mean_word_length': 2.2269151138716357, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3903640', 'n_tokens_mistral': 3551, 'n_tokens_neox': 2498, 'n_words': 871}