GGSound: a lightweight sound engine for games

Discuss NSF files, FamiTracker, MML tools, or anything else related to NES music.

Moderator: Moderators

Post Reply
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

GGSound: a lightweight sound engine for games

Post by GradualGames »

GGSound is a lightweight sound engine for NES games. It can do most of the things you hear in games from the 80's and 90's. It comes with a converter which can convert FamiTracker text exports into asm data for use with GGSound.

Thanks to zxdplay for using GGSound in StarKeeper, this inspired me to keep improving my sound engine and continue to make it available for others.

GGSound can be cloned or downloaded from the Github repository.

There is also a snapshot available on this post, but from now on please use the Github repository.

Features:
-Exporter for FamiTracker text exports
-Works with nesasm3, asm6 and ca65
-Square 1, 2, Triangle, Noise, and DPCM channels
-Volume, Arpeggio, Pitch and Duty envelopes
-Looping envelopes at an arbitrary loop point
-Speed and Tempo
-Looping with the Bxx (must be present in all channels, in unique patterns) command
-Note cuts
-Tempo and pitch adjustment for NTSC, PAL, and Dendy
-Multi-song export
-Sound effects on two channels
-Pause/unpause
-All 87 audible notes in FamiTracker
-No FamiTracker channel effects can be used, only envelopes/macros
-128 of each type of envelope
-128 songs
-128 sound effects
-256 byte long envelopes

You can watch a short intro video for how to use GGSound in a NESASM3 program here:
https://youtu.be/Unc3veECcxc
Attachments
ggsound-master.zip
(147.46 KiB) Downloaded 376 times
Last edited by GradualGames on Mon Jan 15, 2018 7:20 am, edited 35 times in total.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: Gradual Games Sound Engine re-release

Post by GradualGames »

NOTE: The below is obsolete, see OP for most up to date information on GGSound.

I'm coming very close to having a nice new version of my sound engine ready. Updates include:

-1:1 tempo mapping between FamiTracker and my sound engine
-Loop point implementation for envelopes.
-Support for NTSC and PAL, including tempo adjustment from the converter script and correct pitch values for each region
-Multi song export with the converter script, including a facility which interprets all tracks prefixed as sfx_ to be a sound effect, and modifies them accordingly to terminate after the longest envelope finishes (so, loops are ignored for sound effects by default).
-Better song compression. Repeated patterns are re-used.
-Shared envelopes for your entire song/sound effect collection for more efficient ROM space usage.
-support for B00 to loop your song at a point other than the end of your last frame
-sound effects temporarily cancel the playing note on the channel that they overlay, to help reduce ugly volume shifts

Still no arpeggios or DPCM---primarily because I do not intend to use either in my own projects. If you try out GGSound and enjoy its features and ease of use, but would like these features, please post in this thread and I will add them.

Given that there are already several nice solutions around such as FamiTone2, would there be any interest in yet another sound solution, including versions for nesasm and asm6?

The only substantial advantage that I know of between my sound engine and FamiTone2, is that FamiTone2's converter (with my own music anyway) frequently outputs a note range error, which does not happen with my converter script or engine. I assume this was due to a design decision for efficient packing of data on Shiru's part rather than a flaw, but this particular quirk of FamiTone2 pushed me to update my engine to support the features I wanted from FamiTone2.

Another advantage I've learned about from reading others' posts is that it is a little trickier to use sound effects with FamiTone2. GGSound makes this very easy. Just prefix your song name with sfx_ and the converter does the rest.

If there seems to be any interest out there I'll go ahead and prepare a public version of the engine.
Last edited by GradualGames on Mon Mar 21, 2016 6:24 am, edited 3 times in total.
Erockbrox
Posts: 397
Joined: Sun Nov 23, 2014 12:16 pm

Re: GGSound: a lightweight sound engine for games

Post by Erockbrox »

There is interest! :)
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: GGSound: a lightweight sound engine for games

Post by GradualGames »

OP updated. GGSound is now available for ca65, asm6 and nesasm3. There's a readme file, and a quick youtube video showing how to use it with nesasm3. Please use this thread for bug reports or other feedback.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: GGSound: a lightweight sound engine for games

Post by Memblers »

I tried to make an NSF init and play routine, but it's not working yet, can you tell what I screwed up?

Code: Select all

nsf_play:

    jsr sound_update
    jsr sound_upload

   rts


