Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better convolution reverb by generating impulse responses #718

Merged
merged 16 commits into from Oct 4, 2023

Conversation

Bubobubobubobubo
Copy link
Contributor

This PR is proposing the replacement of the old reverb model by a parametric reverb generator.

  • The base mechanisms stays the same, with .room(x) and .size(x) being used to tweak the wet/dry and reverb size.
  • New parameters are introduced to craft bespoke impulse responses:
    • .fade(x): reverb fade time in seconds.
    • .revdim(x): target lowpass filtering goal for reverb tail (in hertz).
    • .revlp(x): lowpass filter applied to incoming wet signal (in hertz).

Documentation and dynamic examples have been added to the Effects page. This is an adaptation of an Apache 2.0 work released here: https://aldel.com/reverbgen/. This work should be usable given that credit is given to the initial dev, Alan de Lespinasse.

Now opening a discussion concerning some details of the implementation. This reverb is generating new impulse responses everytime a parameter is getting tweaked, thus cutting the reverb to start with the new impulse response. This makes it unsuitable for fast algorithmic manipulation. However, this behavior is entirely customizable and we could limit reverb model update to the tweak of one or two parameters. @Froos, what is your opinion about this?

@vasilymilovidov: Now is the time to include your work on impulse responses as well 馃槃

@vasilymilovidov
Copy link
Contributor

can you check if you also get errors like [cyclist] error: undefined is not an object (evaluating 'reverbs[orbit].duration = duration') and [cyclist] error: Cannot set properties of undefined (setting 'duration') when changing size of the reverb?

@Bubobubobubobubo
Copy link
Contributor Author

Bubobubobubobubo commented Oct 1, 2023

It is likely that I forgot to declare a parameter in the reverb.js file. I already fixed most of these errors two commits ago. Take a look to see how to do so :) sorry for this!

It can also be from that chunky condition in superdough.js, where the code checks if a reverb value has changed.

@vasilymilovidov
Copy link
Contributor

it looks like it was confused by reassignments or something.
like this it works without errors:

function getReverb(orbit,
                   duration = 2,
                   fade,
                   revlp,
                   revdim) {
  // If no reverb has been created for a given orbit, create one
  if (!reverbs[orbit]) {
    const ac = getAudioContext();
    const reverb = ac.createReverb(getAudioContext(),
        duration,
        fade,
        revlp,
        revdim);
    reverb.connect(getDestination());
    reverbs[orbit] = reverb;
  }

  const reverbOrbit = reverbs[orbit];

  if (
      reverbOrbit.duration !== duration ||
      reverbOrbit.fade !== fade ||
      reverbOrbit.revlp !== revlp ||
      reverbOrbit.revdim !== revdim
  ) {
    reverbOrbit.setDuration(duration, fade, revlp, revdim);
    reverbOrbit.duration = duration;
    reverbOrbit.fade = fade;
    reverbOrbit.revlp = revlp;
    reverbOrbit.revdim = revdim;
  }

  return reverbOrbit;
}

@vasilymilovidov
Copy link
Contributor

vasilymilovidov commented Oct 1, 2023

I have incorporated my ir() implementation into your code. I can make a pr to yours, or wait for this to merge with main and just update my own

@felixroos
Copy link
Collaborator

looks & sounds good! fixed the bug + tested a bit.

This reverb is generating new impulse responses everytime a parameter is getting tweaked, thus cutting the reverb to start with the new impulse response. This makes it unsuitable for fast algorithmic manipulation. However, this behavior is entirely customizable and we could limit reverb model update to the tweak of one or two parameters. @Froos, what is your opinion about this?

before this PR, the reverb also was regenerated when size changed, so performance wise, it's not much worse, although the new algorithm might take longer, as it is more complex. generally, patterning size + any of the new params fade / revdim / revlp is not a good idea with this setup. It might help to cache impulse responses, but it might also blow up memory when many different values are used

I think the new control names should be changed to more clearly belong to the room keyword:

  • fade -> roomfade|rfade
  • revlp -> roomlp(f?) | rlp(f?)
  • revdim -> roomdim | rdim not sure about that one, maybe change it to behave as factor of the above?

