From Jeskola Buzz Wiki
Jump to: navigation, search

This machine does not exist yet, but I have decided to write a design document on it, in order to highlight some of my thoughts. It's an attempt to get a tracker that doesn't click, doesn't kill the attack of percussion and resamples properly unlike MTrk and UTrk.

Update: This machine is currently in development.

Missing pre-requisites

  • Is it possible to look ahead in the pattern and predict notes? If not, the negative note delay idea is doomed.

The verdict seems to be that such a machine would have to provide it's own GUI for the pattern editor. Maybe PXP has some callbacks tough. Suggesting relocating feature into nice-to-have category and or V2.0 of SideTracker (which will have it's own GUI eventually).

Over-all goals

  • High quality output with no sound artifacts
  • DONE Resamples properly
  • Easy to use
  • Fairly decent performance overhead
  • Works in the current version of Buzz (with clone compatibility as an added bonus)
  • Once the project has taken shape and has matured, it will become open-souce
  • The most commonly used commands will be turned into global parameters or (only if it really makes sense) a per-channel parameter. This will make the pattern editor rather bloated though. We're trying to keep parameters as global rather than per-channel in order to reduce screen space consumption a bit.

Need to have features

  • DONE Support for all 16 bit int, 24 bit int, 32 bit float uncompressed mono/stereo .wav files.
  • Virtual channels and intelligent Global and Track handling. If you play a long sample three times in a row, e.g. C-D-E, you will hear all three. If you then use a "volume slide down" command, you will hear all three samples fade out. To do this, each virtual channel must remember what physical channel started it, and react to any commend on that physical channel.
  • DONE Make sure that 1 sample can be active with the same note on multiple voices.
  • An intelligent method of avoiding clicks. When switching to or from audio that has lots of treble, no de-clicking needs to take place at all. (Maybe the tracker can decide? If not, give the user an easy way to enable/disable declicking.) See De-clicking section below.
  • WORKS Paramete Smoothing should be done earlier than audio output. To do this we introduce a little latency (1ms or so)
  • All commands should exist in two versions placed at adjacent numbers so that it is easy to remember both: Sticky and temporary. Temporary commands (even command numbers) affect the tick or local area they're applied to. Sticky commands (same number but +1) are active until you specifically stop it. An example of this could be "vibrato": Let's say this command is called "14", then the permanent way to enable vibrato would be 14+1 = the "15" command.
  • This tracker must be able to handle sample offset, positive/negative note-delay and probability on the same note.
  • Different resampling algorithms: Fast, Medium, Good (aliasing free). This setting must be stored in a global way, so that if you move Buzz to a new PC, you can easily change this setting for all songs at once.
  • Better envelope controls. I want a "volume decay" command where you can change both the length (in milliseconds) and the decay curve (see graphics).
  • When all volume calculations and manipulations (such as setting volume, randomizing volume etc.) are done, the volume must by multiplied by itself. This is because the linearity of human perception of volume. -12 dB sounds way closer to "half volume" than -6 dB.
  • When panning far to one side, panning should be 3 dB louder in that side to compensate for lost amplitude. Also, panning should be switchable to use the Haas effect using some kind of global parameter (same sort of global parameter as used for choosing Resampling quality). This means that sound coming from the left side hits the left ear before the right ear. The delay is 35 ms at it's most extreme.

Nice to have features

  • Being able to handle any combination of commands.
  • MIDI support
  • Support for Wavetable features like multisample (currently broken..) and Envelopes (currently not really user friendly..)
  • Rudimentary Sample Editing functionality in some GUI
  • High quality pitch-Shifting and time-ttreching (in addition to the high quality resampler that is a must)
  • Support for all .wav formats
  • Drawing the output Waveform in the Sequencer View

Suggested parameters and commands

Adjusting the decay curve shape parameter produces various logaritmic slopes.

Global parameters

  • Decay length in milliseconds (maximum value is default and means no decay)
  • Decay curve shape (see above image) goes from a very logaritmic low slope to a very high slope. The default is not linear but a "normal" logaritmic decay (the middle curve on the decay curve image.)
  • Chord probability. Works like the the "Probability" command (15), with the exception that the same random number is used for all tracks. This way, you can use Probability on an entire chord, and either the entire chord is played, or it is not. 00=Never plays, 80=Plays 50% of the times, FF=All notes always play.

