Могу ли я отправлять значения в Pbind, которые интерпретируются как мидиноты или степени?

Я не уверен, может ли SuperCollider доставлять луны на палочках, но мне бы очень хотелось иметь возможность указывать значения в моем Pbind, которые интерпретируются так же, как midinote или degree: то есть автоматически преобразуются в частоту.

Итак, отрывок такого Pbind, который выдает скольжение в стиле ТБ-303 с одной частоты на другую:

b = Pbind(*[
    out: 0,
    instrument: \acid,
    stepsPerOctave: 19,
    scale: [0, 3, 5, 8, 11, 14, 17],
    octave: 3,
    degree: Pseq([0, \, 3, 3, 4, 4, 9, 4, 4]),
    prevFreq: Pseq([\, \, 0, 3, 3, 4, 4, 9, 4]),
    dur: Pseq([0.4, 0.4, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1]),
]);

... было бы супер-пупер, если бы prevFreq интерпретировалось как содержащее значения градусов так же, как degree.

В отсутствие какого-либо автоматического преобразования я предполагаю, что мне нужно выполнить какой-то расчет в самом синтезаторе, чтобы преобразовать мои значения из значения типа degree в реальную частоту. Я знаю, что могу использовать foo.midicps для преобразования значений типа midinote в частоту, но есть ли аналогичная удобная функция для преобразования значений типа degree в частоту (предположительно также с использованием текущих значений scale и octave)?


person David    schedule 15.09.2013    source источник


Ответы (1)


Если вы посмотрите на файл справки для Event, вы увидите, как он вычисляет частоту по степени и шкале:

note: #{    // note is the note in halftone steps from the root
    (~degree + ~mtranspose).degreeToKey(~scale, ~stepsPerOctave);
}
midinote: #{    // midinote is the midinote (continuous intermediate values)
    ((~note.value + ~gtranspose + ~root) / ~stepsPerOctave + ~octave) * 12.0;
}
freq: #{
    (~midinote.value + ~ctranspose).midicps * ~harmonic;
}
detunedFreq: #{    // finally sent as "freq" to the synth as a parameter, if given
    ~freq.value + ~detune
}

Событие — это ассоциативный массив, и эти ~переменные также можно использовать в качестве ключей к массиву (мы надеемся, что это станет ясно через мгновение. Также можно получить доступ к событиям в Pbind, используя Pfunc. Скажем, мы хотите рассчитать текущую частоту для вашего Pbind:

b = Pbind(*[
    out: 0,
    instrument: \default,
    stepsPerOctave: 19,
    scale: [0, 3, 5, 8, 11, 14, 17],
    octave: 3,
    degree: Pseq([0, \, 3, 3, 4, 4, 9, 4, 4]),
    dur: Pseq([0.4, 0.4, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1]),
    foo: Pfunc({|evt|
        var note, midinote, freq, detuned, result;
        note = (evt[\degree] + evt[\mtranspose]).degreeToKey(evt[\scale], evt[\stepsPerOctave]);
        midinote = ((note + evt[\gtranspose] + evt[\root]) / evt[\stepsPerOctave] + evt[\octave]) * 12.0;
        freq =  (midinote + evt[\ctranspose]).midicps * evt[\harmonic];
        detuned = freq + evt[\detune];
        detuned.postln;
    })
]).play

Расчеты для note, midinot, freq и detuned freq — это те же расчеты, которые мы видели в файле справки по событию. Следовательно, этот Pbind теперь будет печатать частоту, которую вы играете в данный момент.

Что вам на самом деле нужно, так это частота, которую вы играли ранее, которую мы могли бы определить из вашего набора предыдущих степеней. Или мы могли бы просто отслеживать предыдущую частоту в переменной. За этим будет намного легче следить!

(

var prev;

b = Pbind(*[
    out: 0,
    instrument: \default,
    stepsPerOctave: 19,
    scale: [0, 3, 5, 8, 11, 14, 17],
    octave: 3,
    degree: Pseq([0, \rest, 3, 3, 4, 4, 9, 4, 4]),
    dur: Pseq([0.4, 0.4, 0.1, 0.1, 0.1, 0.1, 0.2, 0.1, 0.1]),
    prevFreq: Pfunc({|evt|
        var note, midinote, freq, detuned, result;

        if (evt[\degree] == \rest, { detuned = \rest} , {
            note = (evt[\degree] + evt[\mtranspose]).degreeToKey(evt[\scale], evt[\stepsPerOctave]);
            midinote = ((note + evt[\gtranspose] + evt[\root]) / evt[\stepsPerOctave] + evt[\octave]) * 12.0;
            freq =  (midinote + evt[\ctranspose]).midicps * evt[\harmonic];
            detuned = freq + evt[\detune];
        });

        //detuned.postln;

        if (prev.isNil(), { 
            result = \rest;
            } , 
            {
                result = prev;
        });

        prev = detuned

    })
]).play
)
person les_h    schedule 02.06.2014