Karen_Tipping - Computer Science and Engineering

advertisement
My Beats
1. Introduction
1.1 Team Members
Michael Smith
Dylan Barrett
Karen Tipping
1.2 Background and Motivation
Beat games such as Guitar Hero and Rockband are becoming increasingly popular.
However, players can't play along to any song they'd like. The tracks to popular songs are
pre-made for Guitar Hero and Rockband. If someone wants to play their favorite song on
Guitar Hero, they have to manually create a track for it. This seems like a lot of work!
Music is such an integral part of our society, especially for younger generations. It
makes sense that people would want to play all of their favorite songs on Guitar Hero or
Rockband.
1.3 Project Abstract
This brings us to the goal of our project. Rather than creating the tracks one at a time,
we will create a tool that can take any song and dynamically generate the playable tracks for
the player. This will allow players to play all of their favorite songs, and not have to worry
about creating the tracks themselves. We will focus this semester on dynamically generating
tracks for Guitar Hero only.
2. Available Tools, Frameworks and Constraints
2.1 Framework Constraints
Frets on Fire is an open source environment to play Guitar Hero tracks on. This will
benefit us, since our goal is not to create a user interface. Once we have dynamically
generated the tracks for Guitar Hero, we will play them on Frets on Fire to test them out.
This, of course, limits us to strictly guitar. It also constrains us in the format of our
tracks. The MIDI file must be formatted to work within Frets on Fire, and the music file must
be in ogg format.
2.2 Existing Tools
One of the most important tools that we will be using this semester is Analyze by the
Echo Nest. Analyze takes in a song, and outputs XML files describing that song.
We will have data on the notes, pitches, loudness, timbre, and more. Using this
information, we can analyze the notes and patterns to create realistic and fun tracks.
The Echo Nest also provides a library of various functions that we can use to work with
the information received from Analyze.
2.2.1 Sample XML file of a segment from Analyze
One of the more important XML files is one that represents the segment. A segment is
essentially a note, and the XML file describes the loudness, timbre, and pitch at different tick
marks throughout the span of the defined note.
To get this XML file, the function get_segments can be called. This method returns
the information for all the segments in the file.
Below is an example of the XML file with one segment. If there were more than one
segments, then the segment tags would be repeated to represent the other segments.
<?xml version="1.0" encoding="UTF-8"?>
<response version="2">
<status>
<code>0</code>
<message>Success</message>
</status>
<thingID>TRLFPPE11C3F10749F</thingID>
<method>segmentslt;/method>
<analysis>
<segment start="2.54562" duration="0.29587">
<loudness>
<dB time="0">-29.707</dB>
<dB type="max" time="0.03483">-25.351</dB>
</loudness>
<pitches>
<pitch>0.009</pitch>
<pitch>0.090</pitch>
<pitch>0.010</pitch>
<pitch>0.018</pitch>
<pitch>1.000</pitch>
<pitch>0.017</pitch>
<pitch>0.005</pitch>
<pitch>0.005</pitch>
<pitch>0.028</pitch>
<pitch>0.383</pitch>
<pitch>0.010</pitch>
<pitch>0.016</pitch>
</pitches>
<timbre>
<coeff>31.132</coeff>
<coeff>-51.574</coeff>
<coeff>92.135</coeff>
<coeff>60.049</coeff>
<coeff>77.614</coeff>
<coeff>-17.629</coeff>
<coeff>-47.819</coeff>
<coeff>6.888</coeff>
<coeff>17.400</coeff>
<coeff>-0.635</coeff>
<coeff>-8.109</coeff>
<coeff>-45.552</coeff>
</timbre>
</segment>
</analysis>
</response>
Other functions such as get_beats, get_key, get_loudness, get_tempo,
get_time_signature, and get_duration can be used to get further information as
needed. A list of all the functions, their descriptions, and examples are available on
TheEchoNest.com under Developer APIs.
2.3 Complexity Constraint
Most music has multiple instruments and/or vocals all playing at once. Since
separating out different instruments is beyond the scope of this semester, we will be dealing
with guitar only songs.
To expand our work, we may use songs complete with numerous instruments, but treat
all notes as guitar sounds for a Guitar Hero track. It won't feel as realistic as playing along to
a guitar only song, but it should still be fun.
3. Project Description
The aim of the project is to create a command line tool that accepts as input a
song file containing only guitar and outputs a dynamically generated playable track in
the format used by Frets on Fire based on that song.
3.1 Development Environment
Our tool will be created within the Java environment to allow for easy portability.
Java offers a wide range of networking protocols and also has support for the MIDI
format within the javax.sound.midi API. Below are some of the classes and methods that we
will be using from the package to create our MIDI file.
Within javax.sound.midi, we will mainly be using the classes: Sequence, Track, and
ShortMessage. The class Sequence represents the MIDI file, and the class
ShortMessage will hold a message. A message gives information about segment
beginnings, endings, or other information the track might need. It gets the information
through events. There can be more than one Track running in a Midi file, possibly
corresponding to different instruments.
We will also be using the methods: sequence.createTrack, track.add, and
shortMessage.setMessage. The method add adds a new message to the track by
creating a MidiEvent for it that takes in the message. The method setMessage sets the
information about the message.
3.2 Project Flow
When run, the tool will proceed through the following stages:
3.2.1 Stage 1
Stage one is very basic. It will first prompt the user for the song file location and
the Frets on Fire song library location. After obtaining this information it will check that
each piece is valid and then upload the song file over the network using standard web
protocols to the Analyze servers.
3.2.2 Stage 2
Stage two becomes more complicated. In this stage the results of the Analyze
program will be retrieved, again using basic web protocols, and set up to be organized. We
will use various functions provided for us by the Echo Nest to work with the data. When
retrieving the information on the song defining where and what notes exist, they
will be placed into a data structure that focuses on identifying over all song structure.
This is the prep work that will be done to allow the next stage to generate playable
tracks by analyzing this created structure. This structure could be arranged as a Suffix Tree,
or analyzed using Curve Sampling.
A suffix tree's structure can highlight common subsequences of a pattern. Suppose the
notes of the song are placed chronologically into a string, using letters to represent the notes
like so: “abcefgabcdgfabceeeabcabc.” Using the Suffix Tree would make it quickly apparent
that “abc” is the most commonly recurring sequence found within the song. This is important
because in a song the more repetitive parts are the parts that are more important to having a
song be identifiable. So the notes representing "abc" would not want to be cut out (at least
not all 3 of them.) This will be expanded on in Stage 3.
We may also use Curve Sampling to analyze the notes to decide which can be
discarded, while still leaving a feel for the song. Curve Sampling is an easy concept that
basically says that if there is a lot of change in the song (the pitches are going up and down
and up and down) then you would need a lot of notes to portray this. However if the song
was simply going up in pitch at a steady rate, then you could remove plenty of notes and still
recognize the song. We hope to use this to remove unnecessary notes when creating our
tracks, which have to be compressed down to only five buttons.
3.2.3 Stage 3
Stage three is where the song and song structure will be evaluated to generate
the playable song tracks at different difficulty levels. This is the most complicated stage.
3.2.3.1 Note Compression
The playable music tracks consist of five notes/buttons. A given guitar piece can
consist of any note A-F all up and down the musical scale. As such, the notes within the
song need to be compressed and mapped to one of the five different game note
options. This mapping needs to be even across the range of notes appearing in the
original song. Using various statistical methods, five equal divisions of the appearing
notes can be defined for each analyzed song.
This will need to be a different mapping for every song. If we have a very low song, it
would not be much fun to be playing the low button a million times. So we need to look at
each song individually, and divide up the pitches that appear in that song.
On the easy and medium tracks, the fifth button, played by stretching the pinky out, is
almost never included since it's hard to play. We will have to consider this while creating the
tracks for the difficulties.
3.2.3.2 Difficulty Levels
Each song can have tracks for any difficulty. Some songs only have tracks for Hard,
and some songs have tracks for all difficulties. Frets on Fire supports four difficulties,
including SuperEasy. We will define our songs to generate tracks for the difficulties Easy,
Medium, and Hard. This is how we will define each difficulty:
Easy: This level will have the lowest note density for the player to play. The
notes in this level will consist only of the minimum needed to keep the song identifiable
and give the player a sense that they are still playing the song. As such, it will want to
focus on the most repeated sections of notes in the song as identified by the Suffix
Tree. We will also use Curve Sampling to remove as many notes as possible to still keep the
feel for the song in the track. This will generate an Easy track, in that the notes density will
not be greatly demanding and it will be a set of repeating patterns for the user to play. There
will also not be a lot of buttons that must be played at the same time, since that is a little bit
more difficult. Lastly, by conforming to the pre-existing game standards, this level will only
utilize four out of the five buttons.
Medium: This level will build off the Easy track. Everything included by the Easy
track will be included in the Medium track allowing for players to develop their skills by
moving up a setting in a song and not having to relearn the whole thing. Medium will
also start to incorporate more of the less frequent musical patterns found within the
song. Medium will also include more of the notes within these patterns to yield a
greater note density. And in conforming to the pre-existing game standards, this level
will utilize all five of the game buttons, although the fifth button should be used sparingly.
Hard: Starting with the Medium track, Hard will include the most notes in all the
already included patterns generating the greatest note density of all the levels. It will
also include the most random sections such as solo's and small clips that may only
appear once. This difficulty should employ the fifth button just as frequently as the other four
buttons.
3.2.3.3 Heuristic Evaluation
In order to use the Suffix Tree to determine which notes to actually place into
the song tracks, a set of heuristics will have to be developed to make the decisions. By
utilizing a set of heuristics that can change and evolve rather than a few set decision
making functions, it will allow the program to become smarter with evaluation. If a
player alerts the program that the song was less than satisfactory, then the program can
try tweaking the heuristic values to generate better tracks. For example, a player might report
that the song had too many buttons for his pinky while on Medium. The heuristics can then
be tweaked to ensure there are less next time.
One likely heuristic that will be developed is one that will look at note density. This
heuristic will look at how close notes are to each other in timing and decide for each difficulty
level if there are too many.
Another heuristic is going to have to attempt to separate the more important notes from
the less important notes in a given sequence. For instance, if the pattern “abcbcdafe” is
repeated many times throughout the song, it will be a section that should be included in all
difficulty levels. However, each and every note within that sequence should not be included
especially for the Easy track. In this case the heuristic will use Curve Sampling and will
attempt to remove notes to create a sequence similar to “a c c a e” where the remaining
pattern is still clearly identifiable as the song.
The heuristics will also ensure that there are the right number of buttons that will to be
played together. On an Easy track, the number of buttons played together will need to be
kept small, however on a Hard track there may be many.
A third heuristic can be the length of the buttons (if you want the player to hold the
button instead of just hit it.) This doesn't play a role in difficulty, but it's still important to get
the right balance.
A fourth possible heuristic could be how quickly the player must switch buttons. This
can be difficult if the different buttons are extremely close together or if there are a lot of them.
So, on Easy, quickly changing buttons will have to be kept to a minimum or even left out
completely. However, on Hard, including a lot of these especially in a row would definitely
make the track harder.
Another heuristic could watch out for extremely long sequences with the same button.
If we divide up the song based on the overall pitch of the song, there might still be a section of
the song that's really low. This may go on for a while, and the player will be stuck playing the
same button over and over again. This doesn't make for a very fun song, and will have to be
tweaked.
Many heuristics will be employed to ensure the best player experience that we can
deliver!
3.2.4 Stage 4
Stage 4 consists solely of track output. This stage will take the difficulty tracks
produced by Stage 3 and embed them within a MIDI file in the same format used by
Frets on Fire. This MIDI file, along with the original song file will then be outputted to a
folder within the Frets on Fire song library, making the song available the next time the
user plays the game.
We can now test drive our dynamically generated songs!
4. Task Break Down And Time Line
4.1 September 17 - October 1
During the first few weeks, some working tools need to be created. Some preliminary
things must be figured out before we can start working on the meat of our project. The below
things can be worked on in parallel since they are separate things that don't depend on one
another.
The first is to reverse engineer the Frets on Fire MIDI file format so that we can output
our own files using the javax.sound.midi API. This is Dylan's responsibility. This is important
because without figuring this out, we won't be able to test out our tracks.
The second is to develop a set of Java functions that can interact with the Analyze
servers to upload a song and retrieve the results. This will include retrieving the segments, or
notes, organizing them, and beginning to understand how it works. This is Mike's
responsibility. This needs to happen before anything else as well because without this data,
we have nothing to work with.
We also need to be able to translate MP3 files into OGG format for Frets on Fire to
play in the background of the tracks. This is Karen's responsibility. This is equally important
because without it, our tracks will not have music and we cannot test the timing of our track
buttons or get a feel for how well the tracks represent the song.
All of these tasks can be done in parallel since they are completely separate entities.
They must also be completed before we can proceed to the next stage. Once we put this all
together, we should be able to run a test track on Frets on Fire and start working on the meat
of the project: to dynamically produce a fun track for any song.
4.2 October 1 - October 15
Naturally, we can't start creating tracks until we can test them out on Frets on Fire. At
this point all of the preliminary tasks should be in place, so we can concentrate on the
algorithms for creating the tracks.
At this point, Mike will be working on creating a Suffix Tree containing the information
about the song. He will use this to define the common structures. Later we will use this
information to decide which parts of the song can not be omitted based on their important
standing (such as the chorus).
In parallel, Dylan can also be analyzing the input, but in a different way. He will be
implementing Curve Sampling to prune the notes for the tracks. Dylan will be condensing the
overall song to make it more manageable to ultimately map everything to just 4 or 5 buttons.
Mike's Suffix Tree will be gathering information on the structures, while Dylan will be
making a compressed version of the song. From that compressed version we can use Mike's
information and further truncate it by maybe omitting uncommon subsequences especially for
the easier levels.
4.3 October 15 - October 22
Once the song has been pruned for unnecessary notes using the Curve Sampling, and
short uncommon subsequences have been removed, Karen can begin to map what we have
to buttons. At this point, we have the basic notes that we want to include in a track. We can
now move on to the next stage of deciding which notes should be mapped to which button.
For this preliminary stage of initial mapping, we will be implementing it for only one
difficulty. This may be the hardest difficulty since then we wouldn't have to further prune the
notes that we include in the song.
We must determine for each song how to divide up the notes into the buttons. This
must be done dynamically for each song, since the pitches in songs can vary greatly. Karen
will work on figuring out how to dynamically divide up the track notes into the buttons, and
make it playable on Frets on Fire.
4.4 October 22 - November 12
Now that the dynamic mappings to buttons has been figured out and a basic song track
has been created for one difficulty, we have to expand this knowledge to also deal with all
difficulties. We will be making tracks for SuperEasy, Easy, Medium, and Hard.
In the easier tracks, we will need to further prune the notes that we have. We can use
the suffix tree to omit more uncommon subsequences, and also use Curve Sampling to
reduce the frequency of notes. Determining just how much we should prune using Curve
Sampling, and how many uncommon subsequences we should include will be decided by the
heuristics that we will implement.
In this stage, we will develop the heuristics that will help us determine the frequency of
notes and other factors that make the dynamically created tracks fun. We will play the songs
and tweak the heuristics so that each difficulty has the right balance of note frequency, note
length, note variation, note concurrency, and notes that are representative of the song.
These heuristics will be developed by Mike, who is the most familiar with them. Once
they have been implemented, endless tweaking for best results can be done by all of us.
4.6 November 12 - End of Semester
At this point, everything should be successfully implemented and integrated. This
project requires constant integration, so we should be integrated at the end of each stage.
If any bugs are discovered, the individuals responsible for that section of code will fix
them, since they know the code the best.
We will also use this time to do quality assurance. We will thoroughly test the other
group members' modules, and create a bug list. We will organize it by priority, and work on
fixing the most crucial bugs first.
Glossary
Analyze
An API provided by the Echo Nest that allows
us to use its functions to gather information
about songs. It outputs the data in the form
of an XML file for us to work with.
Buttons
The five notes in the compressed track that
are played.
Curve Sampling
A mathematical way of distinguishing which
notes can safely be removed for the tracks
while keeping the song's structure
recognizable in the track. If the song was
graphed using the notes, the maxes and mins
would need to remain, but some of the
transitioning notes would not.
Frets on Fire
A user interface that simulates Guitar Hero on
the computer. This will be the interface
where we demonstrate the song tracks that
we have produced.
Guitar Hero
A beat game where players push buttons on
a game controller shaped like a guitar and try
to match the circles scrolling along the screen
to the beat of the song.
Heuristics
A problem solving technique where the best
solution is found at successive stages and
helps to find the best solution to the next
step.
MIDI file
A way of representing musical information in
a file. It includes information on pitch, note
beginnings and endings, loudness, and more.
OGG file
The background song format used in Frets on
Fire.
Rockband
A game similar to Guitar Hero with the
addition of a guitar base, drums, and vocals.
They all must follow instructions from the
track that tell players what to do.
Segment
A section of the song that represents a note.
Analyze's function get_segments returns an
XML file that gives various information about
all the segments in the song.
Song
The original song usually in MP3 or OGG
format. (OGG is the song format for Frets on
Fire.)
Suffix Tree
A tree which is organized to show common
sequences. The tree branches off when a
subsequence is different from another
already found. The nodes with the most
children are the most common.
The Echo Nest
A website that provides our tool, Analyze, and
many functions to work easily with the data.
Timbre
The note quality.
Track
The truncated version of the song where the
notes are mapped to buttons. There will be
three tracks for each song: one for Easy, one
for Medium, and one for Hard.
XML file
A file that can be traversed through its tagged
nodes for information. The nodes are
denoted by tags (< > ... </ >) and mark the
beginnings and endings of the information
sections. An example in given in section
2.2.1 of the document.
Download