필터 지우기
필터 지우기

Normalize the amplitude of a sinewave of varying amplitude and frequency

조회 수: 58 (최근 30일)
Austin Bartz
Austin Bartz 2023년 3월 3일
답변: A Wen 2023년 11월 15일
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.

답변 (3개)

Image Analyst
Image Analyst 2023년 3월 3일
편집: Image Analyst 2023년 3월 3일
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.

Star Strider
Star Strider 2023년 3월 3일
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.
.
.

A Wen
A Wen 2023년 11월 15일
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;

카테고리

Help CenterFile Exchange에서 Spectral Measurements에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by