Has anyone had any experiences where they'd go back to old programs they wrote and admire how much they improved in some way? Alternatively, has anyone had any experiences where they'd go back to old programs they wrote and think "Oh gosh, what a idiot I was back then. If I was to do this now, I'd..." and so on? If so, I thought it'd be neat if we could share them here.
Backstory.
So as anyone who checks my profile on a regular basis knows, I'm programming a virtual instrument. I managed to get the program to its first milestone a couple of months ago. Since then, most of my time has been spent writing a MIDI (.mid) file parser. After spending nearly two months on that one part of the program alone my coding style had changed quite a bit. I began to spend more time analyzing my own code between compilations looking for errors myself, I didn't feel as guilty as I used to about declaring new types, I began to make a much more liberal use of enumerations, and overall my coding style changed quite a bit. I think it's for the better.
Partway though writing the MIDI file parser, I had an idea to add another type of sound wave to my program: an oval wave. I figured it'd add a rather interesting sound.
The part of the synthesizer that handles simple periodic waves is (if I may say so myself) very well-written. It took me about 3 minutes to add the wave into the system and add a user interface button so that one could easily select it. However, after testing the wave, I noticed a significant bug in the development branch. I searched around, and realized that it was in the class I wrote to composite samples and to manage the sound generators and effects. Part of the "management" duty of that class is to record and relay note on/off events to the sound generators. That apparently was where the problem lay. I opened the implementation file for the class, and literally my first thought was
"Who in the nine hells wrote this class? It definitely wasn't me. It must've been the gremlin I saw hanging around my porch the other night."
Although I did keep documentation for the class, it did suffer from some readability issues. As an example, here's one of the member functions from the class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
void Synth::noteOn(int halfsteps, sbSample amp) {
if (amp <= 0.0)
return;
for (size_t i = 0; i < notes.size(); ++i) {
if (notes[i].second.first == 0.0) {
notes[i].first = halfsteps;
notes[i].second.first = amp;
if(holdped && !notes[i].second.second)
notes[i].second.second = 'h';
else
notes[i].second.second = false;
for (size_t ation = 0; ation < channelcount; ++ation) {
if (gener[ation] != NULL) //Older/cynical programmers: This does NOT unconditionally evaluate to false.
gener[ation]->noteOn(halfsteps,amp,i);
}
break;
}
}
}
|
Gruesome, isn't it? Without the documentation, I myself wouldn't remember what holds what.
So I spent some time changing that class to better fit my new coding style. Here's how that function looks now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
void Synth::noteOn(int halfsteps, sbSample amp) {
if (amp <= sbSampleZero)
return;
for (size_t i = 0; i < notes.size(); ++i) {
if (notes[i].amp == sbSampleZero) {
notes[i].noteoffset = halfsteps;
notes[i].amp = amp;
if(holdped && notes[i].pedal == NoPedal)
notes[i].pedal = Hold;
else
notes[i].pedal = NoPedal;
for (size_t ation = 0; ation < channelcount; ++ation) {
if (gener[ation] != nullptr)
gener[ation]->noteOn(halfsteps,amp,i);
}
break;
}
}
}
|
Much better, no? :)
-Albatross