Normalize the amplitude of a sinewave of varying amplitude and frequency

43 views (last 30 days)
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.

Answers (2)

Image Analyst
Image Analyst on 3 Mar 2023
Edited: Image Analyst on 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.

Star Strider
Star Strider on 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.
.
.

Tags

Community Treasure Hunt

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

Start Hunting!