Code Monkey home page Code Monkey logo

master_me's People

Contributors

falktx avatar magnetophon avatar trebmuh avatar trummerschlunk avatar x42 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  avatar  avatar  avatar

master_me's Issues

very high cpu usage

opening a ticket to generate a discussion around this.
currently the plugin is quite heavy, ideas for optimizing its cpu usage would be quite welcome.

we could try a few compiler optimization flags and see what works best.
also reducing the gui-oriented calls on the dsp side, as mentioned in other tickets.

this can be a blocker for some people doing live-streams, as the capturing + recording takes a significant amount of cpu. if audio processing does too, the system might not be that much responsive when all parts are on.

Multiband compressor introduces phase smearing

I did a few listening tests, and the confirmed this by measurement. The LR4 cross-over network used by the mscomp adds a 180 deg phase-shift where bands overlap:

mscomp-phase-smearing

A multiband compressor is commonly implemented:

  • Band-split the key signal (x-over network of LR4 is fine here)
  • Analyze each freq band, calculate compression gain
  • Use shelving filters to apply the gain to the signal

I've whipped up some FAUST code for this which should be straight forward to integrate here.

https://gist.github.com/eeb2aa9f9cc4a9083fb2cf2d86645c9a

@magnetophon Since you have significantly contributed to FAUST's compressor lib, you may be interested in this as well.

advanced leveler

(moved to low-prio, as not critical for first release)

  • feedback circuit
  • expander in brake
  • scaled speeds for 'above target' and 'below target'
  • deadzone (strong break if feedback signal is close to target)
  • investigate 'rubberband effect' at higher 'length' for lk2_var

Texts for 'Easy' page

These are the texts for 'Easy' page:

Hi there,

master_me is a free and open source automatic mastering plugin for live streamers, podcasters and internet radio stations.

You are currently in “Easy” mode.
Select a preset from the bottom and forget about it.

Choose “Expert” mode to see and tweak what's under the hood.

Happy streaming!

And on the right side:

master_me
A plugin by Klaus Scheuermann.
With contributions from falkTX, jkbd, magnetophon, x42 and others.
Made with Faust and DPF.
Supported by the Prototype Fund / German Federal Ministry of Education and Research.

presets

there are two kinds of presets:

  • preset buttons on easy page
  • plugin presets loadable from DAW

todo on dsp/faust side:

  • 5 nice 'easy' presets (high-prio)

todo on gui side:

  • store and load preset data (high-prio)
  • export lv2 presets
  • deal with parameter changes after preset load (mid-prio)

Feature request: expose crossover frequencies.

IMHO, anybody who can handle the "expert" interface, will welcome being able to tweak the crossover frequencies.

crossoverFreqs = vslider("v:soundsgood/t:expert/h:[5]mscomp/h:[1]low band/[1]mscomp low freq", 60, 20, 20000, 1),vslider("v:soundsgood/t:expert/h:[5]mscomp/h:[2]high band/[1]mscomp high freq", 8000, 20, 20000, 1):LogArray(Nr_crossoverFreqs);

giving names and symbols to compressor gain reduction controls

There is commented code around the compressor gain reduction naming part:

  //meter(i) = _<:(_, (ba.linear2db:max(-40):min(0):vbargraph("v:soundsgood/t:expert/h:[6]mscomp_meter/[%i][unit:dB]%i[tooltip: gain reduction in dB]", -3, 0))):attach;
  meter(i) = _<:(_, (ba.linear2db:max(-40):min(0):vbargraph("v:soundsgood/t:expert/h:[6]mscomp_meter/[%i][unit:dB][tooltip: gain reduction in dB]", -3, 0))):attach;

From what I could understand, these are dynamic stereo controls, so giving a name makes it appear duplicate.

I guess it is commented out until a solution is found.
This ticket can serve as a reminder, as we need this for the plugin version too.

side eq

I implemented a 'side eq'.

desired function: boost on the side signal in an area (width) around a center frequency (eq side freq) by an amount in dB (eq side gain)

