music_set_theory 0.0.2
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 +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +104 -0
- data/Rakefile +14 -0
- data/examples/mst_chords.rb +25 -0
- data/examples/mst_temperament.rb +46 -0
- data/lib/music_set_theory/chord_generator.rb +331 -0
- data/lib/music_set_theory/chords.rb +406 -0
- data/lib/music_set_theory/musutility.rb +284 -0
- data/lib/music_set_theory/scales.rb +456 -0
- data/lib/music_set_theory/temperament.rb +783 -0
- data/lib/music_set_theory/version.rb +11 -0
- data/lib/music_set_theory.rb +24 -0
- data/sig/music_theory.rbs +4 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2a54615c8b9ddf6ecabe27b78c6d84d76fb9c618fb3120267eadd21ed67e7267
|
4
|
+
data.tar.gz: 9d56b5499b87e6eed6e6c36cf3d396885b6cfb28340f855e79ae8ce2e8fecc0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ffabf6585aade8f22055f93594e9b0f265f4da8fc110917a0460072abb67b2b82953a72c4d31dab145ea9bccdf91bb51743d26f371a1e112f41a201c82b62831
|
7
|
+
data.tar.gz: d5e6d8ed0e69e4e9a865cb233ff96efe92ba48690ae5ac3a7a087ec03e6a8b77e4d3d57e46d96a43528fce92985b6111cba4c86252f0f0dab033591f8a63d45f
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 YAMAMOTO, Masayuki (https://voidptrjp.blogspot.com)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# MusicSetTheory
|
2
|
+
|
3
|
+
`music_set_theory.gem` is ruby version of `musictheory` of python package, by Peter Murphy.
|
4
|
+
> The package has roughly the same philosophy as [Music Set Theory](https://www.jaytomlin.com/music/settheory/help.html) but uses different terminology.
|
5
|
+
|
6
|
+
The music theory treats notes and the relationships among them, i.e., temperament, chords, scale, modes, etc.
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
|
13
|
+
|
14
|
+
Install the gem and add to the application's Gemfile by executing:
|
15
|
+
|
16
|
+
```bash
|
17
|
+
bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
18
|
+
```
|
19
|
+
|
20
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
21
|
+
|
22
|
+
```bash
|
23
|
+
gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
|
24
|
+
```
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
See the `examples/` directory. The scripts for listing chords and scales are there.
|
29
|
+
|
30
|
+
|
31
|
+
## Development
|
32
|
+
|
33
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
34
|
+
|
35
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
36
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
37
|
+
|
38
|
+
### Testing
|
39
|
+
|
40
|
+
If you want to test all:
|
41
|
+
|
42
|
+
```bash
|
43
|
+
bundle exec rake test
|
44
|
+
```
|
45
|
+
|
46
|
+
test a specified one:
|
47
|
+
|
48
|
+
```bash
|
49
|
+
TEST=./test/something_test.rb bundle exec rake test
|
50
|
+
```
|
51
|
+
|
52
|
+
If you want to test a test in a specified file, then:
|
53
|
+
|
54
|
+
```bash
|
55
|
+
TESTOPTS=--name=/pattern-matches-to-the-description/ TEST=./test/something_test.rb bundle exec rake test
|
56
|
+
```
|
57
|
+
|
58
|
+
## Future Works, etc.
|
59
|
+
|
60
|
+
I would like to add some examples, debug more, and refactor the structure and method names...
|
61
|
+
(Actually, I don't have the knowledge about temperament and modes at (almost) all, though I
|
62
|
+
can understand chords and scales a little since I had played the guitar.)
|
63
|
+
|
64
|
+
The state-dependencies exists in the original test cases on `WestTemp`. So I have already removed them.
|
65
|
+
All tests, including commented out one (`TestChords`), are passed now.
|
66
|
+
|
67
|
+
## Contributing
|
68
|
+
|
69
|
+
Bug reports and pull requests are welcome on GitHub at `https://github.com/mephistobooks/music_set_theory`.
|
70
|
+
|
71
|
+
|
72
|
+
## License
|
73
|
+
|
74
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
75
|
+
|
76
|
+
The original [`musictheory`](https://github.com/peterkmurphy/musictheory) is BSD 3-clauses Licence.
|
77
|
+
|
78
|
+
```
|
79
|
+
Copyright (c) 2009-2020 Peter Murphy <peterkmurphy@gmail.com>
|
80
|
+
All rights reserved.
|
81
|
+
|
82
|
+
Redistribution and use in source and binary forms, with or without
|
83
|
+
modification, are permitted provided that the following conditions are met:
|
84
|
+
* Redistributions of source code must retain the above copyright
|
85
|
+
notice, this list of conditions and the following disclaimer.
|
86
|
+
* Redistributions in binary form must reproduce the above copyright
|
87
|
+
notice, this list of conditions and the following disclaimer in the
|
88
|
+
documentation and/or other materials provided with the distribution.
|
89
|
+
* The names of its contributors may not be used to endorse or promote
|
90
|
+
products derived from this software without specific prior written
|
91
|
+
permission.
|
92
|
+
|
93
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
94
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
95
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
96
|
+
DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
97
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
98
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
99
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
100
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
101
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
102
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
103
|
+
```
|
104
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require "standard/rake"
|
13
|
+
|
14
|
+
task default: %i[test standard]
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
#
|
4
|
+
|
5
|
+
require_relative "../lib/music_set_theory"
|
6
|
+
|
7
|
+
|
8
|
+
include MusicSetTheory
|
9
|
+
tmp = WestTempNew()
|
10
|
+
generate_west_chords(tmp).each_with_index{|e, i|
|
11
|
+
puts "(#{i+1}) #{e}:#{e.class}"
|
12
|
+
puts " name: #{e.name}"
|
13
|
+
puts " type: #{e.type}"
|
14
|
+
puts " tment: #{e.tment}"
|
15
|
+
puts " notes: #{e.notes} (unit: number of semitones)"
|
16
|
+
puts " #{e.notes_deg} (unit: degree, base 0)"
|
17
|
+
|
18
|
+
abbr = "abbr: #{e.abbr}"
|
19
|
+
abbr += "; #{e.abbr_others}" if e.abbr_others.size > 0
|
20
|
+
puts " #{abbr}"
|
21
|
+
puts " syns: #{e.syns}"
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
#### endof filename: examples/mt_chords.rb
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# filename: examples/mt_temperament.rb
|
4
|
+
#
|
5
|
+
|
6
|
+
require_relative "../lib/music_set_theory"
|
7
|
+
|
8
|
+
|
9
|
+
include MusicSetTheory
|
10
|
+
# tmp = WestTempNew()
|
11
|
+
generate_west_chords(WestTemp)
|
12
|
+
|
13
|
+
#
|
14
|
+
puts "Temperament."
|
15
|
+
seq_dict = WestTemp.seq_dict
|
16
|
+
nseqtype_dict = seq_dict.nseqtype_maps
|
17
|
+
|
18
|
+
pad = " "*2
|
19
|
+
pad2 = pad*2
|
20
|
+
nseqtype_dict.each {|k, v|
|
21
|
+
puts pad+"dict type (nseqtype): #{NSEQ_TYPE_HASH[k]} (#{k})"
|
22
|
+
|
23
|
+
#
|
24
|
+
dict = v
|
25
|
+
puts pad2+"name_dict (#{dict.name_dict.keys.size}):"
|
26
|
+
dict.name_dict.each_with_index {|(k, v), i|
|
27
|
+
puts pad2+pad+"(#{i+1}) #{k}: #{v}"
|
28
|
+
}
|
29
|
+
puts
|
30
|
+
|
31
|
+
puts pad2+"abbr_dict (#{dict.abbr_dict.keys.size}):"
|
32
|
+
dict.abbr_dict.each_with_index {|(k, v), i|
|
33
|
+
puts pad2+pad+"(#{i+1}) #{k}: #{v}"
|
34
|
+
}
|
35
|
+
puts
|
36
|
+
|
37
|
+
puts pad2+"seqpos_dict (#{dict.seqpos_dict.keys.size}):"
|
38
|
+
dict.seqpos_dict.each_with_index {|(k, v), i|
|
39
|
+
puts pad2+pad+"(#{i+1}) #{k}: #{v}"
|
40
|
+
}
|
41
|
+
|
42
|
+
puts '-'*40
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
#### endof filename: examples/mt_temperament.rb
|
@@ -0,0 +1,331 @@
|
|
1
|
+
#
|
2
|
+
# frozen_string_literal: true
|
3
|
+
#
|
4
|
+
# filename: music_set_theory/chord_generator.rb
|
5
|
+
#
|
6
|
+
# Generating tables of chords associated with scales.
|
7
|
+
|
8
|
+
|
9
|
+
#-*- coding: UTF-8 -*-
|
10
|
+
# chordgenerator.py: Generating tables of chords associated with scales.
|
11
|
+
#
|
12
|
+
# Copyright (c) 2008-2020 Peter Murphy <peterkmurphy@gmail.com>
|
13
|
+
# All rights reserved.
|
14
|
+
#
|
15
|
+
# Redistribution and use in source and binary forms, with or without
|
16
|
+
# modification, are permitted provided that the following conditions are met:
|
17
|
+
# * Redistributions of source code must retain the above copyright
|
18
|
+
# notice, this list of conditions and the following disclaimer.
|
19
|
+
# * Redistributions in binary form must reproduce the above copyright
|
20
|
+
# notice, this list of conditions and the following disclaimer in the
|
21
|
+
# documentation and/or other materials provided with the distribution.
|
22
|
+
# * The names of its contributors may not be used to endorse or promote
|
23
|
+
# products derived from this software without specific prior written
|
24
|
+
# permission.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ''AS IS'' AND ANY
|
27
|
+
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
28
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
29
|
+
# DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
30
|
+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
31
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
32
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
33
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
34
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
35
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
36
|
+
#
|
37
|
+
# This software was originally written by Peter Murphy (2008). It has been
|
38
|
+
# updated in 2011 to use the assoicated musictheory classes. Updated for 2011.
|
39
|
+
#
|
40
|
+
# The goal of this utility is to find all the possible chords (major, minor,
|
41
|
+
# 7th) in common diatonic scales (such as Major and Harmonic Minor). The
|
42
|
+
# results are tables that can be displayed in an HTML file.
|
43
|
+
|
44
|
+
|
45
|
+
require_relative "./musutility"
|
46
|
+
require_relative "./temperament"
|
47
|
+
require_relative "./scales"
|
48
|
+
require_relative "./chords"
|
49
|
+
|
50
|
+
require 'romannumerals'
|
51
|
+
|
52
|
+
|
53
|
+
# import copy, codecs
|
54
|
+
# from .musutility import seqtostr;
|
55
|
+
# from .temperament import WestTemp, temperament, WestTemp, seq_dict,\
|
56
|
+
# NSEQ_SCALE, NSEQ_CHORD, M_SHARP, M_FLAT;
|
57
|
+
# from .scales import MajorScale, MelMinorScale, HarmMinorScale,\
|
58
|
+
# HarmMajorScale;
|
59
|
+
# from .chords import CHORDTYPE_DICT;
|
60
|
+
|
61
|
+
|
62
|
+
#
|
63
|
+
#
|
64
|
+
#
|
65
|
+
module MusicSetTheory
|
66
|
+
|
67
|
+
class ScaleChords; end
|
68
|
+
class ScaleChordRow; end
|
69
|
+
class ScaleChordCell; end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
#
|
75
|
+
#
|
76
|
+
#
|
77
|
+
module MusicSetTheory
|
78
|
+
|
79
|
+
# Used to give a full list of chord types.
|
80
|
+
CHORDTYPE_ARRAY = [
|
81
|
+
"Fifth", "Triad", "Seventh", "Ninth", "Eleventh", "Thirteenth",
|
82
|
+
"Added Ninth", "Suspended", "Suspended Seventh", "Sixth", "Sixth/Ninth",
|
83
|
+
"Added Eleventh",
|
84
|
+
]
|
85
|
+
|
86
|
+
#
|
87
|
+
PRINT_ABBRV = 0
|
88
|
+
PRINT_FNAME = 1
|
89
|
+
PRINT_BOTH = 2
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
module MusicSetTheory
|
95
|
+
|
96
|
+
# Roman numerals are used for the table headers.
|
97
|
+
|
98
|
+
# Following routine comes from "Roman Numerals (Python recipe)".
|
99
|
+
# Author: Paul Winkler on Sun, 14 Oct 2001. See:
|
100
|
+
# http://code.activestate.com/recipes/81611-roman-numerals/
|
101
|
+
|
102
|
+
# """
|
103
|
+
# Convert an integer to Roman numerals.
|
104
|
+
#
|
105
|
+
# Examples:
|
106
|
+
# >>> int_to_roman(0)
|
107
|
+
# Traceback (most recent call last):
|
108
|
+
# ValueError: Argument must be between 1 and 3999
|
109
|
+
#
|
110
|
+
# >>> int_to_roman(-1)
|
111
|
+
# Traceback (most recent call last):
|
112
|
+
# ValueError: Argument must be between 1 and 3999
|
113
|
+
#
|
114
|
+
# >>> int_to_roman(1.5)
|
115
|
+
# Traceback (most recent call last):
|
116
|
+
# TypeError: expected integer, got <type 'float'>
|
117
|
+
#
|
118
|
+
# >>> for i in range(1, 21): print int_to_roman(i)
|
119
|
+
# ...
|
120
|
+
# I
|
121
|
+
# II
|
122
|
+
# III
|
123
|
+
# IV
|
124
|
+
# V
|
125
|
+
# VI
|
126
|
+
# VII
|
127
|
+
# VIII
|
128
|
+
# IX
|
129
|
+
# X
|
130
|
+
# XI
|
131
|
+
# XII
|
132
|
+
# XIII
|
133
|
+
# XIV
|
134
|
+
# XV
|
135
|
+
# XVI
|
136
|
+
# XVII
|
137
|
+
# XVIII
|
138
|
+
# XIX
|
139
|
+
# XX
|
140
|
+
# >>> print int_to_roman(2000)
|
141
|
+
# MM
|
142
|
+
# >>> print int_to_roman(1999)
|
143
|
+
# MCMXCIX
|
144
|
+
# """
|
145
|
+
def int_to_roman(input)
|
146
|
+
raise "#{input} must be greater than zero." if input <= 0
|
147
|
+
|
148
|
+
input.to_roman
|
149
|
+
end
|
150
|
+
|
151
|
+
#
|
152
|
+
# Make a sequence of roman numerals from 1 to num.
|
153
|
+
def make_roman_numeral_list( num )
|
154
|
+
#return([int_to_roman(i) for i in range(1, num + 1)])
|
155
|
+
(1...(num + 1)).map{|i| int_to_roman(i) }
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
|
161
|
+
module MusicSetTheory
|
162
|
+
# Represents all the chords associated with a scale. This is
|
163
|
+
# used to make a tabular representation.
|
164
|
+
#
|
165
|
+
class ScaleChords
|
166
|
+
|
167
|
+
attr_accessor :full_name, :key, :full_notes, :table_title, :rows
|
168
|
+
def initialize( full_name, key, full_notes, table_title )
|
169
|
+
self.full_name = full_name;
|
170
|
+
self.key = key;
|
171
|
+
self.full_notes = full_notes;
|
172
|
+
self.table_title = table_title;
|
173
|
+
self.rows = [];
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Represents different rows (triads, 7ths, 9ths) in tabular
|
178
|
+
# representations of scale chords.
|
179
|
+
#
|
180
|
+
class ScaleChordRow
|
181
|
+
attr_accessor :chord_type, :notes
|
182
|
+
def initialize( chord_type )
|
183
|
+
self.chord_type = chord_type;
|
184
|
+
self.notes = [];
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Represents different cells in the table of chords.
|
189
|
+
class ScaleChordCell
|
190
|
+
attr_accessor :chordname_1, :chordname_2, :notes
|
191
|
+
def initialize( chordname_1, chordname_2, notes )
|
192
|
+
self.chordname_1 = chordname_1;
|
193
|
+
self.chordname_2 = chordname_2;
|
194
|
+
self.notes = notes;
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
module MusicSetTheory
|
202
|
+
|
203
|
+
# Used for converting "C" -> 1, "Db"-> 2b, etc.
|
204
|
+
def makebaserep( notex, base = 0 )
|
205
|
+
notexparsed = WestTemp.note_parse(notex)
|
206
|
+
#pos_rep = str(WestTemp.nat_key_lookup_order[notexparsed[0]] + base)
|
207
|
+
pos_rep = (WestTemp.nat_key_lookup_order[notexparsed[0]] + base).to_s
|
208
|
+
|
209
|
+
if notexparsed[1] > 0
|
210
|
+
ret = pos_rep + (M_SHARP * notexparsed[1])
|
211
|
+
elsif notexparsed[1] < 0
|
212
|
+
ret = pos_rep + (M_FLAT * (-1 * notexparsed[1]))
|
213
|
+
else
|
214
|
+
ret = pos_rep;
|
215
|
+
end
|
216
|
+
|
217
|
+
ret
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
# Returns an instance of scale_chords using the following inputs:
|
222
|
+
#
|
223
|
+
# scale_name: a name of a scale like "Dorian".
|
224
|
+
# key: generally a standard music key like "C".
|
225
|
+
# possiblechords: a sequence of chord types like "Seventh" and "Ninth".
|
226
|
+
#
|
227
|
+
def populate_scale_chords( scale_name, key, possiblechords )
|
228
|
+
our_scale = WestTemp.get_nseqby_name(scale_name, NSEQ_SCALE);
|
229
|
+
num_elem = len(our_scale.nseq_posn);
|
230
|
+
begin
|
231
|
+
int_of_key = key.to_i
|
232
|
+
is_key_an_int = true;
|
233
|
+
rescue ValueError
|
234
|
+
is_key_an_int = false;
|
235
|
+
int_of_key = nil;
|
236
|
+
end
|
237
|
+
|
238
|
+
if is_key_an_int
|
239
|
+
#our_scale_notes = [makebaserep(x, int_of_key) for x in
|
240
|
+
#our_scale.get_notes_for_key("C")];
|
241
|
+
our_scale_notes = our_scale.get_notes_for_key("C").map{|x|
|
242
|
+
makebaserep(x, int_of_key) }
|
243
|
+
else
|
244
|
+
our_scale_notes = our_scale.get_notes_for_key(key)
|
245
|
+
end
|
246
|
+
|
247
|
+
our_chord_data = ScaleChords.new(scale_name, key, our_scale_notes,
|
248
|
+
make_roman_numeral_list(num_elem))
|
249
|
+
|
250
|
+
for i in possiblechords
|
251
|
+
ourchordrow = ScaleChordRow.new(i)
|
252
|
+
our_chord_data.rows.append(ourchordrow)
|
253
|
+
|
254
|
+
for j in range(num_elem):
|
255
|
+
our_slice = CHORDTYPE_DICT[i];
|
256
|
+
if is_key_an_int
|
257
|
+
#our_chord_notes = [makebaserep(x, int_of_key) for x in
|
258
|
+
# our_scale.get_notes_for_key("C", j, our_slice)];
|
259
|
+
our_chord_notes = our_scale.get_notes_for_key("C", j, our_slice).
|
260
|
+
map{|x| makebaserep(x, int_of_key) }
|
261
|
+
else
|
262
|
+
our_chord_notes = our_scale.get_notes_for_key(key, j, our_slice)
|
263
|
+
end
|
264
|
+
|
265
|
+
our_posn = our_scale.get_posn_for_offset(j, our_slice, true)
|
266
|
+
our_chord = WestTemp.get_nseqby_seqpos(our_posn, NSEQ_CHORD)
|
267
|
+
if our_chord
|
268
|
+
ourchordrow.notes.append(ScaleChordCell.new(our_chord.nseq_name,
|
269
|
+
our_chord.nseq_abbrev, our_chord_notes))
|
270
|
+
else
|
271
|
+
ourchordrow.notes.append(ScaleChordCell.new("", "", our_chord_notes))
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
return our_chord_data
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
# (**) I dont need this.
|
282
|
+
# Generates a table representation of a series of scales,
|
283
|
+
# represented by a scale_chords instance.
|
284
|
+
#
|
285
|
+
def chordgentable( scales )
|
286
|
+
startrow = "<tr>\n"
|
287
|
+
endrow = "</tr>\n"
|
288
|
+
thestring = ""
|
289
|
+
|
290
|
+
|
291
|
+
for scale in scales
|
292
|
+
thestring += "<h2>%s</h2>\n" % (scale.key + " " +scale.full_name)
|
293
|
+
thestring += ("<table id=\"%s\" class=\"chordtable\">\n" %
|
294
|
+
(scale.key + ""))
|
295
|
+
thestring += "<caption>%s</caption>\n" %
|
296
|
+
(scale.key + " " + scale.full_name +
|
297
|
+
": " + seqtostr(scale.full_notes))
|
298
|
+
thestring += "<thead>\n" + startrow + "<th>Chord Types</th>\n";
|
299
|
+
for q in range(7):
|
300
|
+
# thestring += "<th>%s</th>\n" % str(int_to_roman(q+1));
|
301
|
+
end
|
302
|
+
thestring += endrow + "</thead>\n<tbody>\n";
|
303
|
+
|
304
|
+
for i in scale.rows:
|
305
|
+
thestring += startrow;
|
306
|
+
thestring += "<td>%s</td>\n" % i.chord_type;
|
307
|
+
for j in i.notes:
|
308
|
+
if not j.chordname_1
|
309
|
+
thestring += ("<td><p>%s<br />" % (str(j.chordname_1)))
|
310
|
+
thestring += ("<i>%s</i><br />" % (str(j.chordname_2)))
|
311
|
+
else
|
312
|
+
thestring += ("<td><p>%s<br />" %
|
313
|
+
(j.notes[0]+" "+str(j.chordname_1)))
|
314
|
+
thestring += ("<i>%s</i><br />" % (j.notes[0]+str(j.chordname_2)))
|
315
|
+
end
|
316
|
+
|
317
|
+
thestring += ("<b>%s</b></p></td>" % seqtostr(j.notes))
|
318
|
+
end
|
319
|
+
thestring += endrow
|
320
|
+
end
|
321
|
+
thestring += "\n</tbody>\n</table>\n"
|
322
|
+
end
|
323
|
+
|
324
|
+
return thestring
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
|
331
|
+
#### endof filename: music_set_theory/chord_generator.rb
|