RhythmTrainer
RhythmTrainer is an application that will help you practice sight-reading rhythms.
More documentation here: https://cpe305.github.io/fall2016-project-dsabsay/
Description
RhythmTrainer presents rhythms in standard music notation. You can then record yourself performing the rhythms using the microphone in your computer. You can perform the rhythm by clapping, snapping, tapping a pencil on a desk, or doing anything else that produces distinct attacks. RhythmTrainer will then grade your performance and give you a score.
Dependencies
- JavaFX
- Music notation is rendered with VexFlow (https://github.com/0xfe/vexflow) and VexTab (https://github.com/0xfe/vextab).
- The open-source (AGPL-3.0) Essentia library is used for the audio analysis. More information about Essentia can be found here: http://essentia.upf.edu
Architecture
RhythmTrainer has a layered architecture and (loosely) employs the model-view-controller design pattern.
Design Patterns
-
Singleton Pattern: MainController
-
Only one instance of MainController for the entire application. Using the Singleton Pattern eliminates the need to pass around a reference to the MainController instance.
public class MainController { private static MainController instance = null; ... public static MainController createInstance(Stage primaryStage, PerformanceRecordRepo recordRepo) { instance = new MainController(primaryStage, recordRepo); return instance; } public static MainController getInstance() throws ControllerException { if (instance == null) { throw new ControllerException("The MainController has not been instantiated."); } return instance; } ... }
-
-
Command Pattern: Recorder
- Recorder has an enclosed class RecordAudio that implements Runnable. This is used to capture audio in a separate thread.
-
Factory Method Pattern: PerformanceScore
-
PerformanceScore has an abstract method that creates a PerformanceRecord object.
public abstract class PerformanceScore { ... public abstract PerformanceRecord createPerformanceRecord(); ... }
The subclasses of PerformanceScore implement this factory method.
public PerformanceRecord createPerformanceRecord() { RhythmRecord record = new RhythmRecord(this.getExercise().getId(), this.getExercise().getType(), this.getExercise().getName(), this.getScore(), this.getScore(), new Date(), 0); return (PerformanceRecord) record; }
-
-
Facade Pattern: Exercise
- The Exercise class only defines high-level information about the underlying exercise. This allows the application's controller to deal with various types of exercise objects in the same way.
-
Strategy Pattern: PerformanceGrader
-
The grading algorithms implement PerformanceGrader. A grading algorithm can be passed as an object to the PracticeController. This allows the PracticeController to use any grading algorithm without much modification.
public interface PerformanceGrader { public PerformanceScore evaluatePerformance(...); } public abstract class RhythmGrader implements PerformanceGrader { ... } public class SimpleRhythmGrader extends RhythmGrader { public PerformanceScore evaluatePerformance(...); }
-