fet 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9a6eaf2c2012e548d709b7c60d8bb087f55062ea7a069fade95adb5ee04f8c70
4
+ data.tar.gz: d9a82a31165883c5219fd94b042dcc0ceda2c12e4e2c8fb915257e5bb02e6df6
5
+ SHA512:
6
+ metadata.gz: 9c78069eab1b047f0e7bf72580e5d5dac1c12467e606ff8be3637fcd202a6e666d009900bbcee3e7bad66992fbf488df3abe049d0a14494a54c9209223401d30
7
+ data.tar.gz: b7d43fc3d8edff904615b9e6b681edc4b77d6becca9beee2a137c3b2e8fdd0071aab9953dffd090a3f107f5b0e24054fd5af4cdfba544920949aa6ee39490fd6
@@ -0,0 +1,18 @@
1
+ name: Ruby
2
+
3
+ on: [push,pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v2
10
+ - name: Set up Ruby
11
+ uses: ruby/setup-ruby@v1
12
+ with:
13
+ ruby-version: 3.0.2
14
+ bundler-cache: true
15
+ - name: Run the default task
16
+ run: bundle exec rake
17
+ env:
18
+ CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /singing/
2
+ /listening/
3
+ /listening_single_note/
4
+ /.bundle/
5
+ /.yardoc
6
+ /_yardoc/
7
+ /coverage/
8
+ /doc/
9
+ /pkg/
10
+ /spec/reports/
11
+ /tmp/
data/.rubocop.yml ADDED
@@ -0,0 +1,47 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+ NewCops: enable
4
+
5
+ Style/StringLiterals:
6
+ Enabled: true
7
+ EnforcedStyle: double_quotes
8
+
9
+ Style/StringLiteralsInInterpolation:
10
+ Enabled: true
11
+ EnforcedStyle: double_quotes
12
+
13
+ Style/TrailingCommaInArrayLiteral:
14
+ Enabled: true
15
+ EnforcedStyleForMultiline: consistent_comma
16
+
17
+ Style/TrailingCommaInArguments:
18
+ Enabled: true
19
+ EnforcedStyleForMultiline: consistent_comma
20
+
21
+ Style/TrailingCommaInHashLiteral:
22
+ Enabled: true
23
+ EnforcedStyleForMultiline: consistent_comma
24
+
25
+ Style/RaiseArgs:
26
+ Enabled: true
27
+ EnforcedStyle: compact
28
+
29
+ Style/WordArray:
30
+ Enabled: true
31
+ EnforcedStyle: brackets
32
+
33
+ Style/SymbolArray:
34
+ Enabled: true
35
+ EnforcedStyle: brackets
36
+
37
+ Layout/CaseIndentation:
38
+ Enabled: true
39
+
40
+ Layout/LineLength:
41
+ Max: 175
42
+
43
+ Style/RedundantReturn:
44
+ Enabled: false
45
+
46
+ Style/EmptyCaseCondition:
47
+ Enabled: false
data/.ruby_version ADDED
@@ -0,0 +1 @@
1
+ 3.0.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2021-08-26
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's runtime dependencies in fet.gemspec
6
+ gemspec
7
+
8
+ group :test do
9
+ gem "minitest", "~> 5.0"
10
+ gem "simplecov", "~> 0.21.2"
11
+ end
12
+
13
+ group :test, :development do
14
+ gem "codecov", "~> 0.6.0"
15
+ gem "pry-byebug", "~> 3.9"
16
+ gem "rake", "~> 13.0"
17
+ gem "rdoc", "~> 6.3", ">= 6.3.2"
18
+ gem "rubocop", "~> 1.7"
19
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,71 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fet (0.2.0)
5
+ gli (~> 2.20, >= 2.20.1)
6
+ ice_nine (~> 0.11.2)
7
+ midilib (~> 2.0, >= 2.0.5)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ast (2.4.2)
13
+ byebug (11.1.3)
14
+ codecov (0.6.0)
15
+ simplecov (>= 0.15, < 0.22)
16
+ coderay (1.1.3)
17
+ docile (1.4.0)
18
+ gli (2.20.1)
19
+ ice_nine (0.11.2)
20
+ method_source (1.0.0)
21
+ midilib (2.0.5)
22
+ minitest (5.14.4)
23
+ parallel (1.20.1)
24
+ parser (3.0.2.0)
25
+ ast (~> 2.4.1)
26
+ pry (0.13.1)
27
+ coderay (~> 1.1)
28
+ method_source (~> 1.0)
29
+ pry-byebug (3.9.0)
30
+ byebug (~> 11.0)
31
+ pry (~> 0.13.0)
32
+ rainbow (3.0.0)
33
+ rake (13.0.6)
34
+ rdoc (6.3.2)
35
+ regexp_parser (2.1.1)
36
+ rexml (3.2.5)
37
+ rubocop (1.20.0)
38
+ parallel (~> 1.10)
39
+ parser (>= 3.0.0.0)
40
+ rainbow (>= 2.2.2, < 4.0)
41
+ regexp_parser (>= 1.8, < 3.0)
42
+ rexml
43
+ rubocop-ast (>= 1.9.1, < 2.0)
44
+ ruby-progressbar (~> 1.7)
45
+ unicode-display_width (>= 1.4.0, < 3.0)
46
+ rubocop-ast (1.11.0)
47
+ parser (>= 3.0.1.1)
48
+ ruby-progressbar (1.11.0)
49
+ simplecov (0.21.2)
50
+ docile (~> 1.1)
51
+ simplecov-html (~> 0.11)
52
+ simplecov_json_formatter (~> 0.1)
53
+ simplecov-html (0.12.3)
54
+ simplecov_json_formatter (0.1.3)
55
+ unicode-display_width (2.0.0)
56
+
57
+ PLATFORMS
58
+ ruby
59
+
60
+ DEPENDENCIES
61
+ codecov (~> 0.6.0)
62
+ fet!
63
+ minitest (~> 5.0)
64
+ pry-byebug (~> 3.9)
65
+ rake (~> 13.0)
66
+ rdoc (~> 6.3, >= 6.3.2)
67
+ rubocop (~> 1.7)
68
+ simplecov (~> 0.21.2)
69
+
70
+ BUNDLED WITH
71
+ 2.2.22
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Dimitrios Lisenko
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Dimitrios Lisenko
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,113 @@
1
+ [![codecov](https://codecov.io/gh/DimitriosLisenko/fet/branch/master/graph/badge.svg?token=6W2B0Z4E4S)](https://codecov.io/gh/DimitriosLisenko/fet)
2
+
3
+ # FET (Functional Ear Trainer)
4
+ Create MIDI files for functional ear training. Each file will contain a major/minor chord progression, followed by note(s) that you should identify the scale degree of by ear.
5
+
6
+ ## Installation
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'fet'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install fet
20
+
21
+ ## Usage
22
+ Refer to [the rdoc](https://github.com/DimitriosLisenko/fet/blob/master/fet.rdoc) for detailed usage instructions and descriptions of commands.
23
+
24
+ ## Filename Format
25
+ The generators will currently create MIDI files. The correct answer is included in the filename.
26
+
27
+ ### Listening exercises
28
+ For listening exercises, here is a potential list of generated MIDI files (for 2 degrees):
29
+ ```sh
30
+ $ find .
31
+ ...
32
+ ./listening/major/DbM_b6(Bbb2)_5(Ab5).mid
33
+ ./listening/major/BbM_7(A4)_2(C6).mid
34
+ ./listening/major/EM_b6(C2)_3(G#2).mid
35
+ ./listening/major/GbM_6(Eb4)_3(Bb5).mid
36
+ ./listening/major/FM_6(D4)_3(A5).mid
37
+ ...
38
+ ./listening/minor/Dm_b7(C3)_1(D4).mid
39
+ ./listening/minor/F#m_b2(G2)_3(A#4).mid
40
+ ./listening/minor/G#m_b6(E1)_b2(A2).mid
41
+ ./listening/minor/Dm_6(B0)_7(C#3).mid
42
+ ./listening/minor/C#m_5(G#4)_6(A#4).mid
43
+ ...
44
+ ```
45
+ The file name contains all the information required for the answer. For example, `EM_b6(C2)_3(G#2).mid`:
46
+
47
+ `EM`: the chord progression is in E Major.
48
+
49
+ `b6`: the bottom note will be the b6 degree
50
+
51
+ `(C2)`: the [scientific pitch notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation) of which is C2
52
+
53
+ `3`: the next note from the bottom will be the 3 degree
54
+
55
+ `(G#2)`: the [scientific pitch notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation) of which is G#2
56
+
57
+ ### Singing exercises
58
+ The singing exercises will generate all possible combinations for keys and degrees as follows:
59
+ ```sh
60
+ $ find .
61
+ ...
62
+ ./singing/major/AM_1.mid
63
+ ./singing/major/BbM_3.mid
64
+ ./singing/major/CM_4.mid
65
+ ./singing/major/CM_5.mid
66
+ ./singing/major/BbM_2.mid
67
+ ...
68
+ ./singing/minor/Am_1.mid
69
+ ./singing/minor/Bbm_3.mid
70
+ ./singing/minor/Cm_4.mid
71
+ ./singing/minor/G#m_4.mid
72
+ ./singing/minor/F#m_1.mid
73
+ ...
74
+ ```
75
+ The file name contains all the information required for the answer. For example, `BbM_3.mid`:
76
+
77
+ `BbM`: the chord progression is in Bb Major.
78
+
79
+ `3`: you should sing the 3rd degree.
80
+
81
+ ### Single Note Listening exercises
82
+ For single note listening exercises, the same note is played across all possible keys:
83
+ ```sh
84
+ $ find .
85
+ ...
86
+ ./listening_single_note/major/CM_1.mid
87
+ ./listening_single_note/major/BM_b2.mid
88
+ ./listening_single_note/major/F#M_b5.mid
89
+ ...
90
+ ./listening_single_note/minor/Am_b3.mid
91
+ ./listening_single_note/minor/G#m_3.mid
92
+ ./listening_single_note/minor/Cm_1.mid
93
+ ...
94
+ ```
95
+ The file name contains all the information required for the answer. For example, `G#m_3.mid`:
96
+
97
+ `G#m`: the chord progression is in G# Minor.
98
+
99
+ `3`: the note that is played is the 3rd degree in this key.
100
+
101
+ ## Development
102
+
103
+ 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.
104
+
105
+ To install this gem onto your local machine, run `bundle exec rake install`. 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).
106
+
107
+ ## Contributing
108
+
109
+ Bug reports and pull requests are welcome on GitHub at https://github.com/DimitriosLisenko/fet.
110
+
111
+ ## License
112
+
113
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/README.rdoc ADDED
@@ -0,0 +1,6 @@
1
+ = fet
2
+
3
+ FET (Functional Ear Trainer)
4
+
5
+ :include:fet.rdoc
6
+
data/Rakefile ADDED
@@ -0,0 +1,23 @@
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 "rubocop/rake_task"
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ require "rdoc/task"
17
+ Rake::RDocTask.new do |rd|
18
+ rd.main = "README.rdoc"
19
+ rd.rdoc_files.include("README.rdoc", "lib/**/*.rb", "bin/**/*")
20
+ rd.title = "FET (Functional Ear Trainer)"
21
+ end
22
+
23
+ task(default: [:test, :rubocop])
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ rm -rf listening
@@ -0,0 +1,2 @@
1
+ #!/bin/bash
2
+ rm -rf singing
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+ for i in ${1}/major/*.mid ; do
3
+ timidity -Ow -o - $i | lame - ${i/mid/mp3}
4
+ # rm $i
5
+ done
6
+
7
+ for i in ${1}/minor/*.mid ; do
8
+ timidity -Ow -o - $i | lame - ${i/mid/mp3}
9
+ # rm $i
10
+ done
11
+
12
+ mv ${1}/major/*.mp3 ${1}/major/mp3
13
+ mv ${1}/minor/*.mp3 ${1}/minor/mp3
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fet"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/fet ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # frozen_string_literal: true
4
+
5
+ require "gli"
6
+ require "fet"
7
+
8
+ # Class in charge of implementing command-line interface
9
+ class App
10
+ extend GLI::App
11
+
12
+ program_desc("Functional Ear Trainer")
13
+
14
+ version(Fet::VERSION)
15
+
16
+ subcommand_option_handling(:normal)
17
+ arguments(:strict)
18
+
19
+ desc("Generate MIDI files for ear training")
20
+ # arg_name "Describe arguments to generate here"
21
+ command(:generate) do |c|
22
+ c.desc("Generate MIDI files for listening")
23
+ c.long_desc("Each MIDI file will contain a chord progression, followed by the specified number of degrees - first harmonically, then melodically after a pause.")
24
+ c.command :listening do |listening|
25
+ listening.desc("Tempo at which the chord progression is played at")
26
+ listening.default_value(120)
27
+ listening.flag([:t, :tempo], type: Integer)
28
+
29
+ listening.desc("Number of degrees to play")
30
+ listening.default_value(1)
31
+ listening.flag([:d, :degrees], type: Integer, must_match: (1..11).map(&:to_s))
32
+
33
+ listening.desc("Number of exercises to generate")
34
+ listening.default_value(200)
35
+ listening.flag([:e, :exercises], type: Integer)
36
+
37
+ listening.desc("Generate all single degree listening exercises (ignores -e and -d flag)")
38
+ listening.default_value(false)
39
+ listening.switch [:a, :"all-single-degree"]
40
+
41
+ listening.action do |global_options, options, args|
42
+ Fet::Cli::Generate::Listening.run(global_options, options, args)
43
+ end
44
+ end
45
+ end
46
+
47
+ command(:generate) do |c|
48
+ c.desc("Generate MIDI files for listening (single note)")
49
+ c.long_desc("Each MIDI file will contain a chord progression, followed the same note across all files.")
50
+ c.command :single_note_listening do |single_note_listening|
51
+ single_note_listening.desc("Tempo at which the chord progression is played at")
52
+ single_note_listening.default_value(120)
53
+ single_note_listening.flag([:t, :tempo], type: Integer)
54
+
55
+ single_note_listening.action do |global_options, options, args|
56
+ Fet::Cli::Generate::SingleNoteListening.run(global_options, options, args)
57
+ end
58
+ end
59
+ end
60
+
61
+ command(:generate) do |c|
62
+ c.desc("Generate MIDI files for singing")
63
+ c.long_desc("Each MIDI file will contain a chord progression, followed by a specified pause, during which the degree should be sung."\
64
+ " The degree is then played for confirmation.")
65
+ c.command :singing do |singing|
66
+ singing.desc("Tempo at which the chord progression is played at")
67
+ singing.default_value(120)
68
+ singing.flag([:t, :tempo], type: Integer)
69
+
70
+ singing.desc("How many seconds to wait before playing the correct note")
71
+ singing.default_value(3)
72
+ singing.flag([:p, :pause], type: Integer)
73
+
74
+ singing.action do |global_options, options, args|
75
+ Fet::Cli::Generate::Singing.run(global_options, options, args)
76
+ end
77
+ end
78
+ end
79
+
80
+ # NOTE: if you need the backtrace for an exception, this can be uncommented
81
+ # on_error do |exception|
82
+ # puts exception.backtrace
83
+ # true
84
+ # end
85
+ end
86
+
87
+ exit App.run(ARGV)