• myQwil

    Works very much the same as trigger except that when you use 'a' for creation arguments, lists that consist of only 1 atom will output as the atom itself and not as a list. This also includes pointers. You'll notice that with trigger, a pointer will output as a list, which makes it difficult to type-check.

    The [unpak] object had a similar problem where it would output lists instead of raw atom values, and that has also been changed with unpak's latest update.

    EDIT: I've made it so that floats default to anything outlets and no creation args defaults to 2 anything outlets.

    x.zip

    posted in extra~ read more
  • myQwil

    Similar to [pack ] and [unpack ] but instead of the default atom type being a float, the default type is anything.

    Also comes with a new creation arg 'a' for anything. Numbers and unrecognized types will also default to anything.

    For strict type checking, use f(loat), s(ymbol), and p(ointer).
    The pak object will also store unrecognized types as symbols and interpret 'b' as a 'bang' symbol.

    EDIT: You can now send lists to any of the additional pak inlets and it will store the list values with the inlet as the starting point. For example, sending the message [foo bar 3 baz( to the 2nd inlet of [pak 1 2 3 4] would result in the list: 1 foo bar 3

    EDIT2: pak still has a bug when setting a pointer from any inlet other than the first one. This became more apparent when trying to work with the object in pd-vanilla.

    EDIT3: pak is much more stable now and works in pd-vanilla. The example includes a new object I've created called [x ], which is a kind of trigger object that dehusks lists that consist of only 1 element when you use 'a' for creation args. For pd-vanilla users, the example also requires zexy's [demux].

    EDIT4: You can now use "." to skip inlets and assign only specific ones.
    For example, sending the message [. . 123( would assign 123 to the 3rd inlet and leave the first two values the same as they were. You can also send these messages to any inlet.

    EDIT5: I made it so that the skip arg feature only applies to list and anything type messages, so if you really want to, you can still assign a single period to an inlet by sending it as a symbol. I also needed to make it so the skip arg feature also works on strict-type inlets.
    It's also worth mentioning that the proxy inlets now have their own pointer, float, symbol, and list functions, rather than an anything function that handles all message types by running string comparisons, so it should be a bit faster if only slightly, and overall better coding practice for a pure data external.

    EDIT6 The skip arg feature was only added to pak so I added the same feature to unpak as well. Using a period as an arg will skip the outlet and not send any value through it.

    pak-unpak.zip

    posted in extra~ read more
  • myQwil

    @ingox I recently made a slight change to how the c external works and went ahead and made the same change to your pd external. I just needed to include the rejection outlet of the left route object. is.pd

    posted in extra~ read more
  • myQwil

    Neat! I've used route with custom messages, but it didn't occur to me that it could also be used as a type checker.

    posted in extra~ read more
  • myQwil

    Returns a boolean 1 or 0 if the value sent to the 1st inlet matches the type specified in the creation arg or 2nd inlet.

    You can set the type to be matched against either as a creation argument or with the message [type $1(, or by sending to the 2nd inlet either the type name or an example of the atom whose type you want matched against.

    EDIT: the "type" method needed a bug fix. The help file has also been slightly altered:

    EDIT2: Now the type can be virtually anything, rather than one of 5 possible types. This allows us to check for specific messages. For example, sending the message [foo 1 2 3( to the object [is foo] will return true.

    EDIT3: Defaults to float if no creation argument given. Also added a pointer example to the help file.

    EDIT4: A memory-freeing method was necessary to clear the proxy inlet.

    is.zip

    posted in extra~ read more
  • myQwil

    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.

    Methods

    • [ 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.

    Creation args

    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.

    gme.zip

    posted in extra~ read more
  • myQwil

    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

    foo_pd.zip

    posted in libpd / webpd read more
  • myQwil

    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..

    factorial.zip

    posted in extra~ read more
  • myQwil

    Hot Binops
    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

    Reverse Binops
    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

    Bitwise Arithmetic
    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.

    hot-rev-bit.zip

    posted in extra~ read more
  • myQwil

    Based on a patch I made a few years ago, which I then tidied up and implemented externals I hadn't yet made at the time, then tweaked some stuff around to give it a new sound, which reminds me a bit of silent hill music.

    sawlent-hill.zip

    posted in patch~ read more

Internal error.

Oops! Looks like something went wrong!