note-transpose 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +0 -0
- data/bin/note-transpose +43 -0
- data/lib/note-transpose.rb +70 -0
- metadata +48 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 267fda6624a3fb3cec72a2b542a7acc962c3eb3d6a7f010135e31ca569802257
|
4
|
+
data.tar.gz: d5a6fe312b3e2e88414f06708cbe256b7efd196e517661db6f10f2b2382bf702
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 47531afdb9e94df614fdebd0460575f3414a2be19bbd1bf5ec4f3898e874ddbc12d351558e36e0cecdca75a2f3c7caefc5810df7e95b88f0fd5b7ed4d940943b
|
7
|
+
data.tar.gz: a2e12cbe20818bce4beec5ffccfc02658a9eed96cb5e281d4136591d695f51460ab5f62ad0d809273764d05c25c91b239d6c148a4eb5eba8d9aa53fa458ced34
|
data/README.md
ADDED
File without changes
|
data/bin/note-transpose
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'note-transpose'
|
4
|
+
|
5
|
+
PREF_FLAT_OPT = "--pref-flat"
|
6
|
+
|
7
|
+
def print_help
|
8
|
+
basename = File.basename(__FILE__)
|
9
|
+
puts <<EOF
|
10
|
+
|
11
|
+
Usage: #{basename} [-]<number half steps> <notes> [#{PREF_FLAT_OPT}]
|
12
|
+
#{PREF_FLAT_OPT} Always uses flat notes in output instead of sharp ones
|
13
|
+
|
14
|
+
Example:
|
15
|
+
❯ #{basename} +1 C G F Am
|
16
|
+
=> #{NoteTranspose.transpose(1, %w(C G F Am))}
|
17
|
+
|
18
|
+
❯ #{basename} 2 C G F Am
|
19
|
+
=> #{NoteTranspose.transpose(2, %w(C G F Am))}
|
20
|
+
|
21
|
+
❯ #{basename} -2 D# G7 F Am7 Cadd7
|
22
|
+
=> #{NoteTranspose.transpose(-2, %w(D# G7 F Am7 Cadd7))}
|
23
|
+
|
24
|
+
❯ #{basename} -2 D# G7 F Am7 Cadd7 --pref-flat
|
25
|
+
=> #{NoteTranspose.transpose(-2, %w(D# G7 F Am7 Cadd7), pref_flat: true)}
|
26
|
+
EOF
|
27
|
+
end
|
28
|
+
|
29
|
+
# Check input
|
30
|
+
input = ARGV.flatten.map { |x| x.dup }
|
31
|
+
half_steps = input.shift.to_i
|
32
|
+
|
33
|
+
if input.nil? || input.empty? || half_steps.zero?
|
34
|
+
print_help
|
35
|
+
exit 1
|
36
|
+
end
|
37
|
+
|
38
|
+
pref_flat = !input.delete(PREF_FLAT_OPT).nil?
|
39
|
+
|
40
|
+
puts <<EOF
|
41
|
+
|
42
|
+
=> #{NoteTranspose.transpose(half_steps, input, pref_flat: pref_flat)}
|
43
|
+
EOF
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# List of musical notes, as sharps and flats
|
4
|
+
NOTES = {
|
5
|
+
sharp: %w(c c# d d# e f f# g g# a a# b),
|
6
|
+
flat: %w(c db d eb e f gb g ab a bb b)
|
7
|
+
}
|
8
|
+
|
9
|
+
|
10
|
+
module NoteTranspose
|
11
|
+
class Error < Exception; end
|
12
|
+
|
13
|
+
# Transposes array of notes by specified number of half_steps
|
14
|
+
#
|
15
|
+
# Examples:
|
16
|
+
#
|
17
|
+
# transpose(-1, %w(C F Am G))
|
18
|
+
# => ["Bb", "Eb", "Gm", "F"]
|
19
|
+
#
|
20
|
+
# transpose(-10, %w(C F Am G))
|
21
|
+
# => ["D", "G", "Bm", "A"]
|
22
|
+
#
|
23
|
+
# transpose(3, %w(D# F Bm G7))
|
24
|
+
# => ["F#", "Ab", "Dm", "Bb7"]
|
25
|
+
#
|
26
|
+
# transpose(3, %w(D# F Bm G7), pref_flat: true)
|
27
|
+
# => ["Gb", "Ab", "Dm", "Bb7"]
|
28
|
+
#
|
29
|
+
def self.transpose(half_steps, *notes, pref_flat: false)
|
30
|
+
notes.flatten!
|
31
|
+
transposed_notes = []
|
32
|
+
|
33
|
+
notes.each do |note|
|
34
|
+
note.downcase!
|
35
|
+
begin
|
36
|
+
m = note.match /^[a-g](#|b)?/
|
37
|
+
actual_note = m[0].downcase
|
38
|
+
|
39
|
+
index = NOTES[:flat].find_index(actual_note)
|
40
|
+
|
41
|
+
if index.nil?
|
42
|
+
source = NOTES[:sharp]
|
43
|
+
index = NOTES[:sharp].find_index(actual_note)
|
44
|
+
else
|
45
|
+
source = NOTES[:flat]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Still haven't found the note
|
49
|
+
raise Error if index.nil?
|
50
|
+
|
51
|
+
index += half_steps
|
52
|
+
index %= source.size
|
53
|
+
|
54
|
+
if pref_flat
|
55
|
+
transposed_note = NOTES[:flat][index]
|
56
|
+
else
|
57
|
+
transposed_note = source[index]
|
58
|
+
end
|
59
|
+
|
60
|
+
transposed_notes << note.gsub(actual_note.downcase, transposed_note.downcase).capitalize
|
61
|
+
rescue
|
62
|
+
puts "'#{note.capitalize}' is not a valid note!"
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# %w(D A G Bm).join ' '
|
68
|
+
transposed_notes.join ' '
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: note-transpose
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vidur Murali
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-24 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- vidur@monkeychai.com
|
16
|
+
executables:
|
17
|
+
- note-transpose
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- README.md
|
22
|
+
- bin/note-transpose
|
23
|
+
- lib/note-transpose.rb
|
24
|
+
homepage: https://github.com/vyder/note-transpose
|
25
|
+
licenses:
|
26
|
+
- MIT
|
27
|
+
metadata: {}
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
requirements:
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 2.7.3
|
45
|
+
signing_key:
|
46
|
+
specification_version: 4
|
47
|
+
summary: A CLI tool to transpose notes by half steps
|
48
|
+
test_files: []
|