Difference between revisions of "Humdrum Lab 1"
(173 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
+ | |||
+ | == Installing Humdrum tools == | ||
+ | |||
+ | If you are using MacOS, first install [https://brew.sh Homebrew]. If you are using Windows, install [https://learn.microsoft.com/en-us/windows/wsl/install Windows Subsystem for Linux] (version 2), or install a linux distribution inside of [http://virtualbox.org VirtualBox], or install [https://www.cygwin.com/ cygwin]. | ||
+ | |||
+ | Then, to use the following commands in a terminal (typically using the [https://en.wikipedia.org/wiki/Bash_(Unix_shell) bash shell], using [https://en.wikipedia.org/wiki/Terminal_(macOS) /Applications/Terminal.app] in MacOS), install the command-line Humdrum tools. | ||
+ | |||
+ | For Windows users, I would recommend installing Linux Subsystem for Windows (LSW2). Your Windows 10/11 should be fairly up to date so that you can install version 2 of LSW. See https://docs.microsoft.com/en-us/windows/wsl for more information. I would also recommend installing Ubuntu linux from the Microsoft App store once LSW is enabled. You can also use a Stanford unix computer (see this [https://web.stanford.edu/class/archive/cs/cs107/cs107.1194/resources/logging-in network unix guide from CS 107]) | ||
+ | |||
+ | The command sequence to install command-line Humdrum tools should look like this: | ||
+ | |||
+ | git clone https://github.com/humdrum-tools/humdrum-tools | ||
+ | cd humdrum-tools | ||
+ | make update | ||
+ | make | ||
+ | make install | ||
+ | |||
+ | The installation can be located in any directory, and "make install" should insert the installation directory into the [https://kb.iu.edu/d/acar command search path]. | ||
+ | |||
+ | To check for updates at a later date, type these commands in the humdrum-tools directory: | ||
+ | |||
+ | make update | ||
+ | make | ||
+ | |||
+ | Check that your installation is successful by re-logging into the terminal. Type this command to see if the Humdrum Tools are installed successfully: | ||
+ | |||
+ | which key | ||
+ | |||
+ | If the command responds with a line of text, installation was successful. To see if the Humdrum Extras tools are installed try typing: | ||
+ | |||
+ | which keycor | ||
+ | |||
+ | . | ||
== Bach Chorales == | == Bach Chorales == | ||
Line 5: | Line 38: | ||
=== Download === | === Download === | ||
− | A Humdrum | + | A Humdrum edition of 4-Part Chorales by J.S. Bach is available at http://kern.ccarh.org/browse?l=chorales |
The data files can be downloaded using the humcat and humsplit commands (first creating a new directory to store all of the downloaded files): | The data files can be downloaded using the humcat and humsplit commands (first creating a new directory to store all of the downloaded files): | ||
+ | |||
+ | cd ~/Desktop # optional to display on Desktop in MacOS | ||
mkdir chorales | mkdir chorales | ||
cd chorales | cd chorales | ||
− | + | humsplit h://chorales | |
− | This should create 370 files in the format chor001.krn, chor002.krn, chor003.krn, etc. | + | |
+ | This should create 370 files in the format chor001.krn, chor002.krn, chor003.krn, etc. You can type "[https://en.wikipedia.org/wiki/Ls ls -asCF]" in a unix terminal ([https://www.youtube.com/watch?v=aKRYQsKR46I&t=884s /Applications/Utilities/Terminal.app in MacOS]) to see the list of files that were downloaded: | ||
+ | |||
+ | |||
+ | [[Image:chorales-ls.png|center|600px]] | ||
+ | |||
+ | ==== Alternate download method ==== | ||
+ | |||
+ | If you want to down all Humdrum files available on GitHub, try these commands: | ||
+ | |||
+ | git clone https://github.com/humdrum-tools/humdrum-data | ||
+ | cd humdrum-data | ||
+ | make | ||
+ | |||
+ | The Bach chorales will downloaded to "bach/chorales-270". You can browse through other repertories of Humdrum files that were downloaded. | ||
+ | |||
+ | ===Verovio Humdrum Viewer=== | ||
+ | |||
+ | The same chorales can be viewed on Verovio Humdrum Viewer from this link | ||
+ | http://verovio.humdrum.org/?file=chorales&k=e | ||
+ | |||
+ | [[Image:humdrumlab1-vhv-chorales.png|center|501px]] | ||
− | === MIDI | + | Clicking on a chorale title will load the work into the editor: |
+ | |||
+ | [[Image:humdrumlab1-chor001.png|center|500px]] | ||
+ | |||
+ | ===Copying data to VHV editor=== | ||
+ | |||
+ | You can also copy a downloaded score into the VHV editor by pasting the contents of the file into the editor. From the terminal in MacOS, you can use the [http://osxdaily.com/2007/03/05/manipulating-the-clipboard-from-the-command-line pbcopy] command: | ||
+ | cat chor001.krn | pbcopy | ||
+ | |||
+ | And then type command-v after clicking in the text editor on the VHV website to paste the score into the editor. | ||
+ | |||
+ | |||
+ | === Playback on the command-line === | ||
+ | |||
+ | If humplay compiled successfully on your computer (in theory it will work in MacOS, Windows and Linux, but will depend on if the MIDI software can be compiled successfully), then try the humplay command to play a score from the command line: | ||
+ | |||
+ | humplay chor146.krn | ||
+ | |||
+ | [[File:humdrumlab1-chor001-humplay.png|center|500px|Screenshot showing humplay in action.]] | ||
+ | |||
+ | You can alternatively download a particular score from the web: | ||
+ | |||
+ | humplay h://chorales/chor146.krn | ||
+ | |||
+ | See documentation of features for humplay at http://extras.humdrum.org/man/humplay | ||
+ | |||
+ | Some commands to try: | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | ! command | ||
+ | ! description | ||
+ | |- | ||
+ | |<tt>4m</tt> | ||
+ | | mute the 4th spine (soprano) | ||
+ | |- | ||
+ | |<tt>></tt> | ||
+ | | speed up | ||
+ | |- | ||
+ | |<tt>5=</tt> | ||
+ | | go to measure 5 | ||
+ | |- | ||
+ | |<tt>p</tt> | ||
+ | | pause | ||
+ | |- | ||
+ | |<tt>+</tt> | ||
+ | | make music louder | ||
+ | |- | ||
+ | |<tt>Q</tt> | ||
+ | | quit player before end of music. | ||
+ | |} | ||
+ | |||
+ | For example, type the characters "2m3m" to mute the 2nd (tenor) and 3rd (alto) voices to listen to only the outer voices. This sort of interactive playback is not (yet) available in VHV. | ||
+ | |||
+ | === MIDI Rendering === | ||
+ | |||
+ | Loading a score into the VHV editor will allow you to press the "play" button to listen to a MIDI rendering of the score; however, more control over the conversion to a MIDI file can be done by using the `hum2mid` command. | ||
Convert a particular chorale into a MIDI file with this command: | Convert a particular chorale into a MIDI file with this command: | ||
Line 19: | Line 131: | ||
The data file can also be downloaded on demand: | The data file can also be downloaded on demand: | ||
− | hum2mid h:// | + | hum2mid h://371chorales/chor001.krn -o chor001.mid |
Once the MIDI file has been created, you can open it by double-clicking in a file browser. On OS X computers, you can type: | Once the MIDI file has been created, you can open it by double-clicking in a file browser. On OS X computers, you can type: | ||
open chor001.mid | open chor001.mid | ||
− | to do the equivalent of double-clicking. You must have a MIDI player associated with the file. For newer OS X computers, you will have to download Quicktime 7 in order to play the MIDI file (recent versions of Quicktime cannot play MIDI files). | + | to do the equivalent of double-clicking. You must have a MIDI player associated with the file. For newer OS X computers, you will have to [https://support.apple.com/kb/dl923?locale=en_US download Quicktime 7] in order to play the MIDI file (recent versions of Quicktime cannot play MIDI files). This no longer works in MacOS Catalina or later, so view the MIDI to MP3 conversion notes at the bottom of [[Quicktime | this page]]. |
To pan the voices in the stereo field, try the <tt>--autopan</tt> option: | To pan the voices in the stereo field, try the <tt>--autopan</tt> option: | ||
hum2mid --autopan chor001.krn -o chor001pan.mid | hum2mid --autopan chor001.krn -o chor001pan.mid | ||
− | + | To play the music with an organ sound try: | |
+ | hum2mid -f 19 chor001.krn -o chor001organ.mid | ||
− | + | ==== Converting all Humdrum files into MIDI files in a directory ==== | |
− | + | This bash for-loop can convert all chorale scores into MIDI files: | |
− | |||
− | + | for file in *.krn | |
− | + | do | |
+ | hum2mid $file -o $(basename $file .krn).mid | ||
+ | done | ||
− | + | To store the converted MIDI files in a separate directory: | |
− | |||
− | + | mkdir midi | |
− | + | for file in *.krn | |
− | + | do | |
− | + | hum2mid $file -o midi/$(basename $file .krn).mid | |
− | + | done | |
− | |||
=== Key === | === Key === | ||
Each chorale is hand-labeled with a musical key. To generate a histogram of key designations in the chorales: | Each chorale is hand-labeled with a musical key. To generate a histogram of key designations in the chorales: | ||
− | + | extractx -s 1 *.krn | egrep -i '^\*[a-g][#-]?:' | sortcount | |
− | The [http://en.wikipedia.org/wiki/Regular_expression regular expression] "<tt>\* | + | The [http://en.wikipedia.org/wiki/Regular_expression regular expression] "<tt>\*[a-g][#-]?:</tt>" translates into English as: |
+ | find lines of text starting with "*" followed by one of the characters "a, b, c, d, e, f, g, A, B, C, D, E, F, G" then optionally one of the characters "#" or "-" followed by a colon. This is the basic structure of a key interpretation in Humdrum **kern data. An optional three-letter modal category can also be added after the colon, such as "*d:dor" for D dorian. | ||
Questions: | Questions: | ||
Line 61: | Line 174: | ||
# What is the least common major key (other than zero counts)? | # What is the least common major key (other than zero counts)? | ||
# What is the least common minor key (other than zero counts)? | # What is the least common minor key (other than zero counts)? | ||
− | # How many chorales are labeled as being in a modal key? | + | # How many chorales are labeled as being in a modal key? Such as *G:mix for G mixolydian. |
+ | |||
+ | You can create a histogram plot by running this command pipeline: | ||
+ | extractx -s 1 *.krn | egrep -i '^\*[a-g][#-]?:' | \ | ||
+ | sortcount -v -T "Key counts" > analysis.html | ||
+ | And then opening the file analysis.html in a webpage (such as by typing "open analysis.html" in MacOS): | ||
+ | |||
+ | <html> | ||
+ | |||
+ | <script src="https://cdn.jsdelivr.net/npm/vega@4.4.0"></script> | ||
+ | <script src="https://cdn.jsdelivr.net/npm/vega-lite@3.0.0-rc12"></script> | ||
+ | <script src="https://cdn.jsdelivr.net/npm/vega-embed@3.29.1"></script> | ||
+ | |||
+ | |||
+ | <div id="plotarea9"></div> | ||
+ | <script type="text/javascript"> | ||
+ | var mydata9 = | ||
+ | { | ||
+ | "$schema": 'https://vega.github.io/schema/vega-lite/v3.json', | ||
+ | "width": 600, | ||
+ | "title": 'Key counts', | ||
+ | "data": { | ||
+ | "values": | ||
+ | [ | ||
+ | {"category": '*G:', "count": 47}, | ||
+ | {"category": '*a:', "count": 42}, | ||
+ | {"category": '*A:', "count": 32}, | ||
+ | {"category": '*g:', "count": 29}, | ||
+ | {"category": '*D:', "count": 27}, | ||
+ | {"category": '*b:', "count": 24}, | ||
+ | {"category": '*e:', "count": 22}, | ||
+ | {"category": '*F:', "count": 21}, | ||
+ | {"category": '*B-:', "count": 20}, | ||
+ | {"category": '*C:', "count": 17}, | ||
+ | {"category": '*d:', "count": 15}, | ||
+ | {"category": '*g:dor', "count": 14}, | ||
+ | {"category": '*d:dor', "count": 13}, | ||
+ | {"category": '*E-:', "count": 12}, | ||
+ | {"category": '*G:mix', "count": 7}, | ||
+ | {"category": '*E:', "count": 6}, | ||
+ | {"category": '*c:dor', "count": 5}, | ||
+ | {"category": '*f#:', "count": 4}, | ||
+ | {"category": '*f:dor', "count": 3}, | ||
+ | {"category": '*A-:', "count": 2}, | ||
+ | {"category": '*c:', "count": 2}, | ||
+ | {"category": '*e:phr', "count": 2}, | ||
+ | {"category": '*a:dor', "count": 1}, | ||
+ | {"category": '*b-:dor', "count": 1}, | ||
+ | {"category": '*A:mix', "count": 1}, | ||
+ | {"category": '*C:mix', "count": 1} | ||
+ | ] | ||
+ | }, | ||
+ | "mark": 'bar', | ||
+ | "encoding": { | ||
+ | "x": { | ||
+ | "field": 'category', | ||
+ | "title": 'x-axis label', | ||
+ | "type": 'ordinal', | ||
+ | "axis": {"labelAngle": -90 }, | ||
+ | "sort": 'count' | ||
+ | |||
+ | }, | ||
+ | "y": { | ||
+ | "field": 'count', | ||
+ | "title": 'count', | ||
+ | "type": 'quantitative' | ||
+ | }, | ||
+ | "tooltip": { | ||
+ | "field": 'count', | ||
+ | "type": 'quantitative' | ||
+ | }, | ||
+ | "color": { | ||
+ | "field": 'category', | ||
+ | "type": 'nominal', | ||
+ | "legend": null | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | ; | ||
+ | |||
+ | vegaEmbed('#plotarea9', mydata9); | ||
+ | </script> | ||
+ | </html> | ||
+ | |||
+ | |||
Line 72: | Line 269: | ||
The best is key G major | The best is key G major | ||
Compare this to the hand-labeled key: | Compare this to the hand-labeled key: | ||
− | egrep -i '^\*[A-G][- | + | egrep -i '^\*[A-G][-#]?:' chor001.krn |
Here is a bash for-loop which can be used to examine the key one chorale at a time: | Here is a bash for-loop which can be used to examine the key one chorale at a time: | ||
Line 80: | Line 277: | ||
echo $i analysis: | echo $i analysis: | ||
keycor $i | keycor $i | ||
− | egrep -i '^\*[A-G][- | + | extractx -s 1 $i | egrep -i '^\*[A-G][-#]?:' |
echo ===================== | echo ===================== | ||
done | less | done | less | ||
− | + | Questions: | |
# Find a chorale where the hand-labeled key does not match the automatically identified key. | # Find a chorale where the hand-labeled key does not match the automatically identified key. | ||
− | # Take that chorale, and run the following commands on it. Do these all give the same key analysis?: | + | # Take that chorale, and run the following commands on it. Do these all give the same key analysis? Which ones give the correct answer: |
keycor chorXXX.krn --aa | keycor chorXXX.krn --aa | ||
Line 93: | Line 290: | ||
keycor chorXXX.krn --kp | keycor chorXXX.krn --kp | ||
keycor chorXXX.krn -s | keycor chorXXX.krn -s | ||
+ | |||
+ | ==== Mkeyscape ==== | ||
+ | |||
+ | The [http://humextra.humdrum.org/man/mkeyscape mkeyscape] program can be used to view a detailed picture of the key throughout a piece of music. The online version of the program is more convenient, plus it has an interactive display of the color-to-key mappings: http://extras.humdrum.org/online?command=mkeyscape%20-ln%20h://370chorales/chor001.krn&run=true | ||
+ | |||
+ | The above link should produce this plot of the key structure, showing it is strongly in G major with no modulations to other keys, with the next strongest key region being C major for one measure (at bar 14): | ||
+ | |||
+ | [[Image:humdrumlab1-mkeyscapechor001.png|center]] | ||
+ | |||
+ | To do this on the command-line with [http://www.imagemagick.org/ Imagemagick] tools installed: | ||
+ | |||
+ | mkeyscape -ln chor001.krn | convert - output.png | ||
+ | |||
+ | To install imagemagick tools in MacOS with [https://brew.sh Homebrew], type: | ||
+ | brew install imagemagick | ||
+ | |||
+ | Most linux distributions should have imagemagick installed already; otherwise, install in some similar manner using "yum", "apt-get" or similar package manager for your version of unix. | ||
+ | |||
+ | ==== Transposition ==== | ||
+ | |||
+ | The Humdrum Extras program [http://extras.humdrum.org/man/transpose transpose] can be used to transpose chorales to another key with the -k option. For example, tranpose the first chorale into F{{music|sharp}} major: | ||
+ | |||
+ | transpose -k f# chor001.krn | less | ||
+ | |||
+ | Also notice that the transpose tool is available as a [http://doc.verovio.humdrum.org/filters/transpose filter] in the VHV editor. Here is the chorale without transposition: | ||
+ | |||
+ | [[Image:humdrumlab1-chor001.png|center|500px]] | ||
+ | |||
+ | And then adding the line: | ||
+ | !!!filter: transpose -k f# | ||
+ | which will transpose the music down a half-step: | ||
+ | |||
+ | [[Image:humdrumlab1-transpose-fsharp.png|center|500px]] | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | The Humdrum Toolkit program [http://www.musiccog.ohio-state.edu/Humdrum/commands/trans.html trans] calculates transpositions as well, but using a different (2D) algorithm. Using trans, it is possible to change the mode of the music. For example, here is how to convert from a major to a minor key: | ||
+ | |||
+ | trans -d -2 chor001.krn | trans -d 2 -c 3 -k '*k[b-e-]' | ||
+ | |||
+ | [[Image:humdrumlab1-chor001-gminor.png|center|500px]] | ||
+ | |||
+ | The first transposition | ||
+ | trans -d -2 chor001.krn | ||
+ | transposes the music from G major to its relative E minor. The second transposition moves the music from E minor up to G minor. the -k option is used to force the key signature to the standard one used for G minor. | ||
+ | |||
+ | The Humdrum Toolkit tools cannot be run from VHV, but to quickly copy an altered score, add the pbcopy command to the end of the pipeline: | ||
+ | |||
+ | trans -d -2 chor001.krn | trans -d 2 -c 3 -k '*k[b-e-]' | pbcopy | ||
+ | |||
+ | and then paste the score into the VHV editor. | ||
=== Vocal Range === | === Vocal Range === | ||
Line 98: | Line 347: | ||
To count all of the notes by pitch-class for each vocal part, use the prange command. Here is a sample command which extracts the bass part data: | To count all of the notes by pitch-class for each vocal part, use the prange command. Here is a sample command which extracts the bass part data: | ||
− | + | extractx -s 1 *.krn | prange | |
or alternatively extracting by text pattern (Bass, Tenor, Alto, Soprano): | or alternatively extracting by text pattern (Bass, Tenor, Alto, Soprano): | ||
extractx -g Bass *.krn | prange | extractx -g Bass *.krn | prange | ||
− | For the bass part, the lowest note is CC (C2) and the highest note is e (E4), with a total vocal range of 28 semitones. The average (base-12) pitch is E- (E | + | For the bass part, the lowest note is CC (C2) and the highest note is e (E4), with a total vocal range of 28 semitones. The average (base-12) pitch is E- (E{{music|flat}}3), which is both the mean and median. |
Do a similar vocal range analysis on the other three parts. | Do a similar vocal range analysis on the other three parts. | ||
Line 109: | Line 358: | ||
# Which voice has the widest range? | # Which voice has the widest range? | ||
# What is the highest and lowest note for each vocal part? | # What is the highest and lowest note for each vocal part? | ||
+ | |||
+ | |||
+ | ==== Graphic display of range using SCORE ==== | ||
+ | |||
+ | Try the command: | ||
+ | |||
+ | humcat *.krn | prange --score > ranges.txt | ||
+ | |||
+ | and then load the file "ranges.txt" into SCORE using the RE command. This should produce the following figure: | ||
+ | |||
+ | [[Image:humdrumlab1-voiceranges.png|center|600px]] | ||
+ | |||
+ | Tip: Paste the PMX data output from "prange --score" into http://score.sapp.org to generate notation online. | ||
+ | |||
+ | Also try | ||
+ | |||
+ | humcat *.krn | prange --score --hover > ranges-hover.txt | ||
+ | |||
+ | to add SVG markup to show note counts when hovering over notes in vocal range histograms. | ||
+ | |||
+ | Try this command: | ||
+ | |||
+ | transpose -k c *.krn | humcat | prange --score --hover > ranges-transpose.txt | ||
+ | |||
+ | What does it do? | ||
=== Scale Degrees === | === Scale Degrees === | ||
The deg command can be used to calculate the scale degree of each note if the key has been indicated. Here is a command to count how often each scale degree occurs in the chorales: | The deg command can be used to calculate the scale degree of each note if the key has been indicated. Here is a command to count how often each scale degree occurs in the chorales: | ||
− | serialize *.krn | deg -a | ridx -H | sed 's/[^1-7]//g' | sort | uniq -c | + | serialize *.krn | deg -a | ridx -H | grep -v r | sed 's/[^1-7]//g' | sort | uniq -c |
− | This should produce the result: | + | This should produce the result (or close enough depending on data and software updates): |
− | + | ||
− | + | 15695 1 | |
− | + | 11267 2 | |
− | + | 12500 3 | |
− | + | 10723 4 | |
− | + | 16225 5 | |
− | + | 9052 6 | |
− | + | 10604 7 | |
+ | |||
The sortcount program can handle sorting and counting. Here is an example with the -p option showing the relative frequency of each scale degree in the data: | The sortcount program can handle sorting and counting. Here is an example with the -p option showing the relative frequency of each scale degree in the data: | ||
− | serialize *.krn | deg -a | ridx -H | sed 's/[^1-7]//g | + | serialize *.krn | deg -a | ridx -H | grep -v r | sed 's/[^1-7]//g' | sortcount -ph |
+ | |||
+ | **pcent **data | ||
+ | 18.85 5 | ||
+ | 18.24 1 | ||
+ | 14.53 3 | ||
+ | 13.08 2 | ||
+ | 12.46 4 | ||
+ | 12.32 7 | ||
+ | 10.51 6 | ||
+ | *- *- | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
The dominant (5) is the most common, and the submediant (6) is the least common. | The dominant (5) is the most common, and the submediant (6) is the least common. | ||
Line 142: | Line 418: | ||
Question: | Question: | ||
# Using the following template, what are the scale-degree frequencies in each part? Are there any differences? | # Using the following template, what are the scale-degree frequencies in each part? Are there any differences? | ||
− | extractx -g Bass *krn | deg -a | ridx -H | sed 's/[^1-7]//g' | + | extractx -g Bass *krn | deg -a | ridx -H | grep -v r | sed 's/[^1-7]//g' | sortcount -ph |
=== Melodic Intervals === | === Melodic Intervals === | ||
+ | |||
+ | Generate a list of the melodic intervals found in all voices, sorted by most common: | ||
+ | |||
+ | serialize *.krn | mint | ridx -H | grep -v r | grep -v '[[]' | sortcount -p | ||
+ | |||
+ | Histogram plot of the same data (limiting to occurrences above 0.5%): | ||
+ | |||
+ | serialize *.krn | mint | ridx -H | grep -v '[[]' | \ | ||
+ | sortcount -pv --min 0.01 -T "Melodic intervals in Bach chorales" > analysis.html | ||
+ | |||
+ | <html> | ||
+ | <div id="plotarea8"></div> | ||
+ | <script type="text/javascript"> | ||
+ | var mydata8 = | ||
+ | { | ||
+ | "$schema": 'https://vega.github.io/schema/vega-lite/v3.json', | ||
+ | "width": 600, | ||
+ | "title": 'Melodic intervals in Bach chorales', | ||
+ | "data": { | ||
+ | "values": | ||
+ | [ | ||
+ | {"category": '-M2', "percent": 20.52}, | ||
+ | {"category": '+M2', "percent": 17.93}, | ||
+ | {"category": 'P1', "percent": 15.08}, | ||
+ | {"category": '-m2', "percent": 12.95}, | ||
+ | {"category": '+m2', "percent": 11.23}, | ||
+ | {"category": '+P4', "percent": 5.16}, | ||
+ | {"category": '-M3', "percent": 2.55}, | ||
+ | {"category": '-P5', "percent": 2.52}, | ||
+ | {"category": '-m3', "percent": 2.45}, | ||
+ | {"category": '-P4', "percent": 1.88}, | ||
+ | {"category": '+P5', "percent": 1.31}, | ||
+ | {"category": '+m3', "percent": 1.29}, | ||
+ | {"category": '+M3', "percent": 0.98}, | ||
+ | {"category": 'r', "percent": 0.92}, | ||
+ | {"category": '+P8', "percent": 0.75}, | ||
+ | {"category": '-P8', "percent": 0.54}, | ||
+ | {"category": 'A1', "percent": 0.44}, | ||
+ | {"category": '-d5', "percent": 0.32}, | ||
+ | {"category": '+M6', "percent": 0.24}, | ||
+ | {"category": '+m6', "percent": 0.22}, | ||
+ | {"category": 'd1', "percent": 0.15}, | ||
+ | {"category": '-m6', "percent": 0.14}, | ||
+ | {"category": '-d4', "percent": 0.11}, | ||
+ | {"category": '-M6', "percent": 0.06}, | ||
+ | {"category": '+d4', "percent": 0.04}, | ||
+ | {"category": '+m7', "percent": 0.04}, | ||
+ | {"category": '+M7', "percent": 0.02}, | ||
+ | {"category": '-d7', "percent": 0.02}, | ||
+ | {"category": '+A4', "percent": 0.02}, | ||
+ | {"category": '+d5', "percent": 0.02}, | ||
+ | {"category": '-m7', "percent": 0.02}, | ||
+ | {"category": '+P11', "percent": 0.01}, | ||
+ | {"category": '+M10', "percent": 0.01}, | ||
+ | {"category": '+A5', "percent": 0.01}, | ||
+ | {"category": '+M9', "percent": 0.01}, | ||
+ | {"category": '+A8', "percent": 0.01}, | ||
+ | {"category": '-M7', "percent": 0.01}, | ||
+ | {"category": '-M9', "percent": 0.01} | ||
+ | ] | ||
+ | }, | ||
+ | "mark": 'bar', | ||
+ | "encoding": { | ||
+ | "x": { | ||
+ | "field": 'category', | ||
+ | "title": 'x-axis label', | ||
+ | "type": 'ordinal', | ||
+ | "axis": {"labelAngle": -90 }, | ||
+ | "sort": 'percent' | ||
+ | |||
+ | }, | ||
+ | "y": { | ||
+ | "field": 'percent', | ||
+ | "title": 'percent', | ||
+ | "type": 'quantitative' | ||
+ | }, | ||
+ | "tooltip": { | ||
+ | "field": 'percent', | ||
+ | "type": 'quantitative' | ||
+ | }, | ||
+ | "color": { | ||
+ | "field": 'category', | ||
+ | "type": 'nominal', | ||
+ | "legend": null | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | ; | ||
+ | |||
+ | vegaEmbed('#plotarea8', mydata8); | ||
+ | </script> | ||
+ | </html> | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | Sorting by interval size: | ||
+ | |||
+ | serialize *.krn | mint | ridx -H | grep -v '[[]' | \ | ||
+ | sortcount -pv --min 0.01 -T "Melodic intervals in Bach chorales" \ | ||
+ | --sort interval > analysis.html | ||
+ | <html> | ||
+ | <div id="plotarea7"></div> | ||
+ | <script type="text/javascript"> | ||
+ | var mydata7 = | ||
+ | { | ||
+ | "$schema": 'https://vega.github.io/schema/vega-lite/v3.json', | ||
+ | "width": 600, | ||
+ | "title": 'Melodic intervals in Bach chorales', | ||
+ | "data": { | ||
+ | "values": | ||
+ | [ | ||
+ | {"category": '-M2', "percent": 20.52}, | ||
+ | {"category": '+M2', "percent": 17.93}, | ||
+ | {"category": 'P1', "percent": 15.08}, | ||
+ | {"category": '-m2', "percent": 12.95}, | ||
+ | {"category": '+m2', "percent": 11.23}, | ||
+ | {"category": '+P4', "percent": 5.16}, | ||
+ | {"category": '-M3', "percent": 2.55}, | ||
+ | {"category": '-P5', "percent": 2.52}, | ||
+ | {"category": '-m3', "percent": 2.45}, | ||
+ | {"category": '-P4', "percent": 1.88}, | ||
+ | {"category": '+P5', "percent": 1.31}, | ||
+ | {"category": '+m3', "percent": 1.29}, | ||
+ | {"category": '+M3', "percent": 0.98}, | ||
+ | {"category": 'r', "percent": 0.92}, | ||
+ | {"category": '+P8', "percent": 0.75}, | ||
+ | {"category": '-P8', "percent": 0.54}, | ||
+ | {"category": 'A1', "percent": 0.44}, | ||
+ | {"category": '-d5', "percent": 0.32}, | ||
+ | {"category": '+M6', "percent": 0.24}, | ||
+ | {"category": '+m6', "percent": 0.22}, | ||
+ | {"category": 'd1', "percent": 0.15}, | ||
+ | {"category": '-m6', "percent": 0.14}, | ||
+ | {"category": '-d4', "percent": 0.11}, | ||
+ | {"category": '-M6', "percent": 0.06}, | ||
+ | {"category": '+d4', "percent": 0.04}, | ||
+ | {"category": '+m7', "percent": 0.04}, | ||
+ | {"category": '-m7', "percent": 0.02}, | ||
+ | {"category": '-d7', "percent": 0.02}, | ||
+ | {"category": '+M7', "percent": 0.02}, | ||
+ | {"category": '+A4', "percent": 0.02}, | ||
+ | {"category": '+d5', "percent": 0.02}, | ||
+ | {"category": '+M9', "percent": 0.01}, | ||
+ | {"category": '+P11', "percent": 0.01}, | ||
+ | {"category": '+A8', "percent": 0.01}, | ||
+ | {"category": '-M7', "percent": 0.01}, | ||
+ | {"category": '-M9', "percent": 0.01}, | ||
+ | {"category": '+M10', "percent": 0.01}, | ||
+ | {"category": '+A5', "percent": 0.01} | ||
+ | ] | ||
+ | }, | ||
+ | "mark": 'bar', | ||
+ | "encoding": { | ||
+ | "x": { | ||
+ | "field": 'category', | ||
+ | "title": 'x-axis label', | ||
+ | "type": 'ordinal', | ||
+ | "axis": {"labelAngle": -90 }, | ||
+ | "sort": ["-M9","-P8","-M7","-m7","-d7","-M6","-m6","-P5","-d5","-P4","-d4","-M3","-m3","-M2","-m2","d1","P1","A1","+m2","+M2","+m3","r","+M3","+d4","+P4","+A4","+d5","+P5","+A5","+m6","+M6","+m7","+M7","+P8","+A8","+M9","+M10","+P11"] | ||
+ | |||
+ | }, | ||
+ | "y": { | ||
+ | "field": 'percent', | ||
+ | "title": 'percent', | ||
+ | "type": 'quantitative' | ||
+ | }, | ||
+ | "tooltip": { | ||
+ | "field": 'percent', | ||
+ | "type": 'quantitative' | ||
+ | }, | ||
+ | "color": { | ||
+ | "field": 'category', | ||
+ | "type": 'nominal', | ||
+ | "legend": null | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | ; | ||
+ | |||
+ | vegaEmbed('#plotarea7', mydata7); | ||
+ | </script> | ||
+ | </html> | ||
Tritones can be notated as augmented 4ths (such as C-F{{music|sharp}}) or diminished fifths (such as C–G{{music|flat}}). | Tritones can be notated as augmented 4ths (such as C-F{{music|sharp}}) or diminished fifths (such as C–G{{music|flat}}). | ||
Line 159: | Line 619: | ||
serialize *.krn | mint | ridx -H | grep -- -d5 | wc -l | serialize *.krn | mint | ridx -H | grep -- -d5 | wc -l | ||
The double dash after grep in the second command indicates the end of options for grep, so that the string "-d5" is treated as the query rather than as the option -d5. | The double dash after grep in the second command indicates the end of options for grep, so that the string "-d5" is treated as the query rather than as the option -d5. | ||
+ | |||
+ | === Harmony === | ||
+ | |||
+ | ==== Harmonic intervals ==== | ||
+ | |||
+ | The [http://www.musiccog.ohio-state.edu/Humdrum/commands/hint.html hint] command can be used to study harmonic intervals. "Hint" stands for "Harmonic INTervals". Here is an analysis of the number of intervals found in all of the chorales: | ||
+ | |||
+ | hint -ac *.krn | serialize -c | ridx -H | sortcount -ph | ||
+ | |||
+ | **pcent **data | ||
+ | 15.88 m3 | ||
+ | 15.43 P5 | ||
+ | 14.2 M3 | ||
+ | 13.42 P1 | ||
+ | 9.51 P4 | ||
+ | 8.83 M6 | ||
+ | 8.74 m6 | ||
+ | 7.04 - | ||
+ | 2.23 M2 | ||
+ | 1.36 m7 | ||
+ | 1.35 A4 | ||
+ | 0.97 d5 | ||
+ | 0.35 m2 | ||
+ | 0.22 M7 | ||
+ | 0.16 r | ||
+ | 0.15 d7 | ||
+ | 0.06 A2 | ||
+ | 0.05 d4 | ||
+ | 0.04 A5 | ||
+ | 0 A6 | ||
+ | 0 d1 | ||
+ | *- *- | ||
+ | |||
+ | The most common interval between voices is a minor 3rd (or minor 3rd plus an octave transposition) at 15.88 of the harmonic intervals. Then 15.43% for perfect 5ths and 14.2 for major thirds. The most common "dissonant" interval is a major second at 2.23% of the intervals. | ||
+ | |||
+ | ==== Chord prototypes ==== | ||
+ | |||
+ | The [http://extras.humdrum.org/man/tntype tntype] program can be used to examine harmonic sonorities in the music: | ||
+ | |||
+ | tntype -a *.krn | tntype -fa | extractx -s '$1-$' | ridx -H | sortcount -ph | ||
+ | |||
+ | Here are the 13 most common harmonic sonorities that will be listed: | ||
+ | |||
+ | 35.09 3-11B {047} | ||
+ | 17.26 3-11A {037} | ||
+ | 9.07 4-27B {0368} | ||
+ | 4.96 4-26 {0358} | ||
+ | 4.36 3-10 {036} | ||
+ | 4.26 3-9 {027} | ||
+ | 2.8 4-20 {0158} | ||
+ | 2.52 4-27A {0258} | ||
+ | 1.99 4-22A {0247} | ||
+ | 1.95 3-7A {025} | ||
+ | 1.73 4-23 {0257} | ||
+ | 1.57 4-14A {0237} | ||
+ | 1.16 3-8A {026} | ||
+ | |||
+ | 35% of all sonorities in the chorales are major chords, which are called 3-11B ("Forte number") in set theory, with the semitone prototype {047} which would be CEG on C, or GBD on G. Minor triads are half as common at 17.26%. The most common 4-note sonority is 4-27B which would be (C, E{{music|flat}}, F{{music|sharp}}, A) which is a fully-diminished seventh chord in tonal music theory. | ||
+ | |||
+ | === Harmony/Melody === | ||
+ | |||
+ | The [http://extras.humdrum.org/man/cint cint] program is a hybrid of the mint and hint programs. It examines 4-note counterpoint modules which contain two harmonic and two melodic intervals. | ||
+ | |||
+ | cint *.krn --raw -to | sortcount -ph | less | ||
+ | |||
+ | Here are all of the counterpoint modules which occur with a frequency of greater than 1%: | ||
+ | |||
+ | **pcent **data | ||
+ | 2.33 5 -2 1 6 | ||
+ | 2.23 6 2 1 5 | ||
+ | 1.91 3 -2 1 4 | ||
+ | 1.89 4 -2 1 5 | ||
+ | 1.82 6 -2 -2 6 | ||
+ | 1.71 5 1 2 6 | ||
+ | 1.66 3 -2 -2 3 | ||
+ | 1.65 3 1 2 4 | ||
+ | 1.62 3 2 2 3 | ||
+ | 1.6 -6 2 2 -6 | ||
+ | 1.57 6 -2 2 8 | ||
+ | 1.47 10 2 -2 8 | ||
+ | 1.39 5 2 -2 3 | ||
+ | 1.37 4 2 1 3 | ||
+ | 1.36 6 1 -2 5 | ||
+ | 1.36 5 1 -2 4 | ||
+ | 1.34 -4 2 -2 -6 | ||
+ | 1.3 -7 -2 1 -6 | ||
+ | 1.28 4 1 -2 3 | ||
+ | 1.2 2 -2 1 3 | ||
+ | 1.2 -6 -2 1 -5 | ||
+ | 1.16 6 2 2 6 | ||
+ | 1.08 -3 2 1 -4 | ||
+ | 1.02 3 1 -2 2 | ||
+ | 1.02 8 1 -2 7 | ||
+ | |||
+ | The module "5 -2 1 6" means that the two voices start together with a fifth, then move to a sixth, with the bottom voice going down a second while the top note stays on the same pitch. | ||
+ | |||
+ | Here is an example method to highlight the counterpoint module "5 -2 1 6" in graphical notation (note: webscore needs updating): | ||
+ | |||
+ | cint -to --mark --search "5 -2 1 6" chor001.krn | satb2gs \ | ||
+ | | webscore > analysis.html | ||
+ | |||
+ | <html> | ||
+ | <script src="https://verovio-script.humdrum.org/scripts/verovio-toolkit.js"></script> | ||
+ | <script src="https://plugin.humdrum.org/scripts/humdrum-notation-plugin.js"></script> | ||
+ | <script>var vrvToolkit = new verovio.toolkit()</script> | ||
+ | <script>displayHumdrum({source: "example1", scale:35})</script> | ||
+ | <script type="text/x-humdrum" id="example1"> | ||
+ | !!!!SEGMENT: h://chorales/chor001.krn | ||
+ | !!!filter: cint -to --mark --search "5 -2 1 6" | satb2gs | ||
+ | !!!COM: Bach, Johann Sebastian | ||
+ | !!!CDT: 1685/02/21/-1750/07/28/ | ||
+ | !!!OTL@@DE: Aus meines Herzens Grunde | ||
+ | !!!OTL@EN: From the Depths of My Heart | ||
+ | !!!SCT: BWV 269 | ||
+ | !!!PC#: 1 | ||
+ | !!!AGN: chorale | ||
+ | **kern **kern **kern **kern | ||
+ | *ICvox *ICvox *ICvox *ICvox | ||
+ | *Ibass *Itenor *Ialto *Isoprn | ||
+ | *I"Bass *I"Tenor *I"Alto *I"Soprano | ||
+ | *>[A,A,B] *>[A,A,B] *>[A,A,B] *>[A,A,B] | ||
+ | *>norep[A,B] *>norep[A,B] *>norep[A,B] *>norep[A,B] | ||
+ | *>A *>A *>A *>A | ||
+ | * *oclefC4 *oclefC3 *oclefC1 | ||
+ | *clefF4 *clefGv2 *clefG2 *clefG2 | ||
+ | *k[f#] *k[f#] *k[f#] *k[f#] | ||
+ | *G: *G: *G: *G: | ||
+ | *M3/4 *M3/4 *M3/4 *M3/4 | ||
+ | *MM100 *MM100 *MM100 *MM100 | ||
+ | 4GG 4B 4d 4g | ||
+ | =1 =1 =1 =1 | ||
+ | 4G 4B 4d 2g | ||
+ | 4E 8cL 4e . | ||
+ | . 8BJ . . | ||
+ | 4F# 4A 4d 4dd | ||
+ | =2 =2 =2 =2 | ||
+ | 4G 4G 2d 4.b | ||
+ | 4D 4F# . . | ||
+ | . . . 8a | ||
+ | 4E 4G 4B 4g | ||
+ | =3 =3 =3 =3 | ||
+ | 4C 8cL 8eL 4.g | ||
+ | . 8BJ 8d . | ||
+ | 8BBL 4c 8e . | ||
+ | 8AAJ . 8f#J 8a | ||
+ | 4GG 4d 4g 4b | ||
+ | =4 =4 =4 =4 | ||
+ | 2D; 2d; 2f#; 2a; | ||
+ | 4GG 4d 4g 4b | ||
+ | =5 =5 =5 =5 | ||
+ | 4FF# 4A 4d 2dd | ||
+ | 4GG 4B 4e . | ||
+ | 4AA 4c 4f# 4cc | ||
+ | =6 =6 =6 =6 | ||
+ | 4BB 4d 2g 4b | ||
+ | 4C 4e . 2a | ||
+ | 4D 8dL 4f# . | ||
+ | . 8cJ . . | ||
+ | =7 =7 =7 =7 | ||
+ | 2GG; 2B; 2d; 2g; | ||
+ | =:|! =:|! =:|! =:|! | ||
+ | *>B *>B *>B *>B | ||
+ | 4GG 4d [4g 4b | ||
+ | =8 =8 =8 =8 | ||
+ | 4GG 4d 8gL] 4b | ||
+ | . . 8f#J . | ||
+ | 4AA 4c 8eL 4cc | ||
+ | . . 8f#J . | ||
+ | 4BB 8BL [4g 4dd | ||
+ | . 8AJ . . | ||
+ | =9 =9 =9 =9 | ||
+ | 4.BB 8BL 8gL] 4.dd | ||
+ | . 8cJ 8aJ . | ||
+ | . 4d 8gL . | ||
+ | 8AA . 8f#J 8cc | ||
+ | 4GG 4d 4g 4b | ||
+ | =10 =10 =10 =10 | ||
+ | 2D; 2d; 2f#; 2a; | ||
+ | [4E 4B 4e 4g | ||
+ | =11 =11 =11 =11 | ||
+ | 4E] 4G 4e 2b | ||
+ | 4D 4B 8f#L . | ||
+ | . . 8gJ . | ||
+ | 4C 4e 4a 4cc | ||
+ | =12 =12 =12 =12 | ||
+ | 4.BB 2d 4a 2dd | ||
+ | . . 4.g . | ||
+ | 8C . . . | ||
+ | 4D 4d . 4cc | ||
+ | . . 8f# . | ||
+ | =13 =13 =13 =13 | ||
+ | 8GGL 2.d 2g 2.b | ||
+ | 8AAJ . . . | ||
+ | 4BB . . . | ||
+ | 4GG . 4f . | ||
+ | =14 =14 =14 =14 | ||
+ | 2C; 2c; 2e; 2g; | ||
+ | 4GG 4d 4g 4b | ||
+ | =15 =15 =15 =15 | ||
+ | 4FF# 8dL 4.a 2dd | ||
+ | . 8cJ . . | ||
+ | 4GG 4B . . | ||
+ | . . 8g . | ||
+ | 4AA 4c 4f# 4cc | ||
+ | =16 =16 =16 =16 | ||
+ | 4BB 2d 2g 2b | ||
+ | 4GG . . . | ||
+ | 4D 8dL [4f# 4a | ||
+ | . 8cJ . . | ||
+ | =17 =17 =17 =17 | ||
+ | 8EL 4B 8f#L] 4.g | ||
+ | 8D . 8eJ . | ||
+ | 8C 4c 8eL . | ||
+ | 8BB . 8f#J 8a | ||
+ | 8AA 4d 4g 4b | ||
+ | 8GGJ . . . | ||
+ | =18 =18 =18 =18 | ||
+ | 2D; 2d; 2f#; 2a; | ||
+ | [4G 4d 4g 4b | ||
+ | =19 =19 =19 =19 | ||
+ | 4G] 2d 2a 2dd | ||
+ | 4F# . . . | ||
+ | [4E 4e 8gL 4cc | ||
+ | . . 8f#J . | ||
+ | =20 =20 =20 =20 | ||
+ | 8EL] 2e 2g 4b | ||
+ | 8DJ . . . | ||
+ | 4C . . 2a | ||
+ | 4D 8dL 4f# . | ||
+ | . 8cJ . . | ||
+ | =21 =21 =21 =21 | ||
+ | 2GG; 2B; 2d; 2g; | ||
+ | == == == == | ||
+ | *- *- *- *- | ||
+ | !!!YOR1: 371 vierstimmige Choralgesänge von Johann Sebastian Bach, | ||
+ | !!!YOR2: 4th ed. by Alfred Dörffel (Leipzig: Breitkopf und Härtel, | ||
+ | !!!YOR3: c.1875). 178 pp. Plate "V.A.10". reprint: J.S. Bach, 371 Four-Part | ||
+ | !!!YOR4: Chorales (New York: Associated Music Publishers, Inc., c.1940). | ||
+ | !!!SMS: B&H, 4th ed, Alfred Dörffel, c.1875, plate V.A.10 | ||
+ | !!!EED: Craig Stuart Sapp | ||
+ | !!!EEV: 2009/05/22 | ||
+ | </script> | ||
+ | |||
+ | </html> | ||
+ | |||
+ | |||
+ | The cint tool is also implemented as a filter in VHV: | ||
+ | |||
+ | http://verovio.humdrum.org/?file=chorales/chor001.krn&k=e&filter=cint%20-to%20--search%20%225%20-2%201%206%22 | ||
+ | |||
+ | [[Image:humdrumlab1-vhv-cint.png|600px|center]] | ||
=== Searching === | === Searching === | ||
+ | |||
+ | This is the search method behind Themefinder. | ||
Create a search index for the chorales: | Create a search index for the chorales: | ||
Line 183: | Line 896: | ||
themax -p "cdefgabc" chorales.index --loc | theloc -m | myank --marks | themax -p "cdefgabc" chorales.index --loc | theloc -m | myank --marks | ||
− | To display matches highlighted in graphical notation: | + | To display matches highlighted in graphical notation for the last chorale in the list: |
− | themax -p "cdefgabc" chorales.index --loc | | + | themax -p "cdefgabc" chorales.index --loc | tail -n 1 | theloc -m \ |
− | + | | webscore --header > analysis.html | |
+ | |||
+ | |||
+ | <html> | ||
+ | <script> | ||
+ | displayHumdrum({ | ||
+ | source: "example2", | ||
+ | header: true, | ||
+ | renderer: vrvToolkit | ||
+ | }); | ||
+ | </script> | ||
+ | |||
+ | <script type="text/x-humdrum" id="example2"> | ||
+ | !!!COM: Bach, Johann Sebastian | ||
+ | !!!CDT: 1685/02/21/-1750/07/28/ | ||
+ | !!!OTL@@DE: Mit Fried und Freud ich fahr dahin | ||
+ | !!!SCT: BWV 83/5 | ||
+ | !!!PC#: 325 | ||
+ | !!!AGN: chorale | ||
+ | **kern **kern | ||
+ | *clefF4 *clefG2 | ||
+ | *^ *^ | ||
+ | *ICvox *ICvox *ICvox *ICvox | ||
+ | *Itenor *Ibass *Isoprn *Ialto | ||
+ | *I"Tenor *I"Bass *I"Soprano *I"Alto | ||
+ | *oclefC4 * *oclefC1 *oclefC3 | ||
+ | !*clefGv2 !*clefF4 !*clefG2 !*clefG2 | ||
+ | *k[] *k[] *k[] *k[] | ||
+ | *d:dor *d:dor *d:dor *d:dor | ||
+ | *M4/4 *M4/4 *M4/4 *M4/4 | ||
+ | *met(c) *met(c) *met(c) *met(c) | ||
+ | *MM100 *MM100 *MM100 *MM100 | ||
+ | 4F 4D 4d 4A | ||
+ | =1 =1 =1 =1 | ||
+ | 4A 4C# 4a 4e | ||
+ | 4d 4D 4a 4f | ||
+ | 4B 4E 4g 4e | ||
+ | 8AL 8F#L 4dd 8dL | ||
+ | 8BJ 8G#J . 8eJ | ||
+ | =2 =2 =2 =2 | ||
+ | 8cnXL 4A 4ccnX 8eL | ||
+ | 8dJ . . 8f#J | ||
+ | 8eL 4E 4b 4g# | ||
+ | 8dJ . . . | ||
+ | 4c;y 4AA; 4a; 4e;y | ||
+ | [4c 4E 4cc 4g | ||
+ | =3 =3 =3 =3 | ||
+ | 8cL] 4D 4a 4fnX | ||
+ | 8BJ . . . | ||
+ | 4A 8EL 4cc 4f | ||
+ | . 8FJ . . | ||
+ | 8G# 2E 8bL 8BL | ||
+ | 4A . 8aJ 8cJ | ||
+ | . . 4b 4d | ||
+ | 8G# . . . | ||
+ | =4 =4 =4 =4 | ||
+ | 2.A;y 2.AA; 2.a; 2.c#;y | ||
+ | 4F 4D 4b 4d | ||
+ | =5 =5 =5 =5 | ||
+ | 4G 4CnX@ 4ccnX 4e | ||
+ | 4d 4D@ 4b 4f | ||
+ | 4c 4E@ 4cc 4g | ||
+ | 4c 4F@ 4a 4f | ||
+ | =6 =6 =6 =6 | ||
+ | 4B- 4G@ 4g 4e | ||
+ | 4c 4A@ 4f 8fL | ||
+ | . . . 8eJ | ||
+ | 4G 4B@ 4g 4d | ||
+ | 4G 4c@ 4e 4c | ||
+ | =7 =7 =7 =7 | ||
+ | 2G;y 2G; 2d; 2B;y | ||
+ | 4A 4.C# 4.a 4.e | ||
+ | 4A . . . | ||
+ | . 8AA 8g 8c# | ||
+ | =8 =8 =8 =8 | ||
+ | 8AL 4.D 8fL 8dL | ||
+ | 8GJ . 8eJ 8cnXJ | ||
+ | 4F . 4d 4B- | ||
+ | . 8E . . | ||
+ | 2F;y 2F; 2c; 2A;y | ||
+ | =9 =9 =9 =9 | ||
+ | 4A 4C# 4a 4e | ||
+ | 4A 4D 4f 4f | ||
+ | 4G 4E 4ccnX 4g | ||
+ | 4c 4F 4a 4f | ||
+ | =10 =10 =10 =10 | ||
+ | 8B-L 8GL 8gL 8eL | ||
+ | 8AJ 8AJ 8fJ 8dJ | ||
+ | 4G 4B- 4g 8c#L | ||
+ | . . . 8dJ | ||
+ | 4E;y 4A; 4a; 4c#;y | ||
+ | 4A 4AA 4g 4c# | ||
+ | =11 =11 =11 =11 | ||
+ | 8AL 4D 4f 8dL | ||
+ | 8GJ . . 8cnXJ | ||
+ | 4F 4GG 8eL 4B- | ||
+ | . . 8dJ . | ||
+ | 4E 8GL 4c# 4A | ||
+ | . 8FJ . . | ||
+ | 4A 8EL 4f 4d | ||
+ | . 8DJ . . | ||
+ | =12 =12 =12 =12 | ||
+ | 4.A 8C#L 8eL 8eL | ||
+ | . 8DJ 8dJ 8fJ | ||
+ | . 4AA 4e 4c# | ||
+ | 8G . . . | ||
+ | 4F#;y 4D; 4d; 4A;y | ||
+ | |||
+ | == == == == | ||
+ | *v *v * * | ||
+ | * *v *v | ||
+ | *- *- | ||
+ | !!!YOR1: 371 vierstimmige Choralgesänge von Johann Sebastian Bach, | ||
+ | !!!YOR2: 4th ed. by Alfred Dörffel (Leipzig: Breitkopf und Härtel, | ||
+ | !!!YOR2: c.1875). 178 pp. Plate "V.A.10". reprint: J.S. Bach, 371 Four-Part | ||
+ | !!!YOR4: Chorales (New York: Associated Music Publishers, Inc., c.1940). | ||
+ | !!!SMS: B&H, 4th ed, Alfred Dörffel, c.1875, plate V.A.10 | ||
+ | !!!EED: Craig Stuart Sapp | ||
+ | !!!EEV: 2009/05/22 | ||
+ | !!!RDF**kern: @= matched note | ||
+ | </script> | ||
+ | |||
+ | </html> | ||
+ | |||
+ | |||
+ | |||
+ | ==== VHV search filter ==== | ||
+ | |||
+ | VHV has a filter which does searching using another program called msearch: | ||
+ | |||
+ | [[Image:Humdrumlab1-vhv-msearch.png|600px|center]] | ||
+ | |||
Questions: | Questions: | ||
# Search for another pattern, and report your findings. | # Search for another pattern, and report your findings. | ||
− | The [http://extras.humdrum.org/man/themax themax] command can search for other melodic features, such as interval, contour, rhythm, meter. | + | The [http://extras.humdrum.org/man/themax themax] command can search for other melodic features, such as interval, contour, rhythm, meter. |
+ | |||
+ | === Randomized Pitch === | ||
+ | |||
+ | The [http://extras.humdrum.org/man/pitchmix pitchmix] program can mix the order of notes in a score, while keeping the rhythm fixed. The default use of pitchmix will randomly move all notes in the score, keeping the rhythm in the original order: | ||
+ | |||
+ | pitchmix chor001.krn > chor001.mixed | ||
+ | |||
+ | Adding the -v option will only mix notes within a voice: | ||
+ | |||
+ | pitchmix -v chor001.krn > chor001.mixed | ||
+ | |||
+ | This can then be listened to on VHV or with MIDI and/or conversion to MP3 files: | ||
+ | |||
+ | pitchmix chor001.krn | hum2mid -f 19 -o mixed.mid && open mixed.mid | ||
+ | |||
+ | The option -f 19 means to force the instrument to be General MIDI #19 (church organ). | ||
+ | |||
+ | For displaying notation, it is best to use the <tt>-n</tt> option which transposes the randomized notes to be within an interval of a fourth from the original note: | ||
+ | |||
+ | pitchmix chor001.krn -n | webscore --header -s 25 -f satb2gs > output.html | ||
+ | |||
+ | |||
+ | <html> | ||
+ | <script> | ||
+ | displayHumdrum({ | ||
+ | source: "example5", | ||
+ | scale: 25, | ||
+ | header: true, | ||
+ | filter: "satb2gs", | ||
+ | renderer: vrvToolkit | ||
+ | }); | ||
+ | </script> | ||
+ | |||
+ | <script type="text/x-humdrum" id="example5"> | ||
+ | !!!COM: Bach, Johann Sebastian | ||
+ | !!!CDT: 1685/02/21/-1750/07/28/ | ||
+ | !!!OTL@@DE: Aus meines Herzens Grunde | ||
+ | !!!OTL@EN: From the Depths of My Heart | ||
+ | !!!SCT: BWV 269 | ||
+ | !!!PC#: 1 | ||
+ | !!!AGN: chorale | ||
+ | **kern **kern **kern **kern | ||
+ | *ICvox *ICvox *ICvox *ICvox | ||
+ | *Ibass *Itenor *Ialto *Isoprn | ||
+ | *I"Bass *I"Tenor *I"Alto *I"Soprano | ||
+ | *>[A,A,B] *>[A,A,B] *>[A,A,B] *>[A,A,B] | ||
+ | *>norep[A,B] *>norep[A,B] *>norep[A,B] *>norep[A,B] | ||
+ | *>A *>A *>A *>A | ||
+ | * *oclefC4 *oclefC3 *oclefC1 | ||
+ | *clefF4 *clefGv2 *clefG2 *clefG2 | ||
+ | *k[f#] *k[f#] *k[f#] *k[f#] | ||
+ | *G: *G: *G: *G: | ||
+ | *M3/4 *M3/4 *M3/4 *M3/4 | ||
+ | *MM100 *MM100 *MM100 *MM100 | ||
+ | 4GG 4d 4A 4a | ||
+ | =1 =1 =1 =1 | ||
+ | 4D 4d 4g 2f# | ||
+ | 4F# 8GL 4f# . | ||
+ | . 8AJ . . | ||
+ | 4D 4B 4B 4gg | ||
+ | =2 =2 =2 =2 | ||
+ | 4B 4E 2d 4.cc | ||
+ | 4D 4C . . | ||
+ | . . . 8dd | ||
+ | 4BB 4F# 4G 4cc | ||
+ | =3 =3 =3 =3 | ||
+ | 4GG 8GL 8gL 4.g | ||
+ | . 8eJ 8B . | ||
+ | 8GGL 4B 8d . | ||
+ | 8BBJ . 8cJ 8dd | ||
+ | 4DD 4g 4d 4a | ||
+ | =4 =4 =4 =4 | ||
+ | 2G; 2g; 2a; 2b; | ||
+ | 4BB 4d 4e 4ee | ||
+ | =5 =5 =5 =5 | ||
+ | 4DD 4c 4B 2ee | ||
+ | 4DD 4A 4a . | ||
+ | 4D 4G 4g 4g | ||
+ | =6 =6 =6 =6 | ||
+ | 4FF# 4A 2a 4dd | ||
+ | 4BB 4d . 2b | ||
+ | 4D 8gL 4a . | ||
+ | . 8GJ . . | ||
+ | =7 =7 =7 =7 | ||
+ | 2FF#; 2F#; 2f#; 2b; | ||
+ | =:|! =:|! =:|! =:|! | ||
+ | *>B *>B *>B *>B | ||
+ | 4FF# 4A [4d 4cc | ||
+ | =8 =8 =8 =8 | ||
+ | 4AA 4B 8dL] 4g | ||
+ | . . 8dJ . | ||
+ | 4D 4G 8cL 4ff# | ||
+ | . . 8bJ . | ||
+ | 4FF# 8GL [4cc 4cc | ||
+ | . 8AJ . . | ||
+ | =9 =9 =9 =9 | ||
+ | 4.FF# 8BL 8ccL] 4.gg | ||
+ | . 8GJ 8eJ . | ||
+ | . 4g 8dL . | ||
+ | 8AA . 8gJ 8ff# | ||
+ | 4BB 4B 4e 4ee | ||
+ | =10 =10 =10 =10 | ||
+ | 2D; 2A; 2c; 2g; | ||
+ | [4G 4e 4a 4f | ||
+ | =11 =11 =11 =11 | ||
+ | 4G] 4G 4e 2b | ||
+ | 4D 4G 8gL . | ||
+ | . . 8dJ . | ||
+ | 4GG 4c 4dd 4b | ||
+ | =12 =12 =12 =12 | ||
+ | 4.FF# 2B 4b 2b | ||
+ | . . 4.g . | ||
+ | 8GG . . . | ||
+ | 4AA 4g . 4a | ||
+ | . . 8b . | ||
+ | =13 =13 =13 =13 | ||
+ | 8CL 2.f# 2d 2.b | ||
+ | 8CJ . . . | ||
+ | 4D . . . | ||
+ | 4BB . 4f# . | ||
+ | =14 =14 =14 =14 | ||
+ | 2GG; 2e; 2g; 2g; | ||
+ | 4DD 4e 4cc 4dd | ||
+ | =15 =15 =15 =15 | ||
+ | 4GG 8eL 4.e 2a | ||
+ | . 8BJ . . | ||
+ | 4C 4c . . | ||
+ | . . 8e . | ||
+ | 4FF# 4c 4f# 4dd | ||
+ | =16 =16 =16 =16 | ||
+ | 4GG 2g 2cc 2cc | ||
+ | 4AA . . . | ||
+ | 4F# 8dL [4c 4dd | ||
+ | . 8dJ . . | ||
+ | =17 =17 =17 =17 | ||
+ | 8DL 4F# 8cL] 4.d | ||
+ | 8C . 8BJ . | ||
+ | 8D 4B 8cL . | ||
+ | 8AA . 8cJ 8b | ||
+ | 8BB 4f# 4g 4ee | ||
+ | 8CJ . . . | ||
+ | =18 =18 =18 =18 | ||
+ | 2E; 2d; 2e; 2dd; | ||
+ | [4E 4g 4b 4dd | ||
+ | =19 =19 =19 =19 | ||
+ | 4E] 2A 2a 2b | ||
+ | 4C . . . | ||
+ | [4C 4c 8gL 4b | ||
+ | . . 8gJ . | ||
+ | =20 =20 =20 =20 | ||
+ | 8CL] 2d 2d 4a | ||
+ | 8DJ . . . | ||
+ | 4D . . 2b | ||
+ | 4BB 8gL 4d . | ||
+ | . 8dJ . . | ||
+ | =21 =21 =21 =21 | ||
+ | 2GG; 2d; 2g; 2d; | ||
+ | == == == == | ||
+ | *- *- *- *- | ||
+ | !!!YOR1: 371 vierstimmige Choralgesänge von Johann Sebastian Bach, | ||
+ | !!!YOR2: 4th ed. by Alfred Dörffel (Leipzig: Breitkopf und Härtel, | ||
+ | !!!YOR3: c.1875). 178 pp. Plate "V.A.10". reprint: J.S. Bach, 371 Four-Part | ||
+ | !!!YOR4: Chorales (New York: Associated Music Publishers, Inc., c.1940). | ||
+ | !!!SMS: B&H, 4th ed, Alfred Dörffel, c.1875, plate V.A.10 | ||
+ | !!!EED: Craig Stuart Sapp | ||
+ | !!!EEV: 2009/05/22 | ||
+ | !!!seed: 1552087490 | ||
+ | </script> | ||
+ | </html> | ||
+ | |||
+ | The <tt>-d</tt> option specifies a randomization envelope over the duration of the music. For example, <tt>-d "0 0 1 1 2 0"</tt> is a list of time/weights: (0, 0), (1, 1), (2, 0) which means that the music starts with no randomization; in the middle of the music, there is an increase to 100% randomization, and by the end of the music, the is a gradual shift back to no randomization. | ||
+ | |||
+ | hum2mid chor001.mixed -o chor001-mixed.mid | ||
+ | |||
+ | There are several options to control the type of pitch mixing. | ||
+ | |||
+ | == Next lab == | ||
+ | |||
+ | Next, you can view [[Humdrum Lab 2]] for a review of the Essen Folksong Collection and some tools for dealing with it. | ||
− | |||
− | + | {{humdrum_labs}} | |
− | |||
− |
Latest revision as of 20:48, 7 March 2024
Contents
- 1 Installing Humdrum tools
- 2 Bach Chorales
- 3 Next lab
Installing Humdrum tools
If you are using MacOS, first install Homebrew. If you are using Windows, install Windows Subsystem for Linux (version 2), or install a linux distribution inside of VirtualBox, or install cygwin.
Then, to use the following commands in a terminal (typically using the bash shell, using /Applications/Terminal.app in MacOS), install the command-line Humdrum tools.
For Windows users, I would recommend installing Linux Subsystem for Windows (LSW2). Your Windows 10/11 should be fairly up to date so that you can install version 2 of LSW. See https://docs.microsoft.com/en-us/windows/wsl for more information. I would also recommend installing Ubuntu linux from the Microsoft App store once LSW is enabled. You can also use a Stanford unix computer (see this network unix guide from CS 107)
The command sequence to install command-line Humdrum tools should look like this:
git clone https://github.com/humdrum-tools/humdrum-tools cd humdrum-tools make update make make install
The installation can be located in any directory, and "make install" should insert the installation directory into the command search path.
To check for updates at a later date, type these commands in the humdrum-tools directory:
make update make
Check that your installation is successful by re-logging into the terminal. Type this command to see if the Humdrum Tools are installed successfully:
which key
If the command responds with a line of text, installation was successful. To see if the Humdrum Extras tools are installed try typing:
which keycor
.
Bach Chorales
Download
A Humdrum edition of 4-Part Chorales by J.S. Bach is available at http://kern.ccarh.org/browse?l=chorales
The data files can be downloaded using the humcat and humsplit commands (first creating a new directory to store all of the downloaded files):
cd ~/Desktop # optional to display on Desktop in MacOS mkdir chorales cd chorales humsplit h://chorales
This should create 370 files in the format chor001.krn, chor002.krn, chor003.krn, etc. You can type "ls -asCF" in a unix terminal (/Applications/Utilities/Terminal.app in MacOS) to see the list of files that were downloaded:
Alternate download method
If you want to down all Humdrum files available on GitHub, try these commands:
git clone https://github.com/humdrum-tools/humdrum-data cd humdrum-data make
The Bach chorales will downloaded to "bach/chorales-270". You can browse through other repertories of Humdrum files that were downloaded.
Verovio Humdrum Viewer
The same chorales can be viewed on Verovio Humdrum Viewer from this link http://verovio.humdrum.org/?file=chorales&k=e
Clicking on a chorale title will load the work into the editor:
Copying data to VHV editor
You can also copy a downloaded score into the VHV editor by pasting the contents of the file into the editor. From the terminal in MacOS, you can use the pbcopy command:
cat chor001.krn | pbcopy
And then type command-v after clicking in the text editor on the VHV website to paste the score into the editor.
Playback on the command-line
If humplay compiled successfully on your computer (in theory it will work in MacOS, Windows and Linux, but will depend on if the MIDI software can be compiled successfully), then try the humplay command to play a score from the command line:
humplay chor146.krn
You can alternatively download a particular score from the web:
humplay h://chorales/chor146.krn
See documentation of features for humplay at http://extras.humdrum.org/man/humplay
Some commands to try:
command | description |
---|---|
4m | mute the 4th spine (soprano) |
> | speed up |
5= | go to measure 5 |
p | pause |
+ | make music louder |
Q | quit player before end of music. |
For example, type the characters "2m3m" to mute the 2nd (tenor) and 3rd (alto) voices to listen to only the outer voices. This sort of interactive playback is not (yet) available in VHV.
MIDI Rendering
Loading a score into the VHV editor will allow you to press the "play" button to listen to a MIDI rendering of the score; however, more control over the conversion to a MIDI file can be done by using the `hum2mid` command.
Convert a particular chorale into a MIDI file with this command:
hum2mid chor001.krn -o chor001.mid
The data file can also be downloaded on demand:
hum2mid h://371chorales/chor001.krn -o chor001.mid
Once the MIDI file has been created, you can open it by double-clicking in a file browser. On OS X computers, you can type:
open chor001.mid
to do the equivalent of double-clicking. You must have a MIDI player associated with the file. For newer OS X computers, you will have to download Quicktime 7 in order to play the MIDI file (recent versions of Quicktime cannot play MIDI files). This no longer works in MacOS Catalina or later, so view the MIDI to MP3 conversion notes at the bottom of this page.
To pan the voices in the stereo field, try the --autopan option:
hum2mid --autopan chor001.krn -o chor001pan.mid
To play the music with an organ sound try:
hum2mid -f 19 chor001.krn -o chor001organ.mid
Converting all Humdrum files into MIDI files in a directory
This bash for-loop can convert all chorale scores into MIDI files:
for file in *.krn do hum2mid $file -o $(basename $file .krn).mid done
To store the converted MIDI files in a separate directory:
mkdir midi for file in *.krn do hum2mid $file -o midi/$(basename $file .krn).mid done
Key
Each chorale is hand-labeled with a musical key. To generate a histogram of key designations in the chorales:
extractx -s 1 *.krn | egrep -i '^\*[a-g][#-]?:' | sortcount
The regular expression "\*[a-g][#-]?:" translates into English as: find lines of text starting with "*" followed by one of the characters "a, b, c, d, e, f, g, A, B, C, D, E, F, G" then optionally one of the characters "#" or "-" followed by a colon. This is the basic structure of a key interpretation in Humdrum **kern data. An optional three-letter modal category can also be added after the colon, such as "*d:dor" for D dorian.
Questions:
- What is the most common key?
- What is the most common major key?
- What is the most common minor key?
- What is the least common major key (other than zero counts)?
- What is the least common minor key (other than zero counts)?
- How many chorales are labeled as being in a modal key? Such as *G:mix for G mixolydian.
You can create a histogram plot by running this command pipeline:
extractx -s 1 *.krn | egrep -i '^\*[a-g][#-]?:' | \ sortcount -v -T "Key counts" > analysis.html
And then opening the file analysis.html in a webpage (such as by typing "open analysis.html" in MacOS):
Computational Key Identification
Use the keycor program to have the computer measure the key of the chorales:
keycor chor001.krn
The computer should reply:
The best is key G major
Compare this to the hand-labeled key:
egrep -i '^\*[A-G][-#]?:' chor001.krn
Here is a bash for-loop which can be used to examine the key one chorale at a time:
for i in *.krn do echo $i analysis: keycor $i extractx -s 1 $i | egrep -i '^\*[A-G][-#]?:' echo ===================== done | less
Questions:
- Find a chorale where the hand-labeled key does not match the automatically identified key.
- Take that chorale, and run the following commands on it. Do these all give the same key analysis? Which ones give the correct answer:
keycor chorXXX.krn --aa keycor chorXXX.krn --bb keycor chorXXX.krn --kk keycor chorXXX.krn --kp keycor chorXXX.krn -s
Mkeyscape
The mkeyscape program can be used to view a detailed picture of the key throughout a piece of music. The online version of the program is more convenient, plus it has an interactive display of the color-to-key mappings: http://extras.humdrum.org/online?command=mkeyscape%20-ln%20h://370chorales/chor001.krn&run=true
The above link should produce this plot of the key structure, showing it is strongly in G major with no modulations to other keys, with the next strongest key region being C major for one measure (at bar 14):
To do this on the command-line with Imagemagick tools installed:
mkeyscape -ln chor001.krn | convert - output.png
To install imagemagick tools in MacOS with Homebrew, type:
brew install imagemagick
Most linux distributions should have imagemagick installed already; otherwise, install in some similar manner using "yum", "apt-get" or similar package manager for your version of unix.
Transposition
The Humdrum Extras program transpose can be used to transpose chorales to another key with the -k option. For example, tranpose the first chorale into F♯ major:
transpose -k f# chor001.krn | less
Also notice that the transpose tool is available as a filter in the VHV editor. Here is the chorale without transposition:
And then adding the line:
!!!filter: transpose -k f#
which will transpose the music down a half-step:
The Humdrum Toolkit program trans calculates transpositions as well, but using a different (2D) algorithm. Using trans, it is possible to change the mode of the music. For example, here is how to convert from a major to a minor key:
trans -d -2 chor001.krn | trans -d 2 -c 3 -k '*k[b-e-]'
The first transposition
trans -d -2 chor001.krn
transposes the music from G major to its relative E minor. The second transposition moves the music from E minor up to G minor. the -k option is used to force the key signature to the standard one used for G minor.
The Humdrum Toolkit tools cannot be run from VHV, but to quickly copy an altered score, add the pbcopy command to the end of the pipeline:
trans -d -2 chor001.krn | trans -d 2 -c 3 -k '*k[b-e-]' | pbcopy
and then paste the score into the VHV editor.
Vocal Range
To count all of the notes by pitch-class for each vocal part, use the prange command. Here is a sample command which extracts the bass part data:
extractx -s 1 *.krn | prange
or alternatively extracting by text pattern (Bass, Tenor, Alto, Soprano):
extractx -g Bass *.krn | prange
For the bass part, the lowest note is CC (C2) and the highest note is e (E4), with a total vocal range of 28 semitones. The average (base-12) pitch is E- (E♭3), which is both the mean and median.
Do a similar vocal range analysis on the other three parts.
Questions:
- Which voice has the widest range?
- What is the highest and lowest note for each vocal part?
Graphic display of range using SCORE
Try the command:
humcat *.krn | prange --score > ranges.txt
and then load the file "ranges.txt" into SCORE using the RE command. This should produce the following figure:
Tip: Paste the PMX data output from "prange --score" into http://score.sapp.org to generate notation online.
Also try
humcat *.krn | prange --score --hover > ranges-hover.txt
to add SVG markup to show note counts when hovering over notes in vocal range histograms.
Try this command:
transpose -k c *.krn | humcat | prange --score --hover > ranges-transpose.txt
What does it do?
Scale Degrees
The deg command can be used to calculate the scale degree of each note if the key has been indicated. Here is a command to count how often each scale degree occurs in the chorales:
serialize *.krn | deg -a | ridx -H | grep -v r | sed 's/[^1-7]//g' | sort | uniq -c
This should produce the result (or close enough depending on data and software updates):
15695 1 11267 2 12500 3 10723 4 16225 5 9052 6 10604 7
The sortcount program can handle sorting and counting. Here is an example with the -p option showing the relative frequency of each scale degree in the data:
serialize *.krn | deg -a | ridx -H | grep -v r | sed 's/[^1-7]//g' | sortcount -ph
**pcent **data 18.85 5 18.24 1 14.53 3 13.08 2 12.46 4 12.32 7 10.51 6 *- *-
The dominant (5) is the most common, and the submediant (6) is the least common.
Question:
- Using the following template, what are the scale-degree frequencies in each part? Are there any differences?
extractx -g Bass *krn | deg -a | ridx -H | grep -v r | sed 's/[^1-7]//g' | sortcount -ph
Melodic Intervals
Generate a list of the melodic intervals found in all voices, sorted by most common:
serialize *.krn | mint | ridx -H | grep -v r | grep -v '[[]' | sortcount -p
Histogram plot of the same data (limiting to occurrences above 0.5%):
serialize *.krn | mint | ridx -H | grep -v '[[]' | \ sortcount -pv --min 0.01 -T "Melodic intervals in Bach chorales" > analysis.html
Sorting by interval size:
serialize *.krn | mint | ridx -H | grep -v '[[]' | \ sortcount -pv --min 0.01 -T "Melodic intervals in Bach chorales" \ --sort interval > analysis.html
Tritones can be notated as augmented 4ths (such as C-F♯) or diminished fifths (such as C–G♭).
serialize *.krn | mint | ridx -H | grep A4 | wc -l serialize *.krn | mint | ridx -H | grep d5 | wc -l
Questions:
- Which of these two spellings of the tritone are more common in the chorales?
- How often do octaves (P8) occur in the chorales?
- For the diminished fifth, what is the most common direction for the melodic interval, up or down? Here are commands to answer this question:
serialize *.krn | mint | ridx -H | grep +d5 | wc -l serialize *.krn | mint | ridx -H | grep -- -d5 | wc -l
The double dash after grep in the second command indicates the end of options for grep, so that the string "-d5" is treated as the query rather than as the option -d5.
Harmony
Harmonic intervals
The hint command can be used to study harmonic intervals. "Hint" stands for "Harmonic INTervals". Here is an analysis of the number of intervals found in all of the chorales:
hint -ac *.krn | serialize -c | ridx -H | sortcount -ph
**pcent **data 15.88 m3 15.43 P5 14.2 M3 13.42 P1 9.51 P4 8.83 M6 8.74 m6 7.04 - 2.23 M2 1.36 m7 1.35 A4 0.97 d5 0.35 m2 0.22 M7 0.16 r 0.15 d7 0.06 A2 0.05 d4 0.04 A5 0 A6 0 d1 *- *-
The most common interval between voices is a minor 3rd (or minor 3rd plus an octave transposition) at 15.88 of the harmonic intervals. Then 15.43% for perfect 5ths and 14.2 for major thirds. The most common "dissonant" interval is a major second at 2.23% of the intervals.
Chord prototypes
The tntype program can be used to examine harmonic sonorities in the music:
tntype -a *.krn | tntype -fa | extractx -s '$1-$' | ridx -H | sortcount -ph
Here are the 13 most common harmonic sonorities that will be listed:
35.09 3-11B {047} 17.26 3-11A {037} 9.07 4-27B {0368} 4.96 4-26 {0358} 4.36 3-10 {036} 4.26 3-9 {027} 2.8 4-20 {0158} 2.52 4-27A {0258} 1.99 4-22A {0247} 1.95 3-7A {025} 1.73 4-23 {0257} 1.57 4-14A {0237} 1.16 3-8A {026}
35% of all sonorities in the chorales are major chords, which are called 3-11B ("Forte number") in set theory, with the semitone prototype {047} which would be CEG on C, or GBD on G. Minor triads are half as common at 17.26%. The most common 4-note sonority is 4-27B which would be (C, E♭, F♯, A) which is a fully-diminished seventh chord in tonal music theory.
Harmony/Melody
The cint program is a hybrid of the mint and hint programs. It examines 4-note counterpoint modules which contain two harmonic and two melodic intervals.
cint *.krn --raw -to | sortcount -ph | less
Here are all of the counterpoint modules which occur with a frequency of greater than 1%:
**pcent **data 2.33 5 -2 1 6 2.23 6 2 1 5 1.91 3 -2 1 4 1.89 4 -2 1 5 1.82 6 -2 -2 6 1.71 5 1 2 6 1.66 3 -2 -2 3 1.65 3 1 2 4 1.62 3 2 2 3 1.6 -6 2 2 -6 1.57 6 -2 2 8 1.47 10 2 -2 8 1.39 5 2 -2 3 1.37 4 2 1 3 1.36 6 1 -2 5 1.36 5 1 -2 4 1.34 -4 2 -2 -6 1.3 -7 -2 1 -6 1.28 4 1 -2 3 1.2 2 -2 1 3 1.2 -6 -2 1 -5 1.16 6 2 2 6 1.08 -3 2 1 -4 1.02 3 1 -2 2 1.02 8 1 -2 7
The module "5 -2 1 6" means that the two voices start together with a fifth, then move to a sixth, with the bottom voice going down a second while the top note stays on the same pitch.
Here is an example method to highlight the counterpoint module "5 -2 1 6" in graphical notation (note: webscore needs updating):
cint -to --mark --search "5 -2 1 6" chor001.krn | satb2gs \ | webscore > analysis.html
The cint tool is also implemented as a filter in VHV:
Searching
This is the search method behind Themefinder.
Create a search index for the chorales:
tindex *.krn > chorales.index
Search for the melodic sequence "C D E F G A B C", counting how many chorales it occurs within:
themax -p "cdefgabc" chorales.index | wc -l
To locate the pattern within the music:
themax -p "cdefgabc" chorales.index --loc | theloc
which should return the result:
chor190.krn::1 58=10B2-65=11B3 chor325.krn::1 17=5B1-24=6B4
This means that the melodic pattern "cdefgabc" occurs in two chorales (190 and 325). In both cases, the bass part (::1) has the pattern. The pattern occurs from note 58 to 65 in the bass part to chorale 190 which is from measure 10 beat 2 until measure 11 beat 3. Similarly, the pattern occurs in the bass part of chorale 325 in measure 5 to 6.
The search matches can be marked in the original data:
themax -p "cdefgabc" chorales.index --loc | theloc -m | less
Each matched note will be prefixed with an "@" sign. Search for these marks in measure 10/11 and 5/6 in the two chorales.
To pull out the measures which contain the matched notes:
themax -p "cdefgabc" chorales.index --loc | theloc -m | myank --marks
To display matches highlighted in graphical notation for the last chorale in the list:
themax -p "cdefgabc" chorales.index --loc | tail -n 1 | theloc -m \ | webscore --header > analysis.html
VHV search filter
VHV has a filter which does searching using another program called msearch:
Questions:
- Search for another pattern, and report your findings.
The themax command can search for other melodic features, such as interval, contour, rhythm, meter.
Randomized Pitch
The pitchmix program can mix the order of notes in a score, while keeping the rhythm fixed. The default use of pitchmix will randomly move all notes in the score, keeping the rhythm in the original order:
pitchmix chor001.krn > chor001.mixed
Adding the -v option will only mix notes within a voice:
pitchmix -v chor001.krn > chor001.mixed
This can then be listened to on VHV or with MIDI and/or conversion to MP3 files:
pitchmix chor001.krn | hum2mid -f 19 -o mixed.mid && open mixed.mid
The option -f 19 means to force the instrument to be General MIDI #19 (church organ).
For displaying notation, it is best to use the -n option which transposes the randomized notes to be within an interval of a fourth from the original note:
pitchmix chor001.krn -n | webscore --header -s 25 -f satb2gs > output.html
The -d option specifies a randomization envelope over the duration of the music. For example, -d "0 0 1 1 2 0" is a list of time/weights: (0, 0), (1, 1), (2, 0) which means that the music starts with no randomization; in the middle of the music, there is an increase to 100% randomization, and by the end of the music, the is a gradual shift back to no randomization.
hum2mid chor001.mixed -o chor001-mixed.mid
There are several options to control the type of pitch mixing.
Next lab
Next, you can view Humdrum Lab 2 for a review of the Essen Folksong Collection and some tools for dealing with it.
Lab 1 (intro) | Lab 2 (Essen) | Lab 3 (searching) | Lab 4 (JRP) | Lab 5 (Wikifonia) | Lab 6 (bar chart) | Lab 7 (regular expressions) | Lab 8 (chorck & cint) |