Normalize the amplitude of a sinewave of varying amplitude and frequency
62 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I have a series of sine waves of varying amplitude and frequency, and I need to normalize them to -1 to +1 in amplitude, but maintain the frequency and not induce a phase shift. The idea being that I need to take the arcsine of this signal, and then the slope of that arcsine to get a 0 to 360deg output sawtooth wave. Such that I can compare them to each other to determine static phase offset, and dynamic phase offset (latency). I'm struggling to get a clean normalization, and pretty sure I'm just not fully understanding the "normalize" function. I feel like this might be a fairly normal function, but just don't know where/what to search for. In my mind I think I need to determine each "cycle" by detecting zero crossings and the peaks and valleys, then determining the peak and vally for that cycle, then normalizing to -1 to +1, but repeat it.
0 commentaires
Réponses (3)
Image Analyst
le 3 Mar 2023
Modifié(e) : Image Analyst
le 3 Mar 2023
If you have any more questions, then attach your data and code to read it in with the paperclip icon after you read this:
In the meantime try rescale
normalizedSignal = rescale(signal, -1, 1); % Global rescaling
This assumes the peaks are all about the same height. If you have a "warbling" or "chirp" signal where the peaks of the sine waves vary over time, then look at the envelope function and divide by that envelope.
0 commentaires
Star Strider
le 3 Mar 2023
‘I need to determine each "cycle" by detecting zero crossings and the peaks and valleys, then determining the peak and vally for that cycle, then normalizing to -1 to +1, but repeat it.’
If you just want to normalise the amplitudes in every cycle, try this —
Fs = 1000;
L = 10;
t = linspace(0, L*Fs, L*Fs+1)/Fs;
s = sin(2*pi*t*0.75) .* cos(2*pi*t*0.05) * 1.5;
figure
plot(t, s)
grid
xlabel('t')
ylabel('s(t)')
title('Original Signal')
zix = find(diff(sign(s))); % Approximate Zero-Crissing Indices
Ls = numel(s);
for k = 1:numel(zix)-1
idxrng = max(1,zix(k)-1) : min(Ls,zix(k)+1);
xv(k) = interp1(s(idxrng),t(idxrng),0); % 'Exact' Zero-Crossings
end
dt = t(2)-t(1); % Sampling Interval
for k = 1:numel(xv)-1
xrng{k,:} = xv(k) : dt : xv(k+1);
ys{k,:} = interp1(t, s, xrng{k}); % Extract Signal Segment By Interpolating Independent Variable
mx = max(ys{k});
mn = min(ys{k});
yv{k,:} = ys{k}/(mx-mn); % Normalise Signal Segment
end
figure
hold on
for k = 1:size(xrng,1)
plot(xrng{k}, yv{k})
end
hold off
grid
xlabel('t')
ylabel('s(t)')
title('Cycle-Normalised Signal')
This breaks the signal into half-cycles and normalises each half-cycle.
.
.
0 commentaires
A Wen
le 15 Nov 2023
A cleaner way to do this is with the Hilbert Transform with extracts the amplitude and phase.
Example code below, which normalizes the amplitude out, but maintains the phase information.
% Create a sample signal with varying amplitude
t = linspace(0, 1, 1000);
signal = sin(2 * pi * 5 * t) .* (1 + 0.5 * sin(2 * pi * 2 * t));
% Apply the Hilbert transform
analytic_signal = hilbert(signal);
% Calculate the envelope (instantaneous amplitude)
envelope = abs(analytic_signal);
% Normalize the amplitude
normalized_signal = signal ./ envelope;
% Plot the original signal, envelope, and normalized signal
figure;
plot(t, signal, 'LineWidth', 1.5, 'DisplayName', 'Original Signal');
hold on;
plot(t, envelope, 'LineWidth', 1.5, 'DisplayName', 'Envelope');
plot(t, normalized_signal, 'LineWidth', 1.5, 'DisplayName', 'Normalized Signal');
hold off;
legend('Location', 'Best');
xlabel('Time');
ylabel('Amplitude');
title('Envelope Detection in MATLAB');
grid on;
0 commentaires
Voir également
Catégories
En savoir plus sur Spectral Measurements 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!