Author of Downstream Dream, Star Trek: Killer Q'egh, and TMNT: Shredder's PREvenge OST. Sound designer for Demi Daggers. Currently making poppy little dance tunes.
The upcoming Pico-8 0.2.6 release will introduce wavetable synthesis via "waveform instruments". Any of this may change before release so I will try to update it as I discover new info about the feature. The waveform instruments are stored in the same sfx indices as regular instruments (0-7) and use a similar encoding scheme to regular sfx:
Bytes 0-63
The first 64 bytes of the sfx contain one signed 8-bit sample per byte. Pico-8 uses signed 16-bit numbers, so signed 8-bit values from -128 to -1 are represented as 128 to 255, while 0 to 127 are represented normally. Signed 8-bit values outside the -96 to 96 range will appear cropped in the visual editor, although it does appear to be possible to draw values in the full range by dragging the mouse cursor beyond the border.
Regarding PCM playback, Pico-8's tracker updates at about 120.4918Hz, and at 64 signed 8-bit samples per cycle, the sample rate would be about 7711.4752Hz. However, because the closest playback frequencies available are A#-0 (A#-2 in standard pitch notation @ 116.54Hz) or B-0 (B-2 in standard pitch notation @ 123.47Hz), it appears that smooth PCM playback will not be possible by stringing waveform instruments together, as waveforms would not have the chance to play exactly one oscillation per tick; instead being slightly cropped or slightly looped (and then cropped). This will result in clipping/distortion, and weird tuning artifacts.
Byte 64
Used for editor mode and sfx filters. This byte serves the same purpose as regular sfx and the filters introduced in 0.2.2 can be used with waveform instruments.
Byte 65
If the lowest bit is set (1), the "bass" option will be activated and the instrument will be transposed down one octave. I assume this is similar to poking byte 0x5f40.
Byte 66
If the highest bit is set (128), the sfx will be activated as a waveform instrument.
Byte 67
Unused
Hi friends, looks like exciting changes are coming soon. I guess this might be the last song I make before 0.2.6 is out so this is my send-off to Pico-8 audio as we knew it. See u on the other side! 🙂
Hi friends,
Here's the OST for @freds72's upcoming release, Demi Daggers. Trying to recreate the complex sound design of Devil Daggers and its OST in Pico-8 was a massive challenge. I hope I did it justice, and I hope you enjoy it!
"II"
Originally composed by Sorath
"III"
Originally composed by Sorath
Hi Zep! :)
I'm not sure if this is by design, but it seems printh()
resolves paths differently than cstore()
, reload()
, etc; where printh()
does path resolution relative to root_path
, while the other funcs resolve paths relative to the running cart.
For example, given the directory structure:
project_dir/ |_dist/ |_foo.p8 |_log.p8l |_utils/ |_bar.p8 |
and launching with:
project_dir $ pico8 -root_path ./ ./utils/bar.p8 |
project_dir/utils/bar.p8:
cstore(0, 0, 0x4300, "./dist/foo.p8") --doesn't write to foo.p8 cstore(0, 0, 0x4300, "../dist/foo.p8") --writes to foo.p8 printh("hello world!", "./dist/log") --writes to log.p8l printh("hello world!", "../dist/log") --bad log error |
I'm not sure which way I think all the funcs should behave, but I'm inclined to say printh()
should resolve paths relative to the running cart like the other funcs, because it would probably be less surprises for the user that way.
Anyway, thx for your time!
Originally composed by:
Jürgen "DJ Jurgen" Rijkers,
Sebastiaan "Pronti" Molijn,
Eelke "Kalmani" Kalberg,
Judith Anna Pronk
The idea for this cart was inspired by a comment @Liquidream made to me a few months ago. 😂 Enjoy your week, everyone!
I hope everyone is taking good care of themselves. Be safe and have a great weekend! 🙂
Hi friends,
@Wolfe3D recently asked me to do the soundtrack for his fan game, Teenage Mutant Ninja Turtles in: Shredder's Prevenge. With such an ambitious and impressive project shaping up, how could anyone say no? I'll be posting music here and on radico8 as Wolfe3D releases the corresponding game content. The soundtrack will feature seven songs plus assorted jingles. I'll lead off here with a couple covers I couldn't resist trying to make. I hope you like them!
(This is a totally free, totally non-commercial fan project, all intellectual property contained within the content below belongs to its respective owners. Please don't sue me.)
11/15/2023: Added Super Smash Turts, Shinobi Sentai Shellranger, lowercase technodrome, Tin Grin.
Tracklist
- Title Theme 🌃
- Main Menu: Go Green Machine! 🛺
- Arena Menu: Super Smash Turts 💥
- Level 1: Uptown Cat Blues 🎸
- Boss Theme: Battlehead 💀
- Arcade Theme: Turtle Tokens 🕹
- Level 2: This is a Cover of Sewer Surfin' 🏄♂️
- Level 3: Shinobi Sentai Shellranger 🎇
- Level 4: lowercase technodrome 🌐
- Final Boss Theme: Tin Grin 👣
- End Credits: This is a Cover of Pizza Power 🍕
Title Theme 🌃
Contains arrangements of the 1987 Teenage Mutant Ninja Turtles theme, originally composed by Chuck Lorre and Dennis Challen Brown.
Main Menu: Go Green Machine! 🛺
Contains arrangements of the 1987 Teenage Mutant Ninja Turtles theme, originally composed by Chuck Lorre and Dennis Challen Brown. Cover art is a scan of the NES box art for TMNT II: The Arcade Game.
Arena Menu: Super Smash Turts 💥
Cover art is a scan of the Japanese Sega Mega Drive box art for TMNT: Tournament Fighters.
Level 1: Uptown Cat Blues 🎸
Contains arrangements of the 1987 Teenage Mutant Ninja Turtles theme, originally composed by Chuck Lorre and Dennis Challen Brown. Cover art is from a Pizza Hut promotional poster for the Coming Out of Their Shells tour.
Boss Theme: Battlehead 💀
Controls:
⬅️➡️⬆️⬇️🅾️❎: Play victory jingle
Contains arrangements of boss themes from the arcade games Teenage Mutant Ninja Turtles and Turtles in Time, originally composed by Mutsuhiko Izumi. Cover art is a scan from the Mirage Studios TMNT comics.
Arcade Theme: Turtle Tokens 🕹
Contains arrangements of the 1987 Teenage Mutant Ninja Turtles theme, originally composed by Chuck Lorre and Dennis Challen Brown. Cover art is a screenshot from the 1987 animated series.
Level 2: Sewer Surfin' 🏄♂️
Originally composed by Mutsuhiko Izumi. Cover art is a screenshot from the arcade game, Turtles In Time.
Level 3: Shinobi Sentai Shellranger 🎇
Cover art is the poster for the 1993 film, Teenage Mutant Ninja Turtles III.
Level 4: lowercase technodrome 🌐
Cover art is a screenshot from the 1987 animated series.
Final Boss Theme: Tin Grin 👣
Cover art is a scan from the IDW Publishing TMNT comics.
End Credits: Pizza Power 🍕
Originally composed by Bob Bejan and Godfrey Nelson. Cover art is a scan of the Coming Out of Their Shells CD insert.
Hi Zep! :)
0.2.5g: In non-C-style for loops, if a multi-line comment is opened/closed before the first variable declaration, without trailing whitespace before the variable name, it will throw a syntax error. All other situations seem to be okay:
--[[ok]]foo = --[[ok]]{1} --ok for --[[ok]]i=0,1 do print(foo[i]) end for --[[ok]] v in all(foo) do print(v) end for --[[ok]] k, --[[ok]]v in pairs(foo) do print(v) end for --[[ok]] k, --[[ok]]v in ipairs(foo) do print(v) end --not ok for --[[oops]]v in all(foo) do print(v) end for --[[oops]]k, --[[ok]]v in pairs(foo) do print(v) end for --[[oops]]k, --[[ok]]v in ipairs(foo) do print(v) end |
On 0.2.5e, the following message is printed to stdout whenever a cart containing any arbitrary meta section is run:
$ pico8 -run test.p8 codo_free fail 21 0 |
test.p8:
pico-8 cartridge // http://www.pico-8.com version 39 __meta:foo__ bar |
Carts seem to run fine, so there don't seem to be any other negative effects.
Hi, friends!
Here's a demo featuring 5 glorious channels of lo-fi audio! Making a chipbreak-style tune in Pico-8 has been in the back of my mind ever since @carlc27843 discovered the undocumented PCM channel, and now I can finally check this off my list! After almost 2 years! 😅
All the drums are samples, triggered by watching the tracker with stat(56). The samples are then fed to the PCM channel by monitoring the buffer with stat(108). I'd originally planned on building a 5-channel tracker from this demo, but I had a tough time getting the samples to sync consistently. I'm not sure if that's because of my own shortcomings, or maybe because as @zep literally said, the sync is "not perfect".
For the gfx, the star animations are also triggered by stat(56), whenever a snare sample is played. The road is just one gigantic image using a palette cycle. It looks like this:
Anyway, I had a lot of fun putting this together. I hope you like it! 😃
Special thanks to @pahammond for GEM, which helped keep this cart under the compressed limit!
Hi Zep! :) I think I found a bug in one of the more esoteric stat calls?
Bug:
According to the manual, stat(56) should return the number of ticks played in the current pattern. Currently (0.2.5e), it seems to poll the leftmost sfx in the pattern for the count. That makes sense bc the overall pattern length is determined by the leftmost sfx which is not a loop, but as the title says, stat(56) will reset back to 0 early if the leftmost sfx is a loop.
Expected behavior:
stat(56) should return the number of pattern ticks played regardless of looped sfx
Thanks for your time! :)
I was going to wait to post this until the weekend, but I have no self-control. 😅 Enjoy the rest of your week, everyone!
Here's another new song! Have a great weekend! 😃
This one is short but sweet. I hope you enjoy it! 😊
View Older Posts