peas 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/peas/{integer_helper.rb → interger_helper.rb} +0 -0
- data/lib/peas/interval.rb +8 -12
- data/lib/peas/pitch.rb +13 -102
- data/lib/peas/pitch_class.rb +29 -82
- data/lib/peas/version.rb +1 -1
- metadata +10 -12
File without changes
|
data/lib/peas/interval.rb
CHANGED
@@ -2,26 +2,22 @@ require 'named_value_class'
|
|
2
2
|
require 'peas/pitch'
|
3
3
|
|
4
4
|
module Peas
|
5
|
+
|
6
|
+
# see: http://en.wikipedia.org/wiki/Interval_(music)
|
7
|
+
#
|
5
8
|
module Interval
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def -(rhs)
|
10
|
-
if [Pitch,PitchClass].include?(rhs.class)
|
11
|
-
raise Peas::InvalidOperation, '(Interval - Pitch) has no meaning'
|
12
|
-
else
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
9
|
+
NamedValueClass Base:Integer, constrain:0..24 do
|
10
|
+
minus_a Pitch, raises:SyntaxError
|
11
|
+
minus_a PitchClass, raises:SyntaxError
|
16
12
|
end
|
17
13
|
|
18
14
|
class Semitone < Base; end
|
19
|
-
|
15
|
+
25.times do |x|
|
20
16
|
Semitone "S#{x}" => x
|
21
17
|
end
|
22
18
|
|
23
19
|
class Wholetone < Base; end
|
24
|
-
|
20
|
+
13.times do |x|
|
25
21
|
Wholetone "W#{x}" => x * 2
|
26
22
|
end
|
27
23
|
|
data/lib/peas/pitch.rb
CHANGED
@@ -1,119 +1,31 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'peas/pitch_class'
|
3
|
-
require 'peas/interval'
|
4
3
|
|
5
4
|
module Peas
|
6
|
-
NamedValueClass Pitch:Fixnum do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
alias _minus :-
|
11
|
-
|
12
|
-
def -(rhs)
|
13
|
-
if rhs.class == Pitch
|
14
|
-
if self >= rhs
|
15
|
-
Interval::Diatonic[super(rhs)] || Interval::Semitone[super(rhs)]
|
16
|
-
else
|
17
|
-
rhs - self
|
18
|
-
end
|
19
|
-
elsif rhs.class == PitchClass
|
20
|
-
self.pitch_class - rhs
|
21
|
-
elsif rhs.is_a? Interval::Base
|
22
|
-
if is_sharp?
|
23
|
-
Pitch.sharps(self._minus(rhs))
|
24
|
-
else
|
25
|
-
Pitch.flats(self._minus(rhs))
|
26
|
-
end
|
27
|
-
end
|
5
|
+
NamedValueClass Pitch:Fixnum, constrain:0..127 do
|
6
|
+
minus_a 'Interval::Base' do |lhs,minus,rhs|
|
7
|
+
result = minus.call(rhs)
|
8
|
+
is_sharp? ? Pitch.sharps[result] : Pitch.flats[result]
|
28
9
|
end
|
29
10
|
|
11
|
+
all_operators_with_a :Pitch, raise:SyntaxError
|
12
|
+
|
30
13
|
def as_flat
|
31
|
-
self.class.flats
|
14
|
+
self.class.naturals[self] || self.class.flats[self]
|
32
15
|
end
|
33
16
|
|
34
17
|
def as_sharp
|
35
|
-
self.class.sharps
|
36
|
-
end
|
37
|
-
|
38
|
-
def self.flats(value)
|
39
|
-
{
|
40
|
-
0 => C_1 , 32 => Ab1 , 64 => E4 , 96 => C7 ,
|
41
|
-
1 => Db_1 , 33 => A1 , 65 => F4 , 97 => Db7 ,
|
42
|
-
2 => D_1 , 34 => Bb1 , 66 => Gb4 , 98 => D7 ,
|
43
|
-
3 => Eb_1 , 35 => B1 , 67 => G4 , 99 => Eb7 ,
|
44
|
-
4 => E_1 , 36 => C2 , 68 => Ab4 , 100 => E7 ,
|
45
|
-
5 => F_1 , 37 => Db2 , 69 => A4 , 101 => F7 ,
|
46
|
-
6 => Gb_1 , 38 => D2 , 70 => Bb4 , 102 => Gb7 ,
|
47
|
-
7 => G_1 , 39 => Eb2 , 71 => B4 , 103 => G7 ,
|
48
|
-
8 => Ab_1 , 40 => E2 , 72 => C5 , 104 => Ab7 ,
|
49
|
-
9 => A_1 , 41 => F2 , 73 => Db5 , 105 => A7 ,
|
50
|
-
10 => Bb_1 , 42 => Gb2 , 74 => D5 , 106 => Bb7 ,
|
51
|
-
11 => B_1 , 43 => G2 , 75 => Eb5 , 107 => B7 ,
|
52
|
-
12 => C0 , 44 => Ab2 , 76 => E5 , 108 => C8 ,
|
53
|
-
13 => Db0 , 45 => A2 , 77 => F5 , 109 => Db8 ,
|
54
|
-
14 => D0 , 46 => Bb2 , 78 => Gb5 , 110 => D8 ,
|
55
|
-
15 => Eb0 , 47 => B2 , 79 => G5 , 111 => Eb8 ,
|
56
|
-
16 => E0 , 48 => C3 , 80 => Ab5 , 112 => E8 ,
|
57
|
-
17 => F0 , 49 => Db3 , 81 => A5 , 113 => F8 ,
|
58
|
-
18 => Gb0 , 50 => D3 , 82 => Bb5 , 114 => Gb8 ,
|
59
|
-
19 => G0 , 51 => Eb3 , 83 => B5 , 115 => G8 ,
|
60
|
-
20 => Ab0 , 52 => E3 , 84 => C6 , 116 => Ab8 ,
|
61
|
-
21 => A0 , 53 => F3 , 85 => Db6 , 117 => A8 ,
|
62
|
-
22 => Bb0 , 54 => Gb3 , 86 => D6 , 118 => Bb8 ,
|
63
|
-
23 => B0 , 55 => G3 , 87 => Eb6 , 119 => B8 ,
|
64
|
-
24 => C1 , 56 => Ab3 , 88 => E6 , 120 => C9 ,
|
65
|
-
25 => Db1 , 57 => A3 , 89 => F6 , 121 => Db9 ,
|
66
|
-
26 => D1 , 58 => Bb3 , 90 => Gb6 , 122 => D9 ,
|
67
|
-
27 => Eb1 , 59 => B3 , 91 => G6 , 123 => Eb9 ,
|
68
|
-
28 => E1 , 60 => C4 , 92 => Ab6 , 124 => E9 ,
|
69
|
-
29 => F1 , 61 => Db4 , 93 => A6 , 125 => F9 ,
|
70
|
-
30 => Gb1 , 62 => D4 , 94 => Bb6 , 126 => Gb9 ,
|
71
|
-
31 => G1 , 63 => Eb4 , 95 => B6 , 127 => G9
|
72
|
-
}[value]
|
73
|
-
end
|
74
|
-
|
75
|
-
def self.sharps(value)
|
76
|
-
{
|
77
|
-
0 => C_1 , 32 => Gs1 , 64 => E4 , 96 => C7 ,
|
78
|
-
1 => Cs_1 , 33 => A1 , 65 => F4 , 97 => Cs7 ,
|
79
|
-
2 => D_1 , 34 => As1 , 66 => Fs4 , 98 => D7 ,
|
80
|
-
3 => Ds_1 , 35 => B1 , 67 => G4 , 99 => Ds7 ,
|
81
|
-
4 => E_1 , 36 => C2 , 68 => Gs4 , 100 => E7 ,
|
82
|
-
5 => F_1 , 37 => Cs2 , 69 => A4 , 101 => F7 ,
|
83
|
-
6 => Fs_1 , 38 => D2 , 70 => As4 , 102 => Fs7 ,
|
84
|
-
7 => G_1 , 39 => Ds2 , 71 => B4 , 103 => G7 ,
|
85
|
-
8 => Gs_1 , 40 => E2 , 72 => C5 , 104 => Gs7 ,
|
86
|
-
9 => A_1 , 41 => F2 , 73 => Cs5 , 105 => A7 ,
|
87
|
-
10 => As_1 , 42 => Fs2 , 74 => D5 , 106 => As7 ,
|
88
|
-
11 => B_1 , 43 => G2 , 75 => Ds5 , 107 => B7 ,
|
89
|
-
12 => C0 , 44 => Gs2 , 76 => E5 , 108 => C8 ,
|
90
|
-
13 => Cs0 , 45 => A2 , 77 => F5 , 109 => Cs8 ,
|
91
|
-
14 => D0 , 46 => As2 , 78 => Fs5 , 110 => D8 ,
|
92
|
-
15 => Ds0 , 47 => B2 , 79 => G5 , 111 => Ds8 ,
|
93
|
-
16 => E0 , 48 => C3 , 80 => Gs5 , 112 => E8 ,
|
94
|
-
17 => F0 , 49 => Cs3 , 81 => A5 , 113 => F8 ,
|
95
|
-
18 => Fs0 , 50 => D3 , 82 => As5 , 114 => Fs8 ,
|
96
|
-
19 => G0 , 51 => Ds3 , 83 => B5 , 115 => G8 ,
|
97
|
-
20 => Gs0 , 52 => E3 , 84 => C6 , 116 => Gs8 ,
|
98
|
-
21 => A0 , 53 => F3 , 85 => Cs6 , 117 => A8 ,
|
99
|
-
22 => As0 , 54 => Fs3 , 86 => D6 , 118 => As8 ,
|
100
|
-
23 => B0 , 55 => G3 , 87 => Ds6 , 119 => B8 ,
|
101
|
-
24 => C1 , 56 => Gs3 , 88 => E6 , 120 => C9 ,
|
102
|
-
25 => Cs1 , 57 => A3 , 89 => F6 , 121 => Cs9 ,
|
103
|
-
26 => D1 , 58 => As3 , 90 => Fs6 , 122 => D9 ,
|
104
|
-
27 => Ds1 , 59 => B3 , 91 => G6 , 123 => Ds9 ,
|
105
|
-
28 => E1 , 60 => C4 , 92 => Gs6 , 124 => E9 ,
|
106
|
-
29 => F1 , 61 => Cs4 , 93 => A6 , 125 => F9 ,
|
107
|
-
30 => Fs1 , 62 => D4 , 94 => As6 , 126 => Fs9 ,
|
108
|
-
31 => G1 , 63 => Ds4 , 95 => B6 , 127 => G9
|
109
|
-
}[value]
|
18
|
+
self.class.naturals[self] || self.class.sharps[self]
|
110
19
|
end
|
111
20
|
end
|
21
|
+
|
112
22
|
PitchClass::NamedValues::Collection.each do |pclass|
|
113
|
-
Pitch "#{pclass}_1" => pclass, pitch_class:pclass, octave:-1
|
23
|
+
Pitch "#{pclass}_1" => pclass.value, pitch_class:pclass, octave:-1,
|
24
|
+
sharp:pclass.is_sharp?, flat:pclass.is_flat?, natural:pclass.is_natural?
|
114
25
|
0.upto(9) do |octave|
|
115
26
|
name = pclass.to_s + octave.to_s
|
116
|
-
Pitch name => (((octave+1)*12)+pclass), pitch_class:pclass, octave:octave
|
27
|
+
Pitch name => (((octave+1)*12)+pclass), pitch_class:pclass, octave:octave,
|
28
|
+
sharp:pclass.is_sharp?, flat:pclass.is_flat?, natural:pclass.is_natural?
|
117
29
|
end
|
118
30
|
end
|
119
31
|
|
@@ -122,4 +34,3 @@ module Peas
|
|
122
34
|
include PitchClass::NamedValues
|
123
35
|
end
|
124
36
|
end
|
125
|
-
|
data/lib/peas/pitch_class.rb
CHANGED
@@ -1,96 +1,43 @@
|
|
1
1
|
require 'named_value_class'
|
2
2
|
|
3
3
|
module Peas
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def -(rhs)
|
10
|
-
if rhs.class == PitchClass
|
11
|
-
if self >= rhs
|
12
|
-
# TODO: stop the insanity
|
13
|
-
Interval::Diatonic[
|
14
|
-
Interval::Diatonic[self._minus(rhs)].interval_class] ||
|
15
|
-
Interval::Semitone[
|
16
|
-
Interval::Semitone[self._minus(rhs)].interval_class]
|
17
|
-
else
|
18
|
-
Interval::Diatonic[rhs - self]
|
19
|
-
end
|
20
|
-
elsif rhs.class == Pitch
|
21
|
-
self - rhs.pitch_class
|
22
|
-
elsif rhs.is_a? Interval::Base
|
23
|
-
result = self._minus(rhs) % 12
|
24
|
-
if is_sharp?
|
25
|
-
PitchClass.sharps(result)
|
26
|
-
else
|
27
|
-
PitchClass.flats(result)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def is_sharp?
|
33
|
-
%w|Bs Cs Ds Es Fs Gs As|.include? @name
|
34
|
-
end
|
35
|
-
|
36
|
-
def is_flat?
|
37
|
-
%w|Bb Cb Db Eb Fb Gb Ab|.include? @name
|
4
|
+
NamedValueClass PitchClass:Fixnum, constrain:0..11 do
|
5
|
+
minus_a 'Interval::Base' do |lhs,minus,rhs|
|
6
|
+
result = minus.call(rhs) % 12
|
7
|
+
is_sharp? ? PitchClass.sharps[result] : PitchClass.flats[result]
|
38
8
|
end
|
39
9
|
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.flats(value)
|
45
|
-
{
|
46
|
-
0 => C, 6 => Gb,
|
47
|
-
1 => Db, 7 => G,
|
48
|
-
2 => D, 8 => Ab,
|
49
|
-
3 => Eb, 9 => A,
|
50
|
-
4 => E, 10 => Bb,
|
51
|
-
5 => F, 11 => B
|
52
|
-
}[value]
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.sharps(value)
|
56
|
-
{
|
57
|
-
0 => C, 6 => Fs,
|
58
|
-
1 => Cs, 7 => G,
|
59
|
-
2 => D, 8 => Gs,
|
60
|
-
3 => Ds, 9 => A,
|
61
|
-
4 => E, 10 => As,
|
62
|
-
5 => F, 11 => B
|
63
|
-
}[value]
|
64
|
-
end
|
10
|
+
all_operators_with_a :PitchClass, raise:SyntaxError
|
11
|
+
all_operators_with_a :Pitch, raise:SyntaxError
|
65
12
|
|
66
13
|
def as_flat
|
67
|
-
self.class.flats
|
14
|
+
self.class.naturals[self] || self.class.flats[self]
|
68
15
|
end
|
69
16
|
|
70
17
|
def as_sharp
|
71
|
-
self.class.sharps
|
18
|
+
self.class.naturals[self] || self.class.sharps[self]
|
72
19
|
end
|
73
20
|
end
|
74
21
|
|
75
|
-
PitchClass Bs:
|
76
|
-
PitchClass C:
|
77
|
-
PitchClass Cs:
|
78
|
-
PitchClass Db:
|
79
|
-
PitchClass D:
|
80
|
-
PitchClass Ds:
|
81
|
-
PitchClass Eb:
|
82
|
-
PitchClass E:
|
83
|
-
PitchClass
|
84
|
-
PitchClass
|
85
|
-
PitchClass F:
|
86
|
-
PitchClass Fs:
|
87
|
-
PitchClass Gb:
|
88
|
-
PitchClass G:
|
89
|
-
PitchClass Gs:
|
90
|
-
PitchClass Ab:
|
91
|
-
PitchClass A:
|
92
|
-
PitchClass As: 10
|
93
|
-
PitchClass Bb: 10
|
94
|
-
PitchClass B: 11
|
95
|
-
PitchClass Cb: 11
|
22
|
+
PitchClass Bs: 0, sharp:true
|
23
|
+
PitchClass C: 0, natural:true
|
24
|
+
PitchClass Cs: 1, sharp:true
|
25
|
+
PitchClass Db: 1, flat:true
|
26
|
+
PitchClass D: 2, natural:true
|
27
|
+
PitchClass Ds: 3, sharp:true
|
28
|
+
PitchClass Eb: 3, flat:true
|
29
|
+
PitchClass E: 4, natural:true
|
30
|
+
PitchClass Fb: 4, flat:true
|
31
|
+
PitchClass Es: 5, sharp:true
|
32
|
+
PitchClass F: 5, natural:true
|
33
|
+
PitchClass Fs: 6, sharp:true
|
34
|
+
PitchClass Gb: 6, flat:true
|
35
|
+
PitchClass G: 7, natural:true
|
36
|
+
PitchClass Gs: 8, sharp:true
|
37
|
+
PitchClass Ab: 8, flat:true
|
38
|
+
PitchClass A: 9, natural:true
|
39
|
+
PitchClass As: 10, sharp:true
|
40
|
+
PitchClass Bb: 10, flat:true
|
41
|
+
PitchClass B: 11, natural:true
|
42
|
+
PitchClass Cb: 11, flat:true
|
96
43
|
end
|
data/lib/peas/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,33 +9,31 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-12-20 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: named_value_class
|
16
|
-
requirement: &
|
16
|
+
requirement: &2151835560 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '0.
|
21
|
+
version: '0.7'
|
22
22
|
- - ! '>='
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: 0.
|
24
|
+
version: 0.7.0
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
|
-
version_requirements: *
|
28
|
-
description:
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
abbreviations.'
|
27
|
+
version_requirements: *2151835560
|
28
|
+
description: Peas defines constants from music theory and allows one to perform math
|
29
|
+
with them. Currently supports pitches (as MIDI values), pitch classes, and intervals
|
30
|
+
using semitones, wholetones, chromatic, latin or diatonic abbreviations.
|
33
31
|
email: mgarriss@gmail.com
|
34
32
|
executables: []
|
35
33
|
extensions: []
|
36
34
|
extra_rdoc_files: []
|
37
35
|
files:
|
38
|
-
- lib/peas/
|
36
|
+
- lib/peas/interger_helper.rb
|
39
37
|
- lib/peas/interval.rb
|
40
38
|
- lib/peas/pitch.rb
|
41
39
|
- lib/peas/pitch_class.rb
|