最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Got any advice in how to start imlementing this strucutre in Matlab (audio signal processing)? - Stack Overflow

programmeradmin2浏览0评论

enter image description here

My problem is that I dont know how start with this structure. I know myself very well that I will do it wrong and therefore wanted some advice in how to implement this structure in Matlab

I already tried a FDN reverb in Matlab. There I did it in real time with ring buffer and so on. Can I apply this Idea to this structure too? What do you think?

Here the code of what I already tried and want to apply to the given structure in the pic

classdef FDNreverbDGL < audioPlugin
    properties
        preDelayT = 0;              % pre delay [ms]
        reverbTime = 3;           % reverb time [s]
        roomSize = 5;
        mix = 50;                  % mix of wet and dry signal [Percent], 100 % -> only wet
        order = enumFDNorder.order8;                      % order of FDN, should be power of 2
        in_coeff = 1/2;         % coeff for in and output lines --- just for now one value for all
        out_coeff = 0.65;
        m_AP = 1;
        D_g;  %sqrt(1-g^(2))
    end

    properties (Access = private)
        N = 8;                  % order of FDN 
        a = 1.1;                    % multiplying factor for delays
        cSound = 343.2;             % speed of sound
        
        primeDelays = [2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 ...
            67 71 73 79 83 89 97 101 103 107 109 113 127 131];

        % following values have to be set manually for Interface
        maxPreDelay = 0.2;          % max pre delay [s] (200ms)
        maxRoomSize = 20.0;         % max room size [m] 

        % following variables initialized in reset method
        
        fs;         % sample rate
        A;                  % feedback matrix
        b;                  % input gain coefficients
        c;                  % output gain coefficients
        f;                  % feedback lines after matrix
        v;                  % signal before delay - v_i(n) = b_i * x(n) + f_i(n)
        s;                  % output lines
        d;                  % signal to be sent to matrix A       
        buffDelayLines;     % buffer delay lines, initialized in reset method
        m;                  % delay in samples of each delay line
        ms;                 % m'
        m2;                 % delay in samples of each delay line
        g;                  % gain coefficients of delay lines
        maxDelay;           % maximum delay in delay lines
        buffInput;          % input buffer for pre delay
        pBuffDelayLines;    % pointer for delay lines buffer
        pBuffInput;         % pointer for input buffer 
        preDelayS;          % preDelay in samples
    end

    properties(Constant)
        PluginInterface = audioPluginInterface( ...
            audioPluginParameter('preDelayT', ...
            'DisplayName', 'Pre Delay [ms]', ...
            'Mapping', {'int', 0, 200}, ...
            'Style', 'rotary', ...
            'Layout', [1,1]), ...
            audioPluginParameter('roomSize', ...
            'DisplayName', 'Room Size [m]', ...
            'Mapping', {'lin', 1.0, 20.0}, ...
            'Style', 'rotary', ...
            'Layout', [1,2]), ...
            audioPluginParameter('reverbTime', ...
            'DisplayName', 'Reverb Time [s]', ...
            'Mapping', {'lin', 0.1, 10.0}, ...
            'Style', 'rotary', ...
            'Layout', [1,3]), ...
            audioPluginParameter('order', ...
            'DisplayName', 'Order of FDN', ...
            'Mapping', {'enum','2', '8', '16', '32'}, ...
            'Layout', [3,2]), ...   
            audioPluginParameter('in_coeff', ...
            'DisplayName', 'Input Gain', ...
            'Mapping', {'lin', 0.0, 1.0}, ...
            'Style', 'rotary', ...
            'Layout', [3,3]), ...
            audioPluginParameter('out_coeff', ...
            'DisplayName', 'Output Gain', ...
            'Mapping', {'lin', 0.0, 1.0}, ...
            'Style', 'rotary', ...
            'Layout', [3,4]), ...
            audioPluginParameter('mix', ...
            'DisplayName', 'Mix', ...
            'Mapping', {'int', 0, 100}, ...
            'Style', 'rotary', ...
            'Layout', [3,1]), ...
            audioPluginGridLayout( ...
            'RowHeight', [100 100 100 100 100 100], ...
            'ColumnWidth',[100, 100 100 100 100 100], ...
            'RowSpacing', 10, ...
            'ColumnSpacing', 10, ...
            'Padding', [10 10 10 10]) ...
            );
    end

    methods

        function plugin = FDNreverb
            init(plugin)
        end

        function out = process(plugin, in) 
            out = zeros(size(in));
            
            for i = 1:size(in,1)
                % Summieren der L/R - Kan�le
                inL = in(i,1);
                inR = in(i,2);
                inSum = (inL + inR)/2;
                plugin.buffInput(plugin.pBuffInput + 1) = inSum;
                
                
                % loop over delay lines
                for n=1:plugin.N
                    % d_n = gain * delayed v_n
                    for k=1:plugin.N  
                        plugin.d(k) = plugin.g(k) * plugin.buffDelayLines(k, mod(plugin.pBuffDelayLines + plugin.m(k)+1, plugin.maxDelay +1) +1);
                       %xa = plugin.buffDelayLines(k, mod(plugin.pBuffDelayLines + plugin.m(k)+1, plugin.maxDelay +1) +1);
                       %xb = plugin.buffDelayLines(k, mod(plugin.pBuffDelayLines + plugin.m(k)+plugin.ms(k)+1, plugin.maxDelay +1) +1);
                       %ya = 
                       %plugin.d(k)= plugin.g(k) *
                       %xa+(sqrt(1-plugin.g(k)^2)/sqrt(1-plugin.g(k)^2))*
                       %(xb-plugin.g(k)*
                       
                       
                       
                       
                        
                    end
                    % f_n = A(n,:) * d'
                    plugin.f(n) = plugin.A(n,:) * plugin.d(:);
                    % v_n with pre delay
                    plugin.v(n) = plugin.b(n) * plugin.buffInput(mod(plugin.pBuffInput + plugin.preDelayS, (plugin.maxPreDelay * plugin.fs + 1)) + 1) ...
                        + plugin.f(n); %An pe delay noch arbeiten
                    

                   

                    plugin.buffDelayLines(n, plugin.pBuffDelayLines + 1) = plugin.v(n);
                    % output lines
                    plugin.s(n) = plugin.c(n) * plugin.d(n);
                
                    out(i,:) = out(i,:) + real(plugin.s(n));
                    
                end

                % Assign to output
                out(i,1) = plugin.mix/100 * out(i,1) + (1.0 - plugin.mix/100) * in(i,1);
                out(i,2) = plugin.mix/100 * out(i,2) + (1.0 - plugin.mix/100) * in(i,2);

                calculatePointer(plugin);
            end 
        end

        function calculatePointer(plugin)
            if (plugin.pBuffDelayLines==0)
                plugin.pBuffDelayLines = plugin.maxDelay;
            else
                plugin.pBuffDelayLines = plugin.pBuffDelayLines - 1;
            end

            if (plugin.pBuffInput==0)
                plugin.pBuffInput = plugin.maxPreDelay * plugin.fs;
            else
                plugin.pBuffInput = plugin.pBuffInput - 1;
            end
        end

        function set.in_coeff(plugin, val)
            plugin.in_coeff = val;
            plugin.b = ones(plugin.N,1) * val;
        end

        function set.out_coeff(plugin, val)
            plugin.out_coeff = val;
            plugin.c = ones(plugin.N,1) * val;
        end

        function set.order(plugin, val)
            plugin.order = val;
            switch (plugin.order)
                case enumFDNorder.order8
                    plugin.N = 8;
                case enumFDNorder.order16
                    plugin.N = 16;
                case enumFDNorder.order32
                    plugin.N = 32;    
            end
            reset(plugin)
        end

        function set.reverbTime(plugin, val)
            plugin.reverbTime = val;
            calculateGainCoeffs(plugin, plugin.reverbTime) %, plugin.reverbTime
            calculateD elays(plugin)
            %sprintf('Set Reverb Time: %f', plugin.reverbTime)
            %disp(['Set Reverb Time: ', num2str(plugin.reverbTime), ' s.']);
        end

        function set.preDelayT(plugin, val)
            plugin.preDelayT = val;
            calculatePreDelayS(plugin, plugin.preDelayT)
            %disp(['Set Predelay: ', int2str(plugin.preDelayT), ' ms.']);
        end

        function set.mix(plugin, val)
            plugin.mix = val;
            %disp(['Set Mix value: ', int2str(plugin.mix), ' %.']);
        end

        function calculateMatrix(plugin)
            plugin.A = generateFDNmatrix(plugin.N);
        end

        function calculateDelays(plugin)
             % calculate sample delays dependent on room size (val) and
             % sample rate (fs)
             % m_1 = trace of sound / cSound * fs
             
             M = ceil(0.15 * plugin.reverbTime * plugin.fs);
             %disp(['M = ', int2str(M)]);
             plugin.m = zeros(plugin.N,1);
             interval = M/(plugin.N*4);
             %test = 0;
             for i=1:plugin.N
                 tmp = interval/2 + (i-1) * interval;
                 e = floor(0.5 + log(tmp)/log(plugin.primeDelays(i)));
                 plugin.m(i) = plugin.primeDelays(i)^(e); %plugin.primeDelays(i)^(e)
             end
            plugin.ms = [1429 1523  1619  1741  1871 1993 2089 2221 2339 2437 2579 2689 2791 2909 3041 3187];
            %plugin.m = [223 569  941  1451  1871 2297 2729 3209 3643 4111 4597 5077 5563 6053 6551 7013]; %JedeVierte

        end

        function calculateGainCoeffs(plugin,val)  %,val
            
            for i=1:plugin.N
               % if mod(i,2) == 0
               plugin.g(i) = 0.8;%10^((-3) * (plugin.m(i)/plugin.fs) / val);
               % plugin.g(i) = -0.9;
               %  else
               %    plugin.g(i) = 0.2;

                %end
            end
            
        end
%% 

        function calculatePreDelayS(plugin, val)
            plugin.preDelayS = val * plugin.fs/100 ;
        end

        function init(plugin)
            plugin.fs = getSampleRate(plugin);

            % initialize buffDelayLines & pointer
            %plugin.maxDelay = floor(plugin.maxRoomSize/plugin.cSound * plugin.fs * plugin.a^(plugin.N)); %probably higher than actual max delay as actual delays get rounded down
            %plugin.maxDelay = ceil(0.15 * 5 * plugin.fs);   % maximum possible delay for max reverb time = 5s
            plugin.maxDelay = 131^2;
            plugin.buffDelayLines = zeros(plugin.N, plugin.maxDelay + 1);
            plugin.pBuffDelayLines = plugin.maxDelay;

            % initialize
          
            
            plugin.A = zeros(plugin.N);
            plugin.b = ones(plugin.N,1) * plugin.in_coeff; % input gain coefficients
            plugin.c = ones(plugin.N,1) * plugin.out_coeff; % output gain coefficients
            plugin.f = zeros(plugin.N,1);             % feedback lines after matrix
            plugin.v = zeros(plugin.N,1);             % signal before delay - v_i(n) = b_i * x(n) + f_i(n)
            plugin.s = zeros(plugin.N,1);             % output lines
            plugin.d = zeros(plugin.N,1);             % signal to be sent fsto matrix A
            plugin.m = zeros(plugin.N,1);             % delay in samples of each delay line
            plugin.ms = zeros(plugin.N,1);             % delay in samples of each delay line m'
            plugin.g = zeros(plugin.N,1);             % gain coefficients of delay lines
            plugin.buffInput = zeros((plugin.maxPreDelay * plugin.fs) + 1, 1);   % input buffer for pre delay, 0.2 = max pre delay of 200ms
            plugin.preDelayS = 0;                     % pre delay in samples
            plugin.pBuffInput = plugin.maxPreDelay * plugin.fs;    % pointer for input buffer

            % calculate sample delays of delay lines
            calculateDelays(plugin)

            % calculate gain coeffs of delay lines
            calculateGainCoeffs(plugin, plugin.reverbTime) %, plugin.reverbTime
            
            % calculate FDN matrix based on set order
            calculateMatrix(plugin) 
        end

        function reset(plugin)
            init(plugin)
        end

        function generateFDNmatrix(order)
            % generates FDN matrix with evenly distributed eigenvalues at
            % the unit circle
            eig_nr = order/2;
            FDNmatrix = zeros(order, order);
            M = orth((rand(order,order)));
            BC_n = zeros(order, order, eig_nr);
            DtD_n = zeros(order, order, eig_nr);
            k1 = 1;
            for k=2:2:eig_nr*2
                x = M(:,k-1);
                y = M(:,k);
                x = x / sqrt(2);
                y = y / sqrt(2);
                B = x * x.';
                C = y * y.';
                D = x * y.';
                BC_n(1:order,1:order,k1) = B + C;
                DtD_n(1:order,1:order,k1) = D.' - D;
                w = pi * k / (eig_nr * 2 + 2);
                temp = 2 * BC_n(:,:,k1) * cos(w) + 2 * DtD_n(:,:,k1) * sin(w);
                FDNmatrix = FDNmatrix + temp;
                k1 = k1 + 1;
            end
        end
    end
end
发布评论

评论列表(0)

  1. 暂无评论