Add most recent novoices findings.

Subversion-branch: /research
Subversion-revision: 1666
This commit is contained in:
Simon Howard 2009-09-12 15:46:06 +00:00
parent 6d81e82c4b
commit d8df0ff0c0
4 changed files with 1835 additions and 0 deletions

View file

@ -1,3 +1,25 @@
Investigating how Doom decides on a voice to discard when it runs out
of OPL voices.
Findings so far:
* The instrument affects the voice that is released (different instruments
give different results). It is the instrument data that is significant,
not the instrument number (identical instruments behave the same - 87/88)
* Sometimes notes are not turned off when they should be. Sometimes notes
are turned off when they should not be (bug?)
* DMX maintains a linked list of the most recently-allocated voices. These
are searched backwards when finding a voice to free, so the most recently
allocated voices are the first to be freed.
* Different MIDI channels have different "priorities", somehow affected
by the instrument in use on that channel.
* When no voices are available, the will search back through the allocated
voices list and discard the most recently used voice from a channel of
a lower priority to the channel for the new note.
* If no lower-priority voices are available, a voice from the same
channel will be discarded.
* If no voices from lower priority channels are available, and none from
the same channel, the first voice in the list is discarded, ignoring
priority.
* The "total level" field for the instrument does NOT determine priority.

91
opl/novoices/gen-sequence5 Executable file
View file

@ -0,0 +1,91 @@
#!/usr/bin/env ruby
def note_on(delay, channel, note, volume)
# note on
putc delay * 6
putc 0x90 + channel
putc note
putc volume
end
def note_off(delay, channel, note)
# note on
putc delay * 6
putc 0x80 + channel
putc note
putc 0x00
end
def program_change(delay, channel, instrument)
putc delay * 6
putc 0xc0 + channel
putc instrument
end
program_change(0x1, 8, 9)
program_change(0x1, 1, 7)
program_change(0x1, 2, 7)
# Turn on some notes and then turn them off, to boost us
# up to the middle of the range of operators.
note_on(0xf, 8, 0x20, 0x40) # voice 1
note_off(0xf, 8, 0x20)
note_on(0xf, 8, 0x21, 0x40) # voice 2
note_off(0xf, 8, 0x21)
note_on(0xf, 8, 0x22, 0x40) # voice 3
note_off(0xf, 8, 0x22)
# Play some notes until we use up all the OPL operators.
note_on(0xf, 8, 0x20, 0x40) # voice 4
note_on(0xf, 1, 0x21, 0x40) # voice 5
note_on(0xf, 2, 0x22, 0x40) # voice 6
note_on(0xf, 8, 0x23, 0x40) # voice 7
note_on(0xf, 1, 0x24, 0x40) # voice 8
note_on(0xf, 2, 0x25, 0x40) # voice 1
note_on(0xf, 8, 0x26, 0x40) # voice 2
note_on(0xf, 1, 0x27, 0x40) # voice 3 3-2-1-8-7-6-5-4
# Now all voices are in use ...
# "no alt" = no inferior channels, first voice from same channel used
note_on(0xf, 8, 0x28, 0x40) # gets v2 2-3-1-8-7-6-5-4 chan 8 < chan 1 (no alt)
note_on(0xf, 1, 0x29, 0x40) # gets v2 chan 1 > chan 8
note_on(0xf, 2, 0x2a, 0x40) # gets v7 7-2-3-1-8-6-5-4 chan 8 < chan 1+2
note_on(0xf, 8, 0x2b, 0x40) # gets v4 4-7-2-3-1-8-6-5 chan 8 < chan 1+2 (no alt)
note_on(0xf, 1, 0x2c, 0x40) # gets v4 chan 1 > chan 8
note_on(0xf, 2, 0x2d, 0x40) # gets v7 7-4-2-3-1-8-6-5 chan 2 < chan 1 (no alt)
note_on(0xf, 8, 0x2e, 0x40) # gets v7 chan 8 > chan 2? (no alt?)
note_on(0xf, 1, 0x2f, 0x40) # gets v7 chan 1 > chan 8
note_on(0xf, 2, 0x30, 0x40) # gets v1 1-7-4-2-3-8-6-5 chan 2 < chan 1 (no alt)
note_on(0xf, 8, 0x31, 0x40) # gets v1 chan 8 > chan 2? (no alt?)
# voices off: 5, 7, 1, 3, 2, 8, 6, 4, 0
note_off(0xf, 8, 0x20)
note_off(0xf, 1, 0x21)
note_off(0xf, 8, 0x22)
note_off(0xf, 1, 0x23)
note_off(0xf, 8, 0x24)
note_off(0xf, 1, 0x25)
note_off(0xf, 8, 0x26)
note_off(0xf, 1, 0x27)
note_off(0xf, 8, 0x28)
note_off(0xf, 1, 0x29)
note_off(0xf, 8, 0x2a)
note_off(0xf, 1, 0x2b)
note_off(0xf, 8, 0x2c)
note_off(0xf, 1, 0x2d)
note_off(0xf, 8, 0x2e)
note_off(0xf, 1, 0x2f)
note_off(0xf, 8, 0x30)
note_off(0xf, 1, 0x31)
# end of track
putc 0x00
putc 0xff
putc 0x2f
putc 0x00

BIN
opl/novoices/novoices5.mid Normal file

Binary file not shown.

File diff suppressed because it is too large Load diff