417
edits
(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 | 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... |
edits