26

(9 replies, posted in Sinclair)

Squashed one more bug today. Also tried to implement resonance, but either I'm doing it wrong, or the volume resolution is insufficient to do it. In any case, this should be it, not planning to do more work on this in the near future.

Would be great to have it in 1tracker. I'm not adding it to Bintracker yet, because the engine plugin format still isn't stable.

27

(9 replies, posted in Sinclair)

Fixed some bugs, and found a way to properly calculate the cutoff 1.5 tables (by doing level 2 on a rising edge and level 1 on a falling edge). In theory this could be extended to other intermediate levels, doubling the cutoff resultion. However the filter response is such that the perceived difference between eg. level 2 and 3 is actually smaller than between 1.5 and 2, so I didn't bother implementing any more *.5 tables. Users can add their own filter tables if needed.

28

(9 replies, posted in Sinclair)

Aaaand voilà. Volume control implemented. Lower volume means less precision for the filters, of course. Updated source is on github, see above.

Now what I would really like to have is resonance. Not sure if it's actually possible with this setup. In any case I can't wrap my head around the math of it.

29

(9 replies, posted in Sinclair)

Ha, last night I realized that volume control is actually possible with this engine. It just requires lots of additional filter tables, but that can be done without increasing the code size.

Anyway, thanks guys.

Ah, L/C/R panning definable in software, excellent. Like the idea of a RISC V MCU, too. How does it fare in terms of price, though? Mouser claims they're selling a ESP32-C3 for around 1€ over here, but pretty much any other seller is asking around 20€.

Yes, that all makes a lot of sense. Also, damn, I keep forgetting that AVR is a Harvard arch.

About the sound system, my main concern at this point would be that it becomes too powerful. 8x1-bit with auto-reset would be wild, of course, but at some point it becomes tempting to treat the whole thing as a quirky kind of DAC and stream PCM on it, similar to how it works on RaspPi.

Btw, any plan for how to implement WiFi yet? I imagine this would add quite some complexity, in addition to possibly needing to introduce not-so-open components to the design.

It all sounds great to me. Unfortunately I can't be of much help with this, since I'm not versed in hardware design at all.

Regarding the sound system, your second idea appeals most to me, as it offers a lot of flexibility while being straightforward and simple to conceptualize. Buffered beeper would be a bit like if PET shift reg would actually work as described. Very powerful, but would lead to a completely different way of writing engines.

One thing that would be very desirable is proper audio plugs, as in RCA or big jack. Small jacks are an absolute nightmare when playing live. And I do want to play this thing live.

It might also be worth considering whether to use a modern instruction set instead of Z80, eg. AVR? Personally my heart beats for Z80, of course, but using AVR might make this device more accessible for programmers that aren't deeply rooted in the 8-bit world.

Regarding configurable emulation rate, this would be great to have exposed as a knob on the hardware.

33

(9 replies, posted in Sinclair)

tldr: 2 pulse channels with lo-pass/hi-pass filters with somewhat variable cutoff.

- 2 pulse wave channels
- variable duty cycle
- duty cycle sweep with variable speed
- noise mode (channel 2 only)
- filters with variable cutoff (6 levels for lo-pass, 5 levels for hi-pass)
- sample rate 9114 Hz
- interrupting PWM sampled drums at 18229 Hz with 7 pitch and 3 volume levels
- player size 3333 bytes (when assembled at a 256b border)

source code


Some points of interest:

- The filter implementation itself is pretty boring, just a lookup into a 14-byte table with values for each pair of (current volume, next raw channel state).

- Noise mode uses a new technique. The engine has one version of the main loop for each volume level, so using self-modifying code to enable/disable the effect was not an option. After just randomly experimenting, I ended up with

  ; hl is oscillator state
  ld a,(MASK)
  and h
  rlca
  xor h
  ld h,a

At 29t it's rather expensive, but I really wanted noise mode and could spare the cycles. Depending on MASK, the divider and the duty cycle, this can produce many wildly different sounds. I found that using a mask of 0x76 and a divider of 0x2712 works well to fake standard white noise, with duties from 0x30-0xc0 being somewhat usable for simulating volume levels. Unfortunately the filters are a bit to crude to really work well on noise.

