Log In  
Follow
packbat

Mid-Atlantic USian. Fan of autobiographical games, unusual game experiences, and heavily stylized graphics. (Also deckbuilders and roguelikes.) Queer, disabled, plural, autistic.

[ :: Read More :: ]

On boot (running NixOS 23.11 with KDE Plasma version 5.27.10) it shows a green "no workspaces" screen with a weird cursor glitch and the SFX workspace icon replaced with a desktop one ... until we click another workspace, at which point everything is fixed.

Edit: GIF of bug:

P#146777 2024-04-16 17:46 ( Edited 2024-04-16 17:51)

[ :: Read More :: ]

One feature of electronic music is varying instrument parameters during the performance - for example, adjusting the depth of the lowpass filter sweep on an acid bassline. I think if there were a way to specify in the instrument design that one (or more) knobs was mapped to a value controlled by the tracker, it would be very easy to do these kinds of musical manipulations.

P#146607 2024-04-14 12:13

[ :: Read More :: ]

Cart #packbats_2node-3 | 2024-04-12 | Embed ▽ | License: CC4-BY-NC-SA
24

As previously threatened, we have created a collection of simple (1-2 nodes, 1-2 envelopes) Picotron instrument patches for anyone to use in their programs. All of the instrument patches are released as CC-0 public domain - you are free to use, modify, and sell without credit. (Although we would appreciate credit if you do make something with it as long as the thing is not, like, evil or bigoted - Nazis, TERFs, and channers, go away.)

With the 1.0 release, there are 25 instruments (mp3 preview), sorted into five categories:

Drum Kit

  • kick
  • tom
  • snare
  • hi hat
  • crash cymbal

Pitched Idiophones

  • marimba
  • celesta
  • steelpan
  • glass pad

Chordophones

  • piano
  • shamisen
  • guitar
  • e guitar
  • violin*
  • harp

Aerophones

  • pipe
  • flute
  • organ
  • oboe*
  • trumpet

Electrophones

  • synth bass
  • fm bass
  • acid bass
  • 64ish pulse
  • bleepbloop

Directions for use are simple: use the scrollbar or mousewheel to navigate the list, click the name of the instrument to get a short preview, and click "copy" to put the data on your clipboard for pasting into sfx.p64's instrument editor. The volumes are roughly (by ear) matched to the default triangle wave instrument to aid in mixing.

* Technical note: the violin and oboe instruments will not preview correctly in the instrument editor, as ENV 1 on each uses a special 0 value on FREQ and SPD, respectively. With this setting, the vibrato of each of these will be synchronized with the SPD of the SFX in which they are used. To change this, simply change this value in the righthand column.

Old post text:

As previously threatened, we have created a collection of simple (1-2 nodes, 1-2 envelopes) Picotron instrument patches for anyone to use in their programs. All of the instrument patches are released as CC-0 public domain - you are free to use, modify, and sell without credit. (Although we would appreciate credit if you do make something with it as long as the thing is not, like, evil or bigoted - Nazis, TERFs, and channers, go away.)

Directions for use are simple: use the scrollbar or mousewheel to navigate the list, click the name of the instrument to get a short preview, and click "copy" to put the data on your clipboard for pasting into sfx.p64's instrument editor.

