Efficient RAM use by a music engine
Moderator: Moderators
Efficient RAM use by a music engine
The music engine used for Concentration Room, and Thwaite uses about 66 bytes of state, yet the replay engines in .sid files allocate only about 20 bytes according to hyarion. Here's how my music engine currently allocates its memory:
psg_sfx_state: 32 bytes of zero page (26 used)
Channel last frequency: 1 byte per channel
Sound effect/percussion data pointer: 2 bytes per channel
Sound effect/percussion data length: 1 byte per channel
Music phrase data pointer: 2 bytes per channel
Order table data pointer: 2 bytes
soundBSS: 64 bytes of main memory (40 used)
Sound effect/percussion data rate: 2 bytes per channel
Instrument number: 1 byte per channel
Envelope current volume: 1 byte per channel
Current note pitch: 1 byte per channel
Current note remaining duration: 1 byte per channel
Current phrase number: 1 byte per channel
Phrase transposition: 1 byte per channel
Tempo: 4 bytes
Order table loop position ("segno"): 2 bytes
Rows left in order table entry: 1 byte
Global music pause: 1 byte
Is there something I appear to be doing horribly inefficiently?
psg_sfx_state: 32 bytes of zero page (26 used)
Channel last frequency: 1 byte per channel
Sound effect/percussion data pointer: 2 bytes per channel
Sound effect/percussion data length: 1 byte per channel
Music phrase data pointer: 2 bytes per channel
Order table data pointer: 2 bytes
soundBSS: 64 bytes of main memory (40 used)
Sound effect/percussion data rate: 2 bytes per channel
Instrument number: 1 byte per channel
Envelope current volume: 1 byte per channel
Current note pitch: 1 byte per channel
Current note remaining duration: 1 byte per channel
Current phrase number: 1 byte per channel
Phrase transposition: 1 byte per channel
Tempo: 4 bytes
Order table loop position ("segno"): 2 bytes
Rows left in order table entry: 1 byte
Global music pause: 1 byte
Is there something I appear to be doing horribly inefficiently?
DNSF2 only uses 5 bytes of ZP, but it uses 147 bytes of regular memory.
But then again, I was optimizing for CPU time, and I have features like subroutines, track volume, combined volume/duty envelopes, pitch envelopes, pitch bends, etc. This is also for 8 channels of sound, 4 channels forming one layer (for music), the other 4 for the sound effect layer.
Don't worry about SID music, a lot of times, the crazy-efficient players will be very constricting, and often times will be tracker based. It might be ram efficient, but how much memory does the song data take up?
But then again, I was optimizing for CPU time, and I have features like subroutines, track volume, combined volume/duty envelopes, pitch envelopes, pitch bends, etc. This is also for 8 channels of sound, 4 channels forming one layer (for music), the other 4 for the sound effect layer.
Don't worry about SID music, a lot of times, the crazy-efficient players will be very constricting, and often times will be tracker based. It might be ram efficient, but how much memory does the song data take up?
Re: Efficient RAM use by a music engine
Did any of those games run low on RAM? To the point where a dozen-or-two extra bytes would have mattered..?tepples wrote:The music engine used for LJ65, Concentration Room, and Thwaite uses about 66 bytes of state,
Your music engine is using about 3% of available RAM. I'd say that's just fine. Of course you could store your music data in a VGM-like format (values to write to the APU registers, mixed with delays) and get away with maybe 3 or 4 bytes of RAM per channel. But the music data would be huge.
If you wanted to use very low ram then you could go as low as :
1 pointer (2 bytes per channel)
1 counter (1 bytes per channel)
tempo (1 byte)
so you'd end up using a dozen of bytes, but then you would have crappy possibilities, no volume envelope, no vibrato, fixed duty cycle.
1 pointer (2 bytes per channel)
1 counter (1 bytes per channel)
tempo (1 byte)
so you'd end up using a dozen of bytes, but then you would have crappy possibilities, no volume envelope, no vibrato, fixed duty cycle.
Useless, lumbering half-wits don't scare us.
- Hamtaro126
- Posts: 783
- Joined: Thu Jan 19, 2006 5:08 pm
the smallest I've seen is what SMB1/VS/2j and the NES version of Spartan X (Kung Fu) uses mostly $F0-$FF (They share the same music engine).
But for me, SMBDIS allows Music RAM in these areas to easily go to places in Main RAM or Extended/Save RAM, such as $6000-$600f
Talk about portability!
But for me, SMBDIS allows Music RAM in these areas to easily go to places in Main RAM or Extended/Save RAM, such as $6000-$600f
Talk about portability!
AKA SmilyMZX/AtariHacker.
- neilbaldwin
- Posts: 481
- Joined: Tue Apr 28, 2009 4:12 am
- Contact:
Some, but they're of very little use.Dwedit wrote:Do SID chips have readable registers? Much RAM use in a NES music engine is from needing to have readable copies of the contents of the audio registers.
What you're missing here (especially comparing to SID) is that you've much more scope for using embedded variables and self-modifying code as the C64 is RAM-based as opposed to the NES being ROM-based.
Self-modifying code is ubiquitous in SID players.
- TmEE
- Posts: 789
- Joined: Wed Feb 13, 2008 9:10 am
- Location: Estonia, Rapla city (50 and 60Hz compatible :P)
- Contact:
I am making a sound system for SMS/GG right now, and I seem to be quite memory hungry, right now each channel uses 16 bytes of memory (but I do need more), and there's 4 of them. I also need some room for SFX etc.
I have set aside 256 bytes of RAM that the system can use up. With FM chip support I will probably do use up most of the 256 bytes.
I have set aside 256 bytes of RAM that the system can use up. With FM chip support I will probably do use up most of the 256 bytes.
- Jarhmander
- Formerly ~J-@D!~
- Posts: 521
- Joined: Sun Mar 12, 2006 12:36 am
- Location: Rive nord de Montréal
- neilbaldwin
- Posts: 481
- Joined: Tue Apr 28, 2009 4:12 am
- Contact:
Probably an inaccurate choice of phrase but what I meant was:~J-@D!~ wrote:Please explain what you mean by 'embedded variables'.neilbaldwin wrote:What you're missing here (especially comparing to SID) is that you've much more scope for using embedded variables and self-modifying code as the C64 is RAM-based as opposed to the NES being ROM-based.
because the C64 is RAM-based, you don't really need to apportion a section of RAM for your variables in the same way you do on the NES. So you could have (C64):
Code: Select all
lda #$01
sta myVariable
rts
myVariable: .db $00
lda #$02
sta myVariable
rts
lda myVariable
sta someHardwareRegister
rts
Or, self-modifying code:
Code: Select all
lda #$01
sta _myVariable+1
rts
lda #$02
sta _myVariable+1
rts
_myVariable:
lda #$00
sta someHardwareRegister
rts
So, it is what I have thought. I have thought of these things before, too, but I was not thinking of it in terms of C64.neilbaldwin wrote:Or, self-modifying code:
Code: Select all
lda #$01 sta _myVariable+1 rts lda #$02 sta _myVariable+1 rts _myVariable: lda #$00 sta someHardwareRegister rts
- Jarhmander
- Formerly ~J-@D!~
- Posts: 521
- Joined: Sun Mar 12, 2006 12:36 am
- Location: Rive nord de Montréal