One day I felt like streaming my music compositions and arrangements made in ModPlug, FamiTracker, and Pently on someone's Discord server. But Discord music bots tend to support only more common audio formats based on compressed samples, such as MP3 and occasionally Ogg Vorbis. So before I can use LAME and oggenc, I first need to turn them into RIFF WAVE files.

So one night, I felt like writing a wrapper around a couple player libraries that I could put in a shell script to render NSF and S3M to RIFF WAVE to MP3/Ogg. Currently it wraps these:

Dynamic Universal Music Bibliotheque (DUMB), originally by Ben Davis, now also maintained by kode54

These two libraries cover most formats in which I have composed over the past 15 years. In the late 1990s, when I developed games using old Allegro, I composed music in Standard MIDI File format, but I dropped that around 2001 in favor of tracker formats where I could more portably control mixing among instruments and between the music and sound effects. And my potatobook's Atom N450 CPU renders NSF at roughly 60x speed.

C source code is included, but not a binary for a popular pane-ful PC operating system. I haven't tested it in anything but GNU/Linux on x86-64. Dependencies are GME, DUMB, GCC, and GNU Make, as described in the build instructions. The license of both this wrapper and DUMB is the zlib License; GME is LGPLv2.1, which requires letting end users relink an updated, ABI-compatible library with an existing application.

// DUMB appears to lack an API to query a DUH for voice count.// The duh_sigrenderer_get_n_channels() call returns how many// output channels it is generating (2 for stereo), not how many// voices are used. Solo should treat all DUHs as having// DUMB_IT_N_CHANNELS channels.void dumb_it_sr_set_channel_muted( DUMB_IT_SIGRENDERER *self, int channel, int muted);

I'll assign your mute and solo feature request to myself once I confirm two things from you:

First, if an NSF has eight voices, such as one with 2A03 and VRC6, they are numbered 1 through 8, not 0 through 7, correct? Screenshots of ModPlug Tracker, Schism Tracker, Game Boy Tracker by Paragon 5, and SPC players number them 1-based.

Second, muting a voice might not have quite the desired effect in the following cases:

Voices mix nonlinearly. This is true of the NES, where the current position of the DAC associated with the DMC controls the volume of the triangle and noise channel.

A tune treats several voices as a single pool and aggressively moves individual notes on the same instrument to different voices. This is true of the SPC rip of Viacom's Zoop.

I'll assign your mute and solo feature request to myself once I confirm two things from you:

First, if an NSF has eight voices, such as one with 2A03 and VRC6, they are numbered 1 through 8, not 0 through 7, correct? Screenshots of ModPlug Tracker, Schism Tracker, Game Boy Tracker by Paragon 5, and SPC players number them 1-based.

Second, muting a voice might not have quite the desired effect in the following cases:

Voices mix nonlinearly. This is true of the NES, where the current position of the DAC associated with the DMC controls the volume of the triangle and noise channel.

A tune treats several voices as a single pool and aggressively moves individual notes on the same instrument to different voices. This is true of the SPC rip of Viacom's Zoop.

I'd use the 1-8 scheme, as that's what sidplay already uses.

I am not looking to separate different instruments, as that would be an unreasonable request. I am looking to just separate the voices. Can you give an example on the NES where separating the voices and then recombining them would result in a different sound?

Something like Sunsoft bass or loud DMC percussion will cause the triangle and noise to be louder when soloed than for the whole mix.

I had to work around a couple quirks of Game_Music_Emu to get them to work:

Silence detection is disabled when at least one channel is muted because GME uses only unmuted voices to determine when to stop playing.

GME pre-renders the first few milliseconds of audio immediately after starting a track. If I mute voices between starting a track and the first render call, render has to restart the track to make the muting take effect without popping all voices back on momentarily.

Here's an example of how to use the new solo feature to split out individual tracks:

A couple small changes so that I could easily spin up an NSF/SPC/whatever player as a make run target, so that I don't have to build an entire ROM and start an entire emulator just to hear changes to the output of an NSF or SPC that I built:

Let me explain why there hasn't been much further development on this:

The intended use case was to export WAV, encode, upload to your own web space, and play from there. But for "security reasons", the major Discord music bots have since disabled playback of arbitrary URLs in favor of whitelisting YouTube, SoundCloud, and a couple other major sites. Because music publishers patrol YouTube and SoundCloud in order to make Content Verification Program claims and counterparts on other services, uploading cover versions to YouTube or SoundCloud exposes a cover artist to a far greater chance of getting caught than uploading cover versions to one's own web space.

Who is online

Users browsing this forum: No registered users and 3 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum