Comment author:gjm
12 April 2012 08:49:51PM
7 points
[-]
I just tried some experiments and I find that if I take Brahms's lullaby (which I think is the one Eliezer means by "Lullaby and Goodnight") and flatten a couple of random notes by a quarter-tone, the effect is in most cases extremely obvious. And if I displace each individual pitch by a random amount from a quarter-tone flat to a quarter-tone sharp, then of course some notes are individually detectable as out of tune and some not but the overall effect is agonizing in a way that simply getting some notes wrong couldn't be.
I'm a pretty decent (though strictly amateur) musician and I'm sure many people wouldn't find such errors so obvious (and many would find it more painful than I do).
Anyway, I'm not sure what our argument actually is. The chapter says, in so many words, that Q. is humming notes "not just out of key for the previous phrases but sung at a pitch which does not correspond to any key" which seems to me perfectly explicit: part of what makes the humming so dreadful is that Q. is out of tune as well as humming wrong notes. And yes, the ability to sing accurate quarter-tones is rare and requires work to develop. So are lots of the abilities Q. has.
(Of course that doesn't require that the wrong notes be exactly quarter-tones.)
Python code snippet for anyone who wants to do a similar experiment (warning 1: works only on Windows; warning 2: quality of sound is Quirrell-like):
import random, time, winsound
for (p,d) in [(4,1),(5,1),(7,3),(None,1), (4,1),(5,1),(7,3),(None,1), (4,1),(7,1),(12,2),(11,2),(9,2),(9,2),(7,1),(None,1), (2,1),(4,1),(5,3),(None,1), (2,1),(4,1),(5,3),(None,1), (2,1),(5,1),(11,1),(9,1),(7,2),(11,2),(12,4)]:
if p is None: time.sleep(0.2*d)
else: winsound.Beep(int(440*2**((p+1*(random.random()-0.5))/12.)), 200*d)
current = [(4.,1.),(5.,1.),(7.,3.),(None,1.), (4.,1.),(5.,1.),(7.,3.),(None,1.),(4.,1.),(7.,1.),(12.,2.),(11.,2.),(9.,2.),(9.,2.),(7.,1.),(None,1.),(2.,1.),(4.,1.),(5.,3.),(None,1.),(2.,1.),(4.,1.),(5.,3.),(None,1.),(2.,1.),(5.,1.),(11.,1.),(9.,1.),(7.,2.),(11.,2.),(12.,4.)]
timeshift = 1;
while 1:
timeshift = timeshift + timeshift * random.uniform(1 - timebias, 1 + timebias)
if timeshift > 1.0 + 2.0 * timebias or timeshift < 1.0 - 2.0 * timebias:
timeshift = random.uniform(1.0 - timebias / 2.0, 1.0 + timebias / 2.0)
key = random.randrange(0, len(current) - 1)
if random.random() > changebias:
if current[key][0] is not None:
current[key] = (current[key][0] + current[key][0] * random.uniform(-1.0 * pitchbias, pitchbias), current[key][1])
else:
current[key] = (current[key][0], current[key][1] + current[key][1] * random.uniform( -1.0 * timebias, timebias))
time.sleep(random.random())
for (p,d) in current:
if p is None: time.sleep(0.2*d * timeshift)
else: winsound.Beep(int(440*2**(p/12.)), int(200*d*timeshift))
Basically, each loop it tweaks the song slightly from the one before it, randomly. The three different bias settings on the top dictate how the song evolves. But besides just changing the song, the rate of any play varies randomly (according to the timebias as well).
The timebias applies to changes of timing. So the tempo of the play, the rate of change of the length of a note and the length of pauses are all shifted by the timebias randomly. increasing this number will create more dramatic swings in time changes from run to run (as well as the overall bounds of the tempo).
The pitchbias applies to pitch changes. Increasing it will let the algorithm drift from the normal song much faster. Too high will cause obvious swings in notes. Too low, and it'll take forever to get a decently maddening change (but perhaps that's part of the master plan).
The changebias indicates the chance that on a particular loop, the pitch of a random note will change, or if the duration will change. This change is carried on to all future plays (and will have a ripple effect)
The result is quite maddening, as parts of the song will randomly trend back towards the correct notes. And notes you could have sworn were wrong will appear normal later. And back and forth it goes. Just repeating, and changing until you get driven mad (or bored) enough to ^C...
Basically, it's a genetic algorithm without a binding fitness function. Its random changes will just propegate infinitely towards chaos. But for a very long time it will have the "feel" of the original song...
I just tried some experiments and I find that if I take Brahms's lullaby (which I think is the one Eliezer means by "Lullaby and Goodnight") and flatten a couple of random notes by a quarter-tone, the effect is in most cases extremely obvious. And if I displace each individual pitch by a random amount from a quarter-tone flat to a quarter-tone sharp, then of course some notes are individually detectable as out of tune and some not but the overall effect is agonizing in a way that simply getting some notes wrong couldn't be.
I'm a pretty decent (though strictly amateur) musician and I'm sure many people wouldn't find such errors so obvious (and many would find it more painful than I do).
Anyway, I'm not sure what our argument actually is. The chapter says, in so many words, that Q. is humming notes "not just out of key for the previous phrases but sung at a pitch which does not correspond to any key" which seems to me perfectly explicit: part of what makes the humming so dreadful is that Q. is out of tune as well as humming wrong notes. And yes, the ability to sing accurate quarter-tones is rare and requires work to develop. So are lots of the abilities Q. has.
(Of course that doesn't require that the wrong notes be exactly quarter-tones.)
Python code snippet for anyone who wants to do a similar experiment (warning 1: works only on Windows; warning 2: quality of sound is Quirrell-like):
Here's a tweak I made that I think keeps to the spirit.
current = [(4.,1.),(5.,1.),(7.,3.),(None,1.), (4.,1.),(5.,1.),(7.,3.),(None,1.),(4.,1.),(7.,1.),(12.,2.),(11.,2.),(9.,2.),(9.,2.),(7.,1.),(None,1.),(2.,1.),(4.,1.),(5.,3.),(None,1.),(2.,1.),(4.,1.),(5.,3.),(None,1.),(2.,1.),(5.,1.),(11.,1.),(9.,1.),(7.,2.),(11.,2.),(12.,4.)]
Basically, each loop it tweaks the song slightly from the one before it, randomly. The three different bias settings on the top dictate how the song evolves. But besides just changing the song, the rate of any play varies randomly (according to the timebias as well).
The timebias applies to changes of timing. So the tempo of the play, the rate of change of the length of a note and the length of pauses are all shifted by the timebias randomly. increasing this number will create more dramatic swings in time changes from run to run (as well as the overall bounds of the tempo).
The pitchbias applies to pitch changes. Increasing it will let the algorithm drift from the normal song much faster. Too high will cause obvious swings in notes. Too low, and it'll take forever to get a decently maddening change (but perhaps that's part of the master plan).
The changebias indicates the chance that on a particular loop, the pitch of a random note will change, or if the duration will change. This change is carried on to all future plays (and will have a ripple effect)
The result is quite maddening, as parts of the song will randomly trend back towards the correct notes. And notes you could have sworn were wrong will appear normal later. And back and forth it goes. Just repeating, and changing until you get driven mad (or bored) enough to ^C...
Basically, it's a genetic algorithm without a binding fitness function. Its random changes will just propegate infinitely towards chaos. But for a very long time it will have the "feel" of the original song...