подготовка к выступлению

main
Arseniy Prosvirnin 1 month ago
parent a1daedeab0
commit dd6cd4bbc0
No known key found for this signature in database
GPG Key ID: CF45A8EE158BBCB6

@ -1,9 +1,106 @@
(
~dict = BmDspAlgs.getDict("spectral/fft_freeze.scd");
~dict[\defaults] = (
attack: 0.01,
release: 0.1,
curve: 1
);
~dict[\sustained] = true;
~dict[\useEnv] = true;
~dict2 = BmDspAlgs.getDict("spectral/fft_freeze_follow.scd");
~dict.makeBufferProcessingNdef(\freeze1);
~dict.makeBufferProcessingNdef(\freeze2);
~dict2.makeBufferProcessingNdef(\freeze3);
"instrumets loaded".postln;
)
Ndef(\freeze1).set(\in, ~inBus.index);
Ndef(\freeze2).set(\in, ~inBus.index);
Ndef(\freeze3).set(\in, ~inBus.index);
"inBus setted as NDefs input".postln;
Ndef(\freeze1).put(10, \filter -> {
|in|
PitchShift.ar(
in,
0.2,
\shift.kr(2),
0.01, 0.01
);
});
Ndef(\freeze2).put(10, \filter -> {
|in|
PitchShift.ar(
in,
0.2,
\shift.kr(2),
0.01, 0.01
);
});
Ndef(\freeze1).set(\wet10, 0);
Ndef(\freeze2).set(\wet10, 0);
// Динамика: компрессор + нормалайзер + лимитер.
// Сжимает громкое, поднимает тихое, не даёт пробить наушники.
Ndef(\freeze1).put(20, \filter -> {
|in|
// Лёгкая компрессия: сжимаем только то, что выше порога (громкое).
var comp = Compander.ar(
in, in,
thresh: \compThresh.kr(0.5),
slopeBelow: 1.0,
slopeAbove: \compSlope.kr(0.5),
clampTime: \compClamp.kr(0.01),
relaxTime: \compRelax.kr(0.1)
);
// Нормалайзер: подтягивает тихий сигнал до норм. уровня (flattens dynamics).
var norm = Normalizer.ar(comp, \normLevel.kr(0.5), \normDur.kr(0.05));
// Лимитер: жёсткий потолок от пробоя наушников.
Limiter.ar(norm, \limLevel.kr(0.002), \limDur.kr(0.01));
});
Ndef(\freeze2).put(20, \filter -> {
|in|
// Лёгкая компрессия: сжимаем только то, что выше порога (громкое).
var comp = Compander.ar(
in, in,
thresh: \compThresh.kr(0.5),
slopeBelow: 1.0,
slopeAbove: \compSlope.kr(0.5),
clampTime: \compClamp.kr(0.01),
relaxTime: \compRelax.kr(0.1)
);
// Нормалайзер: подтягивает тихий сигнал до норм. уровня (flattens dynamics).
var norm = Normalizer.ar(comp, \normLevel.kr(0.5), \normDur.kr(0.05));
// Лимитер: жёсткий потолок от пробоя наушников.
Limiter.ar(norm, \limLevel.kr(0.002), \limDur.kr(0.01));
});
// Применяем specs из словарей к Ndef (нужно для GUI и маппинга контроллера).
// TODO(bmSClib): автоматизировать — см. readme.org, секция TODO.
~dict[\specs].keysValuesDo { |k, v| Ndef(\freeze1).addSpec(k, v) };
~dict[\specs].keysValuesDo { |k, v| Ndef(\freeze2).addSpec(k, v) };
~dict2[\specs].keysValuesDo { |k, v| Ndef(\freeze3).addSpec(k, v) };
// Спек-параметры обёртки processSig (в dict их нет).
[\freeze1, \freeze2, \freeze3].do { |n|
Ndef(n).addSpec(\postAmp, [0, 1, \lin, 0, 1]);
Ndef(n).addSpec(\pan, [-1, 1, \lin, 0, 0]);
};
// Огибающая (useEnv) и питчшифтер есть только у freeze1/2.
[\freeze1, \freeze2].do { |n|
Ndef(n).addSpec(\envGate, [0, 1, \lin, 0, 0]);
Ndef(n).addSpec(\attack, [0.001, 4, \exp, 0.001, 0.01]);
Ndef(n).addSpec(\release, [0.001, 4, \exp, 0.001, 0.1]);
Ndef(n).addSpec(\shift, [0.5, 2, \exp, 0.01, 2]);
Ndef(n).addSpec(\wet10, [0, 1, \lin, 0, 0]);
};
"FX added".postln;
)

