note-transpose 0.1.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.
- 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: []
|