ruby-mext 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 294779db24d6436cc838a41d8673fe440180e95a4dddf2e8cfa0ad6d70998552
4
- data.tar.gz: c456b20be223a8b47589f9b9495465add2d50a3afa0063ec0634c27884ea2ce7
3
+ metadata.gz: d32aaa3192a101dd9ca1c51d9a9971de58e8b1d169101421fdc2bae2d3bab010
4
+ data.tar.gz: 9ba50c10d8f2681d37e5064b72d7767709fd902dd212a409044aeb6902438145
5
5
  SHA512:
6
- metadata.gz: 563369c90b8d73a3f10b070e67051b870ff672ac8dd28ce79a5acac3d94c5aec041e590b42ce2361fe4e6483808c27e6bdaef368cb213f0328d551b5a88754a8
7
- data.tar.gz: fd9e7b2c50a2ebb6b7da7f640a6f2aff96887a50194895cfbedbff0c31606640bacf62ef1e4265800af81836fc814a7965deba9c813f140126d2f5f019285524
6
+ metadata.gz: 5d92e921aed9ef6c445a341272382c60a2eac3d8f0fb7e3d8f78e61dc328036416bea8b8c8e5131d47fc97e72abb4e28215fc5bbcaa02bd91ca533d450db0875
7
+ data.tar.gz: ee4884242a2344ec9790755fb5cde3df9d1327da33c3dba1af0706a8c2f9b14223e88c1aa693db1b5d304d2539e59ea3057e96d3cd696e77576acebf52e54bf1
@@ -6,15 +6,19 @@ module Mext
6
6
  attr_reader :octave, :semi
7
7
 
8
8
  #
9
- # +Mext::Music::PitchClass.new(float_value):
9
+ # +Mext::Music::PitchClass.new(float_value, semi = nil)+:
10
10
  #
11
11
  # pitch class object, where argument is:
12
12
  #
13
13
  # +float_value+: a pitch class in float notation (i.e. 8.00 for middle C, etc.)
14
+ # +or+ an octave value when given in octave, semi pair (see below)
15
+ # +semi+: (optional) when this argument is not nil, then it is assumed
16
+ # that the first argument is the octave, and this one is the
17
+ # semitone value
14
18
  #
15
19
  #:nodoc:
16
- def initialize(fv)
17
- setup(fv)
20
+ def initialize(fv, semi = nil)
21
+ semi ? setup_with_two_arguments(fv, semi) : setup_with_one_argument(fv)
18
22
  end
19
23
 
20
24
  #:doc:
@@ -29,7 +33,7 @@ module Mext
29
33
  # we suppose here that the pitch_class data is well-formed inside the
30
34
  # object
31
35
  #
32
- self.octave + (self.semi / 100.0)
36
+ self.octave + (self.semi / ::Numeric::PCC)
33
37
  end
34
38
 
35
39
  #:doc:
@@ -59,11 +63,14 @@ module Mext
59
63
  # +\+(other)+ (operator plus)
60
64
  #
61
65
  # sums two pitch classes
62
- #
63
66
  #
64
67
  #:nodoc:
65
68
  def +(other)
66
- PitchClass.new((self.to_freq + other.to_freq).cpspch)
69
+ octave = (self.to_semitones + other.to_semitones) / 12.0
70
+ octave = octave >= 0.0 ? octave.floor : octave.ceil
71
+ semis = (self.to_semitones + other.to_semitones) % 12.0
72
+ phase = octave >= 0.0 ? 1 : -1
73
+ PitchClass.new(octave, phase*semis)
67
74
  end
68
75
 
69
76
  #:doc:
@@ -75,7 +82,8 @@ module Mext
75
82
  #
76
83
  #:nodoc:
77
84
  def -(other)
78
- PitchClass.new((self.to_freq - other.to_freq).cpspch)
85
+ tot_semi = self.to_semitones - other.to_semitones
86
+ PitchClass.new(0.0, tot_semi)
79
87
  end
80
88
 
81
89
  #:doc:
@@ -100,6 +108,17 @@ module Mext
100
108
  other.to_semitones - self.to_semitones
101
109
  end
102
110
 
111
+ #:doc:
112
+ #
113
+ # +transpose(semitones)+
114
+ #
115
+ # returns the transposition in semitones
116
+ #
117
+ #:nodoc:
118
+ def transpose(semi)
119
+ self + PitchClass.new(0.0, semi)
120
+ end
121
+
103
122
  class << self
104
123
 
105
124
  #:doc:
@@ -117,13 +136,38 @@ module Mext
117
136
 
118
137
  private
119
138
 
120
- def setup(fval)
121
- @octave = fval.floor
122
- s = (fval-@octave) * 100.0
123
- @octave += (s/12.0).floor
124
- @semi = s % 12.0
139
+ def setup_with_one_argument(fval)
140
+ (o, s) = separate_oct_semi(fval)
141
+ setup_with_two_arguments(o, s)
125
142
  end