@ -1,34 +1,38 @@
(
s.options.memSize_(2.pow(20));
s.waitForBoot({
~makeBuffers = { |path, event, mono = false|
var dir = PathName.new(path);
var contents = dir.entries;
if (contents.select({ |n| n.isFile }).size > 0)
{
var files, bufArray;
files = contents.select({ |n| n.isFile });
files = files.select({ |n|
["aif", "aiff", "wav"].includesEqual(n.extension)
});
if (event[dir.folderName.asSymbol] != nil)
{ "duplicate subfolder name ignored".warn; }
{
bufArray = files.collect({ |n|
if(mono)
{ Buffer.readChannel(s, n.fullPath, channels:[0]) }
{ Buffer.read(s, n.fullPath) };
});
event[dir.folderName.asSymbol] = bufArray;
};
};
if (contents.select({ |n| n.isFolder }).size > 0)
{
var folders = contents.select({ |n| n.isFolder });
folders.do({ |n| ~makeBuffers.(n.fullPath, event, mono) });
};
event;
};
"instruments.scd".loadRelative;
~makeBuffers = { |path, event, mono = false|
var dir = PathName.new(path);
var contents = dir.entries;
if (contents.select({ |n| n.isFile }).size > 0)
{
var files, bufArray;
files = contents.select({ |n| n.isFile });
files = files.select({ |n|
["aif", "aiff", "wav"].includesEqual(n.extension)
});
if (event[dir.folderName.asSymbol] != nil)
{ "duplicate subfolder name ignored".warn; }
{
bufArray = files.collect({ |n|
if(mono)
{ Buffer.readChannel(s, n.fullPath, channels:[0]) }
{ Buffer.read(s, n.fullPath) };
});
event[dir.folderName.asSymbol] = bufArray;
};
};
if (contents.select({ |n| n.isFolder }).size > 0)
{
var folders = contents.select({ |n| n.isFolder });
folders.do({ |n| ~makeBuffers.(n.fullPath, event, mono) });
};
event;
};
s.sync;
// загрузка тестового сэмпла
"test_init.scd".loadRelative;
s.sync;
"instruments.scd".loadRelative;
});
)

