[QUIZ] Music Theory (#229)

B

Ben Rho

Evan Hanson wrote all single >'d lines
I'm not sure when "susb" would cause an issue -- do you mean an
instance like Gsusb? I don't know that that's a chord, but the G would
be read and the susb would raise an exception as an invalid chord
symbol.
Yes, I do mean like Gsusb. Susb wasn't a valid example, but if it was
actually the name of a type of chord, it would be counted as Gbsusb.
Your code (with my comments):
note[1..-1].scan(/./).each do |n| #for every
character in the input except the first store it in n and do the
following ( btw an easier way is simply note[1..-1].each('') ):
if n == 'b' then flat! #if n is b
then flat the base note
elsif n == '#' then sharp! #else, if n
is # then sharp the base note
else raise ArgumentError, 'Invalid note name!' end #otherwise
rase an error
end #endfor
For Gbsusb (assuming susb is a valid chord type) get the second
character, which is b, and if it is b (which it is), flat the base note.
Then do the same for s, then u, then s, then b (and flat it again), etc.
On second thought, the sus should hit the ArgumentError, hm.. Can anyone
explain that?
It actually returns the individual notes in the chord, as generated by
Chord#names.
#...#
@name = note[0,1] #if note="Hello World" this sets
@name to 'H'
#...#
#apply sharps and flats to @name
#...#
def to_s
@name
end
#...#
To me it seems that the base note is stored in @name, which is what is
returned in to_s - so it would just return the base note.
As an aside, can anyone tell me if there is a slick Ruby way to do
what is done in cases like my Key#names, Chord#names, Chord#to_s, etc.
functions, where you're just mapping things from one array to another,
or from one array to a string, etc?
See Jesús' answer. One thing to add - array * str is the same as
array.join(str):
[1,2,3]* #=> ERROR
[1,2,3]*'' #=> '123'
[1,2,3]*' ' #=> '1 2 3'
[1,2,3].join #=> '123'
[1,2,3].join(' ') #=> '1 2 3'

Wait, I just realized some of my arguments are invalid! For some reason
I've been looking at the Note class all along, instead of the Chord
class! *facepalm* Sorry about that..

--------------------------

I started re-doing this Quiz from scratch about an hour ago without
looking at anyone else's code, unfortunately, the results look about the
same as David Springer's code (mine follows).
# Sharps the note in place... Comments are fun!
I agree! They're also useful for anyone trying to read or debug your
code! :)

