Как вы упомянули, серый шум создается путем применения обратной кривой a-взвешивания.
Следующий фрагмент представляет собой пример Matlab (благодаря W. Owen Brimijoin ) для генерации серого шума:
%values from the ISO 66-phon Equal-loudness contour (adjusted for
%optimal spline interpolation):
freqs = [1 5 15 36 75 138 235 376 572 835 1181 1500 2183 2874 3718 ...
4800 5946 7377 9051 10996 13239 15808 18735 22050].*sample_rate/44100;
dB_vals = [61 61 56 40 25 17 11 7 5 4 6 8 3 1 1 4 9 14 17 16 10 5 2 1];
%create level vector for use in inverse Fourier transform:
freq = linspace(0,sample_rate/2,floor(num_samples/2));
spl = spline(freqs,dB_vals,freq); %upsample
levels = [spl,fliplr(spl)]; %reflect vector
levels = 10.^(levels'./10); %change to power
levels(levels==inf) = 0; %remove infinite values
phase_vals = rand(length(levels),1); %generate random phase vals
%now apply an inverse fft:
wave = real(ifft(sqrt(levels).*(cos(2*pi*phase_vals)+1i*sin(2*pi*phase_vals))));
wave = wave./max(abs(wave));
Где levels = the inversed a-weighting array
.
В этом примере создается генератор серого шума и применяется фильтр в частотной области к сигналу перед поворотомсигнал обратно во временную область.
Как вы упомянули, вы сказали, что вам просто нужна формула, так что, возможно, эта конкретная линия поможет больше всего (как только вы уже вычислили обратную кривую а-взвешивания):
wave = real(ifft(sqrt(levels).*(cos(2*pi*phase_vals)+1i*sin(2*pi*phase_vals))));
Как указывалось в начале кода, используется 66-фоновая кривая, поэтому вам может понадобиться настроить массив dB_vals
, если вы хотите использовать другой уровень фононов.
Я нашел эта функция весьма полезна для вычисления различных фоновых кривых для a-взвешивания, если это необходимо.