Planned for 1.0:

  • five more instrument patches (thanks to everyone who's made suggestions so far!)
  • a list that's sorted in a way that makes sense instead of being a total jumble

Edit: Small update to add the marimba - current instrument list:

  • piano
  • violin
  • pipe
  • organ
  • kick
  • snare
  • hi hat
  • crash cymbal
  • synth bass
  • fm bass
  • acid bass
  • glass pad
  • guitar
  • trumpet
  • celesta
  • flute
  • e guitar
  • shamisen
  • 64ish pulse
  • bleepbloop
  • marimba

Edit 2:

  • harp
  • oboe
P#146304 2024-04-10 18:37 ( Edited 2024-04-14 15:03)

[ :: Read More :: ]

Thinking about putting together a collection of free instruments for the community - simple stuff with one or two nodes and one or two envelopes, like this:

...so as to leave a lot of room for modification by users.

What instruments would y'all want in a free patch collection? Right now we have crude versions of:

  • violin
  • piano
  • pipe
  • organ
  • kick
  • snare
  • hat
  • crash

but a single .sfx file can hold up to 24 instruments, so it feels like we should offer more than eight.

edit: instrument collection cart!

P#146047 2024-04-08 13:18 ( Edited 2024-04-10 18:54)

[ :: Read More :: ]

Over a week or so in late March and early April, we've been working on instrument.txt - a detailed (~4.6k words) guide to Picotron's built-in instrument editor, designed for musicians who have Picotron but know nothing about synthesizer sound design. In this guide (currently version 2.0) (html version, web version), we:

  • Detail the Picotron instrument editor UI;
  • Explain how each element - output mixer, oscillators, envelopes, and effects - works; and
  • Guide you through putting this to practice by making a series of simple instruments, including organ sounds, 'piano' sounds, kick drums, snare(-adjacent) drums, and cymbals and hi hats.

If you've been wanting to play with Picotron's tracker but not known how to make it work, we hope this sets you up to make lots of sounds.

Changelog

2.0:

  • added info on the space bar halt-sound control and the random and looping envelope options.
  • clarifications of wording throughout, notably including ADSR values in Exercise 1 and a full rewrite of the "Simple Piano" exercise
  • corrections to a few errors (e.g. to change wavetable, you have to click the WT-# label specifically)

1.2:

  • initial public release
P#145806 2024-04-05 16:15 ( Edited 2024-04-07 15:21)

[ :: Read More :: ]

Cart #threespeed_bgm-0 | 2024-03-30 | Embed ▽ | License: CC4-BY-NC-SA
6

Been experimenting to get the hang of the synth, and we figured we'd donate some of the fruits of that experimentation to the community. Two channels, eight music patterns, six SFX, four instruments, CC BY-NC 4.0. Would love to hear if y'all use it (or its instrument designs) for anything.

P#145074 2024-03-30 04:10

[ :: Read More :: ]

Cart #packbats_laser_rot-0 | 2024-02-25 | Code ▽ | Embed ▽ | No License
2

This PICO-8 chiptune was composed for the 2024 PICO-8 Free Music Jam. It uses three channels - bass and bass percussion on channel 0, melody and mid percussion on channel 1, and high percussion on channel 2 - and requires 16 SFX and 24 music patterns, no custom SFX instruments. The full loop is approximately 1 minute 16 seconds long. You can probably interrupt the high percussion on channel 2 if you need a second channel for sound effects.

This piece of music is being released under a Creative Commons Attribution-ShareAlike 4.0 license. Visualizers are provided by Bikibird's album cart. The cover art is based on the image "Time destroyed CD" by Bernd Hutschenreuther, used under a Creative Commons Attribution-ShareAlike 3.0 license, and processed with ImageMagick and Depict.

P#141904 2024-02-25 02:22

[ :: Read More :: ]

Cart #cubancakewalk_brymn-0 | 2024-02-05 | Code ▽ | Embed ▽ | No License
5

This cart, which uses one of @bikibird's visualizers provided courtesy of the PICO-8 Free Music Jam (in a beta version, as a co-organizer we helped with testing), contains an arrangement of the music of someone we'd never heard of: James Timothy Brymn's "Cuban Cake Walk".

And that's a shame, because (a) Lieutenant James Tim Brymn was apparently an absolutely legendary Black American arranger, composer, and bandleader, one of the people who helped give birth to jazz as we know it today, and (b) while we didn't manage to include the entire composition in this, "Cuban Cake Walk" is a delightful piece of music with a really fun bouncy groove. And if we hadn't clicked on the IMSLP website on a day when it was being featured, we'd know none of this.

So, tossing this up for all y'all, declaring my arrangement to be public domain, feel free to drop this in anything that needs it. The melody and bass line are in channels 0 and 1, main harmony in channel 2, and occasional supplemental harmony in channel 3; we would restrict game SFX to channels 2 and 3 personally.

P#141167 2024-02-05 20:26

[ :: Read More :: ]

Cart #noending_by_packbats-1 | 2024-01-31 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
1

Someone randomly mentioned Minecraft on the official unofficial Discord, and with the PICO-8 Free Music Jam starting tomorrow (plug!), that inspired this chill but slightly dissonant background loop. Approximately two and a quarter minutes long, uses 00, 01, and 02 for custom SFX instruments, total of 15 SFX and 16 patterns.

Music is CC-BY-NC-SA 4.0, art is "Twilight" by RDexter on Flickr, CC-BY-NC 2.0.

P#140937 2024-01-31 16:53 ( Edited 2024-02-03 19:33)

[ :: Read More :: ]

One of the basic problems you might want to solve in doing PCM synthesis is limiting a signal to the range between -1 and +1. Obviously you can just use a mid() function to get hard clipping - the value just locks to the endpoints - but this often has unpleasant side effects. For example, if you hard clip the output, the sound will snap abruptly from smooth to harsh as the volume increases, with very little transition between these. So, people often want to round off that transition, let the sound get gradually harsher, and one of the smoothest options is to use the tanh - hyperbolic tangent - function. Looking at a graph of this function, you can see that it smoothly transitions from reproducing the original x value to squishing it between -1 and 1, just as we often want.

So, I did a bit of experimenting today with sine waves and came up with the following code snippet:

--to use table:
-- tanh = lut[x\0x.01] or sgn(x)
function lut_tanh()
    --lookup table of tanh
    -- between -3 and +3
    -- with step size 1/256
    local tanh={}
    for i_x=-768,768 do
        --naive formula is
        --tanh = 1 - 2/(1+exp(2x))
        local x=i_x>>8 --=i_x*0x.01
        --inspired by https://www.math.utah.edu/~beebe/software/ieee/tanh.pdf formula:
        --1. from 0 to x_small=0x0.01bb, tanh(x) = x
        --2. for x>=0x5.3300, naive formula returns 1
        if abs(x)<=0x.01bb then
            tanh[i_x]=x
        else
            tanh[i_x]=1-2/(1+0x2.b7e1^(2*x))
        end
    end
    return tanh
end

To my ears, with these values, driving a sine wave with an input volume as low as 0.03 sounds only about as bad as the original sine wave does with so few bits to work with, and driving all the way up to 16 there's not a lot of artifacting to the distortion. With some antialiasing you could probably do even better than that.

This function uses 1537 entries in the lookup table, which I think is about 1.4% of Lua memory. I know my ears aren't very trained when it comes to analyzing synth sounds, so feel free to edit this if it seems like too much or not enough, but it seems to me like a fairly practical compromise for PCM slingers.

P#140078 2024-01-13 19:25

[ :: Read More :: ]

Oh hey, a thing we're doing is live!

The PICO-8 Free Music Jam is an itch.io jam for musicians with a very simple concept: PICO-8 devs want music to put in their carts, we're gonna make music for their carts.

It'll be running for the full month of February - no ratings, no competition, just music for PICO-8. And if you wanna get started making music, in PICO-8 or at all, there's loads of resources linked on the jam page.

(edit: And many thanks to the folks in the #music-sfx channel of the official unofficial PICO-8 Discord who came together to hatch this idea and hammer out the details, and to @paraK00PA for the awesome cover art!)

P#139636 2024-01-04 16:21 ( Edited 2024-01-04 17:37)

[ :: Read More :: ]

I don't know if this exists, but I think it would be cool to have a thread of Stuff You Might Not Have Figured Out From Just Messing Around Making Things.

Here's two to start with, from a musician perspective:

  1. If you can, leave SFX 00 through 07 empty. It will help with adding music later - be that you adding music or because those slots can be used for custom SFX instruments that give a lot of character and flavor to compositions.

  2. Decide how many channels to reserve for music. The 4 SFX channels of PICO-8 have to be used by both music and sound effects, and both music and sound effects benefit from having more channels - so think about which is more important to you, and which sound effects can interrupt each other. You can also, if some sound effects are only played sparsely (maybe you have a clicky sound while navigating menus!), try having one channel of music that is interrupted briefly by the sparse effect and then resumes.
P#132103 2023-07-18 15:57

[ :: Read More :: ]

[sfx]

Was listening to some old compositions of mine and realized that I had a nice little instrument that hadn't made it into the midi library!

For the demo, I used the same trick I used then, and split the melody across two separate SFX so the tails of each note could ring out while the next note played. Bit of a faff to do, but it produces a very good effect.

Cart #hifesosani-0 | 2023-02-27 | Code ▽ | Embed ▽ | No License
7

As noted in the cart, at least to me, it still sounds good and has a harp-ish vibe with various combinations of Buzz, Dampen, and Reverb; Detune doesn't work because the bulk of the SFX is the triangle wave.

P#126381 2023-02-27 20:30

[ :: Read More :: ]

So, let's say you're building a synthesizer using the serial PCM output and you want a filter. What do?

Well, what I did was follow a link @luchak posted a while ago in the Discord to this SVF filter design by Andrew Simper, Laurent de Soras, and Steffan Diedrichsen. And then get blasted with noise, because a design that works great with double-precision floating-point numbers is not so great with 16b.16b fixed-point PICO-8 numbers.

Edit: I recommend using the code snippet downthread rather than this one.

Now, I'm not good enough at math to prove mathematically that this is stable, but I'm good enough at hacking together testing code to feel confident that, as long as:

  • the signal being fed into the filter remains in the range -1 to 1,
  • the resonance remains in the range 0 to 1, and
  • the cutoff remains in the range 0 to 2756.25 (the Nyquist frequency for PICO-8's 5512.5 Hz PCM output)

...this should produce an output that remains within the range -3 to 3 -3.5 to 3.5 and is usable.

--this is the initialization section; do it outside the sample calculation loop
local f_low,f_band=0,0

--these are the filter parameters
--I haven't tested changing them while the filter is running but that's what I plan to do, so, here's hoping.
local res=0 to 1
local freq=-2.0*sin(cutoff frequency/22050)--sin( 0.5 * cutoff frequency/(2*sampling frequency) )

--after you set freq and res, these two are derived
local drive=max(0,.05*res-.0125)--0 for res<0.25, increase linearly to 0.0375 for res=1
local damp=min(2.0*(1.0 - res^0.25), min(2.0, 2.0/freq - freq*0.5))

-- --
-- do the calculations here to generate osc, your signal to be filtered
-- --

--2x oversampled filter
local f_notch=osc-damp*f_band
f_low+=freq*f_band
local f_high=f_notch-f_low
f_band-=drive*f_band*f_band*f_band--distortion
f_band+=freq*f_high--filter
local out=(f_notch or f_low or f_high or f_band)>>1--half here...
f_notch=osc-damp*f_band
f_low+=freq*f_band
f_high=f_notch-f_low
f_band-=drive*f_band*f_band*f_band--distortion
f_band+=freq*f_high--filter
out+=(f_notch or f_low or f_high or f_band)>>1--...and half here

To show it off, here's my current very incomplete version of a button keyboard cart. Same keyboard keys as you use for SFX editor note entry; left-right arrows to change octave. This filter is set up with a cutoff frequency of A5 (880 Hz) and a resonance of 1.

Cart #pb_pcmk_filter_demo-0 | 2023-01-28 | Code ▽ | Embed ▽ | No License
6

P#124936 2023-01-28 03:25 ( Edited 2023-09-11 22:19)

[ :: Read More :: ]

I think ever since @carlc27843's Impossible Mission R.T. cart came out, people have been wondering if they could make background music for a cart using PCM synthesis. carlc27843's Emulated Amstrad CPC Chiptunes post discusses using its engine that way, @luchak has had to let people know that the RP-8 groovebox can't be used that way ... folks are curious.

I don't know a lot about digital audio synthesis, but from the conversations that have happened in the PICO-8 Discord, it sounds like there's roughly three sides to the equation:

Cost

  • How many tokens and bytes are cart designers willing to give up to the soundtrack? @bikibird's Speako8 Speech Synthesis Library is under a thousand tokens - is that a good target?
  • What percentage of PICO-8's CPU budget? Four voices with 25% CPU seems possible in a few different ways, but is that too much to give up to background music?
  • How much memory, Lua and addressable? Most forms of synthesis probably run out of CPU first, but this could be a question if you're making a lot of lookup tables.

Usability

  • How do you program tracks? Does it use PICO-8's built-in tracker with its own sound sources? Does it have a custom editor?
  • How do you add them to your games? Presumably you copy a bunch of code into memory and add a function or coroutine to your game loop, but where and how do you store tracks?

Quality

  • How many simultaneous voices? PICO-8's built-in tracker allows 4 simultaneous sounds, but most game BGM is built with 2 or 3.
  • What effects can you add? Reverb is probably out of budget, but echo is possible (if memory-expensive), and distortion and compression are totally feasible. As are filters - certainly low pass, high pass, band pass, and notch.
  • What kind of synth do you make?

It's definitely possible to make:

  • Simple waveform synthesis (e.g. sine, square/pulse, sawtooth, triangle)
  • FM synthesis
  • Sample-based synthesis (very storage-expensive!)
  • Wavetable synthesis (the original PPG Wave synthesizers only had 8-bit samples! but this is also storage-expensive, if less than sample-based synthesis)
  • Subtractive synthesis with any of the above as oscillators

...but the more processing you do, the more sound design tools you add, the more expensive your result will be.

Conclusion?

I don't really have one? But I think it would be good to have a space on the official forums where people who are thinking about this stuff can talk about it. I haven't made a lot of games, so I don't know what what a good budget would be for game developers ... and I haven't made much music with much outside PICO-8 and, like, an actual piano, so I don't know what a good synthesizer would be for game soundtrack composers. And I know barely anything about software synthesis, so I don't know what's possible, what's easy, what's hard, or why my low-pass filter makes hell noises if I give it the wrong parameters.

I think it would be cool to share knowledge, and the forums seems like the best place to do it.

P#124516 2023-01-18 18:45 ( Edited 2023-01-18 19:45)

[ :: Read More :: ]

Cart #pb_line_cbez-0 | 2022-12-23 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA
2

I know a lot of people have posted functions for drawing cubic bezier curves, but I'm tossing my own into the pot because why not. Just skimming threads, it feels like most people use pset() to draw them pixel by pixel; this one uses line() to draw them segment by segment.

Some animated gifs, because they're fun:


demo of the editor in the cart:

drawing demo, dividing the curve into segments:

drawing demo, dividing the curve dynamically based on pixel precision:

To save you digging into the cart, here's the two versions of the algorithm I'd recommend, based on my testing. If you want to see how fast they run, there's a pause menu item in the code that draws sets of 5000 random bezier curves with a bunch of different algorithm parameters in two sizes - 16-pixel square bounding box and 128-pixel square bounding box - and adds up the total CPU needed at 60 FPS.

  1. The polynomial coefficients function. All of the other code uses this.

    --coefficient fn (39 tokens, shared by all)
    function cubic_coef(p0,p1,p2,p3)
    --coefs for cubic bezier
    return
        p0,
        -3*p0+3*p1,
        3*p0-6*p1+3*p2,
        -p0+3*p1-3*p2+p3
    end
  2. Fixed-segments option. This one has 16 segments, which (a) is convenient numerically and (b) doesn't get too messy for small curves but doesn't look too chunky for large ones. From the benchmark, you could draw 220 big curves or 250 small curves in one 60 FPS frame.

    --fixed 16 points (+80 tokens)
    function cbez_16(x0,y0,x1,y1,x2,y2,x3,y3)
    --cubic bez, dt predefined
    
    --precalculate polynomial coefs
    local a0,a1,a2,a3=cubic_coef(x0,x1,x2,x3)
    local b0,b1,b2,b3=cubic_coef(y0,y1,y2,y3)
    
    --set endpoint for first segment
    -- by poking ram with coords
    poke2(0x5f3c,x0) poke2(0x5f3e,y0)
    --  --optional: clear error to avoid bugs
    --  poke(0x5f35,0)--4 tokens
    
    for t=0x.1,1,0x.1 do
        line(
            a0+t*(a1+t*(a2+t*a3)),
            b0+t*(b1+t*(b2+t*b3))
            )       
    end
    end
  3. Adaptive-segments option. This one is a bit faster for small curves - like 320/frame - but much slower for large curves - like 110/frame.

    --recursive, fixed 2px precision
    -- (+186 tokens)
    function cbez_recurs2(x0,y0,x1,y1,x2,y2,x3,y3)
    --cubic bez, adaptive points
    
    --precalculate polynomial coefs
    local a0,a1,a2,a3=cubic_coef(x0,x1,x2,x3)
    local b0,b1,b2,b3=cubic_coef(y0,y1,y2,y3)
    
    --set endpoint for first segment
    -- by poking ram with coords
    poke2(0x5f3c,x0) poke2(0x5f3e,y0)
    --  --optional: clear error to avoid bugs
    --  poke(0x5f35,0)--4 tokens
    
    --poly function
    local function xy(t)
        return
            a0+t*(a1+t*(a2+t*a3)),
            b0+t*(b1+t*(b2+t*b3))
    end
    --subdividing draw function
    local function crawl(tp,tn,xp,xn,yp,yn)
        --draw curve recursively to tn
        local tm=(tp+tn)>>1
        local xm,ym=xy(tm)
        --luchak fast abs
        local xerr,yerr=(xp+xn)>>1,(yp+yn)>>1
        xerr-=xm
        yerr-=ym
        if xerr^^(xerr>>31)>2
        or yerr^^(yerr>>31)>2
        then
            --not precise enough; recurse
            crawl(tp,tm,xp,xm,yp,ym)
            crawl(tm,tn,xm,xn,ym,yn)
        else
            --close enough; draw
            line(xm,ym)
            line(xn,yn)
        end
    end
    local x5,y5=xy(.5)
    crawl(0,.5,x0,x5,y0,y5)
    crawl(.5,1,x5,x3,y5,y3)
    end

    (Shoutout to @luchak, from whom I swiped this fast abs function - I think it ended up reducing runtime by about 3%, which might not be worth it but hey.)

There's probably ways to optimize these further that I haven't thought of - I'm just not very good at that - so please feel free to sound off with any suggestions.

Also, I tried to make good comments, but let me know if anything's unclear.

P#122890 2022-12-23 14:04

[ :: Read More :: ]

Out of curiosity, I was testing to confirm that the new limit on length of audio recordings via extcmd("audio_rec") was per-instance and not per-session ... and discovered that the length of recording I got was 2 minutes instead of the 8 minutes listed in the v0.2.5d changelog.

An 8-minute limit makes sense to me but a 2-minute one doesn't, so I'm assuming this is an error of some sort.

edit: confirmed fixed in v0.2.5g.

P#122402 2022-12-14 17:46 ( Edited 2023-02-15 20:48)

[ :: Read More :: ]

Taking a crack today at building drum kit SFX - I've labeled this one as a "High Tom", but if you play it on a lower note than C2, I think it'll probably serve for whatever tom you need. You do need to take care of fading out the notes yourself, though - the SFX ends on a held G1, just to let the drums have a longer sustain than 32 ticks.

[sfx]

P#118558 2022-10-04 22:55

[ :: Read More :: ]

The trouble with the General Midi 1 standard is that it doesn't include any explanation of what any of the names mean, so I had to spend multiple seconds of research on going to the GM-1 Wikipedia page and scrolling down to the best guess of the editors there. Apparently, by "SynthStrings", they probably mean a string synthesizer, or string synth, an electronic instrument originally intended as a relatively cheap and portable substitute for a strings section, but which people later started to use as an instrument in its own sake.

So, that's what I tried to imitate. And since GM-1 has two SynthStrings program numbers and says nothing about how they should differ, I just tried to follow what GeneralUser GS seemed to do and make the second version a little brighter in timbre.

Here's 050 SynthStrings 1:
[sfx]

...and 051 SynthStrings 2:
[sfx]

P#118465 2022-10-03 22:19

[ :: Read More :: ]

Another simple one, although there's some pretty aggressive ... can you even call it tremolo if it's this slow? In imitation of the VCSL sample I was using as inspiration. Makes for an interesting effect, which I think fits the folk-instrument vibes.

[sfx]

P#118393 2022-10-02 21:08

View Older Posts