- added compressor
git-svn-id: http://moon:8086/svn/matlab/trunk@127 801c6759-fa7c-4059-a304-17956f83a07c
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
all:
|
||||
mkoctfile -mex level_detect.c
|
||||
@@ -0,0 +1,72 @@
|
||||
## Copyright (C) 2020 Jens
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful, but
|
||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see
|
||||
## <https://www.gnu.org/licenses/>.
|
||||
|
||||
## -*- texinfo -*-
|
||||
## @deftypefn {} {@var{retval} =} eq_eval (@var{input1}, @var{input2})
|
||||
##
|
||||
## @seealso{}
|
||||
##
|
||||
## Exapmple: cmp_eval("snip.wav", 0.25, -40, 18);
|
||||
## @end deftypefn
|
||||
|
||||
## Author: Jens <jens@orion>
|
||||
## Created: 2020-06-22
|
||||
|
||||
function cmp_eval (filename_in, R, lev_knee_dB, gain_makeup_dB)
|
||||
|
||||
fs = 48000
|
||||
[x, fs] = audioread(filename_in);
|
||||
N = size(x)(1)
|
||||
num_channels = size(x)(2)
|
||||
filename_out = to_filename_out(filename_in, "out");
|
||||
|
||||
time_look_ahead = 0.01;
|
||||
time_attack = 0.01;
|
||||
time_release = 1.0;
|
||||
|
||||
n_look_ahead = round(time_look_ahead*fs);
|
||||
h_dly = [zeros(1, n_look_ahead-1) 1];
|
||||
|
||||
x_dly = filter(h_dly, 1, x);
|
||||
|
||||
alpha_a = 5/(time_attack*fs);
|
||||
alpha_r = 5/(time_release*fs);
|
||||
|
||||
lev = level_detect(x, alpha_a, alpha_r);
|
||||
lev_dB = max(-120, 20*log10(lev));
|
||||
|
||||
k_makeup_gain = 10^(gain_makeup_dB/20);
|
||||
gain1 = min(8, (1/8)./(lev+0.1));
|
||||
[lev_out_dB, gain2_dB] = cmp_gain(R, lev_knee_dB, lev_dB);
|
||||
gain2 = 10.^(gain2_dB/20);
|
||||
y1 = gain1.*x_dly * 2;
|
||||
y2 = gain2.*x_dly * k_makeup_gain;
|
||||
audiowrite(to_filename_out(filename_in, "gain1"), gain1, fs)
|
||||
audiowrite(to_filename_out(filename_in, "gain2"), gain2, fs)
|
||||
audiowrite(to_filename_out(filename_in, "out1"), y1, fs)
|
||||
audiowrite(to_filename_out(filename_in, "out2"), y2, fs)
|
||||
audiowrite(to_filename_out(filename_in, "lev"), lev, fs)
|
||||
|
||||
gain_out = [];
|
||||
gain_in = [];
|
||||
for g=0:0.1:1,
|
||||
gain_out = [gain_out cmp_gain(R, g, 0.01)];
|
||||
gain_in = [gain_in g];
|
||||
endfor
|
||||
plot(gain_in, gain_out); grid();
|
||||
|
||||
endfunction
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
function [lev_out_dB, gain_out_dB] = cmp_gain(R, lev_knee_dB, lev_in_dB)
|
||||
k = lev_in_dB > lev_knee_dB;
|
||||
lev_out_dB = (1-k).*lev_in_dB + k.*(lev_knee_dB + R*(lev_in_dB - lev_knee_dB));
|
||||
gain_out_dB = - (lev_in_dB - lev_out_dB);
|
||||
endfunction
|
||||
@@ -0,0 +1,42 @@
|
||||
## Copyright (C) 2020 Jens
|
||||
##
|
||||
## This program is free software: you can redistribute it and/or modify it
|
||||
## under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful, but
|
||||
## WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see
|
||||
## <https://www.gnu.org/licenses/>.
|
||||
|
||||
## -*- texinfo -*-
|
||||
## @deftypefn {} {@var{retval} =} eq_eval (@var{input1}, @var{input2})
|
||||
##
|
||||
## @seealso{}
|
||||
## @end deftypefn
|
||||
|
||||
## Author: Jens <jens@orion>
|
||||
## Created: 2020-06-22
|
||||
|
||||
function cmp_gain_eval (R)
|
||||
epsilon = 0.01;
|
||||
dl = 10;
|
||||
gain_out = [];
|
||||
lev_out = [];
|
||||
lev_in = [];
|
||||
for li=-120:dl:0,
|
||||
[lo, go] = cmp_gain(R, -20, li);
|
||||
lev_out = [lev_out lo];
|
||||
lev_in = [lev_in li];
|
||||
gain_out = [gain_out go];
|
||||
endfor
|
||||
close;
|
||||
plot(lev_in, lev_out, lev_in, gain_out); grid();
|
||||
|
||||
endfunction
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <mex.h>
|
||||
#include <math.h>
|
||||
void mexFunction (int nlhs, mxArray *plhs[],
|
||||
int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
const char *funcName = mexFunctionName ();
|
||||
mexPrintf ("You called function: %s\n", funcName);
|
||||
mexPrintf ("I have %d inputs and %d outputs\n", nrhs, nlhs);
|
||||
|
||||
if (nrhs < 3)
|
||||
mexErrMsgTxt ("Too few arguments");
|
||||
|
||||
const mxArray *array_x = prhs[0];
|
||||
const mxArray *scalar_alpha_attack = prhs[1];
|
||||
const mxArray *scalar_alpha_release = prhs[2];
|
||||
|
||||
|
||||
plhs[0] = mxCreateNumericArray (mxGetNumberOfDimensions (array_x),
|
||||
mxGetDimensions (array_x),
|
||||
mxGetClassID (array_x),
|
||||
mxIsComplex (array_x));
|
||||
|
||||
mwIndex channelsDim = 1;
|
||||
double alpha_a = *mxGetPr(scalar_alpha_attack);
|
||||
double alpha_r = *mxGetPr(scalar_alpha_release);
|
||||
|
||||
double *vri = mxGetPr (array_x);
|
||||
double *vro = mxGetPr (plhs[0]);
|
||||
|
||||
mwSize M = mxGetM (array_x);
|
||||
mwSize N = mxGetN (array_x);
|
||||
if (channelsDim == 1)
|
||||
{
|
||||
M = mxGetN (array_x);
|
||||
N = mxGetM (array_x);
|
||||
}
|
||||
|
||||
mexPrintf ("Number of channels = %u\n", M);
|
||||
mexPrintf ("Number of samples per channel = %u\n", N);
|
||||
mexPrintf ("alpha_a = %f\n", alpha_a);
|
||||
mexPrintf ("alpha_r = %f\n", alpha_r);
|
||||
|
||||
double level[M];
|
||||
for (mwIndex m=0; m < M; m++)
|
||||
{
|
||||
level[m] = 0;
|
||||
}
|
||||
|
||||
for (mwIndex n=0; n < N; n++)
|
||||
{
|
||||
for (mwIndex m=0; m < M; m++)
|
||||
{
|
||||
double x = vri[n*M + m];
|
||||
double xmag = fabs(x);
|
||||
|
||||
if (xmag > level[m])
|
||||
{
|
||||
level[m] = (1.0-alpha_a)*level[m] + alpha_a*xmag;
|
||||
}
|
||||
else
|
||||
{
|
||||
level[m] = (1.0-alpha_r)*level[m];
|
||||
}
|
||||
vro[n*M + m] = level[m];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user