nsf_init:
    sta current_song
    ;initialize modules

    lda #0 ; region, don't care
    sta sound_param_byte_0
    lda #<(song_list)
    sta sound_param_word_0
    lda #>(song_list)
    sta sound_param_word_0+1
    lda #<(sfx_list)
    sta sound_param_word_1
    lda #>(sfx_list)
    sta sound_param_word_1+1
    jsr sound_initialize

    ;load a song
    lda current_song
    sta sound_param_byte_0
    jsr play_song

    rts
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: GGSound: a lightweight sound engine for games

Post by GradualGames »

Hmm, I'm not really sure what could be wrong...that all looks right to me. The only possibility I can think of is perhaps an nmi is firing before anybody sets sound_update_disable to a known state...that could potentially mess things up. I may want to introduce some kind of module init prior to the sound init that can be used before nmi is ever turned on to ensure this isn't a problem. Can you let me know any more context of how you're integrating ggsound? Which of the three versions are you using and how is it being used? I don't think I've ever looked into how NSF players are supposed to work---perhaps there are requirements I never thought about, though I have no reason to believe this engine couldn't be adapted to work as one.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: GGSound: a lightweight sound engine for games

Post by Memblers »

D'oh, nevermind, the problem was located between my seat and my keyboard. I was manually putting the NSF header on, and I accidentally left the iNES header on. I took it off the first time but I screwed up elsewhere, fixed that, but left the iNES header on next build. Whoops. As I figured, the more confounding the problem is, the more likely it's something really dumb.

NSF format works by specifying 3 addresses, load, init and play. Load is just where the file is loaded in memory, init gets called with the song number in A, then the play address gets called at the frame rate. It shouldn't be possible for the play address to run first, and NSF format doesn't include NMI or IRQ support (usually the vectors aren't even in the file).

I added it to my NSF benchmarking thread. It looks at CPU usage only.
viewtopic.php?f=6&t=13580&p=160061

Thanks for sharing, it never hurts to have more sound options.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: GGSound: a lightweight sound engine for games

Post by GradualGames »

Cool, thanks for adding it to that thread Memblers!
User avatar
Hamtaro126
Posts: 818
Joined: Thu Jan 19, 2006 5:08 pm

Re: GGSound: a lightweight sound engine for games

Post by Hamtaro126 »

There is a problem... a song I wanted to convert from text is working, but the song seems to go EXTREMELY slow in your engine...

I've tried changing both the song default tempo and using the tempo command... nothing works!
AKA SmilyMZX/AtariHacker.
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: GGSound: a lightweight sound engine for games

Post by GradualGames »

I've encountered this problem before with other adopters. It turned out that he was using Python 2 rather than Python 3 to run the converter script. What version of Python are you using?
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: GGSound: a lightweight sound engine for games

Post by rainwarrior »

If the version of python is critical, you might want to check for that in the script, e.g.

Code: Select all

#!/usr/bin/env python3
import sys
assert sys.version_info[0] >= 3, "Python 3 required."
User avatar
GradualGames
Posts: 1106
Joined: Sun Nov 09, 2008 9:18 pm
Location: Pennsylvania, USA
Contact:

Re: GGSound: a lightweight sound engine for games

Post by GradualGames »

rainwarrior wrote:If the version of python is critical, you might want to check for that in the script, e.g.

Code: Select all

#!/usr/bin/env python3
import sys
assert sys.version_info[0] >= 3, "Python 3 required."
Thanks for the tip, much appreciated!
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: GGSound: a lightweight sound engine for games

Post by rainwarrior »

The #! hashbang line should be the first line in the file. On some systems it can sort out which version of Python to run.

The assert you can put anywhere you want it to check, but probably want that near the top as well.

After looking it up, this might be is an alternative, but not a better #! line: Edit: tepples explains below why the /usr/bin/env version is preferred.

Code: Select all

#! python3
Last edited by rainwarrior on Fri Jan 15, 2016 6:12 pm, edited 1 time in total.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: GGSound: a lightweight sound engine for games

Post by tepples »

I guess it depends on whether you expect all users to be on Windows. Under UNIX, I think the first word of a shebang line has to be an absolute path. Thus /usr/bin/env is used as a placeholder to get it to search the PATH for the python3 executable, which would usually be in either /usr/bin (if provided by a distribution) or /usr/local/bin (if compiled by the machine's owner) but occasionally elsewhere. See GNU env's man page and info page as well as this question on UNIX and Linux Stack Exchange.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: GGSound: a lightweight sound engine for games

Post by rainwarrior »

Ah, I see. Thank you for the tip.

Yeah, the /usr/bin/env version should work on Windows too, that page I linked mentions that the Windows python launcher should simulate them in some way, so I guess it is the better way to do it. Kind of annoying how many established ways there are; but it's also kind of annoying that we're stuck with the Python 2 / 3 schism in the first place. :P
Post Reply