Per-channel parameters

  • Note (well duh!)
  • Sample number. Not setting this means re-using the last set sample number for this channel. This is needed because of PeerControl machines.
  • Volume. Setting this without playing a note will change the volume of the previously playing sample(s) to the current volume. Remember all virtual channels when coding this.
  • Note delay (default is 80 = no delay)
  • Decay length in milliseconds (maximum value is default and means no decay)
  • Decay curve shape (see above image) goes from a very logaritmic low slope to a very high slope. The default is not linear but a "normal" logaritmic decay (the middle curve on the decay curve image.)
  • Effect command (Yes, I really think we can do with only one because all commands now exist in "permanent" versions.)
  • Effect value


Please notice that all commands have two command numbers: An even number means "effect works temporarily on this tick or sample", and if you add one you get the "permanent" version of the same command.

  • 02 xx Slide up xx notches for this tick
  • 03 xx Keep sliding up xx notches
  • 04 xx Slide down xx notches for this tick
  • 05 xx Keep sliding down xx notches
  • 06 xy Vibrato, where x=speed, y=depth
  • 07 xy Vibrato until stopped, where x=speed, y=depth
  • 08 xx Panning, 0=left, 80=middle, FF=right (temporary does not make sense here)
  • 09 xx Same as 08
  • 10 xx Sample offset, 00=start, 80=middle of sample, FF=end of sample
  • 11 xx Same as 10, but affects all notes played on this track from now on
  • 12 xx Note delay. 01=-50% of a tick, 80=no delay, FF=50% of a tick delay (Yes you can do negative note delay now)
  • 13 xx Same as above, but the effect stays on for this track until you issue a "13 80" command.
  • 14 xx Probability. 00=never, 80=50% of the times, FF=always
  • 15 xx Same as 12, but affects all notes played from now on
  • 18 xx Loop fit. xx is the number of ticks the waveform's loop should take to complete. If you change the tempo, the frequency is adjusted accordingly, so that the loop still fits (like mtrk's 12 command)
  • 19 xx Same as above, but stays on for all future samples in this track.
  • 20 xx Randomize volume by xx.
  • 21 xx Same as above, but effects stays on forever until you use "21 00"
  • 22 xx Randomize note delay by xx.
  • 23 xx Same as above, but effects stays on forever until you use "23 00"
  • 24 xx Randomize pitch by xx.
  • 25 xx Same as above, but effects stays on forever until you use "25 00"
  • 30 xx Retrig samples. xx is the amount of retrigs per tick. A value of "3" will play the sample three times.
  • 31 xx Retrig all played samples from now on until we use the "31 01" command to reset things.


  • C, C#, D, D#... offsets just like MTrk for peer control microtuning stuff (courtesy of Kibibu Peertune)

Up for discussions

De-clicking method

De-clicking has to occur in the following scenarios only:

  • When forcing a sample to stop before the actual sample data is over, but only if the sample does not have any treble information.
  • When changing volume or panning in a sudden way, and only if the sample does not have any treble information.
  • When starting to play inside a sample that does not have treble.

When the user disabled virtual channels, we still use them to fade out the old sample while the new one starts playing. This means that you will (theoretically) hear both samples at once for a very brief moment. The new sample is not faded in unless sample offset is used and the sample needs de-clicking.

So when does it need de-clicking? The de-clicking fade length can be determined by the amount of change from one sample to the next. The bigger the per-sample changes, the shorter the fade length. If calculating this dynamically is too cpu-heavy, we can pre-calculate an over-all value for each sample. This should typically give the value "0 ms" for a hihat and "2 ms" for an 808-bassdrum.


The class design could look something like this:

  • Machine

Has all the buzzmachine paperwork.

  • Track
    • MixBuffer[]

Represents a group of channels beeing played. Has the final output buffer of the mixed channels for this track. Note-Off mutes the whole channel (taking into account decay etc)

  • Voice
    • pInstrument
    • active
    • note
    • note delay
    • amplitude

A Voice points to a sample, several voices can point to the same sample. Has properties that can't be tracked in the sample because they are voice dependant. Note-On creates a new voice, sets it active and gets assigned to a free channel.

  • Instrument
    • Data[note][pData]

Represents the Wavetable (multi)sample, but already convertet to 32bit float format and with additional properties.

Things to keep an eye on regarding performance:

  • Allocation Strategy / Memory fragmentation issues. Allocate upfront ?
  • Handling of dynamic lists. Vectors, Linked Lists, Trees etc. ?
  • Cache Misses. Interleaved format ?
  • Denormals ?