#I'll be making this library bigger, given enough time. I'd copy David
Springer's (he has given me his permission), but this is case
insensitive and doesn't have optional notes).
chord_library={
'7' => [3,4,3],
'major' => [4,3],
'maj' => [4,3],
'major7' => [4,3,4],
'maj7' => [4,3,4],
'minor' => [3,4],
'min' => [3,4],
'minor7' => [3,4,3],
'min7' => [3,4,3],
'm7' => [3,4,3],
'sus' => [7],
'sus2' => [2,5],
'sus4' => [5,2]
}
rotated_notes = []
while !((chord=gets.to_s.chomp.downcase).empty?)
base_note = chord[/^[abdeg]b/]
if (base_note == nil)
base_note = chord[/^[acdfg]#/]
if (base_note == nil)
base_note = chord[/^[a-g]/]
if (base_note == nil)
puts 'ERROR: Invalid base note'
next
end
end
end
note_list = ((base_note[1,1]=='b') ? (%w(ab a bb b c db d eb e f gb
g)) : (%w(a a# b c c# d d# e f f# g g#)))
i=-1
rotated_notes = note_list.map do
i += 1
note_list[(i + note_list.index(base_note))%12]
end
variation = ($'.empty?) ? ('major') : ($')
if (chord_library[variation] == nil)
puts 'ERROR: Chord not found'
next
end
out = 'The notes in the chord ' + chord.capitalize + ' are: ' +
base_note.capitalize
note_tally = 0
chord_library[variation].each do |note|
if (note<0)
next
end
out << ' ' + rotated_notes[((note+note_tally)%12)].capitalize
note_tally += note
end
puts out
end
 
B

Ben Rho

#I'll be making this library bigger, given enough time.
Sorry for the double post, but by 'library' I meant 'chord dictionary'..
 
B

Brian Candler

Here's an updated version. I now explicitly give out the scales as well
as chords, and have attempted to optimise the "spelling" of 8-note
scales (which don't sit naturally on the 7 letters A-G). I made some
simplifications too.

Sample interaction:

C7
Scale: C D E F G A Bb
Chord: C E G Bb
C7alt
Scale: C Db Eb Fb Gb Ab Bb
Chord: C Eb Gb Bb
C7b9
Scale: C Db Eb E F# G A Bb
Chord: C E G Bb Db Eb F# A
Cdim7
Scale: C D Eb F Gb Ab A B
Chord: C Eb Gb A
C#dim7
Scale: C# D# E F# G A A# B#
Chord: C# E G A#

Attachments:
http://www.ruby-forum.com/attachment/4550/chords-bc.rb
 
B

Brian Candler

And just to clarify what I mean by 'spelling', I mean the sequence of
letters and accidentals which make a scale. On a 7-note scale each scale
corresponds to the next letter.

Example: G# major

Correct spelling: G# A# B# C# D# E# Fx

(Fx = F double-sharp)

It would be wrong to write something like: G# A# C C# D# F G
because of the gaps and duplications of letters.

This is the reason why a C7 chord is C E G Bb not C E G A#. It's because
the associated scale is
C D E F G A Bb

This scale is called the 'Mixolydian mode' (named by the ancient Greeks,
I believe). It also happens to be the notes of F major with a different
starting point, so fortunately you can re-use your major scale finger
patterns :)

Regards,

Brian.
 
A

Alexander Jesner

Here's an updated version. I now explicitly give out the scales as well
as chords, and have attempted to optimise the "spelling" of 8-note
scales (which don't sit naturally on the 7 letters A-G). I made some
simplifications too.


C
Scale: C D E F G A B
Chord: C E G B

Why does the Chord contain a B?
 
J

Jean Lazarou

Here is a partial solution, it does not support all type of chord
symbols (see
comments in the main script).

The main script is chord_translator.rb, it contains the 'chord' API and
also
translates chords when run from the command line.
Usage: ruby chord_translator.rb {chord-symbols}

Example:
ruby chord_translator.rb C Cdim7 Am F#+7
C => C E G
Cdim7 => C Eb Gb A
Am => A C E
F#+7 => F# A# D E

The chord_translator_test.rb file contain tests validating the currently
supported chord symbols and also presents the APIs implemented by
chord_translator.rb.

The other scripts are files for the GUI version of the tool, they use
the
current trunk version of Swiby (a layer on top of Java/Swing) and need
jRuby.
(the first two scripts can run with any Ruby interpreter)
The startup command is: jruby -I<swiby-trunk>/core/lib
chord_translator_ui.rb
(chord_translator_ui.rb contains the GUI definition and the GUI logic -
pretty
basic -, score_painter.rb paints the musical notation - staff - and
styles.rb
defines the CSS-like styles of the GUI). It uses a font to draw the
musical symbols, downloaded from
http://simplythebest.net/fonts/fonts/musical_symbols.html

The attached ZIP-file contains all the scripts and an image file
presenting a run of the GUI version.

Regards to all...

Attachments:
http://www.ruby-forum.com/attachment/4551/chord.zip
 
D

Daniel Moore

Introduction

*This summary was written by Jean Lazarou.*

This quiz has some tricky aspects; translating a chord symbol to the notes
that it comprise may be ambiguous. The rule to follow when interpreting a
chord symbol may be different from one person to another and still be
correct.

As an example take the C major chord, one may expect three notes (C, E and
G). On a guitar you can produce 6 notes, on a piano you can produce 10
notes. Would you only play three notes? Another example: Cb on the piano
results in hitting the B key. Should a chord like Ab-Cb be rendered as Ab-B=
?
Have a look at the thread of discussion=85

Therefore, I am not considering all interpretation differences. I am not an
expert and I would probably be wrong.
Terminology

In the hope to make the summary clear, let=92s first present the terminolog=
y
we use.

The =91thing=92 the solution program expects as input is a chord symbol.

The chord symbol has a specific syntax. It starts with a note name, a lette=
r
from A to G, that we name the chord root. We can assign a pitch to the note=
,
a flat or a sharp. We write a flatted note by adding the lower case letter
=91b=92 and a sharped by adding the =91#=92 symbol.

After the root note follows the quality and the extension, they are a
limited set of strings defining what notes to include in the produced chord=
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top