post_tonal 0.1.1.pre → 0.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,17 +1,24 @@
1
1
  #CHANGELOG
2
2
 
3
+ ####October 22, 2012 [0.2.0.pre]
4
+ - Implements prime form
5
+ - Fixes normal form logic and updates tests
6
+
7
+ ####October 21, 2012 [0.1.1.pre]
8
+ - Adds homepage information to gem specification
9
+
3
10
  ####October 21, 2012 [0.1.1.pre]
4
- -Add homepage information to gem specification
11
+ - Adds homepage information to gem specification
5
12
 
6
13
  ####October 21, 2012 [0.1.0.pre]
7
- -Implement transposition in PitchClassSet
8
- -Change normal_form, inversion, and transpose so that they each return a PitchClassSet
14
+ - Implements transposition in PitchClassSet
15
+ - Changes normal_form, inversion, and transpose so that they each return a PitchClassSet
9
16
 
10
17
  ####October 20, 2012 [0.0.3.pre]
11
- -Implement inversion in PitchClassSet
18
+ - Implements inversion in PitchClassSet
12
19
 
13
20
  ####October 16, 2012 [0.0.2.pre]
14
- -Implement normal form in PitchClassSet
21
+ - Implements normal form in PitchClassSet
15
22
 
16
23
  ####October 15, 2012 [0.0.1.pre]
17
- - Create PitchClass, PitchClassSet, PitchClassInterval, PitchInterval, and NoteParser
24
+ - Creates PitchClass, PitchClassSet, PitchClassInterval, PitchInterval, and NoteParser
@@ -7,8 +7,9 @@ module PostTonal
7
7
 
8
8
  def initialize(pitch_classes = nil)
9
9
  @pitch_classes = pitch_classes || []
10
- @normalized_pitch_classes = pitch_classes ? self.class.to_normal_form(@pitch_classes) : []
11
- @inverted_pitch_classes = pitch_classes ? invert(@pitch_classes) : []
10
+ @normalized_pitch_classes = @pitch_classes.size > 0 ? self.class.to_normal_form(@pitch_classes) : []
11
+ @inverted_pitch_classes = @pitch_classes.size > 0 ? invert(@pitch_classes) : []
12
+ @prime_pitch_classes = @pitch_classes.size > 0 ? to_prime_form : []
12
13
  end
13
14
 
14
15
  # Add a pitch to the pitch class set
@@ -31,16 +32,17 @@ module PostTonal
31
32
  @pitch_classes << pc
32
33
  @normalized_pitch_classes = self.class.to_normal_form(@pitch_classes)
33
34
  @inverted_pitch_classes = invert(@pitch_classes)
35
+ @prime_pitch_classes = to_prime_form
34
36
  end
35
37
 
36
38
  pc
37
39
  end
38
40
 
39
41
  def eql?(pitch_class_set)
40
- return false if @pitch_classes.size != pitch_class_set.pitch_classes.size
42
+ return false if @pitch_classes.size != pitch_class_set.pitch_classes.size || @pitch_classes.size == 0
41
43
 
42
- @normalized_pitch_classes.each_with_index do |pitch_class, i|
43
- return false if !pitch_class_set.normal_form.pitch_classes[i].eql?(pitch_class)
44
+ @pitch_classes.each_with_index do |pitch_class, i|
45
+ return false if !pitch_class.eql?(pitch_class_set.pitch_classes[i])
44
46
  end
45
47
 
46
48
  true
@@ -75,19 +77,14 @@ module PostTonal
75
77
  if newLen < shortest[:length]
76
78
  shortest = {:array => normal.dup, :length => newLen}
77
79
  elsif newLen == shortest[:length]
78
- (normal.size - 1).downto(q) do |r|
79
80
 
80
- newLen = normal[r].value - normal.first.value
81
- newLen += 12 if newLen < 0
82
- newLen += 12 if newLen == 1 && normal.size > 2
81
+ rs = shortest[:array].reverse
82
+ normal.reverse.each_with_index do |pitch_class, i|
83
+ this_dist = (pitch_class.value - normal.first.value).abs
84
+ that_dist = (rs[i].value - rs.last.value).abs
83
85
 
84
- sNewLen = shortest[:array][r].value - shortest[:array].first.value
85
- sNewLen += 12 if sNewLen < 0
86
- sNewLen += 12 if sNewLen == 1 && normal.size > 2
87
-
88
- if newLen < sNewLen
89
- shortest = {:array => normal.dup, :length => newLen}
90
- break
86
+ if this_dist < that_dist
87
+ shortest = {:array => normal, :length => newLen}
91
88
  end
92
89
  end
93
90
  end
@@ -106,9 +103,21 @@ module PostTonal
106
103
  self.class.new(@normalized_pitch_classes)
107
104
  end
108
105
 
