Создание серого аудиошума с использованием matlab / octave - PullRequest
0 голосов
/ 06 июня 2018

Я могу создать розовый, коричневый, синий звуковой шум с помощью следующего фрагмента кода, выбрав другую переменную invfnorm для использования ниже, но как я могу создать серый шум?

%https://en.wikipedia.org/wiki/Colors_of_noise

mean_amp=mean(yamp_orig.^2); %get mean of all freq amplitudes
amt_of_freq=size(xfreq_orig,1); %number of freq

%invfnorm=1./[1:amt_of_freq]; % 1/f creates pink noise
%invfnorm=[1:amt_of_freq]; % f creates blue noise
invfnorm=1./[1:amt_of_freq].^2; % 1/f^2 creates brown noise

amp_1f_new=sqrt(mean_amp*invfnorm/sum(invfnorm))(:); %new noise amplitudes to use

В ссылке https://en.wikipedia.org/wiki/Colors_of_noise они дают формулы для розового, коричневого, синего звукового шума, но для серого шума они просто говорят, что "перевернутая кривая A-взвешивания" не показывает формулу, мне просто нужноформула.см. спектр ниже.

Grey noise Веб-сайт, на котором я получил информацию, находится здесь серый шум

Ps: я используюОктава 4.2.2, которая похожа на Matlab

1 Ответ

0 голосов
/ 07 июня 2018

Как вы упомянули, серый шум создается путем применения обратной кривой 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-взвешивания, если это необходимо.

...