Additionally, it seems consistent to add r for reverb?

@felixroos
Copy link
Collaborator

maybe a simple debounce timeout could be added for the params that regenerate the ir..

@Bubobubobubobubo
Copy link
Contributor Author

Can't really push this further atm. I can take another look to it at the end of the week if necessary.

@felixroos
Copy link
Collaborator

I've changed the naming as mentioned, now there is:

  • room
  • roomlp / rlp
  • roomdim / rdim
  • roomfade / rfade
  • roomsize / rsize

the first alias will be the alias used by superdirt (relevant for topos @Bubobubobubobubo)
It might make sense to also add the alias r for room

The optimization of recalculations is something we can do in a separate PR. To all properties that trigger a recalc, I've added this line to the docs: When this property is changed, the reverb will be recaculated, so only change this sparsely..

This PR is technically a breaking change, as all the reverbs of existing patterns sound different now (better).
I'll do some more testing of before after of the examples to see if some of the reverb sounds off now.

What do you think?

@Bubobubobubobubo
Copy link
Contributor Author

Sounds good! It鈥檚 also a breaking change compared to the classic SuperDirt implementation but it makes sense to update it now that the model is different.

The reverb sounds good, I guess that this will not raise any complaint given that it is a dramatic improvement over the previous one.

@felixroos felixroos merged commit 0b888ac into tidalcycles:main Oct 4, 2023
1 check passed
vasilymilovidov added a commit to vasilymilovidov/strudel that referenced this pull request Oct 4, 2023
yaxu added a commit that referenced this pull request Nov 17, 2023
* checkbox + number slider

* match number.slider

* Add pink, white and brown oscillators

* Add noise parameter for base oscillators

* Fix noise parameter and FM parameters compatibility

* Cap noise amount to 1

* Add documentation about noise sources

* match slider as function

* use loc as slider id

* add slider function to scope

* Replacing old reverb by better convolution

* make sliders work!

* fix some odd number / string problems

* fix: import

* wip: use sample as an impulse response for the reverb

* Document reverb controls

* bugfixes for parameter passing

* improve mouse tracking

* use sample as an impulse response for the reverb

* cleanup

* simplify: use native events

* add back some margin

* use raw css instead of tailwind

* add extra sliderWithID function
+ add warning to slider function

* remove checkbox

* remove comment

* fix: comment

* fix: import

* hotfix: add missing dependency

* support mininotation '..' range operator, fixes #715 (#716)

* support mininotation .. range operator, fixes #715

* remove logs

* Connecting all parameters to convolution generator

* Connecting new reverb documentation

* codeformat

* fix: reverbs[orbit] is undefined

* eslint ignore reverbGen + snapshot

* Prepare to merge with PR #718

* feat: add step as slider param

* more logical naming + update docs

* snapshot

* codeformat

* add noise heading + hihat example

* refactor synth
- separate waveform / noise oscillators
- pull noise out of getOscillator
- put fm into getOscillator
- simplify overall value plumbing

* proper dry wet + pull out noise to extra file

* fix: imports

* cache noise

* rename zzfx noise to znoise

* snapshot

* fix: slider crash on some platforms

* update internal reverb param names

* simplify createReverb

* consistent naming + simplify

* remove unused reverb method

* Integrate with the new impulse generation functionality

* fix: reverbGen.mjs

* fix: formatting

* fix: reverb regenerate loophole

* consume n with scale

* snapshot

* fix: conflicts

* fix: conflicts

* add compressor + postgain

* fix: hashes in urls

* compressor docs

* format

* snapshot

* fix: roomsize not required

* fix: reverb sampleRate

* bump superdough to 0.9.10

* fix: pitched sample as ir

* vite-vanilla-repl readme fix

