mirror of
https://github.com/vsariola/sointu.git
synced 2025-07-18 21:14:31 -04:00
Rewrote most of the synth to better support stereo signals and polyphony. VSTi removed as there is no plan to update the VSTi to support the new features.
The stereo opcode variants have bit 1 of the command stream set. The polyphony is split into two parts: 1) polyphony, meaning that voices reuse the same opcodes; 2) multitrack voices, meaning that a track triggers more than voice. They both can be flexible defined in any combinations: for example voice 1 and 2 can be triggered by track 1 and use instrument 1, and voice 3 by track 2/instrument 2 and voice 4 by track 3/instrument 2. This is achieved through the use of bitmasks: in the aforementioned example, bit 1 of su_voicetrack_bitmask would be set, meaning "the voice after voice #1 will be triggered by the same track". On the other hand, bits 1 and 3 of su_polyphony_bitmask would be set to indicate that "the voices after #1 and #3 will reuse the same instruments".
This commit is contained in:
188
README.md
188
README.md
@ -1,87 +1,139 @@
|
||||
# 4klang
|
||||
Official 4klang repository
|
||||
|
||||
For discussion or feedback please use our #4klang channel on Slack:
|
||||
[https://64klang.slack.com](https://join.slack.com/t/64klang/shared_invite/enQtNDM1NTY5OTE5Njk2LWRlM2NlZDUzNTdkNTZkYzEzMTA0NWJkMWM3NWI0ZTVlODhkM2FlNWFkMTk5YmE4ZGQ2ZWI1ZWQ4YjZjNjgxZDA)
|
||||
# Sointu
|
||||
A cross-platform modular software synthesizer for small intros, evolved from
|
||||
[4klang](https://github.com/hzdgopher/4klang).
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
||||
4klang is a modular software synthesizer package intended to easily produce music for 4k intros (small executables with a maximum filesize of 4096 bytes containing realtime audio and visuals).
|
||||
Sointu is work-in-progress. It is an evolution of [4klang](
|
||||
https://github.com/hzdgopher/4klang), a modular software synthesizer intended
|
||||
to easily produce music for 4k intros-small executables with a maximum
|
||||
filesize of 4096 bytes containing realtime audio and visuals. Like 4klang, the
|
||||
sound is produced by a virtual machine that executes small bytecode to
|
||||
produce the audio; however, by now the internal virtual machine has been
|
||||
heavily rewritten and extended to make the code more maintainable, possibly
|
||||
even saving some bytes in the process.
|
||||
|
||||
It consists of a VSTi plugin example songs/instruments as well as an example C project showing how to include it in your code.
|
||||
Or if you dare to compile it yourself also the source code for the synth core and VSTi plugin.
|
||||
Project goals and current state
|
||||
-------------------------------
|
||||
|
||||
The repository contains the folders:
|
||||
- 4klang_VSTi (the precompiled plugin(s) and example instruments/songs)
|
||||
- 4klang_source (the VSTi source as well as the needed 4klang.asm file for compilation in your exe)
|
||||
The overly ambitious primary goals of the project:
|
||||
- **Cross-platform support for win / mac / linux**. The build is already based
|
||||
on CMake and compiles on Windows. Cross-platform YASM macros have been
|
||||
drafted and remain to be tested. Once the project is more mature, I will
|
||||
try compiling on other platforms.
|
||||
- **Per instrument polyphonism**. An instrument should have the possibility to
|
||||
have any number of voices. A draft of this has been written, but remains to
|
||||
be tested. The maximum total number of voices will be 32: you can have 32
|
||||
monophonic instruments or any combination of polyphonic instruments adding
|
||||
up to 32.
|
||||
- **Chords / more than one track per instrument**. For example, a polyphonic
|
||||
instrument of 3 voices can be triggered by 3 parallel tracks, to produce
|
||||
chords. A draft of this has been written, but remains to be tested.
|
||||
- **Easily extensible**. Instead of %ifdef hell, the primary extension
|
||||
mechanism will be through new opcodes for the virtual machine. Only the
|
||||
opcodes actually used in a song are compiled into the virtual machine. The
|
||||
goal is to try to write the code so that if two similar opcodes are used,
|
||||
the common code in both is reused by moving it to a function. This opcode
|
||||
extension mechanism is done.
|
||||
- **Take the macro languge to its logical conclusion**. Only the patch
|
||||
definition should be needed; all the %define USE_SOMETHING will be
|
||||
defined automatically by the macros. Furthermore, only the opcodes needed
|
||||
are compiled into the program. Done, see for example
|
||||
[this test](tests/test_vco_trisaw.asm)! This has the nice implication that,
|
||||
in future, there will be no need for binary format to save patches: the .asm
|
||||
is easy enough to be imported into / exported from the GUI. Being a text
|
||||
format, the .asm based patch definitions play nicely with source control.
|
||||
- **Harmonized support for stereo signals**. Every opcode supports a stereo
|
||||
variant: the stereo bit is hidden in the least significant bit of the
|
||||
command stream and passed in carry to the opcode. This has several nice
|
||||
advantages: 1) the opcodes that don't need any parameters do not need an
|
||||
entire byte in the value stream to define whether it is stereo; 2) stereo
|
||||
variants of opcodes can be implemented rather efficiently; in some cases,
|
||||
the extra cost of stereo variant (e.g. most filters) is only 6 bytes. 3)
|
||||
Since stereo opcodes usually follow stereo opcodes, and mono opcodes
|
||||
follow mono opcodes, the stereo bits of the command bytes will be highly
|
||||
correlated and if crinkler or any other compressor is doing its job, that
|
||||
should make them highly predictable i.e. highly compressably. Mostly done.
|
||||
- **Test-driven development**. Given that 4klang was already a mature project,
|
||||
the first thing actually implemented was a set of regression tests to avoid
|
||||
breaking everything beyond any hope of repair. Mostly done, using CTests.
|
||||
Ttests for new opcodes / opcode variants implemented since 4klang are not
|
||||
done.
|
||||
- **Support for 64-bit targets**. Not started.
|
||||
- **Browser-based GUI and MIDI instrument**. Modern browsers support WebMIDI,
|
||||
WebAudio and, most importantly, they are cross-platform and come installed
|
||||
on pretty much any computer. The only thing needed is to be able to
|
||||
communicate with the platform specific synth; for this, the best
|
||||
option seems to be to run the synth inside a tiny websocket server that
|
||||
receives messages from browser and streams the audio to the browser.
|
||||
Only the feasibility of the approach is proven (localhost websocket calls
|
||||
have 1 ms range of latency), but nothing more is done yet.
|
||||
|
||||
The plugin project here is based on Visual Studio 2015, so that and above should compile out of the box.
|
||||
The only additional thing you need for compilation is YASM/vsyasm, so download and follow the instructions here to get it running:
|
||||
Possible, nice-to-have ideas:
|
||||
- **Sample import from gm.dls**. This is Windows only, but implementing it
|
||||
should be easy and the potential payoffs pretty high for Windows users, so
|
||||
it is a nice prospect.
|
||||
- **Tracker**. If the list of primary goals is ever exhausted, a browser-based
|
||||
tracker would be nice to take advantage of all the features.
|
||||
|
||||
https://github.com/ShiftMediaProject/VSYASM
|
||||
Anti-goals:
|
||||
- **Ability to run Sointu as a DAW plugin (VSTi, AU, LADSPA and DSSI...)**.
|
||||
None of these plugin technologies are cross-platform and they are full of
|
||||
proprietary technologies. In particular, since Sointu was initiated after
|
||||
Steinberg ceased to give out VSTi2 licenses, there is currently no legal or
|
||||
easy way to compile it as a VSTi2 plugin. I downloaded the VSTi3 API and,
|
||||
nope, sorry, I don't want to spend my time on it. And Renoise supports only
|
||||
VSTi2... There is [JUCE](https://juce.com/), but it is again a mammoth and
|
||||
requires apparently pretty deep integration in build system in the form of
|
||||
Projucer. If someone comes up with a light-weight way and easily
|
||||
maintainable way to make the project into DAW plugin, I may reconsider.
|
||||
|
||||

|
||||
Design philosophy
|
||||
-----------------
|
||||
|
||||
Examples
|
||||
--------
|
||||
- Try to avoid %ifdef hell as much as possible. If needed, try to include all
|
||||
code toggled by a define in one block.
|
||||
- Instead of prematurely adding %ifdef toggles to optimize away unused
|
||||
features, start with the most advanced featureset and see if you can
|
||||
implement it in a generalized way. For example, all the modulations are
|
||||
now added into the values when they are converted from integers, in a
|
||||
standardized way. This got rid of most of the %ifdefs in 4klang. Also, with
|
||||
no %ifdefs cluttering the view, many opportunities to shave away
|
||||
instructions became apparent. Also, by making the most advanced synth
|
||||
cheaply available to the scene, we promote better music in future 4ks :)
|
||||
- Size first, speed second. Speed will only considered, if the situation
|
||||
becomes untolerable.
|
||||
- Benchmark optimizations. Compression results are sometimes slightly
|
||||
nonintuitive so alternative implementations should always be benchmarked
|
||||
e.g. by compiling and linking a real-world song with [Leviathan](https://github.com/armak/Leviathan-2.0)
|
||||
and observing how the optimizations
|
||||
affect the byte size.
|
||||
|
||||
Some 4k intros using 4klang:
|
||||
Background and history
|
||||
----------------------
|
||||
|
||||
- http://www.pouet.net/prod.php?which=53937
|
||||
- http://www.pouet.net/prod.php?which=68239
|
||||
- http://www.pouet.net/prod.php?which=69642
|
||||
- http://www.pouet.net/prod.php?which=69653
|
||||
[4klang](https://github.com/hzdgopher/4klang) development was started in 2007
|
||||
by Dominik Ries (gopher) and Paul Kraus (pOWL) of Alcatraz. The [write-up](
|
||||
http://zine.bitfellas.org/article.php?zine=14&id=35) will still be helpful for
|
||||
anyone looking to understand how 4klang and Sointu use the FPU stack to
|
||||
manipulate the signals. Since then, 4klang has been used in countless of scene
|
||||
productions and people use it even today.
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
Up to now the 4klang package was available only via http://4klang.untergrund.net
|
||||
|
||||
Lately various subversions of 4klang emerged and i felt it might be a good idea to have a public repo reflecting that.
|
||||
So people can actively contribute, fix things i dont have time for or simply extend stuff.
|
||||
|
||||
Therefore the current branches available here are:
|
||||
|
||||
- 3.0.1 (as listed on http://4klang.untergrund.net)
|
||||
- 3.11 (as listed on http://4klang.untergrund.net)
|
||||
- master (~3.2, contains various fixes and a new unit type 'glitch' for a delay based retrigger effect)
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
4klang development started in 2007 out of need and curiosity of how to write a tiny but flexible software synthesizer which can be used in 4k intros.
|
||||
|
||||
See this small writeup for more info
|
||||
<br>http://zine.bitfellas.org/article.php?zine=14&id=35
|
||||
However, 4klang is pretty deep in the [%ifdef hell](https://www.cqse.eu/en/blog/living-in-the-ifdef-hell/), and the polyphonism was
|
||||
never implemented in a very well engineered way (you can have exactly 2
|
||||
voices per instrument if you enable it). Also, reading through the code,
|
||||
I spotted several avenues to squeeze away more bytes. These observations
|
||||
triggered project Sointu. That, and I just wanted to learn x86 assembly, and
|
||||
needed a real-world project to work on.
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
||||
4klang was developed by
|
||||
<br>Dominik Ries (gopher) and Paul Kraus (pOWL) of Alcatraz.
|
||||
The original 4klang was developed by Dominik Ries (gopher) and Paul Kraus
|
||||
(pOWL) of Alcatraz.
|
||||
|
||||
Among the many sources of inspiration which lead to 4klang in its current state, here is a (probably not complete) list of the most influencial work by others:
|
||||
Sointu was initiated by Veikko Sariola (pestis/bC!).
|
||||
|
||||
- <b>'Stoerfall Ost' by freestyle</b>
|
||||
|
||||
http://www.pouet.net/prod.php?which=743
|
||||
<br>To my knowledge the first 4k intro using the fpu stack as 4klang does, creating the best 4k soundtrack of its time.
|
||||
Conceptually i consider this to be the primary technological input as 4klang evolved around that idea of using the fpu stack.
|
||||
So big respect and greetings to freestyle, particularly muhmac whom i also had some helpful discussions with during 4klang development.
|
||||
|
||||
- <b>V2 by kb of frabrausch</b>
|
||||
|
||||
http://www.pouet.net/prod.php?which=15073
|
||||
<br>https://github.com/farbrausch/fr_public/tree/master/v2
|
||||
|
||||
Before 4klang i wrote my first synth as a V2 clone around 2004/2005 (as many people in the demoscene did actually).
|
||||
Again way ahead of its time in terms of size/quality and in addition with some really helpful articles by kb this was a key to understanding what you need for synth development for a start:
|
||||
<br>http://in4k.untergrund.net/various%20web%20articles/fr08snd1.htm
|
||||
<br>http://in4k.untergrund.net/various%20web%20articles/fr08snd2.htm
|
||||
<br>http://in4k.untergrund.net/various%20web%20articles/fr08snd3.htm
|
||||
<br>http://in4k.untergrund.net/various%20web%20articles/fr08snd4.htm
|
||||
|
||||
- <b>http://www.musicdsp.org</b>
|
||||
|
||||
General source and for various synth module algorithms.
|
||||
PoroCYon's [4klang fork](https://github.com/PoroCYon/4klang) inspired the macros
|
||||
to better support cross-platform asm.
|
Reference in New Issue
Block a user