It's done with a bandpass filter added to the source signal.

  1. I am having trouble calculating the loudness of the bandpass so it feels like a parametric eq. (0 adds nothing, +x adds x db)

  2. My from width to low and high frequency of the bandpass is messy and broken in low frequencies.

Help needed...

whole code only works with compiler option -double

I am not 100% sure, but I guess it's a problem wit ma.EPSILON..?
Does the -double option make the code more cpu-heavy?

With the need for '-double' I can't use the faustide.grame.fr which I find quite comfortable.

Which IDEs do you guys use? I went for ATOM and Faustlive. Not too slick...

GUI related issues and ideas

  • target fader needs some label 'target'
  • mb-ms-comp: name needs multiband reference. Let's make it 'Multiband MidSide Comp'. Hope it fits.
  • mb-ms-comp: numeric readout or scale on the meters.
  • mb-ms-comp: rename 'output-gain' to 'makeup'
  • mb-ms-comp: put 'low' and 'high' below the paramters, so parameters are in horizontal line with kneecomp and limiter.
  • all: separator before meters without 'Outputs:'
  • 'enable' left of pluginname?
  • change plugin name to 'master_me'
  • gate meter missing

unbounded gate meter values

something seems wrong with the new gate meter.
it has a proper value where there is sound input, but cut the input and gate meter value gets lower and lower and lower... eventually stopping at -758.6 dB.

This seems like a bug..

What is the target environment?

In the best case, this software runs everywhere and shines with all the platform dependent details. Sure, beauty is our business.
But what is the most important niche, where it has to run properly as soon as possible? That is:

  • Operating System
  • Plug-in host or interface
  • GUI related environment

Make target slider -2dB max

As previously discussed.

Ticket serves as reminder and to check on progress on the task. Which as of now is still TODO.

Documentation

What's your favorite place and format of documentation for a plugin like this?

Wiki? Markup document?
Preferably here on the repo, right?

kneecomp: order of gui elements in faust/faustlive

Am am not seeing it... why are parameters displayed in wrong order?

sc_compressor =
    (
        (ms_enc,ms_enc):
        (((RMS_compression_gain_N_chan_db(strength,thresh,att,rel,knee,0,link,N)),si.bus(N) )
         : ro.interleave(N,2) : par(i,N,(meter : post_gain : ba.db2linear*(1-bypass)+bypass)*_))
        : ms_dec)
with {
    N = 2;
    bypass = checkbox("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_bypass][1]kneecomp bypass"):si.smoo;
    strength = vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_strength][2]kneecomp strength", 0.1, 0, 1, 0.1);
    thresh = target + vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_threshold][unit:dB][3]kneecomp threshold",init_kneecomp_thresh,-12,6,1);
    att = vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_attack][unit:ms][4]kneecomp attack",40,1,100,1)*0.001;
    rel = vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_release][unit:ms][5]kneecomp release",200,1,1000,1)*0.001;
    knee = vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_knee][6]kneecomp knee",6,0,30,1);
    link = vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_link][7]kneecomp link", 0.6, 0, 1, 0.1);
    meter = _<: _,( vbargraph("v:soundsgood/t:expert/h:[5]kneecomp/[unit:dB]",-6,0)) : attach;

    // dev version of faust has this in the libs, TODO, use co.RMS_compression_gain_N_chan_db
    RMS_compression_gain_N_chan_db(strength,thresh,att,rel,knee,prePost,link,1) =
        RMS_compression_gain_mono_db(strength,thresh,att,rel,knee,prePost);

    RMS_compression_gain_N_chan_db(strength,thresh,att,rel,knee,prePost,link,N) =
        par(i,N,RMS_compression_gain_mono_db(strength,thresh,att,rel,knee,prePost))
        <: (si.bus(N),(ba.parallelMin(N) <: si.bus(N))) : ro.interleave(N,2) : par(i,N,(it.interpolate_linear(link)));

    RMS_compression_gain_mono_db(strength,thresh,att,rel,knee,prePost) =
        RMS(rel) : ba.bypass1(prePost,si.onePoleSwitching(att,0)) : ba.linear2db : gain_computer(strength,thresh,knee) : ba.bypass1((prePost!=1),si.onePoleSwitching(0,att))
    with {
        gain_computer(strength,thresh,knee,level) =
            select3((level>(thresh-(knee/2)))+(level>(thresh+(knee/2))),
                    0,
                    ((level-thresh+(knee/2)) : pow(2)/(2*max(ma.EPSILON,knee))),
                    (level-thresh))
            : max(0)*-strength;
        RMS(time) = ba.slidingRMS(s) with {
            s = ba.sec2samp(time):int:max(1);
        };
    };
    //post_gain
    post_gain =
        _+
        (vslider("v:soundsgood/t:expert/h:[5]kneecomp/[symbol:kneecomp_makeup][unit:dB][8]kneecomp makeup", init_kneecomp_postgain,-10,+10,0.5) :si.smoo);
};