109
- # Transposes the set by a degree (integer)
106
+ # Returns a PitchClassSet of the current PitchClassSet in prime form
107
+ def prime_form
108
+ prime1 = normal_form.transpose_to_zero
109
+ prime2 = inversion.normal_form.transpose_to_zero
110
+ return prime2 if prime2.is_more_packed_than? prime1
111
+ prime1
112
+ end
113
+
114
+ # Transposes the set
115
+ #
116
+ # degree - The number of steps to transpose. May be positive or negative
117
+ # reset_octave - If true, resets octave attribute to 0 for all pitch classes
118
+ #
110
119
  # Returns PitchClassSet of the transposed set
111
- def transpose(degree)
120
+ def transpose(degree, reset_octave = false)
112
121
  transposed = self.class.new
113
122
 
114
123
  @pitch_classes.each do |pitch_class|
@@ -117,8 +126,12 @@ module PostTonal
117
126
 
118
127
  val += degree
119
128
 
120
- oct += val / 12
121
- oct -= 1 if val < 0 && val % 12 == 0
129
+ if reset_octave
130
+ oct = 0
131
+ else
132
+ oct += val / 12
133
+ oct -= 1 if val < 0 && val % 12 == 0
134
+ end
122
135
 
123
136
  transposed.add_pitch(val, oct)
124
137
  end
@@ -126,7 +139,34 @@ module PostTonal
126
139
  transposed
127
140
  end
128
141
 
129
- private
142
+ def reset_octave
143
+ ro = []
144
+
145
+ @pitch_classes.each do |pitch_class|
146
+ ro << PitchClass.new(pitch_class.value)
147
+ end
148
+
149
+ self.class.new(ro)
150
+ end
151
+
152
+ # Check if this pitch class set is more tightly packed to the left than the comparison pitch class set.
153
+ #
154
+ # Returns false if less tightly packed or if is the same set
155
+ def is_more_packed_than?(pitch_class_set)
156
+ return false if (@pitch_classes.size != pitch_class_set.pitch_classes.size || @pitch_classes.size == 0) || eql?(pitch_class_set)
157
+
158
+ rpcs = pitch_class_set.pitch_classes.reverse
159
+ @pitch_classes.reverse.each_with_index do |pitch_class, i|
160
+ this_dist = (pitch_class.value - @pitch_classes.first.value).abs
161
+ that_dist = (rpcs[i].value - rpcs.last.value).abs
162
+
163
+ return true if this_dist < that_dist
164
+ end
165
+
166
+ false
167
+ end
168
+
169
+ protected
130
170
 
131
171
  # Inverts an array of pitch classes. The PitchClass attribute octave may become invalid after inversion.
132
172
  # Returns a PitchClassSet of the inverted pitch classes
@@ -141,5 +181,22 @@ module PostTonal
141
181
  inverted
142
182
  end
143
183
 
184
+ # Returns the normal form of an array of pitch classes
185
+ def to_prime_form
186
+ #prime1 = normal_form.transpose_to_zero.pitch_classes
187
+ #prime2 = inversion.normal_form.transpose_to_zero
188
+
189
+ #return prime1.pitch_classes if prime1.is_more_packed_than? prime2
190
+ #return prime2.pitch_classes_classes
191
+ []
192
+ end
193
+
194
+ def transpose_to_zero
195
+ dist = 12 - @pitch_classes[0].value
196
+ "TT0: #{@pitch_classes}, dist: #{dist}"
197
+ return transpose(dist, true) if dist % 12 != 0
198
+ self
199
+ end
200
+
144
201
  end
145
202
  end
@@ -1,3 +1,3 @@
1
1
  module PostTonal
2
- VERSION = '0.1.1.pre'
2
+ VERSION = '0.2.0.pre'
3
3
  end
@@ -118,6 +118,20 @@ class PitchClassSetTest < Test::Unit::TestCase
118
118
  [6,7,0].each_with_index do |n, i|
119
119
  assert_equal(n, @p7.normal_form.pitch_classes[i].value)
120
120
  end
121
+
122
+ @p8 = PostTonal::PitchClassSet.new
123
+ @p8.add_pitch(0)
124
+ @p8.add_pitch(3)
125
+ @p8.add_pitch(8)
126
+ @p8.add_pitch(9)
127
+
128
+ @p8n = PostTonal::PitchClassSet.new
129
+ @p8n.add_pitch(8)
130
+ @p8n.add_pitch(9)
131
+ @p8n.add_pitch(0)
132
+ @p8n.add_pitch(3)
133
+
134
+ assert_equal(@p8n, @p8.normal_form, "Normal form of #{@p8} should be #{@p8n}")
121
135
  end
122
136
 
123
137
  def test_inversion
@@ -156,4 +170,117 @@ class PitchClassSetTest < Test::Unit::TestCase
156
170
  end
