Allows you to play various game music formats, including:
AY - ZX Spectrum/Amstrad CPC
GBS - Nintendo Game Boy
GYM - Sega Genesis/Mega Drive
HES - NEC TurboGrafx-16/PC Engine
KSS - MSX Home Computer/other Z80 systems (doesn't support FM sound)
NSF/NSFE - Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
SAP - Atari systems using POKEY sound chip
SPC - Super Nintendo/Super Famicom
VGM/VGZ - Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro
The externals use the game-music-emu library, which can be found here: https://bitbucket.org/mpyne/game-music-emu/wiki/Home
[gme~] has 2 outlets for left and right audio channels, while [gmes~] is a multi-channel variant that has 16 outlets for 8 voices, times 2 for stereo.
[gmes~] only works for certain emulator types that have implemented a special class called Classic_Emu. These types include AY, GBS, HES, KSS, NSF, SAP, and sometimes VGM. You can try loading other formats into [gmes~] but most likely all you'll get is a very sped-up version of the song and the voices will not be separated into their individual channels. Under Linux, [gmes~] doesn't appear to work even for those file types.
Luckily, there's a workaround which involves creating multiple instances of [gme~] and dedicating each one to a specific voice/channel. I've included an example of how that works in the zip file.
- [ info ( - Post game and song info, and track number in the case of multi-track formats
- this currently does not include .rsn files, though I plan to make that possible in the future. Since .rsn is essentially a .rar file, you'll need to first extract the .spc's and open them individually.
- [ path ( - Post the file's full path
- [ read $1 ( - Reads the path of a file
- To get gme~ to play music, start by reading in a file, then send either a bang or a number indicating a specific track.
- [ goto $1 ( - Seeks to a time in the track in milliseconds
- Still very buggy. It works well for some formats and not so well for others. My guess is it has something to do with emulators that implement Classic_Emu.
- [ tempo $1 ( - Sets the tempo
- 0.5 is half speed, while 2 is double. It caps at 4, though I might eventually remove or increase the cap if it's safe to do so.
- [ track $1 ( - Sets the track without playing it
- sending a float to gme~ will cause that track number to start playing if a file has been loaded.
- [ mute $1 ... ( - Mutes the channels specified.
- can be either one value or a list of values.
- [ solo $1 ... ( - Mutes all channels except the ones specified.
- it toggles between solo and unmute-all if it's the same channel(s) being solo'd.
- [ mask ($1) ( - Sets the muting mask directly, or posts its current state if no argument is given.
- muting actually works by reading an integer and interpreting each bit as an on/off switch for a channel.
- -1 mutes all channels, 0 unmutes all channels, 5 would mute the 1st and 3nd channels since 5 in binary is 0101.
- [ stop ( - Stops playback.
- start playback again by sending a bang or "play" message, or a float value
- [ play | bang ( - Starts playback or pauses/unpauses when playback has already started, or restarts playback if it has been stopped.
- "play" is just an alias for bang in the event that it needs to be interpreted as its own unique message.
Both externals optionally take a list of numbers, indicating the channels that should be played, while the rest get muted. If there are no creation arguments, all channels will play normally.
Note: included in the zip are libgme.* files. These files, depending on which OS you're running, might need to accompany the externals. In the case of Windows, libgme.dll almost definitely needs to accompany gme(s)~.dll
Also, gme can read m3u's, but not directly. When you read a file like .nsf, gme will look for a file that has the exact same name but with the extension m3u, then use that file to determine track names and in which order the tracks are to be played.
- [ info ( - Post game and song info, and track number in the case of multi-track formats
This is a spiritual successor to amPd. It's much more stable and has many more features than amPd:
reads/writes metadata to/from patches. This is done by storing the info in the form of comments, in a canvas called [pd meta] or [pd info]. If no such canvas exists, foobar will add it in the top left-hand corner of your patch.
comes with a Win32 Dialog UI element, containing sliders, toggles, buttons, and edit-text/button combos to send messages to your patch.
- foobar looks in your patch for a canvas called [pd mix] and uses the parameters of whatever sliders, bang objects, or toggles it finds there to give your UI controls similar functionality.
How playback works
- libpd sends a 1 to vol, then a bang to play.
- Generally this is where, in your patch, you have an [r play] hooked up to your metro, and an [r vol] connected to a [*~ ] before your output reaches [dac~].
- the length of the song is arbitrarily set by the user.
- This affects the trackbar's cursor visibility and ability to set a position.
- If the length is 0, there will be no trackbar cursor. Otherwise, the cursor, when moved, will send its position in seconds to pos. From there, it's up to your patch to take that information from [r pos] and work it into song events.
- The patch will not actually stop and move on to the next track until libpd receives a bang from [s stop].
How the mixer works
- all mixer controls go inside of [pd mix]
- horizontal and vertical sliders are turned into slider controls in the UI element
- labels assigned to sliders in the patch become labels for the UI element's slider controls. The same applies for send symbols.
- min and max values of sliders on the UI element work in integers only, so if you want a gradual shift from, say, 0 to 1, write "gradient" in the slider's receive symbol, and the slider's range will be broken down into roughly 200+ individual steps.
- there are currently 7 sliders in the UI element
- bang objects with no label become simple buttons in the UI
- their send symbols will be reflected in the button's name and they will send a bang when clicked.
- there are currently 3 buttons
- bang objects with a label assigned become message buttons
- these have an edit text field associated with them, where you can type out any message you want and send it to the destination.
- the bang's label is placed inside of the edit text field as a suggested message to send.
- pure data strips commas out of labels, so I'm using apostrophes to denote where commas should go. ex: do this' then this
- there are currently 2 message buttons, with the 'any' button being a potential 3rd.
- a bang object with a label written in the format dest : msg will be assigned to the 'any' button.
- the 'any' button has an editable destination field, giving you access to basically any receive symbol in your patch.
- also substitutes as a third normal message button, when the other two are already in use
- toggles become checkboxes
- each checkbox can have a label and send symbol assigned to it
- there are currently 4 checkboxes
- right-clicking a track shows the context menu entry Pd Player -> Load mixer.
- basically, you can load mixers of tracks not currently playing for some potentially interesting exchanges between patches. After loading the mixer, you still need to hit the Refresh button to show the changes.
foo_pd's copy of libpd.dll contains only the externals that I needed to run the example patches. If you want your own patches to work with foo_pd, you might need to make another build using MSYS2. If you're not sure which objects aren't instantiating, foobar's console prints all of pd's messages while audio is being processed. I'll also add more externals over time.
I'll be maintaining foo_pd at https://github.com/myQwil/foo_pd where you can also find the latest builds
Cool object. This is a late response but I was checking out your code and wound up making a bunch of changes to it to address 3 bugs I found:
- 1 - [n! ] doesn't instantiate on its own. it needs a prior instantiation of [factorial] to load. Normally to fix that, what you'd do is make a copy of the binary and rename it to n!.pd_darwin, but there still needs to be a setup function with the object's name in it, or a function that's just called "setup", which you should probably try to avoid just because it's not very self-documenting.
- 2 - It doesn't successfully find the help file. Pd automatically adds "-help" or "-help.pd" on its own. It also automatically creates a help file reference. The sethelpsymbol function is pretty much only good for when you have multiple objects of different classes that need to refer to a common help file.
- 3 - It freezes and sometimes crashes pd if it's fed a really big number, because it'll start looping endlessly..
Performs binop arithmetic with 2 hot (active) inlets, which means that the usage of either inlet will trigger an output. Some of the objects require the hexloader library to load properly.
The naming convention is a # symbol, followed by the expression.
examples: [#+ ] [#- ] [#== ] [#!= ] [#&& ] [#|| ] etc.
The collection is based on the binop objects found in x_arithmetic.c. This includes:
binops 1: +, -, *, /, pow, max, min
binops 2: ==, !=, >, <, >=, <=
binops 3: &, |, &&, ||, <<, >>, %, mod, div
Performs binop arithmetic with the inlets having switched roles. Some objects require the hexloader library.
The naming convention is an @ symbol, followed by the expression.
examples: [@- ] [@/ ] [@pow ] [@<< ] etc.
The collection consists of binop objects where the swapping of inlets would have a noticeable difference in results. These include:
-, /, pow, <<, >>, %, mod, div
Consists of two bitwise objects to perform bitwise negation [!~ ] and XOR ([^ ] and [#^ ]). Bitwise negation has another alias of [~ ] but it will not load unless [!~ ] is loaded first, or if the object is placed in pd/extra/!~ and "!~" is added to your list of libraries.
splits and joins the sign, exponent, and mantissa of a float
accepts bangs and floats
accepts 1 creation argument for assigning the stored value
has 1 extra inlet for assigning the stored value
outputs the sign, exponent, and mantissa of the stored float
accepts bangs and floats (mantissa is assigned the float)
accepts 3 creation arguments for assigning the mantissa, exponent, and sign
has 3 extra inlets for assigning these values
outputs a float by combining these values together
help file included
A number base converter that accepts 1 creation argument to specify which number base to convert to. If nothing is specified, or the number is out of range (1-64), it defaults to 16. The converted number is sent in the form of a symbol type. Much of the code is based on the musl library's vfprintf function.
The symbol array is as follows:
"0123456789abcdef" "ghijkmnopqrstuvw" "xyzACDEFGHJKLMNP" "QRTUVWXYZ?!@#%^&"
Some letters were taken out for looking too similar to numbers or other letters.
Similar to [muse], containing many of the same functions, except that [muse] sends new midi/frequency values through the same two outlets, whereas [harm] uses a 1-to-1 note-to-outlet approach, which allows us to make chords. More creation arguments results in more inlets and outlets, of which there should be an equal amount. If we created the object:
[harm 45 22 26 29 33]
This would have 6 inlets and 6 outlets.
The first inlet receives lists, floats, and bang messages. Numeric lists reassign the scale, floats send a single frequency through the appropriate outlet, and bang messages send the respective frequencies through each available outlet. The inlets that follow assign each of the creation arguments to a new value. An additional outlet is created to handle all octaves.
use the message [midi 0 | 1( to switch between using either midi notes or frequencies (default).
They're like [mtof] and [ftom], but now the objects accept 2 parameters:
- the reference pitch for middle A (default value is 440)
- the number of tones (default value is 12)
So let's say you want your reference pitch to be 432, considered by some to be a more mellow frequency, you would write:
- [ntof 432]
and to split an octave into just 8 distinct tones instead of the most conventional 12, you'd write:
- [ntof 432 8]
You can change these values after instantiation by using messages:
- [ref $1(
- changes the reference pitch
- [tet $1(
- changes the number of tones (in equal temperament)
It also comes with two counter objects: [cupq], and [cupqb]
[cupq] has three inlets:
- left inlet decrements
- right inlet increments
- middle inlet changes the step size.
[cupqb] is similar, but it includes an atom box, allowing you to slide the current count. It has two inlets:
- first inlet receives [+ $1( and [- $1( messages
- second inlet controls the step size.
[cupq] and [cupqb] are .pd files, so there's actually more you can do with them than what I've specified here.
These files are also on my github page under pd-externals.
EDIT: My musical scale object [muse] now also takes advantage of the ref and tet messages. Its help file allows you to play around with these features. The files have now also been added to the zip.