diatone 0.0.0

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/diatone.rb +425 -0
  3. metadata +44 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b1891043456d7d8a3e971665bc28c0debee53d3b
4
+ data.tar.gz: 6c10bf03a8d281010f3a69576506510bed5db98e
5
+ SHA512:
6
+ metadata.gz: f1af8f3006b3cff11f83a14852fd7ea56457d36d048b482c63e9b27e407d048de6df5ff86d3b9e4a6c028876c1677a5450bf3d9a707d674b4d418c80323449ec
7
+ data.tar.gz: 9f5e0af4b2471695aa1005e7b072d9b072a8679bc3d5e0a1ecc0733e8225cea6c1fe4515117353fd6e85c71ab175941194ae92b65b497cc38b9510fe8d2bb6e7
data/lib/diatone.rb ADDED
@@ -0,0 +1,425 @@
1
+ # coding: utf-8
2
+ ### Yakup Cetinkaya 2012
3
+
4
+
5
+ module Diatone
6
+
7
+ CHR = 12.0
8
+ STEP = 2 ** (1/ CHR)
9
+ TONES = ['C','C♯','D','D♯','E','F','F♯','G','G♯','A','A♯','B']
10
+ SCALES = {
11
+ '' => "221222",
12
+ 'm' => "212212",
13
+ }
14
+ CHORDS = {
15
+ '' => [0,2,4],
16
+ '6' => [0,2,4,5],
17
+ '7' => [0,2,4,6.4],
18
+ '9' => [0,2,4,6.4,8],
19
+ '6/9' => [0,2,4,5.4,8],
20
+ '11' => [0,2,4,6.4,8,10],
21
+ '13' => [0,2,4,6.4,8,10,12],
22
+
23
+ 'maj7' => [0,2,4,6],
24
+ 'maj9' => [0,2,4,8,6],
25
+ 'maj11' => [0,2,4,6,8,10],
26
+ 'maj13' => [0,2,4,6,8,10,12],
27
+
28
+ 'm' => [0,2.4,4],
29
+ 'm6' => [0,2.4,4,5],
30
+ 'm7' => [0,2.4,4,6.4],
31
+ 'min7' => [0,2.4,4,6],
32
+ 'm9' => [0,2.4,4,6.4,8],
33
+ 'm6/9' => [0,2.4,4,5.4,8],
34
+ 'm11' => [0,2.4,4,6.4,8,10],
35
+ 'm13' => [0,2.4,4,6.4,8,10,12],
36
+
37
+ 'sus2' => [0,1,4],
38
+ 'sus4' => [0,3,4],
39
+ 'dim' => [0,2.4,4.4],
40
+ 'dim7' => [0,2.4,4.4,6.3],
41
+ '+' => [0,2,4.6],
42
+ 'majb5' => [0,2,4.4],
43
+ '5' => [0,4],
44
+
45
+ }
46
+
47
+ class Note
48
+
49
+ def self.ord2tone ( i, key = false )
50
+ i += 48
51
+ s = TONES[i% CHR]
52
+ s = s + (i/ CHR).floor.to_s unless key
53
+ return s
54
+ end
55
+
56
+ def self.tone2ord (s)
57
+ if s[-2] == s[-2].to_i.to_s
58
+ i = s[-2..-1].to_i * CHR
59
+ elsif s[-1] == s[-1].to_i.to_s
60
+ i = s[-1].to_i * CHR
61
+ else
62
+ i = 48
63
+ end
64
+
65
+ if s[1] == 'b' then i -= 1 elsif s[1] == '♯' then i += 1 end
66
+ return i + TONES.rindex { |a| a == s[0].upcase } - 48
67
+ end
68
+
69
+ def self.fix(i)
70
+ if i.is_a? Numeric
71
+ return i
72
+ end
73
+ unless i.to_s[0] == i[0].to_i.to_s
74
+ i = tone2ord(i)
75
+ end
76
+ return i
77
+ end
78
+
79
+ def self.key(s, ord=true)
80
+ s = fix(s)
81
+ s = ord2tone(s, true)
82
+ unless ord
83
+ return s
84
+ end
85
+ return TONES.rindex {|a| a == s }
86
+ end
87
+
88
+ def self.get (s)
89
+ return [key(s,false)]
90
+ end
91
+
92
+ def self.name (s)
93
+ return key(s,false)
94
+ end
95
+
96
+ def self.getFreq (i)
97
+ i = fix(i)
98
+ return 440.0 * ( STEP ** (i-9) )
99
+ end
100
+
101
+ end
102
+
103
+ class Scale
104
+
105
+ def self.abbr (t)
106
+ t.gsub!(' major','')
107
+ t.gsub!('major','')
108
+ t.gsub!('maj','')
109
+ t.gsub!(' minor','m')
110
+ t.gsub!('minor','m')
111
+ t.gsub!('min','m')
112
+ return t
113
+ end
114
+
115
+ def self.get (s)
116
+ if s.length > 1
117
+ if s[1] == '♯' or s[1] == 'b'
118
+ tonic = Note.key s[0..1]
119
+ type = abbr(s[2..-1])
120
+ else
121
+ tonic = Note.key s[0]
122
+ type = abbr(s[1..-1])
123
+ end
124
+ else
125
+ tonic = Note.key s
126
+ type = ''
127
+ end
128
+ i = Note.key(tonic)
129
+ scale = [ TONES[i] ]
130
+ if SCALES.include? type
131
+ SCALES[type].split('').each do |interval|
132
+ i += interval.to_i
133
+ scale.push TONES[i% CHR]
134
+ end
135
+ else
136
+ return [false,type]
137
+ end
138
+ return scale
139
+ end
140
+
141
+ def self.name (s)
142
+ if s[1] == '♯' or s[1] == 'b'
143
+ note = Note.key s[0..1], false
144
+ type = abbr(s[2..-1])
145
+ else
146
+ note = Note.key s[0], false
147
+ type = abbr(s[1..-1])
148
+ end
149
+ return note+type
150
+ end
151
+
152
+ end
153
+
154
+ class Chord
155
+
156
+ def self.abbr (t)
157
+ t.gsub!(' major','maj')
158
+ t.gsub!('major','maj')
159
+ t.gsub!(' minor','m')
160
+ t.gsub!('minor','m')
161
+ t.gsub!('min','m')
162
+ t.gsub!('aug','+')
163
+ return t
164
+ end
165
+
166
+ def self.get (s)
167
+ notes = []
168
+ if s[1] == '♯' or s[1] == 'b'
169
+ scale = Scale.get s[0..1]
170
+ type = abbr(s[2..-1])
171
+ else
172
+ scale = Scale.get s[0]
173
+ type = abbr(s[1..-1])
174
+ end
175
+ if CHORDS.include? type
176
+ CHORDS[type].each do |n|
177
+ if n == n.to_i
178
+ notes.push scale[n%scale.length]
179
+ else
180
+ r = ((n*10).to_i%10)-5
181
+ s = scale[n.to_i%scale.length]
182
+ f = Note.fix(s) + r
183
+ n = Note.key(f, false)
184
+ notes.push(n)
185
+ end
186
+ end
187
+ else
188
+ return [false,type]
189
+ end
190
+ return notes
191
+ end
192
+
193
+ def self.name (s)
194
+ if s[1] == '♯' or s[1] == 'b'
195
+ note = Note.key s[0..1], false
196
+ type = abbr(s[2..-1])
197
+ else
198
+ note = Note.key s[0], false
199
+ type = abbr(s[1..-1])
200
+ end
201
+ return note+type
202
+ end
203
+ end
204
+
205
+
206
+ class Strat
207
+
208
+ $chordcolors = [['#FD0202', '#F24D16', '#E88829', '#DDB439', '#D2D248', '#ABC855', '#8FBD60'], ['#FD7602', '#F2B316', '#E8E029', '#BADD39', '#92D248', '#76C855', '#64BD60'], ['#FDEA02', '#CCF216', '#97E829', '#6FDD39', '#53D248', '#55C869', '#60BD87'], ['#9CFD02', '#67F216', '#3FE829', '#39DD4F', '#48D27D', '#55C89E', '#60BDB2'], ['#29FD02', '#16F22B', '#29E86B', '#39DD9B', '#48D2BD', '#55BDC8', '#609DBD'], ['#02FD4F', '#16F291', '#29E8C3', '#39D3DD', '#48A8D2', '#5588C8', '#6072BD'], ['#02FDC3', '#16EEF2', '#29B4E8', '#3988DD', '#4868D2', '#5755C8', '#7960BD'], ['#02C3FD', '#1688F2', '#295CE8', '#393CDD', '#6848D2', '#8C55C8', '#A460BD'], ['#024FFD', '#1623F2', '#4D29E8', '#8239DD', '#A848D2', '#C155C8', '#BD60AB'], ['#2902FD', '#6F16F2', '#A529E8', '#CD39DD', '#D248BD', '#C85599', '#BD6080'], ['#9C02FD', '#D516F2', '#E829D2', '#DD39A1', '#D2487D', '#C85564', '#BD6B60'], ['#FD02EA', '#F216AA', '#E82979', '#DD3955', '#D25348', '#C87A55', '#BD9660']]
209
+ $dists = []
210
+ $firstfretwidth = 76
211
+ $boardwidth = 80
212
+ $boardend = 110
213
+ $boardmargin = 5
214
+ $boardstep = ( $boardwidth - $boardmargin*2 ) / 5
215
+ $numfrets = 22
216
+
217
+ def self.handles(st)
218
+ handles = []
219
+ 6.times do |h|
220
+ x = ($boardmargin + h * $boardstep).to_s
221
+ xx = (3+h*15)
222
+ yx = (-68-h*44)
223
+ t = {
224
+ 'type' => 'text',
225
+ 'x' => (xx-36).to_s,
226
+ 'y' => (yx-12).to_s,
227
+ 'text' => st[h],
228
+ 'count' => h,
229
+ 'fill' => '#666',
230
+ 'font' => "bold 18px 'Georgia'",
231
+ 'transform' => 'R -79',
232
+ }
233
+ handles.push(t)
234
+ end
235
+ return handles
236
+ end
237
+
238
+ def self.fretboard ()
239
+ y = $firstfretwidth;
240
+ yy = 0;
241
+ board = []
242
+ head = {
243
+ 'type' => 'path',
244
+ 'path' => "m 0,0 c 0.67553,-13.141072 -4.48542,-17.874924 -30.62047,-25.353202 l 93.57286,-287.670447 c 13.79673,-28.33919 54.14057,-31.93149 75.04833,-12.57035 9.11046,9.06332 20.55453,35.78224 9.28602,60.61698 -5.45523,12.0228 -17.15423,23.82984 -36.50441,32.19232 0,0 -2.81387,3.53158 -1.91422,9.86513 4.11709,28.98438 32.13336,129.84242 24.99516,141.72309 -7.13821,11.880669 -48.15894,10.032667 -52.87363,81.339695 z",
245
+ 'stroke' => 'none',
246
+ 'fill' => '90-#8b512e-#cd8f69:10-#c07040'
247
+ }
248
+ board.push(head)
249
+
250
+
251
+ body = {
252
+ 'type' => 'path',
253
+ 'path' => "m -4,770 c -4.5242,43.39873 -83.3941,32.78475 -108.7634,-11.67981 -20.7376,-36.34659 5.2806,-91.30037 -19.9816,-102.2859 -30.8976,-13.43602 -80.1227,35.57216 -72.3811,129.47097 7.3335,88.948316 57.1253,131.731505 44.9389,217.090413 -12.1864,85.358817 -110.4576,200.116007 -85.1837,318.218047 25.2739,118.10213 162.8277,135.95354 274.3877,145.03181 111.5601,9.07826 263.55221,6.37368 287.47455,-128.09349 24.6158,-138.36507 -67.0671,-209.42944 -74.31643,-304.36328 -3.18581,-41.719804 14.39068,-62.103376 22.96767,-88.367288 8.5803,-26.274115 25.80111,-44.13946 23.04036,-96.234742 -4.57647,-86.35794 -45.45078,-70.88739 -48.67796,-70.97081 -27.19304,7.98078 -15.26175,59.28649 -42.35049,85.685817 -8.8064,8.582202 -30.3951,18.925638 -49.5918,18.485334 -60.499,-1.387536 -54.4462,-20.583252 -61.4426,-35.736221 -8.599,-18.62415 -90.1201,-76.25085 -90.1201,-76.25085 z",
254
+ 'stroke' => 'none',
255
+ 'fill' => 'maroon'
256
+ }
257
+ board.push(body)
258
+ white = {
259
+ 'type' => 'path',
260
+ 'path' => "m -96,1140 c 0.098,7.01566 0.8747,14.03337 2.4142,21.22344 8.7356,48.54034 40.2199,58.7572 74.4886,53.05809 40.0337,1.66041 95.5773,-7.43657 154.943,7.6553 50.2963,12.78628 73.79222,31.93169 94.91923,51.95945 17.53567,15.74884 37.64893,32.96362 55.5543,23.46872 30.22696,-20.56269 -2.85821,-89.94559 -13.0125,-115.40769 -21.34736,-53.00201 -47.47667,-93.35326 -50.38964,-150.820522 -2.42253,-47.791858 16.95174,-74.49973817 24.01244,-96.120565 10.32302,-31.610493 24.49009,-41.3072 21.99337,-88.420203 -2.10544,-39.72965 -11.89005,-48.9677 -14.67067,-50.69193 -1.3903,-0.86212 -2.28921,-0.9382 -3.72532,-0.90891 -0.71806,0.0145 -1.44538,0.0977 -2.28269,0.24145 -0.18297,0.031 -0.46873,0.0898 -0.67735,0.12887 -0.0684,0.19233 -0.14486,0.42621 -0.76059,1.67448 -1.49359,3.02792 -3.37982,9.69246 -5.23772,18.05192 -3.60708,16.22961 -7.38026,39.85959 -25.58263,58.765547 l 0.0275,0.02835 c -0.50003,0.606339 -1.06013,1.131786 -1.57707,1.716489 -11.46688,12.97011 -26.98306,22.595111 -42.57546,25.085465 -16.2953,2.602665 -32.6136,-1.418191 -48.8761,-5.556621 -32.5252,-8.276954 -65.6194,-25.061756 -95.7875,-39.87163 -30.1681,-14.80978 -58.4564,-27.17844 -71.6229,-28.67619 -6.5833,-0.74888 -6.5511,0.23292 -6.2433,-0.0811 0.2923,-0.29824 -2.0298,2.90505 -2.0368,13.55084 15.6979,74.226032 12.888,128.553187 -6.4573,178.417869 -18.2156,46.953021 -37.3243,86.480971 -36.8373,121.528471 z",
261
+ 'stroke' => 'none',
262
+ 'fill' => 'White'
263
+ }
264
+ board.push(white)
265
+ fboard = {
266
+ 'type' => 'path',
267
+ 'path' => 'M 0 0 L 80 0 L 85 910 C 87 930 -7 930 -5 910 Z',
268
+ 'stroke' => 'none',
269
+ 'fill' => 'Black'
270
+ }
271
+ board.push(fboard)
272
+ $numfrets.times do |t|
273
+ i = [5,7,9,15,17,19,21].rindex {|a| a == t}
274
+ if i
275
+ circle = {
276
+ 'type' => 'circle',
277
+ 'cx' => 40,
278
+ 'cy' => yy-y/2,
279
+ 'r' => 5,
280
+ 'fill' => 'Silver'
281
+ }
282
+ board.push circle
283
+ elsif t == 12
284
+ board.push ( {
285
+ 'type' => 'circle',
286
+ 'cx' => 16,
287
+ 'cy' => yy-y/2,
288
+ 'r' => 5,
289
+ 'fill' => 'Silver'
290
+ })
291
+ board.push ( {
292
+ 'type' => 'circle',
293
+ 'cx' => 63,
294
+ 'cy' => yy-y/2,
295
+ 'r' => 5,
296
+ 'fill' => 'Silver'
297
+ })
298
+ end
299
+ if t == 0 then w = 9 else w = 3 end
300
+ fret = {
301
+ 'type' => 'path',
302
+ 'path' => 'M'+(-yy/184).to_s+' '+(yy).to_s+' H'+(80+yy/184).to_s,
303
+ 'stroke-width' => w,
304
+ 'stroke' => 'Gainsboro'
305
+ }
306
+ board.push fret
307
+ $dists.push (yy-8)
308
+ y /= STEP
309
+ yy += y.round
310
+ end
311
+ tresh = {
312
+ 'type' => 'path',
313
+ 'path' => 'M 0 0 L 80 0 L 80 -10 L 0 -10 Z',
314
+ 'stroke' => 'none',
315
+ 'fill' => 'Black',
316
+ 'fill-opacity' => 0.6
317
+ }
318
+ #board.push(tresh)
319
+ $dists.push (yy-8)
320
+ 6.times do |h|
321
+ x = ($boardmargin + h * $boardstep).to_s
322
+ xx = (3+h*15)
323
+ yx = (-68-h*44)
324
+ l = {
325
+ 'type' => 'path',
326
+ 'path' => 'M'+x+' 0 L '+(xx+5).to_s+' '+yx.to_s,
327
+ 'stroke-width' => 2.5-h/3.0,
328
+ 'stroke' => 'Silver',
329
+ }
330
+ board.push(l)
331
+ c = {
332
+ 'type' => 'circle',
333
+ 'cx' => xx.to_s,
334
+ 'cy' => yx.to_s,
335
+ 'r' => 8,
336
+ 'stroke' => 'none',
337
+ 'fill' => 'r(.8,.4)#666-#ddd',
338
+ }
339
+ board.push(c)
340
+ end
341
+ 6.times do |s|
342
+ x = ($boardmargin + s * $boardstep).to_s
343
+ xx = (s * 17 - 3).to_s
344
+ string = {
345
+ 'type' => 'path',
346
+ 'path' => 'M'+x+' 0 L '+xx+' 1280',
347
+ 'stroke-width' => 2.5-s/3.0,
348
+ 'stroke' => 'Silver'
349
+ }
350
+ board.push string
351
+ end
352
+ return board
353
+ end
354
+
355
+ def self.blisters (choice=nil,strings=['E2','A2','D3','G3','B3','E4'],scale=nil)
356
+ blisters = {}
357
+ if choice == nil
358
+ return blisters.to_json
359
+ end
360
+ tonic = Note.key(choice[0],true)%12
361
+ colors = $chordcolors[tonic]
362
+ 6.times do |s|
363
+ blisterstr = []
364
+ st = strings[s]
365
+ t = Note.fix st
366
+ $numfrets.times do |f|
367
+ n = Note.key(t,false)
368
+ i = choice.rindex {|a| a == n}
369
+ if i
370
+ color = colors[i]
371
+ if i == 0 then rad = 7 else rad = 5 end
372
+ if f == 0
373
+ blister = {
374
+ 'type' => 'circle',
375
+ 'cx' => $boardmargin+s*$boardstep,
376
+ 'cy' => $dists[f]+8,
377
+ 'r' => rad-1,
378
+ 'count' => Note.ord2tone(t.to_i),
379
+ 'coord' => [s,f],
380
+ 'index' => i,
381
+ 'stroke' => color,
382
+ 'stroke-width' => 3,
383
+ 'fill' => 'black'
384
+ }
385
+ blisterstr.push blister
386
+ else
387
+ xc = ($dists[f]/460.0)
388
+ blister = {
389
+ 'type' => 'circle',
390
+ 'cx' => $boardmargin-xc*2.5+s*($boardstep+xc),
391
+ 'cy' => $dists[f],
392
+ 'r' => rad,
393
+ 'count' => Note.ord2tone(t.to_i),
394
+ 'coord' => [s,f],
395
+ 'index' => i,
396
+ 'fill' => color,
397
+ #'fill-opacity' => 1.2-f/($numfrets*1.0),
398
+ 'stroke' => 'none'
399
+ }
400
+ blisterstr.push blister
401
+ end
402
+ end
403
+ t += 1
404
+ end
405
+ blisters[s] = blisterstr
406
+ end
407
+ legend = []
408
+ ords = []
409
+ choice.length.times do |c|
410
+ nt = choice[c]
411
+ cl = colors[c]
412
+ o = Note.fix(nt+'4').to_i
413
+ if c > 0 and o < ords[c-1]
414
+ o += 12
415
+ end
416
+ ords.push o
417
+ legend.push(nt+','+cl+','+o.to_s)
418
+ end
419
+ blisters['legend'] = (legend.join(';'))
420
+ return blisters
421
+ end
422
+ end
423
+
424
+ end
425
+
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: diatone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yakup Cetinkaya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2010-04-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Gemification of a module written years ago
14
+ email: yakup.cetinkaya@gmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/diatone.rb
20
+ homepage: http://rubygems.org/gems/diatone
21
+ licenses:
22
+ - GPL-3.0
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.6.10
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Diatonal calculations
44
+ test_files: []