Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Vowel fx needs an overhaul #2904

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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ethancrawford opened this issue Oct 21, 2021 · 3 comments
Closed

Vowel fx needs an overhaul #2904

ethancrawford opened this issue Oct 21, 2021 · 3 comments

Comments

@ethancrawford
Copy link
Collaborator

There have been questions previously about the effectiveness of the :vowel fx. (See #1992 for example).

Xav has said that the current implementation leaves much to be desired. He is interested in eventually rewriting it, and has said it should be easier this time, particularly with the use of SCLang. (We might use FormantTable).

@xavriley
Copy link
Collaborator

This is the example (from the docs for FormantTable) I'd like to base it off:

// Saw freq is controlled by mouse X position
// BBandPass filter is controlled by
// FormantTable data (frequencies, resonances, amplitudes)
(
    SynthDef(\formantVoice, { arg
        f = #[ 400, 750, 2400, 2600, 2900 ],
        a = #[ 1, 0.28183829312645, 0.089125093813375, 0.1, 0.01 ],
        q = #[ 0.1, 0.10666666666667, 0.041666666666667,
            0.046153846153846, 0.041379310344828 ];
    var scale = [0, 2, 4, 7, 9]; // pentatonic major
    var scaleBuf = LocalBuf(scale.size, 1).set(scale);
    var degree = Index.kr(scaleBuf, MouseX.kr(0, BufFrames.kr(scaleBuf)));
    var vibrato = SinOsc.kr(6, mul:4);
    var base = 5 * 12;
    var in = Saw.ar(((degree + base).midicps + vibrato).lag(0.3));
    Out.ar(0, Mix.new(BBandPass.ar(in, f, q) * a).dup);
}).send(s);
)

// create a menu of the FormantTable options for preview
(
    var voices = FormantTable.keys.asArray;
    voices.sort;

    // start an instance of the synth
    #f, a, q = FormantTable.get( voices.first );
    x = Synth(\formantVoice, [\f, f, \a, a, \q, q]);
    w = Window("FormantTable Browser",
        Rect(Window.screenBounds.width/2 - 150,
        Window.screenBounds.height/2 - 30,
        300, 60));
    StaticText(w, Rect(0, 5, w.view.bounds.width, 20))
        .font_(Font("Helvetica", 11))
        .string_("Move mouse left/right to change pitch")
        .align_(\center);
    PopUpMenu(w, w.view.bounds.insetBy(15, 20).moveBy(0, 10))
        .items_(voices)
        .action_({ |v|
            // change the data based on user action
            #f, a, q = FormantTable.get( v.item );
            x.setn(\f, f);
            x.setn(\a, a);
            x.setn(\q, q);
        });
    w.onClose_({ x.free });
    w.front;
)

nb. the FormantTable class is part of the sc3-plugins repo so you need to have that set up in order for the above to work.

@samaaron
Copy link
Collaborator

Sounds cool - although just to check, is the SCLang FormantTable class used just to compile the synthdef or is it necessary to generate the correct runtime args?

@ethancrawford
Copy link
Collaborator Author

@samaaron - at first glance it appears to me that it's just a utility that holds the correct numbers for the filter values, so perhaps not needed at runtime.

@sonic-pi-net sonic-pi-net locked and limited conversation to collaborators Jul 21, 2022
@samaaron samaaron converted this issue into discussion #3163 Jul 21, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests

3 participants