fet 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a6eaf2c2012e548d709b7c60d8bb087f55062ea7a069fade95adb5ee04f8c70
4
- data.tar.gz: d9a82a31165883c5219fd94b042dcc0ceda2c12e4e2c8fb915257e5bb02e6df6
3
+ metadata.gz: 6482a7f1b9a0e8375267c1220690f706e9058b0b485bb3079c174726425594ec
4
+ data.tar.gz: 0fd439a8ac3631db1f88d345bb8c50a8f0baf1dd267017b88ec7884613f4b867
5
5
  SHA512:
6
- metadata.gz: 9c78069eab1b047f0e7bf72580e5d5dac1c12467e606ff8be3637fcd202a6e666d009900bbcee3e7bad66992fbf488df3abe049d0a14494a54c9209223401d30
7
- data.tar.gz: b7d43fc3d8edff904615b9e6b681edc4b77d6becca9beee2a137c3b2e8fdd0071aab9953dffd090a3f107f5b0e24054fd5af4cdfba544920949aa6ee39490fd6
6
+ metadata.gz: 8e3bec0d13c52547ab1f71aa2197b38ec85abf794f8d2e160fbb34bf45219e006a28e47cbab9d6f86e9067694cedbff2164621684fa9339ab21c424b3f722d7f
7
+ data.tar.gz: bc68f79d35ba1114f79963f027ee3155b260f462e0a6589b3e5562f82615a1910ca01ea5b2fea5e2c99c4936b31e6a75c0b4f6ad788a10e0e4358079400abdb8
@@ -7,6 +7,8 @@ jobs:
7
7
  runs-on: ubuntu-latest
8
8
  steps:
9
9
  - uses: actions/checkout@v2
10
+ - name: Ruby2D dependencies
11
+ run: sudo apt-get install -y libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev
10
12
  - name: Set up Ruby
11
13
  uses: ruby/setup-ruby@v1
12
14
  with:
data/.rubocop.yml CHANGED
@@ -44,4 +44,7 @@ Style/RedundantReturn:
44
44
  Enabled: false
45
45
 
46
46
  Style/EmptyCaseCondition:
47
+ Enabled: false
48
+
49
+ Style/ExplicitBlockArgument:
47
50
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
- ## [Unreleased]
1
+ ## [Released]
2
2
 
3
- ## [0.1.0] - 2021-08-26
3
+ ## [0.3.0] - 2021-09-06
4
4
 
5
- - Initial release
5
+ - Smoother singing MIDI exercises.
6
+ - UI for listening exercises.
7
+
8
+ ## [0.2.0] - 2021-09-01
9
+
10
+ - Initial release.
11
+ - Convert individual binaries to a self-contained gem and add 100% test coverage.
data/Gemfile CHANGED
@@ -7,7 +7,9 @@ gemspec
7
7
 
8
8
  group :test do
9
9
  gem "minitest", "~> 5.0"
10
+ gem "minitest-stub_any_instance", "~> 1.0", ">= 1.0.2"
10
11
  gem "simplecov", "~> 0.21.2"
12
+ gem "timecop", "~> 0.9.4"
11
13
  end
12
14
 
13
15
  group :test, :development do
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fet (0.2.0)
4
+ fet (0.3.0)
5
5
  gli (~> 2.20, >= 2.20.1)
6
6
  ice_nine (~> 0.11.2)
7
7
  midilib (~> 2.0, >= 2.0.5)
8
+ ruby2d (~> 0.10.0)
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
@@ -20,6 +21,7 @@ GEM
20
21
  method_source (1.0.0)
21
22
  midilib (2.0.5)
22
23
  minitest (5.14.4)
24
+ minitest-stub_any_instance (1.0.2)
23
25
  parallel (1.20.1)
24
26
  parser (3.0.2.0)
25
27
  ast (~> 2.4.1)
@@ -46,12 +48,14 @@ GEM
46
48
  rubocop-ast (1.11.0)
47
49
  parser (>= 3.0.1.1)
48
50
  ruby-progressbar (1.11.0)
51
+ ruby2d (0.10.0)
49
52
  simplecov (0.21.2)
50
53
  docile (~> 1.1)
51
54
  simplecov-html (~> 0.11)
52
55
  simplecov_json_formatter (~> 0.1)
53
56
  simplecov-html (0.12.3)
54
57
  simplecov_json_formatter (0.1.3)
58
+ timecop (0.9.4)
55
59
  unicode-display_width (2.0.0)
56
60
 
57
61
  PLATFORMS
@@ -61,11 +65,13 @@ DEPENDENCIES
61
65
  codecov (~> 0.6.0)
62
66
  fet!
63
67
  minitest (~> 5.0)
68
+ minitest-stub_any_instance (~> 1.0, >= 1.0.2)
64
69
  pry-byebug (~> 3.9)
