investigate tic80 audio
task id: investigate-tic80-audio2024-07-07 09:48: want to examine audio code and capabilities in tic80 today #investigate-tic80-audio
2024-07-07 14:07: Examining TIC-80 codebase for audio #investigate-tic80-audio #timelog:00:21:25
The idea is to find the files, then add them to codestudy.
I think I found the music. One file sound.c
, almost 600 lines. Not too bad, actually.
Adding to codestudy.
why didn't sound.c import?
oh it did, but the CSS broke. why did it break? Gotta look into this. again.
2024-07-07 15:23: Back to tic80 #investigate-tic80-audio #timelog:00:49:55
2024-07-07 15:42: What things call these functions? #investigate-tic80-audio
I want to see an audio callback.
2024-07-07 17:06: Next steps #investigate-tic80-audio
I think I'm pretty close to understanding how the callback stores audio into buffers. There's a resampling step which I need to figure out more, but I believe I know where I can inject custom DSP. At that point, I'll be ready to make a follow-up task.
2024-07-08 09:10: TIC-80 investigations part 2. #investigate-tic80-audio #timelog:01:017:34
2024-07-08 09:19: 8-bit audio. #investigate-tic80-audio
I shouldn't be terribly surprised by this, but the output is 8-bit.
2024-07-08 09:48: second-guessing myself on the 8-bit depth #investigate-tic80-audio
It could be that that's just a raw byte format. The sound code here is fairly involved. I'm going to need to look at this more.
2024-07-08 09:50: Unclear what is a buffer and what is a tick #investigate-tic80-audio
It is unclear to me when things are computing a single sample of audio (tick), and when it's writing to a buffer.
For example, SOKOL seems to be writing shorts (16-bit).
What I do know is that samples eventually show up in something called "product->samples.buffer", but I cannot find that definition yet (there's a lot of macro magic in this repo). There is also a buffer count too. It appears that these could be interleaved samples.
2024-07-08 10:20: So much is implicitly defined #investigate-tic80-audio
As far as I can tell, product.samples
is dynamically generated. It's not actually anywhere in a struct. The tic80
stuct I have yet to actually find. Same goes for product.samples.buffer
and product.samples.count
.
There are two top audio callbacks that tell tic80 to generate soud (how much sound not sure? but it's definitely multi-channel). I'm looking at the one sokol uses called studio_sound
. This calls tic_core_synth_sound()
, which I assume writes to product.samples.buffer
somehow. If I can inject an effects processor right after the buffer is fully written, I think that can be enough for me.
2024-07-08 10:30: =runPcm()= and =stereo_synthesize()= are things to look at #investigate-tic80-audio
These calls seem to happen right before they are resampled.
2024-07-09 08:19: Initial investigation completed, now onto initial challenge: sine tone test. #investigate-tic80-audio #tic80-sine-tone
I think I know about enough to get started on hacking in a sine tone into the TIC-80 sound codebase.
A sine tone is ideal because it's a pitched pure tone, and it can be easy to tell if I'm getting the buffering and sample rate correct. If I can get a sine.
How hackable is it? Is it feasible to shove my rust DSP code into the TIC80, audio callback, and control it from tic80 code?
I think this could be a fruitful way to build an ecosystem of toys that match my current aesthetic. I have semi-long term plans for this potentially.
I say "semi-potentially" because for its constraints, the software has quite a complex software stack. I don't expect this to be the most portable thing in the world. The most portable things are ideas, and after that, bytes of data (8 bits to a byte is fairly universal). There is a cartridge format, which may end up being a promising data format for portability, but we'll see.
Short term (as in this batch), portability or longevity is not a concern. I just want to hack stuff.