- Using a rather low sample rate for the PWM drums here. Not sure if that's such a great idea, but hey, we've got noise mode to make up for the low upper frequency limit. Originally I wanted to do synth drums instead (using the new noise mode of course), but in the end PWM is much more convenient for the composer.

- Still got some cycles left, so this can be pushed further. Phaser with filters would be really cool, and might be doable. Aside from needing to find some additional registers, the main challenge would be to swap the xor/or/and without smc.

I'm also wondering whether it is possible to increase the cutoff resolution. In theory the number of volume levels can be doubled by going from 16t to 8t per volume level, but that has the problem that we cannot render level 1 properly on ZX beeper. On hardware, this can be done by sacrificing levels 0 and 1 and using level 2 as new level 0, but on emulators this is inherently beepy (that's why zbmod has an "emulator" version). So I don't want to go down that route. In ulasyn, each volume level is generated twice per sample, so one could theoretically jump to the previous or next level half-way. The problem is that if this happens repeatedly at the same volume, we get an audible parasite tone from the mixing. So the filter tables and total volume calculation would need to take that into account. Right now what's being looked up is the answer to the question: Given the current volume 0..6 and the unfiltered next volume (either 0 or 6), what should be the next volume? This needs an added delta, ie: Assuming that the unfiltered next volume does not change,will the volume increase, decrease, or stay the same in the sample after the next one? Based on this, we can select the next volume "core" as follows:

- If both channels want to increase the volume further, jump half-way from volume to volume+1.
- Likewise, if both channels want to decrease the volume further, jump half-way from volume to volume-1.
- Else, do not jump half-way.

This way, repeated jumps from the same initial volume can only occur when the volume lookahead is wrong (because unfiltered state changed from 0 to 6 or vice versa), which should be rare enough to avoid parasite tones. This would give us one additional bit of cutoff precision.

34

(10 replies, posted in Sinclair)

Voilà. Haven't tested it extensively so there might still be bugs lurking here and there.
Ended up implementing drums as 8-bit PWM at 27210 Hz. Tried to do it at 54420 Hz, but it's impossible. It wouldn't make much sense anyway since 54420 Hz would leave us with a lower range limit of ~212 Hz unless we'd go 16-bit.

Btw, looks like Furnace can't actually compile z80 code yet. So this is going to take a while in any case.

Edit: source updated with a small tweak to reduce row transition noise

Edit 2: cut player size down to 3333 bytes

35

(10 replies, posted in Sinclair)

Ah, great, it's a binary. 1990s called, they want their file formats back. Even after decompressing it, I can't make much sense of it.

