How do I convert this obscure allpass from matlab into gen code
Blair
8月 30 2023 | 1:54 午前
I found this allpass filter in the form of matlab code. Its a special filter used to create inharmonicty in strings waveguides. I was wondering if anyone would be willing to help me port it to genexpr?
I am unsure where something like a history operator fits in, where the actual input and output signal go,
also little things like the periods which are in some lines, I heard it might be something to do with an array?
another confusing thing is the colons on this line, which i heard is like a counter?phik = pi*[1:2:2*nap-1];
function sos = adf(f0,B,df,beta)
% adf.m
%
% Allpass dispersion filter design
% J.S. Abel, V. Valimaki, and J.O. Smith, "Robust, Efficient Design of
% Allpass Filters for Dispersive String Sound Synthesis," IEEE Signal
% Processing Letters, 2010.
%
% Parameters:
% f0 = fundamental frequency, Hz
% B = inharmonicity coefficent, ratio (e.g., B = 0.0001)
% df = design bandwidth, Hz
% beta = smoothing factor (e.g., beta = 0.85)
%
% Examples:
% sos = adf(32.702,0.0002,2100,0.85);
% sos = adf(65.406,0.0001,2500,0.85);
% sos = adf(130.81,0.00015,4300,0.85);
%
% The output array sos contains the allpass filter coefficients
% as second-order sections.
%
% Created: Vesa Valimaki, Dec. 11, 2009
% (based on Jonathan Abel's Matlab code)
%% initialization
% system variables
fs = 44100; %% sampling rate, Hz
nbins = 2048; %% number of frequency points
%% design dispersion filter
% period, samples; df delay, samples; integrated delay, radians
tau0 = fs/f0; %% division needed
pd0 = tau0/sqrt(1 + B*(df/f0).^2); %% division and sqrt needed
mu0 = pd0/(1 + B*(df/f0)^2);
phi0 = 2*pi*(df/fs)*pd0 - mu0*2*pi*df/fs;
% allpass order, biquads; desired phases, radians
nap = floor(phi0/(2*pi));
phik = pi*[1:2:2*nap-1];
% Newton single iteration
etan = [0:nap-1]/(1.2*nap) * df; %% division needed
pdn = tau0./sqrt(1 + B*(etan/f0).^2); %% division and sqrt needed
taun = pdn./(1 + B*(etan/f0).^2);
phin = 2*pi*(etan/fs).*pdn;
theta = fs/(2*pi) * (phik - phin + (2*pi/fs)*etan.*taun) ./ (taun - mu0);
% division needed
% compute allpass pole locations
delta = diff([-theta(1) theta])/2;
cc = cos(theta * 2*pi/fs);
eta = (1 - beta.*cos(delta * 2*pi/fs))./(1 - beta); %% division needed
alpha = sqrt(eta.^2 - 1) - eta; % sqrt needed
% form second-order allpass sections
temp = [ones(nap,1) 2*alpha'.*cc' alpha'.^2];
sos = [fliplr(temp) temp];
bertrandfraysse
8月 30 2023 | 10:15 午前
as there's this line -> nbins = 2048; %% number of frequency points
it may mean it's an FFT type of treatment.
the array would mean what you need to do on each bins
maybe ?
Blair
8月 30 2023 | 10:49 午前
i don't think its FFT because in the whitepaper this filter is based on they don't mention it, however someone told me that the filter is moreso based on an array vs sample by sample. so i am kind of just more confused now :')
https://www.researchgate.net/publication/224106863_Robust_Efficient_Design_of_Allpass_Filters_for_Dispersive_String_Sound_Synthesis
Wetterberg
8月 30 2023 | 11:54 午後
>An efficient allpass filter design method is introduced to match the dispersion characteristics of vibrating stiff strings. The proposed method designs an allpass filter in cascaded biquad form directly from the target group delay, placing the poles at frequencies at which the group delay area function achieves odd integer multiples of π
So this is essentially an array of allpass filters, and the paper describes a method of spreading out their phases and frequencies, if I'm reading it right.
So we're basically looking at a resonator/reverb with a TON of allpasses. using "odd integer multiples of Pi" is a common method of avoiding unwanted resonances building up from harmonics inside reverbs/diffusion.
First time I heard software using this sort of process creatively has to be the GRM tools and Soundhack?
For getting into this, have a sniff in the help examples: Examples->Gen -> gen~.karplus_strong_strange
I think you'll find interesting shades of that paper inside that gen~ file in this patch.
Roman Thilenius
8月 31 2023 | 1:31 午後
soundhack was fft only and if i am not mistaken the grm plug was more like reson~ than a "normal" feedback loop.
i find the idea very interesting to use the same feedback loop (think tapin~) for loops of different sizes at a time - no matter if with allpasses, the teeth object, or with yet another tapping buffer inside the feedbackloop. less objects, less connections, less CPU. and be prepared for some suprising results.