126
-
143
+
144
+ def separate_oct_semi(fval)
145
+ octave = fval >= 0.0 ? fval.floor : fval.ceil
146
+ s = (fval-octave) * ::Numeric::PCC
147
+ [octave, s]
148
+ end
149
+
150
+ #
151
+ # +setup_with_two_arguments(oct, semi)+:
152
+ #
153
+ # we must make sure that the two values are congruent, that is:
154
+ # +oct+ is a float number and +semi+ is between 0..11.999999
155
+ # taking into account that pitch classes can be positive or negative
156
+ #
157
+ def setup_with_two_arguments(oct, s)
158
+ octsemi = (s / 12.0)
159
+ octsemi = case
160
+ when octsemi > 0.0 then octsemi.floor
161
+ when octsemi < 0.0 then octsemi.ceil
162
+ when octsemi == 0.0 then 0.0
163
+ end
164
+ oct += octsemi
165
+ remainder = s >= 0.0 ? (s % 12.0) : (s % -12.0)
166
+ @octave = oct
167
+ @semi = remainder
168
+ self
169
+ end
170
+
127
171
  end
128
172
 
129
173
  end
@@ -0,0 +1,34 @@
1
+ class Numeric
2
+
3
+ #
4
+ # a set of constants needed for pitch classes and MIDI
5
+ #
6
+
7
+ #
8
+ # +MIDI_MIDDLE_C+: the central C (Do) in MIDI jargon
9
+ #
10
+ MIDI_MIDDLE_C = 60
11
+
12
+ #
13
+ # +PITCH_MIDDLE_C+: the central C (Do) in pitch-class jargon
14
+ #
15
+ PITCH_MIDDLE_C = 8.0
16
+
17
+ #
18
+ # +CHROMATIC_NOTES_PER_OCTAVE+ (short: +CNPO+): the number of notes per octave
19
+ #
20
+ CHROMATIC_NOTES_PER_OCTAVE = CNPO = 12.0
21
+
22
+ #
23
+ # +ZERO_MIDI_PITCH+ (short: +ZMP+): where does the +0.00+ pitch-class reside
24
+ # in terms of midi notes
25
+ #
26
+ ZERO_MIDI_PITCH = ZMP = MIDI_MIDDLE_C - (PITCH_MIDDLE_C * CNPO)
27
+
28
+ #
29
+ # +PITCH_CLASS_CENTS+ (short: +PCC+): the number of parts in every semitone
30
+ #
31
+ PITCH_CLASS_CENTS = PCC = 100.0
32
+
33
+
34
+ end
@@ -9,12 +9,25 @@ class Numeric
9
9
 
10
10
  def mtopch
11
11
 
12
- intv = (self - MIDI_MIDDLE_C) / CHROMATIC_NOTES_PER_OCTAVE
12
+ semi = (self - ZMP) / CNPO
13
+ oct = semi.to_i
14
+ semi = (semi - oct) * CNPO
15
+ semi %= CNPO
16
+ semi = (self > ZMP) ? semi : -((CNPO - semi) % CNPO)
13
17
 
14
- intv_octave = intv.to_i
15
- intv_semi = (intv - intv_octave) * CHROMATIC_NOTES_PER_OCTAVE;
18
+ oct + (semi / PCC)
19
+
20
+ # intv = self - MIDI_MIDDLE_C
21
+ # intv /= CHROMATIC_NOTES_PER_OCTAVE
22
+
23
+ # intv_octave = intv.floor
24
+ # intv_semi = (intv_octave >= 0.0) ? (intv - intv_octave) : (1 - (intv_octave - intv))
25
+ #
26
+ # intv_semi *= CHROMATIC_NOTES_PER_OCTAVE;
27
+ # intv_semi %= CHROMATIC_NOTES_PER_OCTAVE;
28
+
29
+ # PITCH_MIDDLE_C + intv_octave + (intv_semi/100.0);
16
30
 
17
- PITCH_MIDDLE_C + intv_octave + (intv_semi/100.0);
18
31
  end
19
32
 
20
33
  end
@@ -6,9 +6,6 @@ class Numeric
6
6
  # interprets its receiver as a pitch class and returns its corresponing MIDI note
7
7
  #
8
8
  #:nodoc:
9
- MIDI_MIDDLE_C = 60
10
- PITCH_MIDDLE_C = 8.0
11
- CHROMATIC_NOTES_PER_OCTAVE = 12.0
12
9
 
13
10
  def pchtom
14
11
  p_octave = self.to_i
data/lib/mext/numeric.rb CHANGED
@@ -16,6 +16,7 @@ module Mext
16
16
  mmtot
17
17
  )
18
18
  NON_VECTORIZABLE_METHODS = %w(
19
+ constants
19
20
  pitch_fork
20
21
  )
21
22
  ADDED_METHODS = NON_VECTORIZABLE_METHODS + VECTORIZABLE_METHODS
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mext
2
- VERSION = '0.9.0'
2
+ VERSION = '0.9.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-mext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicola Bernardini
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-05-01 00:00:00.000000000 Z
11
+ date: 2019-05-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -127,6 +127,7 @@ files:
127
127
  - lib/mext/music/pitch_class.rb
128
128
  - lib/mext/numeric.rb
129
129
  - lib/mext/numeric/ampdb.rb
130
+ - lib/mext/numeric/constants.rb
130
131
  - lib/mext/numeric/cpspch.rb
131
132
  - lib/mext/numeric/dbamp.rb
132
133
  - lib/mext/numeric/ftom.rb