* Add shabda shortcut (#406)

* Update samples/shabda documentation

* Prettier doc file

* fixed

* document function

* fixed example test failure

* add recipes

* add understand cycles

* move stuff around

* fix: loud example

* format

* Add test snapshots for shabda shortcut

* fix: trailing slash confusion

* fix: trailing slash confusion

* fix: try different trailing slash behavior

* completely revert config mess

* Fix krill build command in README

* Support international alphabets in mininotation

* Add a human-readable error message for invalid char in step

* Revert error message length limitation

* use new vite-pwa-astro version from file

* basic hydra integration

* add play function

* also return pat

* add docs + fix hydra for mini repl

* add H function to plug patterns into Hydra

* document H function

* ignore hydra.mjs in linter

* add px in zen mode to fix logo overlap

* fix: flip scope in y direction

* fix: additive synthesis

* fix: scale offset

* Document striate function

* Document adsr function

* replace strudel.tidalcycles.org with strudel.cc

* functions

* move to signal file with other choose functions

* use 0.1.4 @vite-pwa/astro

* use new flag

* snapshots

* add doc chapters

* integrated vscode bindings

* Fix chunk, add fastChunk and repeatCycles (#712)

* Match behaviour of chunk with tidal, add fastChunk for old strudel behaviour. Also adds repeatCycles. fixes #689

* documentation

* (hopefully) fixed broken lock file

* Update CONTRIBUTING.md

fix prettier instructions

* fixed style issues

* fix: share copy to clipboard + alert

* rename bindings key

* remove obsolete config

* update to astro 3

* no double !

* initial commit

* add xfade + docs

* snapshot

* fix: namespace mini-repl styles

* Implement optional hover tooltip with function documentation

* Add pianoroll function documentation

* Add label function documentation

* Add color function documentation

* Fix pianoroll documentation

* Add function params in reference tab

* Update pianoroll documentation

* tweaking to make it sound good

* fix: scope pos

* document scope functions

* snapshot

* samples loading shortcuts:
- use main branch by default in github shortcut
- add bubo shortcut

* don't use anchor links for reference

* change to bus effect experiment

* Update first-sounds.mdx

in eine sogenannte Funktion -> in einer sogenannten Funktion

* Update first-effects.mdx

grammatical amendments

* Update pattern-effects.mdx

grammatical amendments

* Update recap.mdx

Adds a few missing translations

* FIXES: table

* cleaning up

* cleaning up

* cleaning up

* turn off of depth is 0

* update doc

* create free running lfos for different orbits

* add more parameters

* fixed doc

* snapshots

* phaser shortcuts

* doc: phaser synonyms

* add params to superdough readme

* add to doc page

* dedupe / move supertdirt phaser controls

* format

* simplify

* refactor: move vibrato up + cleanup oscillator

* fix: sampler broke without vibrato

* support multiple named serial connections, change default baudrate to 115200 (#551)

* Document wordfall

* Document slider

* Document euclidLegatoRot

* Add snapshot for euclidLegatoRot

* remove unwanted cm6 outline for strudelTheme

* move fix to Repl.css

* fix codeformat

* add option to disable active line highlighting in Code Settings

* fix typo

* remove pseudo note variables

* p and q methods + all function

* + add hush
+ add the ability to evaluate without clearing

* fix tests

* add q1 .. q9 shortcuts

* add p1 .. p9 shortcuts as well

* bump superdough

* Mark optional slider params

---------

Co-authored-by: Felix Roos <flix91@gmail.com>
Co-authored-by: Raphael Forment <raphael.forment@gmail.com>
Co-authored-by: Vasilii Milovidov <vasily.milovidov@gmail.com>
Co-authored-by: Alexandre G.-Raymond <alex@ndre.gr>
Co-authored-by: Jade Rowland <jaderowlanddev@gmail.com>
Co-authored-by: Dsm0 <willrinkoff@gmail.com>
Co-authored-by: Will <45471522+Dsm0@users.noreply.github.com>
Co-authored-by: Bernhard Wagner <github.comNotification20120125@xmlizer.net>
Co-authored-by: Bernhard Wagner <gitcommit@nosuch.biz>
Co-authored-by: Kaspars <kasparsj@gmail.com>
Co-authored-by: Alexandre Gravel-Raymond <agravelraymond@deezer.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants