Project Velocity for Spring Semester
First Iteration:
4 stories completed with a total estimate of 29 hours. The iteration took us
roughly 50 hours.
Second Iteration:
6 stories completed with a total estimate of 42 hours. The iteration took us
roughly 30 hours.
Third Iteration:
4 stories completed with a total estimate of 15 hours. The iteration took us
roughly 14 hours.
Meeting Logs
February 18
On the 18th, the played the planning game. Our customer decided on the user
stories we should work on the beginning of this semester then the developers
estimated them. The stories and estimations follow:
1. Volume control per grid square - 6 hrs
2. Tempo control (while playing) - 5 hrs
3. Save/load files - 12 hrs
4. Render to .wav format - 6 hrs
5. Play samples longer than 16th note - 4 hrs
6. Synchronize instruments properly - 4 hrs
7. Convert raw data to manageable form - 8 hrs
The stories the customer has asked us to work on this iteration are stories 7,
2, 3, and 6. The pairs for the beginning of this iteration are as follows:
7. Convert raw data to manageable form - Ed, Jason
3. Save/load files - Colin, Toby
6. Synchronize instruments properly - Andrew
February 21
Last night, Feb. 21st, we had our first coding session of the second semester.
Toby wasn't able to attend, but everyone else got some good work done. Here's
the wrap-up:
Jason and Ed:
Wrote code to convert byte array to int array where each int is the value of
one sample in the sound file. The solution thus far incorporates
multi-channeled files, different sample sizes, and big/little-endianess. The
code has yet to be fully tested. The next steps are: convert to floats,
operate on floats, and convert back to bytes.
Colin:
Worked on a spike for saving/loading sequencer state into a file. Added
toolbar buttons for Save and Load. Save and Open dialogs pop up when their
respective buttons are pressed. A majority of the sequencer state is
saved/loaded to/from the user-selected file. The sound data is not yet saved
or loaded.
Andrew:
Got the instruments to synch correctly, and added the ability to add
instruments during playback. The solution sets up a default line that gets
swapped out when additional instruments are added during playback. The
drawback is a click heard when the default line gets cuts off (even though
only zeros are being placed on the line). Also, the code is ugly (need
refactoring).
February 25
We finally got everyone together on Feb. 25th and got down to business. The
first subject, however, was a new spike. Andrew, reading his "Refactoring"
book, came up with an idea to shorten our thread class a great bit by
abstracting the sound data into its own class. We all thought it was a good
idea and since he finished the bug fix (synchronization), we all decided he
should work on it. Andrew suggested that once our current stories get
finished, we should see how close or how off our initial estimates were so we
can plan better in the future. Here's the break-down on everyone:
Jason and Ed:
Figured out format conversion doesn't work using Java Sound guru's code. We're
not sure where the fault lies, but we cannot convert formats using the quick
and easy two statement method. Code to move byte array into int array might be
ready to test, yet still not sure the best way to test it.
Colin and Toby:
Colin introduced Toby to the code. Commented a great deal of the save/load
code. Came up with a possible fix of the close bug submitted late last week.
They also found another possible bug in the load code Colin wrote last
Wednesday.
Andrew:
Refactored (technical term: extracted class) the InstrumentThread class.
Created AudioData class to hold more than half of the code previously in
InstrumentThread. The code needs more refactoring, even though it's getting
less ugly all the time. He got the sounds to play using the AudioData
class.
February 28
On the 28th of Feb. the Music Sequencer group got together again. While Andrew
was late (proctoring a 225 test), the rest of the group struggled to find
direction. We ended the night with a bit of progress, thought not up to our
former efforts, unfortunately.
Jason and Ed:
Stole code from Tritonus (don't worry it's LGPL'd). Modified it to fit our
format conversion needs. Added accessors to work with their functions. Once
again: we are ready to test. BTW: anyone have ideas on testing this?
Colin and Toby:
First closed bug: improper shutdown. Andrew, the customer, signed off on it
before it was closed. For next time: assign the bug to someone before closing
it. We live, we learn. They also figured out that the previously mentioned
"load bug" is not reproducible. More investigation will be done.
Andrew:
Did more massive refactoring of InstrumentThread. Got setInstrument() method
down to 8 lines during the refactoring. The code is flexible and workable, but
more optimization needs to be done because the threads are getting out of
synch when a new AudioData object is created.
Ed (again):
Overused the colon punctuation operation in his "Tracker" write-up. Maybe it's
just late.
March 4
We got together on Sunday, March 4th for our fourth coding session this
semester. Some good progress was accomplished:
Ed (Jason was mysteriously absent):
Added functionality to the ConversionTest spike class so it could convert from
float to byte (borrowed code). Added function to modify volume of a float
sample array. Tested these enhancements by playing "ding" at 5 different
volume levels. Efficiency (and therefore the amount of needed optimization)
has yet to be determined.
Colin and Toby:
Checked out Andrew's code (see Andrew). Added a "manager" class named
Sequencer that will store all the sequencer information (and might replace a
lot of the functionality in MenuBar). Their code compiles, but doesn't run.
Working on this refactoring to enable save/load stories on this iteration.
Andrew:
Checked in AudioData and InstrumentThread files. He says they're 98% good.
Added a tempo slider that sometimes blue screens. This behavior is still under
investigation. When not crashing the system, the slider works and looks
pretty.
March 7
Wednesday March 7th, the last full meeting before Spring Break, went well.
Progress was made, and it looks as though our first iteration (scheduled to
conclude in our next meeting) will be on schedule. Since Jason is the only
group member that will be out of town this coming Sunday, we are having what
will probably be our last meeting of Iteration One. Major refactoring is on
the agenda, as well as some basic additional functionality in the Manageable
Data spike. Wednesday's meeting went as thus:
Jason and Ed:
Cut out a bunch of code from the spike. This was facilitated by the customer
saying that 24 and 32 bit samples need not be supported. Realized that all
output had to be of one format, so got to work on that. Code now converts 8
and 16 bit, big and little endian, signed and unsigned, mono and stereo clips
all to 16bit, little, signed, stereo output. The last piece of this puzzle is
converting 22kHz to 44.1kHz. That is planned for Sunday.
Colin and Toby:
Continued on SequencerState class. The big Refactorama II is brewing with
their code.
Andrew:
Came up with some ideas on refactoring. Talked with Colin and Toby about
refactoring a great bit. Informed Jason and Ed to the scope of the
refactoring. Looked through all the code we have so far.
March 11
The beginning of Spring Break and four out of five were still around. We got
together on Sunday and worked for 4 hours polishing up the system and getting
it reqady for refactoring (still).
Ed:
Added sample rate and mono->stereo conversion to the "manageable data"
spike and it was pretty much production ready code. At the end of the session,
merged the code with a local copy of the tree to find out if it all worked in
the system. Found out that the synchronization problem is almost completely
corrected with the new code. That is, not switching lines because all audio
data is the same format reduces synch problems.
Colin and Toby:
Argued about refactoring for a long while, coming up with a plan of sorts.
Also played with the "transient" keyword to see if we could have a
serializeable class with unserializeable private members: we can. Worked some
more on getting load/save up to speed.
Andrew:
Went through all the code we have now and argued about the refactoring as
well. Realized after doing so, that a rewrite is not needed and a simple
refactoring will dothe job nicely. Made drawings and plans for the big
refactoring.
March 18
End of Spring Break and four out of five make it again. Colin is sick. Worked
again for 4 hours in the nice and quiet (and empty) lab. Got major
accomplishments (and major screwups), but overall the night went well. For
next time: finish save/load and add tempo slider to the GUI toolbar and the
corresponding functionality elsewhere.
Andrew and Ed:
Refactored to separate the GUI from the guts, worked on the GUI side of
things. Changed the GUI components and remaned SequencerFrame to
RiffDesignerFrame. Took out all the functionality from the GUI elements.
Added conversion code (the spike) to AudioData and changed InstrumentThread
accordingly. AudioData now only has one format and it is a serializeable
object because we used "transient public static final". Whew. Ed also made a
mockery of CVS, or himself. Screwed up some stuff, but eventually figured it
out. We now have a "couple_gui_code" top-level directory that has nothing but
crap in it. Yeah Ed.
Jason and Toby:
Refactored the other side of the system, the guts. Took everything cut out of
the GUI and put it into the new RiffEngine and RiffState classes. Also created
RiffDesigner as master class that will start both the engine and the GUI.
Worked into the wee hours of the night (Andrew and Ed left at 12:30am and they
were still working) on getting Save and Load to work with the newly refactored
(and checked in) system. Did they check their code in when they were finished?
We'll never know... No, they didn't (just checked).
March 21
Everyone was back this Wednesday, March 21st. We finished iteration 1
(finally) and now our project works in other operating systems (Linux). We put
in 3 and a half hours finishing everything up and our next meeting will be
another planning game for iteration 2.
Andrew and Ed:
Refactored AudioData and fixed bug that was causing the right channel of a
22kHz stereo sound to be muted. Added code to project and checked it in.
Colin, Jason, and Toby:
Made save load work on the new system incorporating the bug fixed by Andrew
and Ed.
Andrew, Ed, and Jason (afterwards):
Put tempo into the GUI and made all the necessary changes to the different
project files to make it work.
March 25
We all got together in Andrew's office and planned out the second iteration.
We worked for two and a half hours.
We decided that the RiffEngine needs to be rebuilt this iteration.
Unfortunately that will hold up development of the only three stories not
accomplished in iteration 1. Volume, Play greater thatn 16th note, and Render
to wav will all be pushed back until after the Engine Rebuild. We figured the
Engine Rebuild would take about 16 total hours. Another task currently needed
is System Tests. Now that we completely changed the running interface, tests
need to be written to make sure everything works like it should. The Engine
interface isn't going to be changed much in the future, so we can write these
tests now and have them until the end of the semester. We figured 2 hours
would be good to write the tests. Past those, we decided to plan for the
second phase of the project. We will be lining up Riff Engines in a larger
"Composer" interface. The important stories for the Composer are: Make grid
entry, Load a riff engine, Play song. Because Load riff and Play song are
dependant upon Make grid entry, we only estimated Make grid entry. The
estimation was 8 hours. Aside from planning, we also checked our previous
estimates. What was estimated to take a total of 29 pair hours took slightly
over 50, so this iteration we are doubling our estimates. The breakdown
follows:
Engine Rebuild -> 16 hrs -> 32 hrs
System Tests -> 2 hrs -> 4 hrs
Make a grid entry (Composer) -> 8 hrs -> 16hrs
The assignments for Wednesday are as follows:
Engine rebuild: Andrew and Jason
System test: Colin (Andrew might do some off the clock work)
Make grid entry: Ed and Toby
March 28
Started work on the second iteration. Some work was started before today
off-the-clock, but not too much. Just enough to give us a good start this
Wednesday.
Ed and Toby:
Started work on the Composer. Got about halfway with the first story of Make a
grid entry. Lots of JFC knowledge and the book helped.
Andrew, Colin, and Jason:
Did something else. Anyone remember? I guess I didn't write it down...
April 1
This Sunday, April 1st, we met for two hours and got very far into iteration
2. Here's the breakdown:
Ed and Toby:
Worked on finishing up Make Grid Entry story. Works for the most part, but
isn't that pretty. Started work on Load Riff. We had trouble with
dependancies between palette and composer frame. Starting to hammer them
out.
Andrew, Colin, and Jason:
Integrated Rhythm Event into everything. In RiffState, they added gets and
sets for all needed values. Fixed a random problem with the file chooser and
its constructor being void. Why does java let you do that!? Anyway, they
changed the tempo meter to move between 60 and 200 bpm. It looks nice. They
closed some bug, but didn't really tell me which one. They also checked all
their code in without my help. Yippee!
April 4
Keep on chugging on iteration 2 with this Wednesday's meeting. Actually had
three groups this time. Way to go us!
Ed and Toby:
Continued our mad GUI skills with Load Riff. Got it finished pretty quickly
and started work on Edit Riff (or Edit Color of Riff). Ran into implementation
issues when changing color and color not updating in grid. That's for next
time.
Andrew:
System is now completely RhythmEvent based and it's sounds awesome. Started on
Volume, didn't check in though. Also noted that a master volume is needed but
no plans for it yet. Shouldn't be too hard, he thinks. Fixed a bug, but once
again, he didn't tell me which.
Colin and Jason:
Started work on Save To WAV. Writing a method to do it all at once. They did
some checking to see if JavaSound implemented this, but it wasn't clear. Also
looked at a bunch of JavaSound documentation.
April 8
Continued work on iteration 2. It's coming along nicely, though today was a
step backward for one group. Here's what happened:
Ed and Toby:
We broke everything. And I mean everything. We didn't try to compile Composer
even once, because we messed it up so much. We worked on getting a decent
design, because we were running into a lot of problems that couldn't be fixed.
Started copying RiffDesigner design with Engine and State. It's looking pretty
good, but still very messy. Hopefully it will work.
Andrew:
Checked in volume per grid entry code. Also got the saved filename to appear
in the RiffDesignerFrame title bar.
Colin and Jason:
Worked on GUI elements for Save to WAV. Their code is writing to wav files,
but they are getting mass exceptions. Something isn't going correctly. They're
making progress, tho.
April 11
Getting very close in iteration 2. Only enough work for two groups this time.
Is that a good thing?
Ed and Toby:
Finished Load Riff and Edit Riff Color. The colors in the grid now update.
Most of our crazy design decisions are finalized and not too ugly. Still need
to work on them.
Andrew:
Jumped on with Colin and Jason (see below).
Colin and Jason (and the Lazy Customer):
Got Render to WAV a lot closer. Wavs aren't coming out correcly, but they're
not getting exceptions any longer.
April 15
Finished up Iteration 2. Amazing! Only two groups again. It's looking awfully
nice, though. Here's the breakdown:
Ed and Toby:
We made Composer look pretty. We added row and column headers to the grid, as
well. Added some sparse comments so people know what's going on next
iteration. Made PaletteFrame thinner and line up correctly with Composer
Frame. Clicking on PaletteFrame's close window button doesn't close it. Later
this week I checked in our code with a massive reorganization of our CVS
files. RiffDesigner and MusicComposer directories now, not just 'code'.
Andrew, Colin, and Jason:
Made Save to WAV work. Added permanent button for it. Master volume also got
mysteriously added (Andrew). Removed the many instances of FileFilter
subclasses and created a CustomFileFilter class that is now used in
RiffDesigner, but not in MusicComposer yet. Checked it all in. Finito!
April 18
This is going to be our last iteration, so we figured out the final stories
we're going to work on to make this a great project by semester end. Here's
what we came up with:
1. Playback for Composer estimated at 6 hrs.
- get first bar
- add them up for all tracks
- get second bar (if all goes well)
- add toolbar class with play/stop button
2. Tempo estimated at 1 hr.
- slider and member variable
3. Set Playback Position/Monitor Playback estimated at 6 hrs.
- need GUI elements to tell where playback is
- need way to set playback position
- need to update playback position while playing
- need variable and functions for getting and setting
4. Set Track Volume estimated at 4 hrs.
- volume slider for each track
- functionality added to playback in Engine
5. Save/Load estimated at 2 hrs.
- GUI element
- same as in RiffDesigner
The Customer (Andrew) gave us priorities of:
1. Playback
2. Tempo
3. Playback Position
4. Save/Load
5. Track Volume
Starting next time, the groups will be:
Playback: Andrew and Colin
Tempo: POOF! (Andrew will finish this before next time)
Playback Position: Ed and Jason
Save/Load: Toby
April 22
Worked in the middle of a Sunday for a change. IT worked out well. Colin was
mysteriously absent though.
Ed and Jason:
Put row and column headers into their own classes cause they now have added
functionality. This will probably change because of the problems we ran into
at the end of the session. Buttons clicks on the column header now highlights
the column of grid cells. Need to find out when playback position changes in
ComposerEngine, because polling it would be a bad idea. Ed talked with Andrew
about this and did some investigating on his own. Observer iand Observable are
what we want to work with. This will start before we meet again. It's actually
one of the Design Patterns. Imagine that!
Toby:
Got Save/Load to work. It's weird because each frame knows about the other,
but it works. He checked in his code. This might actually be changed with the
discovery of Observer, but I haven't consulted the group on this yet. Toby
already did some good work.
Andrew:
Refactored RiffEngine because he didn't want to bring any design mistakes into
ComposerEngine playback. Also added functions for getBarOfData, possibly with
a volume paramter, to RiffEngine.
April 25
Making great headway on Iteration 3 even though this was only our second
meeting for it. Playback, estimated at 6hrs, is done in 4. Playback Position,
also 6hrs, is also done in 4.
Ed and Toby:
Finished up Playback Position with observer and all. Also opened and closed a
bug regarding lost selection in the Palette after a color edit. Made plans for
adding unclicking. Opened two more bugs in Sourceforge (synching and
unclicking).
Andrew and Colin:
Did Playback. It works and is nice. The playback position in GUI is not
correct with the sound coming out. Looked at it, but nothing done yet. Also
helped with the observer stuff by making ComposerEngine an Observable object
(and implementing Runnable instead of extending from Thread).
April 29
Wrapping up the semester. Not much functionality needed to get done. Just some
odds and ends.
Ed:
Checked in the 'unclick' bug fix. Worked on getting playback position synched
with GUI. Got it to work after not the prettiest fixes. ComposerEngine now
"suspends" and "resumes" when "stop" and "play" are pressed. Checked in this
code. Added code to make color chooser pop up when adding a riff file to the
palette. Checked in this code as well. Closed the two bugs fixed.
Toby:
Learned JavaDoc and taught everyone else. Learned about packages and got them
to work well, but didn't check in code because everyone else was writing
JavaDoc comments.
Andrew, Colin, and Jason:
Worked individually on commenting RiffDesigner files in JavaDoc format. Andrew
guided us, figuring out all we had to do by the end of the semester. Andrew
also came up with a fix for InstrumentButton update problems. We were storing
the name in the button without extension, then the name with extension was
getting saved in the state. This should be fixed now because he and Jason
added it to their files, but all the files are on different accounts, so we
won't know for sure until next week when everyone checks in.
May 2
Jason:
Added JavaDoc documentation to designer and composer. Tested most recent
revisions of designer and composer.
Colin:
Added JavaDoc documentation to designer and composer.
Andrew:
Tried to remove empty directories in CVS and failed. (Agonizing.) Created
designer, composer, and util packages. Checked in newly packaged code:
musicsequencer/designer/*.*
musicsequencer/composer/*.*
musicsequencer/util/*.*
All other files in CVS are old, and most of them should be deleted.
Toby:
Tried to remove empty directories in CVS and failed. (Agonized with Andrew.)
Removed CVS aliases, which helped, but still didn't let us delete directories.
Generated JavaDocs for new code. (Works for newly packaged code!) Created
Music Sequencer homepage and added JavaDocs to it. (Yes, we have a homepage
now!)
Updated 2001-06-29. Copyright (c) 2001 Music Sequencer Group