Difference between revisions of "User:Buddha^/GSoC2007-ProjectDiary"

Jump to navigation Jump to search
Fixed link (palex.py -> agi-palex.py)
(Added more info on MIDI breakages with Apple IIGS MIDI resources (Mostly from King's Quest IV Apple IIGS version))
(Fixed link (palex.py -> agi-palex.py))
 
(58 intermediate revisions by the same user not shown)
Line 1: Line 1:
= [[User:Buddha^|Buddha^]]'s Google Summer of Code 2007 Project Diary =
Here's the archive of the project diary I kept during my
Google Summer of Code 2007 participation.
== 2007-05-28 (Monday) - GSoC starts! ==
== 2007-05-28 (Monday) - GSoC starts! ==


Line 646: Line 651:


So I made a tool for extracting palettes from Amiga AGI games' executable files
So I made a tool for extracting palettes from Amiga AGI games' executable files
and added it to ScummVM's trunk. You can see the source code [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/tools/palex.py?revision=28035&view=markup here].
and added it to ScummVM's trunk. You can see the source code [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/tools/agi-palex.py?revision=28035&view=markup here].
My first Python program, yay!
My first Python program, yay!


Line 1,094: Line 1,099:
== 2007-08-09 (Thursday) - Committed Apple IIGS instrument and wave file loading code ==
== 2007-08-09 (Thursday) - Committed Apple IIGS instrument and wave file loading code ==


Committed the Apple IIGS instrument and wave file loading code the the trunk.
Committed the Apple IIGS instrument and wave file loading code to the trunk.


Diffs:
Diffs:
Line 1,155: Line 1,160:
** 0xE0: 00000146 "Pitch Wheel" (Only used with parameter 0x2000 i.e. wheel center)
** 0xE0: 00000146 "Pitch Wheel" (Only used with parameter 0x2000 i.e. wheel center)
** 0xFC: 00000271 "Stop sequence" (No parameters for this, ends the stream)
** 0xFC: 00000271 "Stop sequence" (No parameters for this, ends the stream)
(Update on 2007-08-30: The numbers given above aren't totally correct as
I parsed delta-time as a variable length quantity - rather than a single byte
as it seems to be in these files - when I generated these statistics).


== 2007-08-17 (Friday) - First Apple IIGS sample playing! ==
== 2007-08-17 (Friday) - First Apple IIGS sample playing! ==
Line 1,181: Line 1,190:


== 2007-08-19 (Sunday) - Some more Apple IIGS MIDI hacking ==
== 2007-08-19 (Sunday) - Some more Apple IIGS MIDI hacking ==
=== Broken MIDI files ===


Seems like King's Quest II's starting song (Greensleeves, sound resource 0)
Seems like King's Quest II's starting song (Greensleeves, sound resource 0)
Line 1,239: Line 1,250:
00000045 00 98 43 7c
00000045 00 98 43 7c
</pre>
</pre>
King's Quest IV's MIDI sound resource 105:
<pre>
0000001a 00 b7 07 71
0000001e ec 94 3e 23 -- Here at 0x1e with 0xec again the same kind of breakage
00000022 00 95 4a 23
</pre>
King's Quest IV's MIDI sound resource 109:
<pre>
00000017 00 b3 07 78
0000001b 93 93 31 4e -- Here at 0x1b with 0x93 again the same kind of breakage
0000001f 02 91 59 52
</pre>
King's Quest IV's MIDI sound resource 207:
<pre>
0000001a 00 b5 00 78
0000001e 8a 95 3e 54 -- Here at 0x1e with 0x8a again the same kind of breakage
00000022 03 40 41 05
</pre>
Mixed-Up Mother Goose's MIDI sound resource 7:
<pre>
0000003d 00 b8 07 73
00000041 95 92 43 6f -- Here at 0x41 with 0x95 again the same kind of breakage
00000045 00 95 4f 66
</pre>
Mixed-Up Mother Goose's MIDI sound resource 37:
<pre>
0000003d 00 b8 07 72
00000041 96 92 47 76 -- Here at 0x41 with 0x96 again the same kind of breakage
00000045 00 95 53 73
</pre>
=== Possible explanation for the broken MIDI files ===
It might just be that Apple IIGS AGI MIDI files don't use a variable
length quantity for the delta-time but always use a single byte delta-time
which *can* be >= 0x80! Investigating... (If this is so then it's a non-standard
behaviour for a MIDI file)
Update! Okay, so it seems these MIDI files don't use variable length quantities
for delta-time. Delta-time is always one single byte even if it might be >= 0x80.
But! That delta-time byte also acts as a shorthand for commands like 0xFC
(Stop sequence) or 0xF8 (Timer sync).
So let's read a single byte from the stream. If it's 0xFC it stops the
sequence right there. If it's 0xF8 we can probably just jump over it as we
probably don't need it. Otherwise you use the byte's value as a delta-time
and then you read the command byte, parameters etc normally (Running status
is also used). At least this is my current theory based on experiments with
a Python program I wrote for parsing these MIDI files.
I checked some files and yes it really does seem we do need to check for end
of sequence (0xFC) before reading the delta-time as some files do use 0xFC
where the delta-time would be.
=== I'm going bughunting... be vevy vevy quiet! ===
I wasn't planning on going bughunting but as I tried to submit
my MIDI parsing/stepping-through code into SVN I found out that
sound didn't work with AGI in the SVN. Possibly Fingolfin inadvertently
broke it with the OOficiation/clean-up -commits to the AGI's sound code
or made the bug somehow come up more easily (At least AFAIK it
didn't crash like that before ;-)). Well, in the wee hours I disgruntently
tried to fix the bug and at last I succeeded (Here's the [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28671&r2=28672&sortby=date diff]
for the fix. The crash was happening because the PCjr sound mixing code tried to use uninitialized values (e.g. phase, ins) when mixSound was called before anything was playing).
Come to think of it I'm not really sure how it has been able to *not* crash before :).
After fixing the crashing bug I got to the point where I could commit
the MIDI parsing/stepping-through code into the SVN. Whee, it's not
perfect (Speed's probably off), it doesn't use the MIDI classes yet etc,
but it steps through the MIDI files (That aren't totally standard) hopefully
quite correctly :).
== 2007-08-20 (Monday) - Juryrigged Apple IIGS MIDI output for first sound testing! ==
Juryrigged the Apple IIGS MIDI parsing code to fill the sound buffer with a sine wave
when encountering a Note On -command in the MIDI stream (Using the Note On -command's
note frequency data to adjust the sine wave's frequency too). What sounds I got :-)
heh, but at least I recognized the Greensleeves -theme from King's Quest II's intro ;).
Hopefully the wiki's upload file functionality will be working again in the near
future so I could upload a sample of the buzzes I saved from the testings :).
Later today I thought about the mixing stuff and I'm thinking it quite probable that
we'll hear some real samples soon! (Not possibly the correct samples yet because
the Program Change -command's parameter isn't deciphered yet so I'm not certain what
instrument should go where).
== 2007-08-21 (Tuesday) - Oscillator mode comparison etc ==
Compared the used oscillator modes in the Apple IIGS AGI games from
both the instruments and samples:
I found these used combinations of modes:
* Both waves (A and B) in an oscillator use the same mode:
** Oneshot (Used very much by samples and by a few instruments (Probably drums, I presume))
** Loop (Used quite much by samples, very much by instruments)
** Loop + Halt (The only thing using this is the unique instrument that has four oscillators)
** Swap (The only thing using this is the unique instrument that has four oscillators)
* Waves A and B in an oscillator use different modes:
** Oneshot / Loop + Halt (Used quite much by samples and by a few instruments)
** Loop / Loop + Halt (The only thing using this is Police Quest I's sample 12)
** Swap / Swap + Halt (The only thing using this is Gold Rush's sample 60)
This means I can ignore the Sync (Amplitude Modulation) oscillator mode for now
as it's not used by at least the Apple IIGS AGI games I tested. And ignoring the
Swap oscillator mode isn't going to hurt much *if* the one unique instrument that
has four oscillators isn't used much (I don't know how much it's used yet though,
so there's still a bit of a risk). Oh, and I do presume the Gold Rush's sample 60
isn't used very widely :-) (It's a sound of a horse's hoof hitting pavement).
== 2007-08-22 (Wednesday) - My birthday! ==
This is my birthday! Yay! Spent most of the day with my family, played with
my niece (We were a bunny family and we were scared of the wolves around our
house so we called the police who came and locked the wolves into prison and
shot the ones that tried to run away :-)), had some coffee and cake, went
to sauna and watched Zorba The Greek during the late evening.
Oh and I discovered/realized that at least Apple IIGS King's Quest I's volume
files are not encrypted. So I can just go and write new MIDI codes straight
into the files and run the game through an emulator to try to hear what
program change corresponds to what instrument. Whee :-) This is good.
== 2007-08-23 (Thursday) - Investigating MIDI controller commands and instruments ==
Used Python to write test MIDI data into Apple IIGS King's Quest I's disk image
(Straight onto the MIDI sound resource number 0 i.e. the intro song) and ran it through MESS
and KEGS32. It seems you can use just about any controller on a channel and all
it does is change its volume :-). So controller 0, 7, 64, whatever, they seem to
be only for changing volume (Haven't done extensive testing yet, so it is possible
they may act differently in some situations).
Wrote some test MIDI data to see what the program changes do. They seem to change
the instrument played on a channel, that's for sure, but I'm not yet sure of the
mapping between the program change parameter and the instrument number.
Also tried varying the velocity of note on and note off commands (Used program 36
on channel 0). It didn't do jack :). But! As the velocity information *is* there,
it might be used even if Apple IIGS AGI didn't use it (There's of course the possibility
that the emulators just mess it up somehow, but MESS should be quite good, eh?-)).
So we might even hear more articulate versions of the songs using ScummVM if we'll
use the velocity info! We shall see...
== 2007-08-28 (Tuesday) - Reverse engineering the program change to instrument mapping ==
Been trying to reverse engineer the Apple IIGS AGI MIDI files' program change command's
parameter value to instrument number mapping recently. Tried a few approaches that didn't work
but came up with a way that works quite well. Here's the preliminary mapping from
program numbers to instrument numbers (Instrument number 6 seems to be mostly used to
mean an "undefined instrument" or a "not used instrument"):
=== Preliminary MIDI program change to Apple IIGS AGI instrument mapping ===
Programs 0-9:
* Instruments: 21, 22, 24, 25, 23, 26, 6, 6, 6, 6
Programs 10-19:
* Instruments: 7, 9, 12, 8, 13, 11, 17, 10, 6, 6
Programs 20-29:
* Instruments: 19, 18, 20, 14, 16, 6, 6, 6, 6, 6
Programs 30-39:
* Instruments: 0, 1, 2, 4, 3, 5, 17, 2, 2, 2
** The trailing 2's are probably somehow modified so they don't sound identical
Programs 40-49:
* Instruments: 27, 15, 15, 27, 6, 6, 6, 6, 6, 6
I'd venture that the used instruments in different base 10
parts (First ten programs, second ten programs etc) are
different instrument categories (e.g. programs 20-29 are
for drums). Haven't yet tested this but it would seem logical.
Oh and this preliminary mapping is for the newer Apple IIGS AGI instrument set (i.e.
used by all other test subjects except Space Quest I).
== 2007-08-29 (Wednesday) - Program changes comparison etc ==
Here's some info about the Apple IIGS AGI MIDI files' program changes:
Older Apple IIGS AGI instrument set: (Space Quest I, AGI v1.002):
* Used programs: [0, 1, 2, 4, 5, 10, 16, 20, 22, 32, 33, 36, 38, 39, 40]
* Unused programs (Range 0-43): [3, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 34, 35, 37, 41, 42, 43]
Newer Apple IIGS AGI instrument set: (All others together, AGI v1.003+):
* Used programs: [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43]
* Unused programs (Range 0-43): [6, 7, 8, 9, 17, 18, 19, 25, 26, 27, 28, 37]
Not using programs 6-9 and 18-19 makes sense because they use
the instrument 6 that seems and sounds somewhat weird.
Not using programs 25-29 would make sense for the same reason
but it seems program 29 is used... by only Manhunter I's MIDI
sound resources 116 and 142! So it *might* be only a fluke but
not necessarily so.
Programs 32 and 37-39 seem to use the same instrument but still
sound different. Although program 37 seems not to be used
at all there are still programs 32, 38 and 39 to look into.
Maybe some additional tweaking somewhere else than in the
instrument data?
Programs 40 and 43 use the same samples and probably the same instrument.
Same goes for programs 41 and 42. Gotta investigate them more closely too...
As a sidenote program 17 seems ok but for some reason it seems not to be used
at all. Maybe just not a particularly popular instrument?-)
== 2007-08-30 (Thursday) - SIERRASTANDARD investigation etc ==
The Apple IIGS AGI uses a file named SIERRASTANDARD that holds
the sample data used by the instruments. It's 65536 bytes in size,
it holds 8-bit unsigned sample data and all the different samples
start on 256 byte boundaries. None of the SIERRASTANDARD files I've
tested have zeroes in them (A zero would mark a premature end of a sample).
After some investigation (Looking at the file rawly imported into Audacity) etc
here's some info on it (This info applies directly to the newer SIERRASTANDARD
file used with Apple IIGS AGI v1.003+. There are some little differences in
the older SIERRASTANDARD file that's used at least with Space Quest I (AGI v1.002)):
=== Samples in the newer SIERRASTANDARD file ===
* Number of samples (Not all unique!):
** 34
* Sample redundancy (May be incomplete):
** Samples 18 and 30 are identical (A base drum)
** Samples 21 and 31 are identical (Sounds like a drum stick hit)
** Samples 24 and 32 are identical (Sounds like hihat)
** Samples 27 and 33 are identical (Sounds quite like a shaman drum)
* "Dummy" samples
** Sample 4 is full of byte 0x50 (i.e. about -0.38 if amplitude is normalized to range [-1, +1])
* Unused samples (i.e. not used by the instrument data. May be incomplete):
** None of the instruments in either the older or the newer instrument set use samples 29-33
*** This means we could theoretically ditch the last 16KiB of the SIERRASTANDARD file
** None of the instruments in the older instrument set use samples 2-4
** None of the instruments in the newer instrument set use sample 4
* Sample sizes log2 (2**x will give the true sample size):
** sampleSizesLog2 = [10, 10, 10, 9, 9, 10, 10, 10, 10, 10, 10, 11, 10, 10, 10, 10, 10, 10, 11, 10, 10, 11, 10, 10, 11, 10, 10, 11, 14, 13, 11, 11, 11, 11]
* Sample sizes (This table can be calculated from the sample sizes log2):
** sampleSizes = [1024, 1024, 1024, 512, 512, 1024, 1024, 1024, 1024, 1024, 1024, 2048, 1024, 1024, 1024, 1024, 1024, 1024, 2048, 1024, 1024, 2048, 1024, 1024, 2048, 1024, 1024, 2048, 16384, 8192, 2048, 2048, 2048, 2048]
*** Way to calculate this with Python: sampleSizes = map(lambda x: 2**x, sampleSizesLog2)
*** Note that sum(sampleSizes) should always be 65536 (The size of SIERRASTANDARD)
* Sample positions (This table can be calculated from the sample sizes):
** samplePos = [0, 1024, 2048, 3072, 3584, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 12288, 13312, 14336, 15360, 16384, 17408, 18432, 20480, 21504, 22528, 24576, 25600, 26624, 28672, 29696, 30720, 32768, 49152, 57344, 59392, 61440, 63488]
*** Way to calculate this with Python:  samplePos = [sum(sampleSizes[:end]) for end in xrange(len(sampleSizes))]
=== Differences between the older SIERRASTANDARD and the newer SIERRASTANDARD file ===
Here are all the differences between the older and the newer SIERRASTANDARD file:
* Sample 2 (Offsets 2048-3071) differs between SIERRASTANDARD versions
** Sample data
*** The older version of sample 2 starts with some real sample data but a bit over half of it is completely silent (i.e. centerline i.e. byte 0x80)
*** Newer version of sample 2 contains real sample data
** Instrument usage
*** None of the instruments of the older instrument set use sample 2
*** Instruments 19 and 20 of the newer instrument set use sample 2
* Sample 3 (Offsets 3072-3583) differs between SIERRASTANDARD versions
** Sample data
*** The older version of sample 3 is full of byte 0x50
*** The newer version of sample 3 contains real sample data
** Instrument usage
*** None of the instruments of the older instrument set use sample 3
*** Instrument 4 of the newer instrument set uses sample 3
* Sample 17 (Offsets 17408-18431) differs between SIERRASTANDARD versions
** Sample data
*** Both versions of SIERRASTANDARD use real sample data here
*** Newer version's sample has a higher pitch than the old version and the wave looks more triangle like
** Instrument usage
*** Instruments 5 and 18 of the older instrument set uses this sample
*** Instrument 6 of the newer instrument set uses this sample
* Sample 27 (Offsets 30720-32767) differs between SIERRASTANDARD versions
** Sample data
*** The older version of sample 27 consists mostly of silence (Byte 0x80) followed by some 0x0F
*** The newer version uses real sample data here (Identical to the last sample i.e. sample 33)
** Instrument usage
*** Instruments 5 and 23 of the older instrument set use this sample
*** Instruments 6 and 25 of the newer instrument set use this sample
== 2007-12-11 (Tuesday) - End of GSoC 2007 project diary ==
I thought I'd add a clarifying end note to my project diary. I'm not going to update the
diary anymore but I leave it here for archival purposes. It might prove an interesting or even
a useful read for someone else applying for GSoC in ScummVM. It was a good ride...
417

edits

Navigation menu