in article 42356642$1@cs1, Rene at rene@home.nl wrote on 03/14/2005 05:37:> robert bristow-johnson wrote: > >> in article 1110613336.330448.148760@f14g2000cwb.googlegroups.com, >> george_barr@yahoo.com at george_barr@yahoo.com wrote on 03/12/2005 02:42: >> >> >> >>> I figured it out. I can use the hilbert() matlab function to convert a >>> real signal into a complex signal. Here is the m-file to compute the >>> instantaneous frequency and it seems to work. >>> >>> >> >> i think you still have phase unwrapping issues to work out. if you don't >> want to explicitly unwrap your phase angle, perhaps you want to compute your >> phase difference with a trig identity that i can't remember. it's for >> >> arctan(q[n]/i[n]) - arctan(q[n-1]/i[n-1]) = something >> >> if you find that identity and use it for phase difference (which is >> proportional to frequency), you won't have to worry about unwrapping. >> >> >> > in Matlab following formula works also (signal must be complex): > > freq = Fs/2/pi * diff( unwrap (imag (log (signal))));and if signal is not yet complex freq = Fs/2/pi * diff( unwrap (imag (log (hilbert(signal))))); or, as long as you have MATLAB freq = Fs/2/pi * diff( unwrap (angle(hilbert(signal)))); and that's nice. but for the sake of implementation somewhere else, i have considered the unwrapping logic to be inelegant. so now i looked it up: arctan(y) - arctan(x) = arctan( (y-x)/(1 + y*x) ) as long as |arctan(y) - arctan(x)| <= pi/2 f[n] = Fs/(2*pi)* arctan(Im(s[k])/Re(s[k])) - arctan(Im(s[k-1])/Re(s[k-1])) f[n] = Fs/(2*pi) * arctan( ( Im(s[k])*Re(s[k-1]) - Re(s[k])*Im(s[k-1]) ) / ( Re(s[k])*Re(s[k-1]) + Im(s[k])*Im(s[k-1]) ) ) that should work, too. and if it weren't MATLAB, that's what i would do, since there is no unwrapping decisions. -- r b-j rbj@audioimagination.com "Imagination is more important than knowledge."
generating I & Q
Started by ●March 11, 2005
Reply by ●March 14, 20052005-03-14
Reply by ●March 14, 20052005-03-14
I will try Robert B.s method.
I would get negative frequencies and heard about unwrapping. I played
with the mathematics and came up with this scheme. It seems to work
out. Is this as good as the other schemes? Any comments or ways to
improve this code in terms of run time efficiency, space, etc?
function result = fm_iq31
% format long;
Fi = [7200 8400 11600 15900]; % Frequency of interest.
Should be Fi <= Fs / 2.
Fs = max(Fi)*3; % Number of samples. Should be Fs >= 3 *
(highest freq, max(Fi)).
Fc = 10000; % Center freq.
Fi = [7200 8400 11600 15900]; % Frequency of interest.
Should be Fi <= Fs / 2.
Ts = 1 / Fs;
t = Ts*(0:Fs-1)';
x = [];
for i = 1:length(Fi)
temp = cos(2*pi*Fi(i)*t);
x = [x;temp];
nResults(i) = 0;
end
x = hilbert(x);
num_outputs = 0;
num_errors = 0;
str1 = '';
for i = (52000*0)+2:Fs*length(Fi)
% cur_q = imag(x(i));
% cur_i = real(x(i));
last_i = real(x(i-1));
cur_i = real(x(i));
cur_a = atan(imag(x(i)) / cur_i); % atan(Q / I)
last_a = atan(imag(x(i-1)) / last_i);
freq = (Fs * (cur_a - last_a)) / 2 * pi / 10;
freq = 1.01321183642348 * freq; % Frequency correction.
if (freq <= 0)
temp = floor(Fs / abs(freq));
freq = (abs(freq)*(temp-2) + mod(Fs, abs(freq))) / 2;
end
index = floor((i-1)/Fs) + 1;
error = ((Fi(index) / freq) - 1) * 100; % catch divide by
zero here
if (abs(error) > 5)
str1 = sprintf('%s, %20.12f', str1, error);
num_errors = num_errors + 1;
end
num_outputs = num_outputs + 1;
disp(sprintf('Freq: %20.12f, Error: %20.12f %%', freq,error));
nResults(index) = nResults(index) + 1;
end
disp(sprintf('Number of outputs: %d', num_outputs));
disp(sprintf('Number of errors: %d', num_errors));
disp(nResults);
disp(sprintf('str1: %s', str1));
Thanks,






