Log In  


Cart #12679 | 2015-08-15 | Code ▽ | Embed ▽ | No License
30

I wanted to experiment with modifying SFX data via a cart.

Features:

  • Compose and edit music
  • Copy and Paste selections within patterns and between patterns
  • Transpose selection by octaves
  • Save to cart

Known issues:

  • Modifying selections only works if the selection was made in a leftwards direction.
  • The music staff isn't actually accurate at all. It just uses one px per semitone.
  • Green play line isn't always accurate if you've changed the speed or pattern length, restarting playback fixes it.

SFX Data Layout for anyone interested:

Starting from 0x3200
Blocks of 68 bytes for each SFX pattern 64 bytes of sound data and then 4 bytes of metadata.

Each sound data chunk is made of a 16 bit value divided into
6 bits for the note, 3 bits for the instrument, 3 bits for the volume, 3 bits of the FX, 1 bit unused.

0bUFFFVVVIIINNNNNN

byte 65 is the speed
byte 66 is loop start
byte 67 is the loop end

30


Cool to see that you made this! I may have to pass it on to my musician friend.


Really nice work, this is looking great.


I love how this community goes from "hey that'd be cool to make" to "hey I made this thing we talked about the other day." Really slick work, and a very intuitive interface.


Okay, honest question here about the way speed works. I've got a boss fight where I want the music to increase in speed as he takes damage, but when you modify the speed of all tracks while the music is playing, the current measure runs for as long as the old speed. So if the delay is decreased and notes play faster, there's a silent pause for a bit until the next measure starts up. And if the delay is increased then the last few slower notes get cut off and the next measure starts early.

Is there another place in memory where the current pattern speed/delay is stored, probably calculated as the max of the four tracks speed * 32 notes? Can I access this so the current measure timing gets updated?

For now I'm checking the current note index via stat(20)==31, and only updating the track speeds on that last note so it has a very short silence or cutoff on the last note. But there has to be a better way!


@Shazang I know! what I really like about pico8 is how quick it is to go from an idea to a working prototype, to a useful thing.

@innomin good question! I'm not sure how that music stuff works, might need to ask zep.
good to know about stat(20) though!


Why yes, this game does need mouse input!


p8: http://codepad.org/OeRl6oIq

Here's the patch:

3a4,23
> 
> mouse = {
>   init = function()
>     poke(0x5f2d, 1)
>   end,
>   -- return int:x, int:y, onscreen:bool
>   pos = function()
>     local x,y = stat(32)-1,stat(33)-1
>     return stat(32)-1,stat(33)-1
>   end,
>   -- return int:button [0..4]
>   -- 0 .. no button
>   -- 1 .. left
>   -- 2 .. right
>   -- 4 .. middle
>   button = function()
>     return stat(34)
>   end,
> }
> 
7c27,28
< 	handx,handy=0,0
---
> 	mouse.init()
> 	handx,handy=mouse.pos()
213,216c234
< 	if btn(0) then handx-=(fast and 2 or 1) end
< 	if btn(1) then handx+=(fast and 2 or 1) end
< 	if btn(2) then handy-=(fast and 2 or 1) end
< 	if btn(3) then handy+=(fast and 2 or 1) end
---
> 	handx,handy = mouse.pos()

This music studio is wonderful (even if I'm more used to trackers), and the mouse patch is a nice addition!


Amazing, will definitely try using this instead of the sfx editor. I actually had a similar idea (something more akin to a MIDI sequencer) but this is way better than what I had in mind.


Interestingly the mouse click doesn't work in the web player on my Mac using Safari or Chrome? Though I can point with the mouse and press keys to click.


matt, i don't think there's any code to handle the button press in that patch, would need to add some extra logic.



[Please log in to post a comment]