@ -1,46 +1,54 @@
~samples = ~makeBuffers.("/home/dude/code/24_09_2026_gig", ());
~sample = ~samples[\samples][0];
~inBus = Bus.audio(s, 1);
Ndef(\testSignal).set(\gain, 0.1);
(
Ndef(\testSignal, {
var sig, sig2;
sig = BufRd.ar(2, ~sample, Phasor.ar(0, BufRateScale.kr(~sample), 0, BufFrames.kr(~sample)));
Out.ar(~inBus, sig.sum);
sig * \gain.kr(0.01);
}).play;
Ndef(\freeze1).play;
Ndef(\freeze2).play;
Ndef(\freeze3).play;
)
Ndef(\testSignal).ar(2);
Ndef.clear
Ndef(\freeze1).set(\in, ~inBus.index);
Ndef(\freeze2).set(\in, ~inBus.index);
Ndef(\freeze3).set(\in, ~inBus.index);
Ndef(\freeze3).set(\in, ~inBus);
Ndef(\freeze1).set(\amp, 1.7);
Ndef(\freeze2).set(\amp, 2.6);
Ndef(\freeze3).set(\amp, 10.05);
// FREEZE1
(
// Статические параметры. Не меняются
Ndef(\freeze1).set(\attack, 4.0);
Ndef(\freeze1).set(\release, 4.0);
// Динамические параметри. Меняются.
Ndef(\freeze1).set(\amp, 0.3);
Ndef(\freeze1).set(\envGate, 1);
Ndef(\freeze1).set(\pan, 0.0);
// Сброс фриза
Ndef(\freeze1).set(\freezeGate, 0);
Ndef(\freeze1).set(\freezeGate, 1);
Ndef(\freeze2).set(\freezeGate, 1);
Ndef(\freeze3).set(\freezeGate, 1);
Ndef(\freeze3).set(\rel, 0.1);
Ndef(\freeze3).set(\atk, 0.1);
Ndef(\freeze3).set(\ampGate, 0.0001);
Ndef(\freeze1).set(\pan, 0);
Ndef(\freeze3).set(\amp, 0.1);
Ndef(\freeze1).set(\amp, 0.7);
(
Ndef(\freeze1).set(\freezeGate, 0);
Ndef(\freeze1).set(\freezeGate, 1);
)
Ndef(\freeze1).set(\wipe, 0.3);
Ndef(\freeze1).set(\reshuffle, 0.1);
Ndef(\freeze1).set(\binShift, 0.4);
Ndef(\freeze1).set(\stretch, 0.1);
// Крутим НА САУНДЧЕКЕ!!!
// После не трогать!!!
Ndef(\freeze1).set(\limLevel, 0.003);
// Настройки питчшифтера
//Рабочие значения (для freeze1 поверх замороженного спектра):
//Чуть расстроенные (биения между слоями, «расщеплённый» звук):
//- \range1 = 1.0, \range2 = 1.0125 → синтонная комма 81/80, лёгкое «волнение»
//- \range1 = 1.0, \range2 = 1.024 → диезис 128/125
//- \range1 = 1.0, \range2 = 1.0293 → четвертьтон 2^(1/24)
3
//Чистые нетемперированные интервалы (классика just intonation, даёт «странный» консонанс/диссонанс):
//- 16/15 = 1.0667 (малая секунда)
//- 25/24 = 1.0417 (хроматический полутон)
//- 21/20 = 1.05
//- 28/27 = 1.0370
//Тричетвертьтон и около:
//- 2^(3/24) = 1.0905
//- 7/6 = 1.1667, 8/7 = 1.1429 (септимальные интервалы — звучат «не по-нашему»)
Ndef(\freeze1).set(\shift, 2.0);
Ndef(\freeze1).set(\wet10, 1.0);
)
(
Ndef(\freeze3).put(10, \filter -> {
@ -68,27 +76,7 @@ Ndef(\freeze3).put(10, \filter -> {
)
(
Ndef(\freeze1).put(10, \filter -> {
|in|
var sig = 0;
var shPitched = PitchShift.ar(
in,
0.2,
SinOsc.kr(0.1).range(2, 4),
0.01,
0.01
) * 2.0;
var shPitched2 = PitchShift.ar(
in,
0.2,
SinOsc.kr(0.05).range(4, 6),
0.01, 0.01
) * 2.0;
sig = Mix([in, shPitched, shPitched2]) * 0.9;
sig;
});
)
(
@ -97,12 +85,16 @@ Ndef(\freeze2).stop;
Ndef(\freeze3).stop;
)
(
Ndef(\freeze1).play;
Ndef(\freeze2).play;
Ndef(\freeze3).play;
)
Ndef(\testSignal).stop;
Ndef(\testSignal).set(\gain, 1.0);
NdefMixer
n = NdefMixer(s);
// FREEZE3
// NB! Очень громкий!!!
Ndef(\freeze3).set(\amp, 0.1);
Ndef(\freeze3).set(\freezeGate, 0);
// Ближе к 1 - апекствин
Ndef(\freeze3).set(\ampGate, 0.001);

Loading…
Cancel
Save