This should be my last post for help before actually attempting to port a song into the Taito engine. Thus far I have a repository with song pointers, init routines, and note array data labeled for the Taito audio engine (Bubble Bobble). I wrote a small Python script to go through the game's NSF file and export notes and corresponding register values. These notes are put into a basic midi file and on my first or second go the exported midi was sounding pretty close to the real deal when guessing note durations.
Problem:
While the envelope, sweep, and frequency parts of the register values are making sense according to nesdev's APU definitions, I cannot make much of the note duration/length counter values. Specifically this table structure is not lining up with my findings. This game's basic structure of a pulse channel's note data array is as follows:
; Array of Note Structures (The most important part of structure is pointer to NoteData)
activityByte; if this is non-zero a different activity occurs. For 90% of notes this is zero and the note is initialized and played in linear order.
dutyEnvelopeByte; Directly corresponds to $4000 per this definition. The length counter halt never appears to be set.
sweepByte; This is often zero for basic pulse output but seems to be the value for $4001.
ptrToNoteData; When dereferencing this you reach two bytes of data.
;NoteDataPtr dereferences to.
4002Byte; When combining these two bytes for note data the math works out perfect for all note frequencies.
4003Byte; When taking the top 5 bits here to represent the length load counter I couldn't make sense of the values.
The length counter load values I see are 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, and 0x12. 0x06 appears the most throughout the theme song so I assumed this as a quarter note based on sheet music I found online that is pretty close. Unfortunately when I try and stay true to the length counter table on nesdev the song sounds out of whack.
Here are the first few notes in the song with their corresponding duration values:
('Bb5', '0x6')
('A5', '0x6')
('G5', '0x0')
('F5', '0x2')
('A5', '0x6')
('G5', '0x6')
('F5', '0x6')
('Eb5', '0x6')
('G5', '0x6')
('F5', '0x6')
('Eb5', '0x2')
('D5', '0x6')
('F5', '0x4')
The notes match up well to the expected when listening to the theme. These note values start at about 9 seconds after the small intro. When I reach the duration of 0x00 I am not sure what is going on. Any help is appreciated. If this post is not structured well let me know and I will re-read and try to make things shorter/clearer.
Problem:
While the envelope, sweep, and frequency parts of the register values are making sense according to nesdev's APU definitions, I cannot make much of the note duration/length counter values. Specifically this table structure is not lining up with my findings. This game's basic structure of a pulse channel's note data array is as follows:
; Array of Note Structures (The most important part of structure is pointer to NoteData)
activityByte; if this is non-zero a different activity occurs. For 90% of notes this is zero and the note is initialized and played in linear order.
dutyEnvelopeByte; Directly corresponds to $4000 per this definition. The length counter halt never appears to be set.
sweepByte; This is often zero for basic pulse output but seems to be the value for $4001.
ptrToNoteData; When dereferencing this you reach two bytes of data.
;NoteDataPtr dereferences to.
4002Byte; When combining these two bytes for note data the math works out perfect for all note frequencies.
4003Byte; When taking the top 5 bits here to represent the length load counter I couldn't make sense of the values.
The length counter load values I see are 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, and 0x12. 0x06 appears the most throughout the theme song so I assumed this as a quarter note based on sheet music I found online that is pretty close. Unfortunately when I try and stay true to the length counter table on nesdev the song sounds out of whack.
Here are the first few notes in the song with their corresponding duration values:
('Bb5', '0x6')
('A5', '0x6')
('G5', '0x0')
('F5', '0x2')
('A5', '0x6')
('G5', '0x6')
('F5', '0x6')
('Eb5', '0x6')
('G5', '0x6')
('F5', '0x6')
('Eb5', '0x2')
('D5', '0x6')
('F5', '0x4')
The notes match up well to the expected when listening to the theme. These note values start at about 9 seconds after the small intro. When I reach the duration of 0x00 I am not sure what is going on. Any help is appreciated. If this post is not structured well let me know and I will re-read and try to make things shorter/clearer.