Module: MusicSetTheory::MusUtility
- Included in:
- MusicSetTheory, MusicSetTheory, NoteSeq, Temperament, Temperament
- Defined in:
- lib/music_set_theory/musutility.rb,
lib/music_set_theory/musutility.rb,
lib/music_set_theory/musutility.rb
Constant Summary collapse
- SPACECOMMA =
Generates a unicode string from the items in seq delimited by commas. For example repseq([1, 2, 3]) produces "1, 2, 3". Arguments: seq: a sequence of items. pre_process: a function taking one argument and returning another. The function will execute this on each item in seq before concatenating them together. By default, nothing is done to each argument.
", "
Instance Method Summary collapse
- #deep_freeze(obj) ⇒ Object
- #deep_melt(obj) ⇒ Object
-
#enl_seq(seq_of_seq, otherentries) ⇒ Object
Returns a sequence of sequences, with each element consisting of an element from otherentries appended to a sequence from seq_of_seq.
-
#multislice(seq, slice, mod: 0, offset: 0) ⇒ Object
The multislice function takes a multiple-element-slice (see below) of a sequence, rotates it if necessary afterward, and returns it.
-
#norm_seq(seq, mod) ⇒ Object
This function takes a sequence (of numbers) and "normalizes" it.
- #repseq(seq, pre_process = lambda{|x| x}) ⇒ Object
-
#rotate(seq, offset) ⇒ Object
Original comments: Rotates a seq to the left by offset places; the elements shifted off are inserted back at the end.
-
#rotate_and_zero(seq, offset, mod = 0, debug_f: false) ⇒ Object
Original comments: Returns the result of: (a) rotating a sequence to a given offset; and then, (b) scalar subtracting the resulting first element from the rotated sequence.
-
#scalar_addition(seq, scalar, mod = 0) ⇒ Object
Original comments: Returns the result of adding scalar (a number) to all elements in seq.
-
#seqtostr(value) ⇒ Object
Make sequences representable as strings.
Instance Method Details
#deep_freeze(obj) ⇒ Object
271 272 273 |
# File 'lib/music_set_theory/musutility.rb', line 271 def deep_freeze( obj ) IceNine.deep_freeze(obj) end |
#deep_melt(obj) ⇒ Object
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 |
# File 'lib/music_set_theory/musutility.rb', line 275 def deep_melt( obj ) case obj when Hash obj.each_with_object({}) do |(key, value), new_hash| new_hash[deep_melt(key)] = deep_melt(value) end when Array obj.map { |element| deep_melt(element) } when Object # インスタンス変数の解除 obj.instance_variables.each do |var| deep_melt(var) value = obj.instance_variable_get(var) obj.remove_instance_variable(var) obj.instance_variable_set(var, deep_melt(value)) end obj.dup rescue obj # 凍結状態を解除 else obj.dup rescue obj end obj.dup rescue obj end |
#enl_seq(seq_of_seq, otherentries) ⇒ Object
Returns a sequence of sequences, with each element consisting of an element from otherentries appended to a sequence from seq_of_seq.
Note: this is used for building chords.
223 224 225 226 227 228 229 230 231 |
# File 'lib/music_set_theory/musutility.rb', line 223 def enl_seq( seq_of_seq, otherentries ) ret = [] for i in seq_of_seq for j in otherentries ret.append(i + [j]) end end ret end |
#multislice(seq, slice, mod: 0, offset: 0) ⇒ Object
The multislice function takes a multiple-element-slice (see below) of a sequence, rotates it if necessary afterward, and returns it. The arguments:
Args
- seq
a sequence to slice and/or rotate.
- slice
another sequence which specifies the elements preserved in seq. This consists of integers, which indicate the indices of elements in seq to preserve. If i is in slice, then seq is preserved; otherwise, it is discarded. (Slicing always happens before rotation).
- mod
if present, then all indices in slice are taken modulo this number. I.e., seq is preserved if and only if j some k modulo mod, where k is in slice.
- offset
after slicing, this sequence is rotated this number of places.
def multislice( seq, slice, mod = 0, offset = 0 )
183 184 185 186 187 188 189 190 191 |
# File 'lib/music_set_theory/musutility.rb', line 183 def multislice( seq, slice, mod: 0, offset: 0 ) ret = nil if 0 == mod ret = slice.map{|index| rotate(seq, offset)[index] } else ret = slice.map{|index| rotate(seq, offset)[index % mod] } end ret end |
#norm_seq(seq, mod) ⇒ Object
This function takes a sequence (of numbers) and "normalizes" it. To be specific, it evaluates all numbers inside seq modulo mod. The result is then sorted, and any duplicates are removed.
Note: this function is useful for looking up chords by their patterns.
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/music_set_theory/musutility.rb', line 240 def norm_seq( seq, mod ) #sorted_seq = sorted([x % mod for x in seq]) sorted_seq = seq.map{|x| x % mod }.sort # We remove duplicates. The following code is straight outta the Python FAQ. # last = sorted_seq[-1] # for i in range(len(sorted_seq)-2, -1, -1) (sorted_seq.size-2).step(0, -1) do |i| if last == sorted_seq[i] # del sorted_seq[i] sorted_seq.delete_at(i) else last = sorted_seq[i] end end sorted_seq end |
#repseq(seq, pre_process = lambda{|x| x}) ⇒ Object
202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/music_set_theory/musutility.rb', line 202 def repseq( seq, pre_process = lambda{|x| x} ) if seq.size == 0 return "" end #str_out = ''.join([(str(pre_process(item)) + SPACECOMMA) # for item in seq[:-1]]) + str(pre_process(seq[-1])); # ret = (seq[0...-1].map{|item| pre_process.(item).to_s }.join(SPACECOMMA)) + # + SPACECOMMA + pre_process.(seq[-1]).to_s ret = (seq[0...-1].map{|item| pre_process.(item).to_s } + [pre_process.(seq[-1]).to_s]).join(SPACECOMMA) ret end |
#rotate(seq, offset) ⇒ Object
Original comments: Rotates a seq to the left by offset places; the elements shifted off are inserted back at the end. By setting offset to the negative number -N, this function rotates the sequence N places.
Note: this algorithm is a modification of one originally provided by Thorsten Kampe; this version handles zero sequences and right shifts. See: http://bytes.com/topic/python/answers/36070-rotating-lists
110 111 112 |
# File 'lib/music_set_theory/musutility.rb', line 110 def rotate( seq, offset ) seq.rotate(offset) end |
#rotate_and_zero(seq, offset, mod = 0, debug_f: false) ⇒ Object
Original comments: Returns the result of:
(a) rotating a sequence to a given offset; and then,
(b) scalar subtracting the resulting first element from the rotated
sequence.
The result always begins with zero (except when seq is []). If mod is not 0, then all subtraction occurs modulo mod.
Note: this function is useful in generating different modes of a scale and different synonyms of a chord.
153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/music_set_theory/musutility.rb', line 153 def rotate_and_zero( seq, offset, mod = 0, debug_f: false ) return seq if seq.empty? rotated_seq = rotate(seq, offset) first_elem = rotated_seq[0] $stderr.puts "{#{__method__}} seq: #{seq}, offset: #{offset}" if debug_f $stderr.puts "{#{__method__}} rotated: #{rotated_seq}," + " 1st: #{first_elem.inspect}" if debug_f return scalar_addition(rotated_seq, 0 - first_elem, mod) end |
#scalar_addition(seq, scalar, mod = 0) ⇒ Object
Original comments: Returns the result of adding scalar (a number) to all elements in seq. If mod is not 0, then all addition occurs modulo mod.
Note: this function is an "analogue" of scalar multiplication - an operation where every element in a sequence is multiplied by a scalar. We can also use this function to perform "scalar subtraction" - the subtraction of a scalar from all elements in a sequence. """
130 131 132 133 134 135 136 137 138 |
# File 'lib/music_set_theory/musutility.rb', line 130 def scalar_addition( seq, scalar, mod = 0 ) seq.map{|index| if 0 == mod index + scalar else (index + scalar) % mod end } end |
#seqtostr(value) ⇒ Object
Make sequences representable as strings.
Writes a sequence as a comma delimited string.
78 79 80 81 82 |
# File 'lib/music_set_theory/musutility.rb', line 78 def seqtostr( value ) ary = value ary = ary.to_a unless ary.is_a? Array ary.join(", ") end |