Filter löschen
Filter löschen

Generate pinknoise with same power as audio

11 Ansichten (letzte 30 Tage)
L
L am 25 Aug. 2023
Beantwortet: Mathieu NOE am 28 Aug. 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)

Akzeptierte Antwort

Mathieu NOE
Mathieu NOE am 28 Aug. 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

Weitere Antworten (0)

Kategorien

Mehr zu Fourier Analysis and Filtering finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by