|
ForumsSega Master System / Mark III / Game GearSG-1000 / SC-3000 / SF-7000 / OMV |
Home - Forums - Games - Scans - Maps - Cheats - Credits Music - Videos - Development - Hacks - Translations - Homebrew |
Author | Message |
---|---|
|
Banjo - SMS music and sfx driver using Furnace
Posted: Thu Mar 21, 2024 4:53 pm
|
I wrote a basic sound driver for my SMS compo entry Shootagem last year and I've spent the last couple of months trying to get it to a place where it supports SDCC/SDAS, can play back more effects and is hopefully a bit more user friendly! I've called it Banjo cause that's a musical instrument which has a bit of my name in it.
Github link is here: https://github.com/joffb/banjo Youtube video of the "visualiser" example (uses DevkitSMS): It supports SN7 and OPLL (both normal and rhythm modes) and can play back a song and one sound effect at a time. Sound effects are limited to one channel, but they're essentially played back as little songs so they both support the same features. You set up tables of songs and sfx (you can have different ones for different chips) then queue songs and sfx by their index in the table. The banjo_update function should run once a frame and handles the queues and updates playback. It's not a VGM format - stuff like arpeggios, slides and vibrato are all done in software, so it takes more CPU time but less ROM space. The format mirrors the Furnace one, so it uses lines, patterns and orders like the tracker. If a channel's pattern is repeated, the data is only stored once. It uses a couple of python scripts to get songs/sfx into the correct format. furnace2json converts Furnace .fur files to a big json file, then json2sms converts that json to an asm or c file. The output file isn't just binary, it uses defines and labels in asm and structs in c so you can see what the format looks like, including the commands, like a pattern looks like unsigned char const cmajor_sn_patterns_0_0[] = {
INSTRUMENT_CHANGE, 4, VOLUME_CHANGE, 144, NOTE_ON, 43, (END_LINE | 3), NOTE_ON, 52, (END_LINE | 1), NOTE_ON, 53, (END_LINE | 1), NOTE_ON, 55, (END_LINE | 3) ... }; |
|
|
Posted: Thu Mar 21, 2024 7:35 pm |
that is cool, but 4000 bytes for the driver and 400 bytes ram usage... do you think it is possible to make it smaller?
I think it is very possible to integrate it with gbdk-2020/zgb: https://www.smspower.org/forums/20004-ZGBLibraryForTheSMSGG May i do that? Repo does not mention any license. |
|
|
Posted: Fri Mar 22, 2024 1:38 am |
Good point about the license - I've gone ahead and MIT licensed it. It should be compatible with most licenses and also means people are free to use it for games they want to sell. Would you include the banjo repo as a submodule in the ZGB repo?
I'm sure some size can be trimmed from the code. As it handles three types of channel (SN7, OPLL and OPLL rhythm) there'll probably be places where some code can be moved to apply to all of them. Could potentially lose some RAM from the music state. Channels are the bulk of the ram usage though - I've tried my best to keep them capped out at 32 bytes each |
|
|
Posted: Fri Mar 22, 2024 6:54 am |
no, because that mean compiling and so on, and ZGB make system is not too simple to complicate it even further. as made for the hUGEDriver and GBT Player i am planning to include the compiled driver as an object, and include the python conversion tools together with license into the toolchain similar way: https://github.com/untoxa/ZGB/tree/develop/tools/mod2gbt i think i have to modify the driver a bit - simplify API a bit (remove song tables, just pass the pointer to struct), because of how ZGB handles the music assets... |
|
|
Posted: Fri Mar 22, 2024 8:23 am |
Very interesting. How does banjo do performance-wise? How many scanlines per frame does updating the channels take (PSG, FM, both)?
And how did you solve the problem with FM sfx? Afaik, you can't stop FM notes and pick them back up in the same spot of the ADSR envelope, so you either start them anew in the wrong place or keep the channel silent until the next note is played. In MBMplay I opted for the latter, but it requires the composer to keep this in mind and leave room for sfx by having a channel where disruption doesn’t do much damage. |
|
|
Posted: Fri Mar 22, 2024 10:15 am |
This is really nice! Great work! :D
I'm looking at the code and I will do some tests later, and I'm also very interested in gauging the performance, as Kagesan.
Could be a binary file output also a third option or do the songs need to be compiled together with code to work? I'm wondering if they could be handled like the other regular assets from devkitSMS for instance... |
|
|
Posted: Sat Mar 23, 2024 11:04 am |
Emulicious has a nice profiler, so it is rather easy to tell how fast the driver is. The average banjo_update_song() call is only 3330 cycles which is more than fine for the homebrew! Not taking into account the advantages of the tracker structure of the music over the huge VGM dumps!
|
|
|
Posted: Mon Mar 25, 2024 12:40 am |
Both SN and FM just keep the channel silent - definitely didn't want to retrigger the FM envelope and in most cases with the SN a volume macro will pick the sound back up afterwards.
Not with how it's currently written - it uses the assembler/linker to calculate the location of the instruments/macros/patterns so it doesn't have to add the relative position of the pattern or whatever to the address of the start of the song. Have been doing some work on it over the weekend with toxa to help get it working with ZGB so you don't have to use the queue system and how its banking works, you can change banks yourself and use the banjo_play_song/sfx and banjo_update_song/sfx functions |
|
|
Posted: Mon Mar 25, 2024 8:49 am |
I thought so. Thanks! :) |
|