image

IO level meters have init/default/start at 0dB

Either something wrong in faust, or the way the meters are defined.
The "init" or default value for the level meters (and maybe others, not sure) is 0dB instead of the expected matching minimum.

This makes it so that, under a few hosts, the UI starts with the meters at 0dB and trigger the falloff on start.

Would be nice if the init/default values for level meters would be set as its minimum (as if there was no audio) instead of 0dB as it is now.

avoid sqrt() calls in inner loop DSP for mid/side calc

https://github.com/trummerschlunk/soundsgood/blob/e8eb9ba756971c22c5da8ca5a1f887f9f342faac/soundsgood.dsp#L395

One usually uses a factor or 0.5 when converting left/right to mid/side and then just sums for the inverse

mid = 0.5 * (left + right)
side = 0.5 * (left - right)

and then

left = mid + side
right  = mid -side

As opposed to the sqrt() approach, this also ensure that the mid value will not exceed 1.0, if both source values are below 1.0.

Note multiply by 0.5, which is faster than diving by two (although some compilers change this with fast-math)

Missing parameter units

A few parameters do not have units, this ticket serves to track down these and possibly make a decision on them.

Switches (including bypass) do not need them.
But others should have them, if possible.

(Personally I find 0-100% more readable than 0.0-1.0 raw values)

Current parameters without unit:

  • leveler gain (passive)
  • leveler gate (passive)
  • gate attack
  • gate hold
  • gate release
  • leveler speed
  • leveler max+
  • leveler max-
  • eq tilt gain typo (db vs dB)
  • eq side gain typo (db vs dB)
  • eq side bandwidth
  • kneecomp strength
  • kneecomp knee
  • kneecomp link
  • kneecomp fffb
  • kneecomp drywet
  • everything in mscomp except output gain (active)
  • limiter strength
  • limiter attack
  • limiter release
  • limiter fffb
  • limiter knee

who wins, when leveler and limiters fight against each other? max-gain!

There is one problematic situation with the new feedback concept of the leveler (which works so nicely now):

If target is higher than possible with the settings of limiter and brickwall, they will fight against each other resulting in maximum gain of the leveler.

I think it cannot be avoided, but with limiting certain ranges.
An 'expert' will not set these settings.

What are your ideas on that?

dsp code TODOs

  • global bypass

  • leveler: try expander instead of gate for silence detection

  • leveler: fix wrong calculation

  • side-eq: try different shelf eqs

  • kneecomp: drywet control (after makeup)

  • kneecomp: feedforward/feedback control

  • limiter: try different limiters available in faust

Tracking plugin version progress

I am making a DPF-based plugin version for soundsgood, with faustpp for the templating stuff, which nicely gets us a C++ class with some filled in values based on a template.
Check the dpf branch for current progress, there are builds via github actions too.

Also see #23 for the GUI sketches, where discussion on the layout and other high level concepts should happen.
This ticket is only about the implementation, and mostly so others can easily follow current progress.
We can assume I will do all these things, anything that requires intervention I will open as separate tickets.

