Giter Site home page Giter Site logo

wavesabre's Introduction

WaveSabre

build status License Slack

Description

WaveSabre is a software synthesizer and toolchain for music for 64K intros.

See our docs for more info.

Getting started

Please see our docs for prerequisites, building, etc (and let us know what we're missing!).

Status/contributing

As WaveSabre is hot and fresh right out of the oven, we've got some kinks to work out; particularly with documentation, support for more Visual Studio versions, and supporting various VST SDK versions. We'd appreciate any help we can get on any of these fronts, so please talk to us on Slack so we can guide you in the right direction and help you help us!

Contributions are very welcome, however as the public release is still in its infancy, we'd greatly appreciate it if we could discuss contributions on Slack, rather than just opening up for pull requests for the time being, in order to avoid duplicate work. This will change in the future when things mature/settle down a bit. :)

Productions

WaveSabre has been used in several intros, demos, and executable music productions, including (but not limited to):

You can find a more exhaustive production list here.

Team

WaveSabre is made by ferris and h0ffman of logicoma, with additional contributions by:

And several others! (Please let us know if we forgot someone!)

Talks/seminars

License

WaveSabre is licensed under the MIT license (see LICENSE or http://opensource.org/licenses/MIT).

wavesabre's People

Contributors

armak avatar djh0ffman avatar kusma avatar lamogui avatar lestahl avatar porocyon avatar tagsemb avatar yupferris avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wavesabre's Issues

Proposed fixes for the biquad filter and Leveller device

Having done some investigations, I've identified three different issues related to the Leveller EQ/filter device. I'm including all of these in the same issue since in some ways they are interrelated and something that I think would be good to try to fix in the same go. The issues in order of importance are:

1. Biquad filter imprecision at low cutoff frequencies

The current biquad filter implementation (based on the classic RBJ digital filters[1]) suffers from imprecision when the cutoff frequency becomes very low, specifically lower than about 200 Hz, but it's especially bad below 100 Hz. In this picture the cutoff of the Leveller low cut filter is to 20 Hz, and Q is set to neutral 0.70710678... (sqrt(2)/2), yet the filter peaks at about +4dB. Just moving the cutoff up to above 200 Hz gradually improves the filter behavior and it ceases to exhibit this peaking behavior (ignore the peaking at the high end of the spectrum, this is a separate issue that I will talk about later).

biquad q problem

Also worth noting that even though the cutoff is set to 20 Hz, the resonance isn't actually at 20 Hz, but rather closer to 50 Hz or just below it. This appears to be an additional issue produced by the imprecision. We can also try to compensate this peaking by reducing the Q below the neutral 0.7071... value, but we have to assign the Q very close to zero in this case to eliminate the problem. It also doesn't fully resolve the problem, because the filter still starts cutting way too high and is -3dB at around 40 Hz rather than the intended 20, whereas at 20 Hz were down almost -13dB:

filter problem 2

The issue seems to stem from the lookup tables used for the trigonometric functions. Simply increasing the size of the table from the current 512 entries appears to eliminate the problem completely. 1024 entries is a lot better but still exhibits audible peaking, 2048 entries only has a slight amount of error, and 4096 is near perfect.

The magenta/lila colored graph is the current version, and the pink/salmon colored is with increased LUT size (4096 samples). Notice that the filter is now correctly -3dB down at 20 Hz.

leveller q problem

There might be another less of a "brute force" way of fixing this, but increasing the LUT size seems effective anyway. Only performance consideration from it might be cache efficiency, but this remains to be tested.

2. Using neutral Q by default

In the current version the Leveller device and the helper functions that map scalar values to Q and vice versa treat 1.0 as the neutral value: all Leveller Qs are initialized to this, and it's the center 50% setting in all of the Q knobs. However, as with most filter and indeed the RBJ biquad as well, the neutral Q is actually the aforementioned square root of two divided by two, or 0.70710678... .

I would suggest both initializing all Q properties by default to this value, and re-scaling the Q mapping functions so that the middle Q would also map to the same value (might be worth re-thinking the entire function as well). This would eliminate the remaining peaking behavior the low and high cut filters currently have by default, and make it much easier to find the exact neutral Q setting on the knobs.

You can see the previous image for an example of using the neutral Q in Leveller, with the aforementioned biquad problem also addressed.

3. Cutoff frequency mapping ranges

This is less crucial than the other ones in my opinion, but I still wonder whether the range of a cutoff parameter could or should be expanded. The current ParamToFrequency and FrequencyToParam helper functions implicitly define the range as 20 Hz to 20 kHz, which certainly is a sensible range, but filters still start cutting frequencies already before those cutoffs are reached. Sometimes you might want to extend e.g. the cutoff of a highpass filter to below 20 Hz, so that no potentially audible frequencies would be cut. Same applies to the top end.

Of course most digital filters have the issue that they start cramping near the nyquist, so we can't extend the upper range all the way there, but just below it. Not sure how much of a margin is necessary in practice before numerical problems start to appear, but a 22 kHz cutoff seems to still be fine at a 44.1 kHz sampling rate.

Finally, below is a comparison of graphs between the current Leveller device at its initial settings, compared to a possible "Leveller 2" with all of the proposed changes above, at default settings as well.

leveller full changes

[1] https://www.musicdsp.org/en/latest/Filters/197-rbj-audio-eq-cookbook.html

Dual license MIT and GPLv3

Doing this would allow us to properly comply with the VST3 SDK requirements without signing the proprietary agreement, including distributing binary plugin builds which would be licensed as GPLv3 only, while the rest of WS (including the core/player code, which is what users will pack in their binaries) can still be MIT-licensed (or, GPLv3 if they so choose, which is a possibility we've not offered before).

I think this logic is sound, but other opinions/interpretations would be appreciated.

Build issues for windows

CMake -B build didn't work on windows 10.
cmake . (in the wavesabre directory did)
but, I get one error:
WaveSabreVstLib.lib(vstplugmain.obj) : error LNK2019: unresolved external symbol "class AudioEffect * __cdecl createEffectInstance(int (__cdecl*)(struct AEffect *,int,int,int,void *,float))" (?createEffectInstance@@YAPAVAudioEffect@@P6AHPAUAEffect@@HHHPAXM@Z@Z) referenced in function _MAIN
1>

Add new sampler device

I developed pulsejet specifically to replace our usage of GSM06.10 here (and because it was really fun!), however, I never actually did the integration work, and I keep forgetting to with other projects/life stuff happening lately. Thus, this tracking issue.

I don't think we really need to reinvent the wheel and deep-dive into better resampling strategies than we use currently in Specimen (we could consider that for future versions, for example), so the work to be done is roughly as follows:

  • Fork Specimen (perhaps even just call it "Specimen 2")
  • Replace usage of GsmSample with something pulsejet-related
  • Add a target bitrate parameter/knob (and ideally a matching display) to control codec quality
  • Make sure we store both the uncompressed sample data as well as the compressed sample data in the device chunk so that we can re-encode as the quality parameter changes (only in the VST ofc; at runtime we should assume this is static)
  • As the pulsejet encoder/decoder are fairly slow (the encoder may be improved in future versions but the decoder is unlikely to change in this area unless we need really long samples or something), at least encoding should ideally happen on a separate thread, but this may not be entirely necessary.
  • Strip the uncompressed sample data from the chunk in the converter (this means the device needs to support cases where the encoded sample data is missing, which shouldn't be too difficult as this data shouldn't ever actually be used by the device, only made available to the VST)
  • Deprecate Specimen
  • Optionally, warn/error if the quality parameter is automated (at conversion time)

Binary plugin distribution

This is actually a big licensing mess. See the following comments for some of my notes:

I believe the best strategy for this, as outlined in the last comment above, is to migrate to VST 3 proper, still BYOSDK for developers, and sign the VST 3 proprietary agreement myself in order to ship binary builds on behalf of the project (at least covering the main repo; we might need to be very explicit that other folks couldn't distribute the same plugs under these terms). As far as I can tell, this avoids any legal grey-areas and allows us to be fully compliant with the license terms, but could actually be considered a breaking change, as it locks out older DAWs that don't support VST 3. One such DAW is Live 9, which we've used for years and currently have test projects for in the converter test suite. I'm not entirely sure if this matters tho; afaik most folks are on Live 10 or even 11 by now, but still (so this implies that #81 would have to be solved as well).

In any case, this would be extremely useful for non-coders to compose with WS (especially if we have plugins built on multiple platforms), whereas folks incorporating the synth into prods would still have to deal with source, which is perfectly reasonable IMO.

Revisit (and likely remove) metaplugin/jbridge setups

These were made at a time where we only supported 32-bit plugin builds, and some DAWs didn't natively support sidechaining. I believe both of these are non-issues now, so if possible, it would be nice to remove the dead weight.

Investigate potential improvements to StateVariableFilter

This is a decent and very compact filter design, ultimately originating from [1] (though in this particular case I believe I took the code from Sonant, and somewhere online before that). Its derivation is covered here (among many other places).

However, this particular filter construction has known instabilities at higher frequencies. To get around this, we employ a simple 2x oversampling scheme, equivalent to a linear upsampling filter before the SV filter, and a 2-tap moving average filter after. This setup effectively halves its (normalized) cutoff frequency, thus avoiding said instabilities (note that “avoiding” is used here instead of “eliminating” as I haven’t actually analyzed/proved it properly; I can only say I haven't experienced/heard of of any instances where it's “popped” in a very long time!).

While the code for this is very simple, the up/downsample processes alone are likely introducing noticeable artifacts even in the absense of the actual SV filter, which surely degrades the perceived quality of the SV filter itself. It's likely that with a bit of investigation, we can find a similarly-cheap, yet more-transparent strategy, so we should look into this.

Alternatively, since this filter is used wherever an "analog-style"/"coloring"/"non-surgical" filter is desired (eg. in the synths and many creative effects), it's possible that another filter topology (perhaps VA or similar) that's inherently stable (thus avoiding up/downsampling entirely) is more attractive altogether.

[1] H. Chamberlin,Musical Applications of Microprocessors, Second Edition, New Jersey: Hayden Books,1985.

FL Studio project file conversion broken in FL Studio 20.9

ConvertTheFuck and ProjectManager are not able to load FL Studio project files created with FL Studio 20.9.
When trying to convert them, the error message Object reference not set to an instance of an object. is displayed.

Project files created by FL Studio 20.1 can be converted successfully.
Find project files with the same content that can be used to reproduce the problem here: project-files-to-reproduce.zip

Add version in file header

Something that would be useful would be for the (binary) files to have a version header. I would like to add WaveSaber playback support to HippoPlayer/HippoPlayer#60 at some point and in order to make sure that files are playable it would be good to be able to check a version of the file to ensure the player is new enough to play the format. Talking with @yupferris a suggestion would be ta have a WSBR 4 byte tag + a 4 byte value (for example a xx.xx.xx.xx semantic version would work here)

Consider more consistent and precise time handling in converter/song

So far we've been a bit sloppy and sometimes use samples and sometimes seconds, whichever is convenient. However, this leads to tiny differences due to imprecision when we change code sometimes, and even though these differences are neglible from a musical perspective, it's still a source of unpredictability and a nuisance when running/updating tests.

Since we're working with musical data, times could probably be expressed in terms of something more musical. Off the top of my head, a bar_index: uint, time_offset: rational_notes pair is probably sufficient and not prone to rounding errors.

It might even make sense to take this structure all the way to the player code in cases where it's needed, or just flatten to a single representation (likely sample counts) at the end (similar to what we currently do, but since it would always be the last thing we did, then changing things like operation order wouldn't affect the final output).

This is somewhat of a deep change that requires investigation.

Support VST3

This is just going to be something we have to do at some point, and I'm convinced that either we migrate to VST3 and break VST2 compatibility (simpler if we ignore old projects) or build our own (hopefully small) abstraction over VST2/VST3 and make both opt-in, but by default build VST3 (I think this is mostly doable).

Assuming we want to migrate to VST3, I've started work on this branch and I think overall it will simplify a lot of things. It's still somewhat early, though, and due to other obligations (and the fact that the docs are currently down right now, ugh) I can't take it much further right now.

Investigate including VST3 SDK as a submodule

This doesn't count as distribution as far as I'm aware, so long as our source releases don't actually include this source, we should be able to do this, which simplifies BYOSDK greatly.

Cover more VS versions when building in CI

We currently only build with Visual Studio 2013, yet most of our userbase is currently using 2019 iirc, or at the very least, 2015/2017. Ideally we'd have all of these covered.

Update converter test refs

It seems these are super out of date. I recall doing some automation optimizations (specifically 86e5ccf, and perhaps others), and it looks like these weren't updated after that, since all of the errors (that I looked at; I stopped after 4-5 projects) appear to be automation-related:

Arps9.als: MISMATCH
Converted song does not match stored ref.
Diff (test, ref):
    Track 12: [ [BASS] ]
        Track Name: [BASS],
        Automation 1:
            Point counts don't match: 7, 12
    Track 19: [ Less Sex But Still Sex Arp ]
        Track Name: Less Sex But Still Sex Arp,
        Automation 1:
            Point counts don't match: 5, 6

We should also do a quick pass to make sure we're not missing anything in the diff data structures.

Add changelog

Now that we’re doing “proper” releases we should keep track of this stuff.

Fix out-of-the-box vs2019 support for x86

While x64 appears to work without fuss, x86 builds seem to rely on some MSVCRT functions that we have incorrect definitions for - particularly, _alldiv, _allmul, and _allshl. I've verified that when using the old msvcrt_old.lib file that we used to ship as a binary blob, we could get things to work. I also tried to shim them in by hand with code from here (with some project config changes outlined here) and that also works, though I don't just want to copy that code for copyright reasons (though I'm not sure how else we can make similar shims in a nice way, maybe in C?).

To be fair, I do have working x64 squishy builds, and there was even one WS exemusic entry released using it already. It would be really great if we could just start focusing on x64 and drop x86 altogether. However, the packer alone just isn't enough; I haven't gotten x64 compression on par with x86 and I'm suspecting we won't be able to close the gap as much as I'd hoped, as the code is just denser. So, I think we're stuck supporting both for the time being.

Lock down versioning/release process

I really want to do this ASAP, both to make it easier for users to get up and running without necessarily building anything (assuming we'd ship pre-built VSTs and perhaps also libs/converter tools as part of the releases) but also as I think WS could be made a lot better with a few fundamental changes/fixes, and I'd rather start doing those after we get a release of WS in its current state made, so users can in theory always have something to go back to for old projects if it's important to them (though I suspect users are almost always happier with new toys than ways to keep the old ones working).

Proper tutorial(s)

At least building/getting plugs set up would be really nice, and especially targeting (potentially) non-developers, eg. musicians who want to author WS songs.

Additionally, some info on converting/analyzing tracks, using the various included tools, unit tests, etc, would also be good to have covered in some capacity.

Get converter tests running in CI

I noticed that the converter tests are currently out of date (see #63). We should be running these in CI to prevent future breakages.

This will likely also require some test modifications, since they're currently always interactive, which is not what we want in CI.

Fix VS 2015 support; add to CI matrix

I briefly looked into this in #78, and this was the only version (besides 2013, 2017, and 2019) that didn't work properly with the code we have today. I suspect it's likely fixable, but I don't think anybody using WS really cares about VS versions prior to the latest anyways, so I don't want to spend time on it. Still, it's nice to track an issue for it in case someone else wants to look into it.

Add preset system

Hello @yupferris

With a musician we are really thinking to use this master piece synth for our next 64k intro.
He want to have the ability to save preset of each synth (he is using renoise), so I created this issue with a plan to complete it later. I posted the issue here as a reminder because I don't find a issue panel on my fork, if it bother tell me I will remove it.

lamogui

Consider parameter smoothing solution

This likely has to be implemented at the device level, and it may be that we need to redesign how we store/fetch parameters for all devices. Fortunately, this may also present both size optimization (in the form of internal quantization/better data layout) opportunities as well as additional type safety/simplified value mapping.

However, these would obviously be fundamental breaking changes.

Synth sound regression

While trying out 64bit stuff, it seems the reverence test project sounds quite different than it used to, in addition to being about 1kb larger, even with latest squishy. It sounds the same in 64/32-bit, so I suspect some kind of regression somewhere. Note that I used vs2019 on Windows. This should probably be bisected, but I haven't looked further into it yet.

Investigate possible size regressions, likely with vs2019

In #57 I noticed that Reverence is about 1kb larger with squishy in recent builds compared to compressing the original uncompressed executable. It might just be bloat from the latest VS (in which case perhaps we can find some new option tweaks to try and improve it), or it might be a mistake we've made somewhere (and if that's a regression, we should identify and fix it).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.