65
70
  rake (~> 13.0)
66
71
  rdoc (~> 6.3, >= 6.3.2)
67
72
  rubocop (~> 1.7)
68
73
  simplecov (~> 0.21.2)
74
+ timecop (~> 0.9.4)
69
75
 
70
76
  BUNDLED WITH
71
77
  2.2.22
data/README.md CHANGED
@@ -1,7 +1,11 @@
1
1
  [![codecov](https://codecov.io/gh/DimitriosLisenko/fet/branch/master/graph/badge.svg?token=6W2B0Z4E4S)](https://codecov.io/gh/DimitriosLisenko/fet)
2
2
 
3
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.
4
+ This is a functional ear trainer, meaning that it teaches you to identify degrees in a key.
5
+
6
+ Every level, a chord progression is played to identify a major/minor key, followed by random notes played harmonically. The degrees of these notes should be identified and selected.
7
+
8
+ <img src="./assets/readme/demo.gif">
5
9
 
6
10
  ## Installation
7
11
  Add this line to your application's Gemfile:
@@ -19,12 +23,42 @@ Or install it yourself as:
19
23
  $ gem install fet
20
24
 
21
25
  ## Usage
22
- Refer to [the rdoc](https://github.com/DimitriosLisenko/fet/blob/master/fet.rdoc) for detailed usage instructions and descriptions of commands.
23
26
 
24
- ## Filename Format
27
+ ### Ear Training via the UI
28
+ The UI currently supports listening exercises, where a chord progression is played to establish a key, followed by notes played harmonically. The degrees of these notes should be identified by selecting them in the UI.
29
+
30
+ The binary can be executed as follows:
31
+ ```sh
32
+ fet play listening --degrees 1 --key-type major --next-on-correct --tempo 200
33
+ ```
34
+
35
+ All flags are optional, and serve the following purposes:
36
+
37
+ | Flag | Description |
38
+ | ------------- | ------------- |
39
+ | --degrees | How many unique degrees to play for the random notes - maximum of 11. |
40
+ | --key-type | Type of key to play, can be "major" or "minor". |
41
+ | --[no-]next-on-correct | Go to the next level automatically when answered correctly. |
42
+ | --tempo | The tempo at which the chord progression is played. |
43
+
44
+ When using the UI, the following keyboard shortcuts are defined to allow for mouse-free interaction:
45
+ | Keyboard Shortcut | Description |
46
+ | ------------- | ------------- |
47
+ | ENTER | Go to the next level once this level is over. |
48
+ | q | Quit the application. |
49
+ | c | Repeat the chord progression only. |
50
+ | n | Repeat the notes only. |
51
+ | l | Repeat the question (looping). |
52
+ | 1-7 | Select the degree, e.g. "2" selects the 2nd degree. |
53
+ | - | Modify the above degree to flatten it, e.g. "-" followed by "2" will select the b2nd degree. |
54
+ | + | Modify the above degree to sharpen it, e.g. "+" followed by "4" will select the #4th degree. |
55
+ | 0 | Make the degree natural, e.g. "+" followed by followed by "0" followed by "4" will select the 4th degree. |
56
+
57
+ ### Ear Training via MIDI files
58
+ #### Filename Format
25
59
  The generators will currently create MIDI files. The correct answer is included in the filename.
26
60
 
27
- ### Listening exercises
61
+ #### Listening exercises
28
62
  For listening exercises, here is a potential list of generated MIDI files (for 2 degrees):
29
63
  ```sh
30
64
  $ find .
@@ -54,7 +88,7 @@ The file name contains all the information required for the answer. For example,
54
88
 
55
89
  `(G#2)`: the [scientific pitch notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation) of which is G#2
56
90
 
57
- ### Singing exercises
91
+ #### Singing exercises
58
92
  The singing exercises will generate all possible combinations for keys and degrees as follows:
59
93
  ```sh
60
94
  $ find .
@@ -78,7 +112,7 @@ The file name contains all the information required for the answer. For example,
78
112
 
79
113
  `3`: you should sing the 3rd degree.
80
114
 
81
- ### Single Note Listening exercises
115
+ #### Single Note Listening exercises
82
116
  For single note listening exercises, the same note is played across all possible keys:
83
117
  ```sh
84
118
  $ find .
@@ -98,6 +132,9 @@ The file name contains all the information required for the answer. For example,
98
132
 
99
133
  `3`: the note that is played is the 3rd degree in this key.
100
134
 
135
+ ### More Information
136
+ Refer to [the rdoc](https://github.com/DimitriosLisenko/fet/blob/master/fet.rdoc) for detailed usage instructions and descriptions of commands.
137
+
101
138
  ## Development
102
139
 
103
140
  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.
@@ -0,0 +1,94 @@
1
+ Copyright (c) 2010, ParaType Ltd. (http://www.paratype.com/public),
2
+ with Reserved Font Names "PT Sans" and "ParaType".
3
+
4
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
5
+ This license is copied below, and is also available with a FAQ at:
6
+ http://scripts.sil.org/OFL
7
+
8
+
9
+ -----------------------------------------------------------
10
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
11
+ -----------------------------------------------------------
12
+
13
+ PREAMBLE
14
+ The goals of the Open Font License (OFL) are to stimulate worldwide
15
+ development of collaborative font projects, to support the font creation
16
+ efforts of academic and linguistic communities, and to provide a free and
17
+ open framework in which fonts may be shared and improved in partnership
18
+ with others.
19
+
20
+ The OFL allows the licensed fonts to be used, studied, modified and
21
+ redistributed freely as long as they are not sold by themselves. The
22
+ fonts, including any derivative works, can be bundled, embedded,
23
+ redistributed and/or sold with any software provided that any reserved
24
+ names are not used by derivative works. The fonts and derivatives,
25
+ however, cannot be released under any other type of license. The
26
+ requirement for fonts to remain under this license does not apply
27
+ to any document created using the fonts or their derivatives.
28
+
29
+ DEFINITIONS
30
+ "Font Software" refers to the set of files released by the Copyright
31
+ Holder(s) under this license and clearly marked as such. This may
32
+ include source files, build scripts and documentation.
33
+
34
+ "Reserved Font Name" refers to any names specified as such after the
35
+ copyright statement(s).
36
+
37
+ "Original Version" refers to the collection of Font Software components as
38
+ distributed by the Copyright Holder(s).
39
+
40
+ "Modified Version" refers to any derivative made by adding to, deleting,
41
+ or substituting -- in part or in whole -- any of the components of the
42
+ Original Version, by changing formats or by porting the Font Software to a
43
+ new environment.
44
+
45
+ "Author" refers to any designer, engineer, programmer, technical
46
+ writer or other person who contributed to the Font Software.
47
+
48
+ PERMISSION & CONDITIONS
49
+ Permission is hereby granted, free of charge, to any person obtaining
50
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
51
+ redistribute, and sell modified and unmodified copies of the Font
52
+ Software, subject to the following conditions:
53
+
54
+ 1) Neither the Font Software nor any of its individual components,
55
+ in Original or Modified Versions, may be sold by itself.
56
+
57
+ 2) Original or Modified Versions of the Font Software may be bundled,
58
+ redistributed and/or sold with any software, provided that each copy
59
+ contains the above copyright notice and this license. These can be
60
+ included either as stand-alone text files, human-readable headers or
61
+ in the appropriate machine-readable metadata fields within text or
62
+ binary files as long as those fields can be easily viewed by the user.
63
+
64
+ 3) No Modified Version of the Font Software may use the Reserved Font
65
+ Name(s) unless explicit written permission is granted by the corresponding
66
+ Copyright Holder. This restriction only applies to the primary font name as
67
+ presented to the users.
68
+
69
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
70
+ Software shall not be used to promote, endorse or advertise any
71
+ Modified Version, except to acknowledge the contribution(s) of the
72
+ Copyright Holder(s) and the Author(s) or with their explicit written
73
+ permission.
74
+
75
+ 5) The Font Software, modified or unmodified, in part or in whole,
76
+ must be distributed entirely under this license, and must not be
77
+ distributed under any other license. The requirement for fonts to
78
+ remain under this license does not apply to any document created
79
+ using the Font Software.
80
+
81
+ TERMINATION
82
+ This license becomes null and void if any of the above conditions are
83
+ not met.
84
+
85
+ DISCLAIMER
86
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
87
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
88
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
89
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
90
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
91
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
92
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
93
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
94
+ OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file
Binary file
data/bin/fet CHANGED
@@ -77,11 +77,38 @@ class App
77
77
  end
78
78
  end
79
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
80
+ desc("Run the ear training application")
81
+ # arg_name "Describe arguments to generate here"
82
+ command(:play) do |c|
83
+ c.desc("Run the ear training application for listening")
84
+ c.long_desc("Each level will contain a chord progression, followed by the specified number of degrees - first harmonically, then melodically after a pause.")
85
+ c.command :listening do |listening|
86
+ listening.desc("Tempo at which the chord progression is played at")
87
+ listening.default_value(120)
88
+ listening.flag([:t, :tempo], type: Integer)
89
+
90
+ listening.desc("Number of degrees to play")
91
+ listening.default_value(1)
92
+ listening.flag([:d, :degrees], type: Integer, must_match: (1..11).map(&:to_s))
93
+
94
+ listening.desc("Type of the chord progression")
95
+ listening.default_value("major")
96
+ listening.flag([:k, :"key-type"], type: String, must_match: ["major", "minor"])
97
+
98
+ listening.desc("Automatically go to the next exercise when the answer was correct")
99
+ listening.default_value(true)
100
+ listening.switch [:n, :"next-on-correct"]
101
+
102
+ listening.action do |global_options, options, args|
103
+ Fet::Cli::Play::Listening.run(global_options, options, args)
104
+ end
105
+ end
106
+ end
107
+
108
+ on_error do |exception|
109
+ puts exception.backtrace
110
+ true
111
+ end
85
112
  end
86
113
 
87
114
  exit App.run(ARGV)
data/fet.gemspec CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency "gli", "~> 2.20", ">= 2.20.1"
32
32
  spec.add_dependency "ice_nine", "~> 0.11.2"
33
33
  spec.add_dependency "midilib", "~> 2.0", ">= 2.0.5"
34
+ spec.add_dependency "ruby2d", "~> 0.10.0"
34
35
 
35
36
  # RDoc configuration
36
37
  spec.extra_rdoc_files = ["README.rdoc", "fet.rdoc"]
data/fet.rdoc CHANGED
@@ -92,3 +92,41 @@ List commands one per line, to assist with shell completion
92
92
 
93
93
 
94
94
 
95
+ ==== Command: <tt>play </tt>
96
+ Run the ear training application
97
+
98
+
99
+ ===== Commands
100
+ ====== Command: <tt>listening </tt>
101
+ Run the ear training application for listening
102
+
103
+ Each level will contain a chord progression, followed by the specified number of degrees - first harmonically, then melodically after a pause.
104
+ ======= Options
105
+ ======= -d|--degrees arg
106
+
107
+ Number of degrees to play
108
+
109
+ [Default Value] 1
110
+ [Must Match] ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]
111
+
112
+
113
+ ======= -k|--key-type arg
114
+
115
+ Type of the chord progression
116
+
117
+ [Default Value] major
118
+ [Must Match] ["major", "minor"]
119
+
120
+
121
+ ======= -t|--tempo arg
122
+
123
+ Tempo at which the chord progression is played at
124
+
125
+ [Default Value] 120
126
+
127
+
128
+ ======= -n|--[no-]next-on-correct
129
+ Automatically go to the next exercise when the answer was correct
130
+
131
+
132
+
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fet
4
+ module Cli
5
+ module Play
6
+ # CLI implementation for the "play listening" command
7
+ module Listening
8
+ def self.run(_global_options, options, _args)
9
+ Fet::Ui::Game.new(
10
+ tempo: options[:tempo],
11
+ degrees: options[:degrees],
12
+ key_type: options[:"key-type"],
13
+ next_on_correct: options[:"next-on-correct"],
14
+ ).start
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
data/lib/fet/degree.rb CHANGED
@@ -33,6 +33,10 @@ module Fet
33
33
  return degree_name.size == 2 ? degree_name[1].to_i : degree_name[0].to_i
34
34
  end
35
35
 
36
+ def degree_index
37
+ return DEGREE_NAMES.index { |degree_names| degree_names.include?(degree_name) }
38
+ end
39
+
36
40
  private
37
41
 
38
42
  attr_writer :degree_name
data/lib/fet/degrees.rb CHANGED
@@ -23,10 +23,18 @@ module Fet
23
23
  return Degree::DEGREE_NAMES[degree_index_of_midi_value(midi_value)]
24
24
  end
25
25
 
26
+ def degree_index_of_midi_value(midi_value)
27
+ return MidiNote.new(midi_value).degree(root_midi_value)
28
+ end
29
+
26
30
  def note_name_of_degree(degree_name)
27
31
  return degree_to_note_name[Degree.new(degree_name).degree_name]
28
32
  end
29
33
 
34
+ def select_degrees_from_midi_values(midi_value_range, number_of_degrees)
35
+ return select_degrees_from_midi_values_recursive(midi_value_range, [], number_of_degrees)
36
+ end
37
+
30
38
  private
31
39
 
32
40
  attr_writer :root_name,
@@ -54,8 +62,17 @@ module Fet
54
62
  return result
55
63
  end
56
64
 
57
- def degree_index_of_midi_value(midi_value)
58
- return MidiNote.new(midi_value).degree(root_midi_value)
65
+ def select_degrees_from_midi_values_recursive(all_notes, chosen_notes, number_of_degrees)
66
+ return chosen_notes if number_of_degrees.zero?
67
+
68
+ selected_note = all_notes.sample
69
+ chosen_notes << selected_note
70
+
71
+ all_notes_without_note_degree = all_notes.reject do |note|
72
+ Fet::MidiNote.new(note).degree(root_midi_value) == Fet::MidiNote.new(selected_note).degree(root_midi_value)
73
+ end
74
+
75
+ select_degrees_from_midi_values_recursive(all_notes_without_note_degree, chosen_notes, number_of_degrees - 1)
59
76
  end
60
77
  end
61
78
  end