In keeping with my point #3#2, there are a bunch of objects, and certainly a lot more lines of code. But, I feel the object model gives us the beginnings of a foundation upon which we could build a music theory app of arbitrary size - and remain sane in the process.
In keeping with my point #3, there are a bunch of objects, and certainly a lot more lines of code. But, I feel the object model gives us the beginnings of a foundation upon which we could build a music theory app of arbitrary size - and remain sane in the process.
In keeping with my point #2, there are a bunch of objects, and certainly a lot more lines of code. But, I feel the object model gives us the beginnings of a foundation upon which we could build a music theory app of arbitrary size - and remain sane in the process.
I dabble in music so your post caught my eye.
Here are my thoughts:
If I had to pick one word to describe the app, it would be "procedural". You have successfully defined an algorithm, but I'd say that it reads more like FORTRAN than C#. It even includes
goto
... which I've never seen used before in C#.When working in an object-oriented language, I prefer to let the domain drive the object model. In my experience, modelling what exists in reality goes a long way toward making software maintainable and expandable.
Instead of a giant
switch
statement, you might want to go with aDictionary<string, int>
In my spare time I whipped up my take on an object-oriented musical scale and chord "generator" app, which I have posted here: https://github.com/lucidobjects/MusicalKeys
In keeping with my point #3, there are a bunch of objects, and certainly a lot more lines of code. But, I feel the object model gives us the beginnings of a foundation upon which we could build a music theory app of arbitrary size - and remain sane in the process.
My app lacks some of the features that yours has, like interactive input and modes. But, my aim was to show an object-oriented approach to the problem rather than achieve feature parity.
Here’s a screenshot of the class files. While the preferred terminology may vary from musician to musician, various elements of music theory are present and accounted for.
Classes
To see how the program runs, check out App.cs.
public void Run()
{
var steps = new Steps();
var scalePatterns = getScalePatterns(steps).Select(p => p as Pattern).ToList();
var intervals = new Intervals();
var chordPatterns = getChordPatterns(intervals).Select(p => p as Pattern).ToList();
var tones = new Pitches();
///define the Key of A and output individual elements from it
var keyOfA = new Key(tones.A, scalePatterns, chordPatterns);
Console.WriteLine(keyOfA.Scales.Get("Major").ToString());
Console.WriteLine(keyOfA.Scales.Get("Natural Minor").ToString());
Console.WriteLine(keyOfA.Scales.Get("Melodic Minor").ToString());
Console.WriteLine(keyOfA.Chords.Get("M").ToString());
Console.WriteLine(keyOfA.Chords.Get("M7").ToString());
Console.WriteLine(keyOfA.Chords.Get("7").ToString());
Console.WriteLine(keyOfA.Chords.Get("m7").ToString());
Console.WriteLine(keyOfA.Chords.Get("m7b5").ToString());
Console.WriteLine(keyOfA.Chords.Get("dim7").ToString());
Console.WriteLine();
///shortened syntax to define the Key of F# and output all of its scales and chords
Console.WriteLine(new Key(tones.Fsharp, scalePatterns, chordPatterns).ToString());
///define and print a single scale
var scalePattern = new StepPattern("Major Scale", "WWHWWWH");
var scale = new ToneSet(tones.Dsharp, scalePattern);
Console.WriteLine(scale.ToString());
///define and print a single chord
var chordPattern = new IntervalPattern("Major 7th", "M7", "P1 M3 P5 M7");
var chord = new ToneSet(tones.C, chordPattern);
Console.WriteLine(chord.ToString());
///define and print another single chord
var chordPattern2 = new IntervalPattern("Dominant Seventh", "7", "P1 M3 P5 m7");
var chord2 = new ToneSet(tones.G, chordPattern2);
Console.WriteLine(chord2.ToString());
}
And here’s the output:
Output