157
171
  end
158
172
 
173
+ def test_prime_form
174
+ @p1 = PostTonal::PitchClassSet.new
175
+ @p1.add_pitch(0)
176
+ @p1.add_pitch(1)
177
+ @p1.add_pitch(4)
178
+ @p1.add_pitch(7)
179
+
180
+ @p1p = PostTonal::PitchClassSet.new
181
+ @p1p.add_pitch(0)
182
+ @p1p.add_pitch(1)
183
+ @p1p.add_pitch(4)
184
+ @p1p.add_pitch(7)
185
+
186
+ assert_equal(@p1p, @p1.prime_form)
187
+
188
+
189
+ @p2 = PostTonal::PitchClassSet.new
190
+ @p2.add_pitch(6)
191
+ @p2.add_pitch(7)
192
+ @p2.add_pitch(8)
193
+
194
+ @p2p = PostTonal::PitchClassSet.new
195
+ @p2p.add_pitch(0)
196
+ @p2p.add_pitch(1)
197
+ @p2p.add_pitch(2)
198
+
199
+ assert_equal(@p2p, @p2.prime_form)
200
+
201
+ @p3 = PostTonal::PitchClassSet.new
202
+ @p3.add_pitch(0)
203
+ @p3.add_pitch(3)
204
+ @p3.add_pitch(8)
205
+ @p3.add_pitch(9)
206
+
207
+ @p3p = PostTonal::PitchClassSet.new
208
+ @p3p.add_pitch(0)
209
+ @p3p.add_pitch(1)
210
+ @p3p.add_pitch(4)
211
+ @p3p.add_pitch(7)
212
+
213
+ assert_equal(@p3p, @p3.prime_form)
214
+
215
+
216
+ @p4 = PostTonal::PitchClassSet.new
217
+ @p4.add_pitch(1)
218
+ @p4.add_pitch(5)
219
+ @p4.add_pitch(6)
220
+ @p4.add_pitch(7)
221
+
222
+ @p4p = PostTonal::PitchClassSet.new
223
+ @p4p.add_pitch(0)
224
+ @p4p.add_pitch(1)
225
+ @p4p.add_pitch(2)
226
+ @p4p.add_pitch(6)
227
+
228
+ assert_equal(@p4p, @p4.prime_form)
229
+
230
+ @p5 = PostTonal::PitchClassSet.new
231
+ @p5.add_pitch(0)
232
+ @p5.add_pitch(2)
233
+ @p5.add_pitch(4)
234
+ @p5.add_pitch(7)
235
+ @p5.add_pitch(11)
236
+
237
+ @p5p = PostTonal::PitchClassSet.new
238
+ @p5p.add_pitch(0)
239
+ @p5p.add_pitch(1)
240
+ @p5p.add_pitch(3)
241
+ @p5p.add_pitch(5)
242
+ @p5p.add_pitch(8)
243
+
244
+ assert_equal(@p5p, @p5.prime_form)
245
+
246
+ @p6 = PostTonal::PitchClassSet.new
247
+ @p6.add_pitch(3)
248
+ @p6.add_pitch(6)
249
+ @p6.add_pitch(7)
250
+ @p6.add_pitch(8)
251
+ @p6.add_pitch(9)
252
+ @p6.add_pitch(10)
253
+
254
+ @p6p = PostTonal::PitchClassSet.new
255
+ @p6p.add_pitch(0)
256
+ @p6p.add_pitch(1)
257
+ @p6p.add_pitch(2)
258
+ @p6p.add_pitch(3)
259
+ @p6p.add_pitch(4)
260
+ @p6p.add_pitch(7)
261
+
262
+ assert_equal(@p6p, @p6.prime_form)
263
+
264
+ @p7 = PostTonal::PitchClassSet.new
265
+ @p7.add_pitch(0)
266
+ @p7.add_pitch(2)
267
+ @p7.add_pitch(5)
268
+ @p7.add_pitch(6)
269
+ @p7.add_pitch(7)
270
+ @p7.add_pitch(9)
271
+ @p7.add_pitch(10)
272
+ @p7.add_pitch(11)
273
+
274
+ @p7p = PostTonal::PitchClassSet.new
275
+ @p7p.add_pitch(0)
276
+ @p7p.add_pitch(1)
277
+ @p7p.add_pitch(2)
278
+ @p7p.add_pitch(4)
279
+ @p7p.add_pitch(5)
280
+ @p7p.add_pitch(6)
281
+ @p7p.add_pitch(7)
282
+ @p7p.add_pitch(9)
283
+
284
+ assert_equal(@p7p, @p7.prime_form)
285
+ end
159
286
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: post_tonal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1.pre
4
+ version: 0.2.0.pre
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-21 00:00:00.000000000 Z
12
+ date: 2012-10-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda