Effacer les filtres
Effacer les filtres

Generate pinknoise with same power as audio

11 vues (au cours des 30 derniers jours)
L
L le 25 Août 2023
I need to read an audio file and generate a pinknoise with the same power.
I tought using generatepinknoise(), but the built-in function does not accept a power specification.
Any ideas?
I was trying something based on https://stackoverflow.com/questions/17795675/making-pink-noise-1-f-using-list-of-frequencies, but it dosen't sound anything like pinknoise.
% Generate pinknoise with same power as sound
% get sound (2 channels)
[y,Fs] = audioread('S5.wav');
Y=fft(y);
A1 = abs(Y(:,1)); P1 = mean(A1.^2);
A2 = abs(Y(:,2)); P2 = mean(A2.^2);
N = length(Y); invfnorm = 1./[1:N]';
Anew1 = sqrt(P(:,1)*invfnorm/sum(invfnorm)); Anew2 = sqrt(P(:,2)*invfnorm/sum(invfnorm));
noise = ifft([Anew1 .* exp(1i*angle(Y(:,1))) Anew1 .* exp(1i*angle(Y(:,1))) ] ,'symmetric');
soundsc(noise,Fs)

Réponse acceptée

Mathieu NOE
Mathieu NOE le 28 Août 2023
hello
this would be my suggestion . You don't need to do a fft to get the power of a signal (you can compute it directly in time domain too)
here I tested it on my own audio signal (piano.wav)
% Generate pinknoise with same power as sound
% get sound (2 channels)
[y,Fs] = audioread('S5.wav'); % your file
% [y,Fs] = audioread('piano.wav'); % mine
[samples,channels] = size(y);
y_power = mean(y.^2,1); % power of signals
pn = mypinknoise(samples);
pn_power = mean(pn.^2); % yes it's 1 because normalized std as explained in the subfunction
% let's assume we want same pink noise power as audio channel of largest
% power
pow_factor = max(y_power)/pn_power;
% now the pink noise signal must be multiplied by the square root of the
% power factor
pn = pn*sqrt(pow_factor);
pn_power = mean(pn.^2); % double check ; now we have same noise power as the audio signal
% concatenate signals for replay
out = [y; pn(:)*ones(1,channels)];
soundsc(out,Fs);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function y = mypinknoise(N)
% function: y = pinknoise(N)
% N - number of samples to be returned in a row vector
% y - a row vector of pink (flicker) noise samples
% The function generates a sequence of pink (flicker) noise samples.
% In terms of power at a constant bandwidth, pink noise falls off at 3 dB/oct, i.e. 10 dB/dec.
% difine the length of the vector and
% ensure that the M is even, this will simplify the processing
if rem(N, 2)
M = N+1;
else
M = N;
end
% generate white noise
x = randn(1, M);
% FFT
X = fft(x);
% prepare a vector with frequency indexes
NumUniquePts = M/2 + 1; % number of the unique fft points
n = 1:NumUniquePts; % vector with frequency indexes
% manipulate the left half of the spectrum so the PSD
% is proportional to the frequency by a factor of 1/f,
% i.e. the amplitudes are proportional to 1/sqrt(f)
X = X(1:NumUniquePts);
X = X./sqrt(n);
% prepare the right half of the spectrum - a conjugate copy of the left one,
% except the DC component and the Nyquist component - they are unique
% and reconstruct the whole spectrum
X = [X conj(X(end-1:-1:2))];
% IFFT
y = real(ifft(X));
% ensure that the length of y is N
y = y(1, 1:N);
% ensure unity standard deviation and zero mean value
y = y - mean(y);
y = y/std(y, 1);
end

Plus de réponses (0)

Catégories

En savoir plus sur Fourier Analysis and Filtering dans Help Center et File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by