Current TODO for plugin/dsp side:

  • implement custom bypass
  • report latency to host (is there a final decision whether to use faust modules that use latency?, related to #13)
  • properly name all parameters (depends on #22)
  • update static lv2 ttl to match dpf exported one (for handling states)

Current TODO for UI appearance:

  • define and implement consistent color palette
  • finalize widget styling

Current TODO for UI widgets:

  • easy vs expert mode switch (stored as plugin state)
  • finalize lufs meters
  • finalize gain reduction meter (db scaling for drawing)
  • allow both horizontal and vertical drag for parameter sliders
  • target slider dragging offset with correct dB scaling

Current TODO for UI layout:

  • finish easy mode layout (non-final widgets, but everything mapped to params)
  • finish expert mode layout (non-final widgets, but everything mapped to params)
  • add arrows to expert mode
  • make UI scalable
  • show version/git-tag in UI

Current TODO for UI features:

  • reuse nanovg context across widgets (see #82)
  • slider double-click for text input of parameter values

Can be left for later or v1.1:

  • proper UI level metering (depends on #9 and #16)

Unclear at the moment:

  • how do we define presets? UI only or exported with plugin?
  • do we want UI to be resizable? or stick with only a small set of zoom factors?

slider double-click

A ticket to discuss the double-click text input topic in particular.

Few things to do:

  • make font size match theme one
  • make highlight color match current slider background color?
  • ensure no right-click menus can be used (would go into imgui widgets, which dont match plugin ones)

after those are done, we will need testing.

level meters are mono

More like a question, not sure if this is intentional or not but currently seems all meters are mono.
Is this on purpose?

translations?

just wondering if there is a need or preference for translations.
germans typically like to see things in german 🇩🇪
but maybe audio production terms go with english? tbh I am not sure how german producers handle this.

just asking, setting up a switch for english | german mode is quite doable with the current code.

sync level meters output with GUI drawing

this is an issue as a form of question, because I dont know faust enough to understand how this is typically done.

we want to have level meters on the gui, but in order to make these meters actually useful the dsp level-meter side needs to keep going until notified by the ui that it has read the meter values.

the amateur approach is typically to calculate RMS and other values within a process cycle, every cycle, and set the passive / output meter value to that.
this is not a good approach, as the meter values would then be block-size dependent. also there could be several meter values calculated and reset before the GUI even shows a single one..
in short, level meters should run as commanded by the UI.

the flow is typically:

  1. plugin is running, no UI visible yet. plugin has internal values for level metering but we skip them to save cpu load
  2. UI is open, and tells dsp to start level meter stuff
  3. dsp now has level metering active, and keep setting the level-meter value(s) across several audio cycles (that is, the maximum or average value keeps being calculated until told otherwise)
  4. UI repaint happens, it reads the last level-meter value(s) and tells the dsp to start again
  5. dsp sets its internal maximum/average to 0 and continues with the level-metering, same as step 3
  6. another UI repaint, same as step 4
  7. steps 5 and 6 keep going while UI is open
  8. UI is closed, it tells the dsp side it can stop the level metering

There are possible deviations to this, we can keep level metering active with a fixed time (in ms) if we want for example lv2 control outputs to have useful values even while UI is not open.

now my question is... how do we deal with this with faust?
can we specify a time-window for the metering? can it run "forever" (not bound to time) and wait for a signal to reset its internal values?

limiter: missing latency report

The brickwall limiter, when enabled, adds a a latency of 480 samples (@ 48kHz).
it's really limiter_lad_lookahead = 0.01; * ma.SR

When bypassing the limiter (or the whole effect), either the latency has to be reset to 0, or ideally a crossfade happens with a signal that is delayed by latency.

Optiimzation - avoid log() calls in inner loop

https://github.com/trummerschlunk/soundsgood/blob/e8eb9ba756971c22c5da8ca5a1f887f9f342faac/soundsgood.dsp#L348

The value is for display only. With a custom GUI it's preferable to have the GUI call it.
Currently FAUST compiles this into the inner loop and calls log10() for each sample!

Since it's for display only, accuracy is not required you might want to investigate a fast_log implementation
https://www.flipcode.com/archives/Fast_log_Function.shtml

Use `stdfaust.lib` for smoothing

I think, lp1p(cf) is identical to si.smooth(ba.tau2pole(foo)) with foo = 1/(2*ma.PI*cf).

I looked at the C++-Code generated from

process = _ <: lp1p(cf), si.smooth(ba.tau2pole(1/(2*ma.PI*cf)))
with {
  cf = ma.E;
};

which yields

for (int i0 = 0; i0 < count; i0 = i0 + 1) {
	float fTemp0 = fConst1 * float(input0[i0]);

	fRec0[0] = fConst0 * fRec0[1] + fTemp0;
	output0[i0] = FAUSTFLOAT(fRec0[0]);
	fRec1[0] = fTemp0 + fConst0 * fRec1[1]; // summands swapped
	output1[i0] = FAUSTFLOAT(fRec1[0]);

	fRec0[1] = fRec0[0];
	fRec1[1] = fRec1[0];
}

I would prefer using the standard library. At first, lp1p(cf) made me think, "oh, super-elaborated ballistics going on".

leveler gate -> leveler brake

As the silence detection function s not a gate anymore, but an expander which puts a 'brake' on 'speed', it needs renaming.

leveler_gate meter -> leveler_brake meter
leveler_gate_threshold -> leveler_brake_threshold

symbols and labels

Dealing with keyboard input on plugin hosts

Reaper by default does not give plugin UIs keyboard focus, which makes it super easy to press backspace and have it delete the plugin 😡

It is the same issue as dealt in DISTRHO/Cardinal#304
We need the same hacks here too, likely best pushed as direct DPF functionality.

Expose a few more parameters, increase some ranges.

I understand that the main goal is to make more or less subtle corrections to the audio based on presets.

At the same we want to expose te expert interface as well.
It would be nice if that one allows to do heavy corrections or creative sound design.

Finally, I think the plugin would become more intuitive to work with if all similar parameters and displays have the same range.
With a consistent mapping between the visual position of a fader (or meter) and it's meaning you can get used to them quicker and focus on the sound more.

Therefore, I propose the following ranges:

  • all GR meters to -24 dB - 0 dB
  • all thresholds -24 dB to +24 dB
  • all makeup gains -24 dB to +24 dB
  • all eq gains -24 dB to +24 dB
  • all knee parameters exposed (so every compressor and limiter you choose to include), range -24dB to 0dB
  • all attack & release 0 to 1000 ms, log scale (IIUC a log scale cannot start at 0, so in reality ths needs to be a 'faked' log scale)
  • hp freq 0 to 1000 Hz, 'faked' log scale.
  • all eq freqs 20 Hz to 20 kHz
  • all comp strengths 0 to 8, ideally with 1 being the middle.
  • make each dynamics block have the option of MS or stereo.

Oddities with leveler gate meter values

The leveler gate meter has % unit, but range of 0 to 1.
Plus minimum value only seems to ever each 0.143, which is weird

Currently looks wrong on the gui too, as it does not behave like all the other meters.
For this one we want the meter to go from left to right, correct? (ie, from 0 to 100%..?)

error building under macOS 11 with homebrew faust

Getting this error on macOS 11, for the CI automated build:

ERROR : path '/soundsgood/expert/mscomp_meter/1' is already used

any hints?

issue does not happen on macOS 12 or on Linux, so perhaps a faust side issue?

Project Title

Dear all,

I have been wrapping my head around this for quite some time now.
I kind of like 'soundsgood' as the name for a tool you throw at the master and hopefully then it 'soundsgood'.

I also like master_me as the project from which this one came...

So. If you have any other ideas for naming this beast, please share - thank you!

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.