Archive
Music hack roundup
Disclaimer: the opinions expressed are my own and do not represent that of my employer, Google
I love music. And programming. I really like pieces of technology that either create new or modify existing pieces of music. Here I detail some of my favorite projects I’ve found in the past few years.
Songsmith
Songsmith is a project from Microsoft Research. From the project description page:
Songsmith generates musical accompaniment to match a singer’s voice. Just choose a musical style, sing into your PC’s microphone, and Songsmith will create backing music for you. Then share your songs with your friends and family, post your songs online, or create your own music videos.
There was a commercial that detailed how the project worked, but what I found really great was what the community did with it. They fed the vocals of famous songs through the software to see what sort of music came out. The results are, ahem, mixed.
First, one that I think sounds pretty interesting – a swing version of Katy Perry’s I Kissed a Girl
Then going into the realm of hilarious:
We Will Rock You – Queen Vs Songsmith
Mortorhead’s Ace of Spades
Nirvana’s In Bloom
Enter Sandman
Roxanne
The Beatle’s A Day in the Life
The Swinger
According to musicmachinery.com’s writeup,
The Swinger is a bit of python code that takes any song and makes it swing.
If you’re not into music theory (or old music) you might not know what constitutes swing. The following video (only need to watch the first 30 seconds or so) is a great example of the difference of straight vs swing styles:
As you can hear, it sounds very different. The first half of each beat is stretched out, and the second half is shrunk down. It sounds even more different when you start listening to familiar songs converted from straight to swing, or vice versa. While most of the links have died, Daft Punk’s Around The World still plays, as does Jefferson Airplane’s White Rabbit.
The source code is available at https://github.com/echonest/remix/blob/master/examples/swinger/swinger.py.
Autocanonizer
From musicmachinery.com’s writeup of The Autocanonizer:
It takes any song and tries to make a canon out of it. A canon is a song that can be played against a copy of itself.
Wikipedia has a bit more information on what exactly a Canon is:
In music, a canon is a contrapuntal compositional technique that employs a melody with one or more imitations of the melody played after a given duration (e.g., quarter rest, one measure, etc.). The initial melody is called the leader (or dux), while the imitative melody, which is played in a different voice, is called the follower (or comes). The follower must imitate the leader, either as an exact replication of its rhythms and intervals or some transformation thereof (see “Types of canon”, below). Repeating canons in which all voices are musically identical are called rounds – “Row, Row, Row Your Boat” and “Frère Jacques” being widely known examples. An example of a classical strict canon is the Minuet of Haydn’s String Quartet in D Minor, Op. 76, No. 2 (White 1976, 66).
With that in mind, here are some example.
My favorite is Adele’s Someone Like You. This one sounds close to a round.
- Over The Rainbow – starts rough but 30 seconds in it sounds good
- The Fox – I like it. Lots of self harmonizing. The doubled up chorus actually works. It gets out of sync with itself at some points
- Take Five – demonstrates that the technique works with odd meter too. Not perfectly lined up at some points
See all the examples available at http://static.echonest.com/autocanonizer/loader.html
Source code available at: https://github.com/plamere/autocanonizer
Hat tip to Greg Linden whose Google+ post alerted me to this, and reminded me of these other projects I’d seen before.
MajorVsMinor
MajorVsMinor is a slight departure from the others I’ve listed because there is a human in the loop – it’s not all algorithmic. From Oleg Berg’s description from olegberg.com
Hello! I am Oleg Berg, a musician from Donetsk, Ukraine. I digitally re-edit famous compositions altering harmonic scale, and I call this experimental music project «Major versus Minor». It may sound surprising and unusual, but it is always interesting. Listen to the music videos below. And please donate to keep the project going
[…]
I by no means intend to enhance the famous music hits as I rework them; they are perfect already. I simply imagine what would it sound like, had the author written it in another mood. And it appears, I succeed in my imaginations.
Again, if you’re not a music nerd you might not know what the difference between major key and minor is. In general picture minor = sad, major = happy. You’ll instantly hear the difference in these versions.
First, a must if you’re an Arrested Development fan.
“Final Countdown in Major key”
My favorite comment from MYxxLxxCHIBI1:
I was literally coming down here to say that myself. GOB finally got accepted to the Alliance of Magicians
Maybe my favorite one –
“Be Worry, Don’t Happy”: Minor Key
I like this one too.
Jingle Bells
“Hey Jude” in minor key
See the whole channel at https://www.youtube.com/user/MajorVsMinor
Since this isn’t a software project per se, there is no link to the source code. According to Asshat8182’s comment on Smells Like Teen Spirit in Major key (with a name like that, he must be a reliable source of information), the way it’s accomplished is
The ‘somehow’ is called Celemony Melodyne. Specifically the DNA function
According to Wikipedia:
Celemony Software GmbH is a German musical software company that specializes in digital audio pitch correction software. It produces Melodyne, an industry standard audio pitch modification tool similar to Auto-Tune
Conclusion
I hope you’ve found this short roundup of music hacks interesting. There are some very creative people out there. If you find what they’re doing interesting, please let them know and/or donate so they’ll keep making great stuff.
Go gotcha #1: variable shadowing within inner scope due to use of := operator
Disclaimer: Go is open source and developed by many Google employees. I work for Google, but the opinions expressed here are my own and do not necessarily represent that of Google.
Last week I described how the range
keyword in conjunction with taking the address of the iterator variable will lead to the wrong result. This week I’ll discuss how it’s possible to accidentally shadow one variable with another, leading to hard to find bugs.
Let’s take the same basic setup as last week; we have a Solution
struct, and we’re searching for the best (lowest cost) one in a slice of potential candidates.
package main
import "fmt"
type Solution struct {
Name string
Cost int
Complete bool
}
func FindBestSolution(solutions []*Solution) *Solution {
var best *Solution
for _, solution := range solutions {
if solution.Complete {
if best == nil || solution.Cost < best.Cost {
best := solution
fmt.Printf("new best: %v\n", *best)
}
}
}
return best
}
func main() {
solutions := []*Solution{
&Solution{
Name: "foo",
Cost: 10,
Complete: true,
},
}
fmt.Printf("Best solution is: %v", FindBestSolution(solutions))
}
Output:
new best: {foo 10 true}
Best solution is: <nil>
Program exited.
What’s going on? We see that we have a good candidate solution from the debugging information. Why does the function return the wrong value?
The bug is in this line:
best := solution
The problem is that we’re declaring and initializing a new variable (with the :=
operator) rather than assigning to the existing best
variable in the outer scope. The corrected line is
best = solution
Use =
to change the value of an existing variable, use :=
to create a new variable.
If I had not referenced the new variable with the debug print statement, this code would not have compiled:
if best == nil || solution.Cost < best.Cost {
best := solution
}
prog.go:16: best declared and not used
[process exited with non-zero status]
Why is this shadowing of variables in other scopes allowed at all?
There is a long thread on the subject on Go-nuts, debating this subject.
Arguments For
type M struct{}
func (m M) Max() int {
return 5
}
func foo() {
math := M{}
fmt.Println(math.Max())
}
If shadowing didn’t work, importing math would suddenly break this program.
…
My point was about adding an import after writing a lot of code (when
adding features or whatever), and that without shadowing, merely importing
a package now has the potential to break existing code….The current shadowing rules insulate code inside functions from what
happens at the top level of the file, so that adding imports to the file
will never break existing code (now waiting for someone to prove me wrong
on this 😉
There is a simpler and better solution: use a short variable declaration
when you actually want to declare a variable, and use an assignment
operator when all you want to do is assign a value to a variable which
you’ve previously declared. This doesn’t require any change to either
the language or the compiler, particularly one which is that cryptic.
Arguments Against
See it this way. I can carry a gun in my hand aiming towards a target. I
pull the trigger and hit the target. Everything happens exactly the whay
it is expected to happen.Suddenly an inner block jumps in … the instructor. Me, a gun in my
hand, the instructor in between and on the other side the target. I pull
the trigger.Still … everything happens exactly the way it is told to behave. Which
still makes the end results not a desirable result. Adding an “inner
block”, which by itself is behaving in a fully specified way,
influences the whole.Somewhat odd I admit, but you may get what I mean?
Conclusion
I don’t think that the shadowing should be an error but I do think there should be a warning. The go vet tool already helps find common mistakes, such as forgetting to include arguments to printf. For instance:
example.go:
package main
import "fmt"
func main() {
fmt.Printf("%v %v", 5)
}
Run:
go vet example.go
example.go:6: missing argument for Printf verb %v: need 2, have 1
If the vet tool were modified to add this warning, it would occasionally yield false positives for those cases where the shadowing is done intentionally. I think this is a worthwhile tradeoff. Virtually all Go programmers I’ve talked with have made this mistake, and I would be willing to bet that these cases are far more frequent than intentional shadowing.