Meanwhile, massaged the engine a bit so it does 60Hz updates (at a sample rate of 9114Hz, can't go faster anyway). Now I'm wondering what to do with the drums. Documentation says they're pitchable 1-bit PCM drums up to a max length of 2048 samples running at a rate of 54420 Hz. Not sure why you would want to do it this way, but ok. I'd use PWM drums in any case, but 54420Hz comes down to about 63t, which I don't think is enough to decode either 1-bit PCM or PWM AND calculate pitch. Might have to cut some corners here.

36

(10 replies, posted in Sinclair)

rough engine draft

37

(10 replies, posted in Sinclair)

That actually looks quite workable, for a start. I think it could be compressed well enough by first condensing each row so that duplicate data is omitted and presence/absence of entries is marked with some control byte, then adding each unique row to a dictionary and constructing a sequence of pointers to the dictionary.

The question would be what to do with those 60Hz updates. Could be implemented as such in the engine, at the cost of lowering the sample rate and sacrificing accuracy in the time domain (ie. updates would be applied on consecutive loop iterations instead of all at once), or one could recalculate any effects for a lower update rate. In any case effects would need to be flattened/precalculated.

Some things in this dump are a mystery to me as well though. 4: NOTE_ON 24 2 might be a trigger for the interrupting PWM channel, but then where's the sample data and what defines the playback length of the sample?

Edit: Another problem with the stream dump format is that it does not seem to distinguish actual triggers from notes continued from the previous row. Also, where is the instrument information (eg duty)?

38

(10 replies, posted in Sinclair)

It's a shame Furnace doesn't put more effort into actually getting tracks to run on hardware, since it has already become somewhat of a de-facto standard in the scene and attracts a lot of young talent. But here's the point: That young talent doesn't have access to actual hardware for the most part, so they don't care if it runs on hardware. For them, this is as close to "real" as it gets. That's the reality of chiptune in 2024, like it or not. Can't blame the Furnace devs either - they focus on providing what the majority of their users want, and that works for them, both in terms of number of users as well as number of people involved with development.

The only chance for setting things right from our perspective would be to implement hw support for the two Furnace players ourselves. I think it's doable, the specs are relatively sane. There are a couple of issues - if I understand correctly both engines assume 50Hz updates, which is not feasible for QuadTone, and QuadTone seems to assume an internal loop time of >224t, which obviously is going to have much more of a parasite tone than what is currently emulated. But with a few minor adjustments it could be done. I'm not willing to work on it though for a number of reasons, at least not the C++ side of things.

39

(10 replies, posted in Sinclair)

quad tone is the Furnace one afaik

40

(111 replies, posted in Sinclair)

Looks like Multimatograf is going to have a beeper compo this year. Deadline is April 28th.

https://events.retroscene.org/mf2024#zx_beeper

41

(111 replies, posted in Sinclair)

Congrats AER smile A well-deserved win.

Thanks! I've given a few talks over the years, though I'm not sure if there are any recordings out there. Not that you'd want to see the ones from 15 years ago anyway yikes Would like to give more talks in the future, in any case.

43

(43 replies, posted in Atari)

If there is a new engine with not-too-difficult data format, I can add it to Bintracker. If game_music_emu supports GTIA then 1tracker would also be an option.

I don't think the SampleTracker engine will sound too great on GTIA. It's pretty bad on ZX beeper as well from what I remember. I think Shiru added that more with AY/Covox in mind.

Yay, Beep'em all VI! Great collection.

44

(43 replies, posted in Atari)

Well, in the end I was too lazy again to make something yikes Looks like I wasn't the only one, though.
To be honest I'm also somewhat demotivated by the lack of new engines (with the exception of TritoneFX, which is not so useful, sadly). I think if we want to put GTIA back on the map, we need some new, state-of-the-art GTIA engines. Preferably native Atari ones. Atari 8-bit is a more powerful machine than Spectrum, so in theory it should be possible to make a more powerful 1-bit engine for it, shouldn't it?

Wow, massive collection, pretty neat. I'd love to also see some demo songs from old PC Speaker editors like Music Construction Kit, Note Baron, VMusic, etc.

There might be some more on https://battleofthebits.com - however, finding them would require to dig through all the recent entries and see if anyone posted a .1tm source in the track description or in the comments. In the botb browser you can filter by type (zxb, last button in the list of formats) and sort by date ("when").

47

(43 replies, posted in Atari)

xxl wrote:

This year at SV I am exhibiting the Beep'em All 6 music collection.

Yesss!

xxl wrote:

I hope that there will also be original songs in 1bit compo

To be honest I completely lost track of what is available on GTIA nowadays. Could you post a list of currently available engines?

48

(16 replies, posted in Other Platforms)

I can't remember the details, sorry. It was only some specific places where it was happening, not all around. I'll look into it again after next week.

49

(16 replies, posted in Other Platforms)

Alright, got it working. Quick'n'dirty test doodle attached.
The SDL number keys seem a bit wonky, sometimes returning the "last entry" instead of the actual number of the key pressed. Other than that I couldn't spot any issues on my quick try-out.

50

(16 replies, posted in Other Platforms)

Can confirm that the build works. However I can't run it, it's complaining about a missing data/ebt.cfg.