1 (edited by Shiru 2016-03-07 22:51:34)

Topic: BuzzKick (1tracker)

In order to do some experiments with the mixed PFM/square synthesis, I decided to make a FuzzClick-like engine first. It uses the same sound synthesis loop, the same two channels with sustain control, but different, much simpler format and parsing code. It also has some features I wanted to have - no interrupts enabled (no random clicks), detune support, per-row speed control, and customizeable sampled drums (lifted up from Phaser3).

You can re-download 1tracker to get this engine.

However, the engine sounds somewhat different than the original FuzzClick, and has more noticeable cross-detune issues (compared side-by-side). Honestly, I never fully understood the concept of this exact kind of engines, so maybe I did something wrong. So, utz and introspec, please look into it by a chance. Would be nice to sort out the issues before moving further.

website - 1bit music - other music - youtube - bandcamp - patreon - twitter (latest news there)

Re: BuzzKick (1tracker)

Neat, I'm especially surprised you managed to balance the volume between the sampled drums and the tone channels.
I'm still pretty bad at reading other people's code, so I'll need a bit of time to really dig into the code.

Also noticed there are some UI changes... got any plans with that, or is it just changes in SDL?

3 (edited by Shiru 2016-03-08 18:30:54)

Re: BuzzKick (1tracker)

The UI changes is just different font.bmp file, it allows to customize the looks (along with the .cfg file). Tried to do something more comfortable to work with on my PC. Tracker code itself had no changes yet, although yes, I want to eventually add some things from SNESGSS interface, that also had pattern-less approach.

Sound generation loop from this engine, that closely matches SpecialFX:

soundLoop

    ld a,3                ;7 - this part is just 62t delay, to align the (empty) loop to 168t, allowing to have lowest E note
    dec a                ;4
    jr nz,$-1            ;7/12=50t
    jr $+2            ;12

    dec d                ;4 - channel 1 8-bit counter
    jp nz,.ch2            ;10

.ch1freq=$+1
    ld d,0            ;7 - reload counter

.ch1delay1=$+1
    ld a,0                ;7 - first variable delay, that is like bottom of a pin, it gets changed by the decay envelope
    dec a                ;4
    jr nz,$-1            ;7/12

.ch1out=$+1
    ld a,0                ;7  - output a set bit (or reset, if the channel is muted)
    out (#fe),a            ;11

.ch1delay2=$+1
    ld a,0                ;7 - second variable delay, that is top of a pin
    dec a                ;4
    jr nz,$-1            ;7/12

    out (#fe),a            ;11 - reset output, pin is ended

.ch2

    ld a,3                ;7 - the same for the second channel
    dec a                ;4
    jr nz,$-1            ;7/12=50t
    jr $+2            ;12

    dec e                ;4
    jp nz,.loop            ;10

.ch2freq=$+1
    ld e,0                ;7

.ch2delay1=$+1
    ld a,0                ;7
    dec a                ;4
    jr nz,$-1            ;7/12

.ch2out=$+1
    ld a,0                ;7
    out (#fe),a            ;11

.ch2delay2=$+1
    ld a,0                ;7
    dec a                ;4
    jr nz,$-1            ;7/12

    out (#fe),a            ;11

.loop

    dec b                ;4
    jr nz,soundLoop        ;7/12=168t

The weird part of PFM engines of this kind, with separate pins (not combined like QChan or Octode), that I don't really understand, is that they output both 0 and 1 parts of a pin with corresponding delay, not just 1. If you omit the 0 part with its delay, cross-detune gets just horrible, even with two channels.

website - 1bit music - other music - youtube - bandcamp - patreon - twitter (latest news there)

Re: BuzzKick (1tracker)

Hmm, I don't even understand why this doesn't cause massive cross-detune all the time.
That said, wouldn't it be possible to combine the pins after all, by adding up the delay values of both channels?

Edit: What exactly are the values that get fed into the variable delay? Is the delay for the 0-pulse some kind of inverse of the 1-pulse, ie the longer the 1-pulse delay, the shorter the 0-pulse one?

Re: BuzzKick (1tracker)

Unfortunately, combining the pins gives different timbre. Not sure how to describe it, and I didn't analyze it, but it feels like it has different harmonics. Engines of this kind, with separate pins, were underdeveloped in modern era. In the past it was FuzzClick, the Code Masters engine (Whittaker's?), Tim Follin's, the one from Dark Fusion, etc, and currently there is next to none (just original Beep Tracker). Worth experimenting, I think.

The overall delay1+delay2 always equals to the same time, so width of a pin (0 and 1 parts) is always the same. Initial values are tricky for FuzzClick, delay1 is the frequency counter value shifted >>2 or >>3 (for channel 1 and 2 respectively, gives different 'volume'), and delay2 is 1. I replicated exactly the same, as I wanted to have the same sound.

website - 1bit music - other music - youtube - bandcamp - patreon - twitter (latest news there)

Re: BuzzKick (1tracker)

I see. So it makes sense that there is detune if the 0-delay is omitted - but that should be a self-detune, not a cross-detune, no?
Also, what do you think about "correcting" the other channel's counter when a pulse is triggered? I don't think it'd even need to be accurate, just decrement the counter by roughly ((pin delay length/undelayed sound loop length)+1) and if it overflows, jump right into pin pulse generation for the other channel (+ timer update as required), else skip the other channel update.

Re: BuzzKick (1tracker)

These engines (SpecialFX, Music Synth and so on) are all based on the same principle of playing with the duty cycle, i.e. the 0/1 balance of a period, on a small enough scale where modifying the cycle is still perceived more as a change in volume rather than the timbre. The reason they employ this two-part delay scheme is reducing volume-dependent timing fluctuations/cross detune. One delay counter is decreased while the other one is increased at the same time as the envelope decays. This allows the length of the pulse to remain the same throughout regardless of volume, so that whichever cross-detune issues remain are frequency related.

8 (edited by gotoandplay 2016-03-11 22:34:52)

Re: BuzzKick (1tracker)

It's no understatement to say that the 1-bit development is progressing so much faster than the rest of the chipscene. There seems to be more updates, engine creations and overall activity that I can't keep up with it, haha! Keep up the good work smile

Re: BuzzKick (1tracker)

Well said, my friend. That's indeed one of the reasons I'm hooked on 1-bit music. There's a lot of uncharted territory waiting to be explored.

Re: BuzzKick (1tracker)

Hey hey, yes there does seem to be a lot of activity recently. It's great  smile