Converting audible sound to ultrasonic - matlab

I have sound clips that are about 3-4 seconds in human audible range. I want to convert them into ultrasonic range so that when I transmit them they are not audible to humans. I read that I need to use amplitude modulation. I used the modulate function of matlab.
[y,Fs] = audioread('TakeASelfie.mp3');
x = modulate(y,30700, 62000, 'amdsb-tc');
soundsc(x,62000)
audiowrite('modulated.wav', x, 62000)
In the above example, I was trying to convert my audio clip to 30.7kHz. However, after I performed modulation, the length of the clip was decreased. How can I change the frequency of my sound clip without changing the length of it? I am also not sure if the approach I am taking is the right one.

One way to do it (this method will give you lowwer sideband, for example if your audio signal have spectra from 200 to 2000 Hz and carrier frequency f0 = 40000 Hz, your ultrasound signal will have spectra from 39800 to 38000 Yz):
fs=96000; % samplig frequency (should be at least x2.2 of f0 )
[sb, fd]=wavread('as4.wav'); % signal in audio domain
if fd ~= fs % change sampling prequency to target
sb = resample(sb, fs, fd);
end
sb=sb./max(sb); % normalization
A = 1; % amplitude of carrier tone
T = length(sb) / fs; % length of signal
f0 = 40000; % carrier frequency
Fi0 = pi/2; % initial phase
N = T * fs; % number of samples
t = (0 : N-1) / fs; % time stamps
sa = A * sin(2 * pi * f0 * t + Fi0); % samples of carrier tone
% first method
s = sb .* sa + imag(hilbert(sb)) .* imag(hilbert(sa));
% to have upper sideband use
% s = sb .* sa - imag(hilbert(sb)) .* imag(hilbert(sa));
% second method
s = ssbmod(sb, f0, fs);
s=s./(max(s)); % normalization of modulated signal

Related

Designing a narrow bandpass filter in MATLAB

I'm working on signal filtering in MATLAB. I wrote a signal with 3 different frequencies:
Fs = 8000; %// Sampling frequency
T = 1/Fs; %// Sample time
L = 16000; %// Length of signal
t = (0:L-1)*T; %// Time vector
y = 40*sin(2*pi*50*t) + 500*sin(2*pi*51*t) + 500*sin(2*pi*49*t);
Now I want to extract the 50Hz signal by bandpass window filtering using a Hanning window. Here is my code to design the filter:
function Hd = HannFilter1
Fs = 8000; %// Sampling Frequency
N = 4096; %// Order
Fc1 = 49.5; %// First Cutoff Frequency
Fc2 = 50.5; %// Second Cutoff Frequency
flag = 'scale'; %// Sampling Flag
win = hann(N+1);
b = fir1(N, [Fc1 Fc2]/(Fs/2), 'bandpass', win, flag);
Hd = dfilt.dffir(b);
After that, I do filtering using filter like this:
yfilter = filter(Hd.Numerator,1,y);
NFFT = 2^nextpow2(L);
Y = fft(yfilter,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1);
figure;
subplot(2,1,1);
plot(yfilter);
subplot(2,1,2);
plot(f,2*abs(Y(1:NFFT/2+1)))
Why is this filter unable to extract the 50Hz signal?
I'm doing something wrong in this simulation?
How can I filter out the 50Hz signal?
what is the best sample rate for 50Hz signal? and very important question! in real world, like balancing system, the main signal is about 20Hz and environment is very too noisy and filtering by my solution does not give a correct answer. in this case,how can i use or choose the best filtering algorithm?
if my sample rate be 8000Hz and I can buffered only 20000 samples, how can Designing a narrow bandpass filter?
So, I Solve problem by decrease sample rate and increase sample data by this code: ( as Matt was Said )
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sample time
L = 60000; % Length of signal
t = (0:L-1)*T; % Time vector
for j=1:20
r1 = 5 + (1000-5).*rand(1,1);
r2 = 5 + (1000-5).*rand(1,1);
y = 10*sin(2*pi*14.8*t) + r1*sin(2*pi*14.2*t) + r2*sin(2*pi*15.5*t) + 1.1*rand(size(t));
yfilter = filter(Hd.Numerator,1,y);
max(yfilter(40000:50000))
end
my filter is KAISER ( FIR Badpass filter ) :
Fs = 1000; % Sampling Frequency
Fstop1 = 14.2; % First Stopband Frequency
Fpass1 = 14.6; % First Passband Frequency
Fpass2 = 15; % Second Passband Frequency
Fstop2 = 15.2; % Second Stopband Frequency
Dstop1 = 1e-06; % First Stopband Attenuation
Dpass = 0.057501127785; % Passband Ripple
Dstop2 = 1e-06; % Second Stopband Attenuation
flag = 'scale'; % Sampling Flag
% Calculate the order from the parameters using KAISERORD.
[N,Wn,BETA,TYPE] = kaiserord([Fstop1 Fpass1 Fpass2 Fstop2]/(Fs/2), [0 ...
1 0], [Dstop1 Dpass Dstop2]);
% Calculate the coefficients using the FIR1 function.
b = fir1(N, Wn, TYPE, kaiser(N+1, BETA), flag);
Hd = dfilt.dffir(b);
and filter amplitude for 20 iteration and random noise signal is :
max(yfilter(40000:50000))
10.01
10.02
10.01
10.00
10.01
10.03
10.01
10.02
....
that is a great result for me, and filtered signal is :
but there is some problem :
1- my sample data length is 60000 bytes, in other hand by sampling rate at 1000Hz, I wait for 60 Seconds for gathering data, and that is too long time!!!
when i decrease sample data length to about 3000 samples, filtered result is so bad because of number of filter's coefficients is about 4097.
how can i filter my signal when it's length is 3000 samples and my filter's coefficients is about 4097 bytes? when i decrease filter's coefficients , filtered signal result is so noisy.
2- what is the best sample rate fo 15 Hz signal?
thanks.

Frequency Modulation Matlab

i want to make a continious sinwave which will change his frequency 3 times, like in the photo. I tryied with the fmmod function but i can't make it work, so is there any other way , thanks in advance.
here is my code
Fs = 44100; % Sampling rate of signal
Fc = 3000; % Carrier frequency
t = [0:Fs-1]'/Fs; % Sampling times
x = sin(2*pi*4000*t)+sin(2*pi*5000*t)+sin(2*pi*8000*t); % my signal
dev = 50; % Frequency deviation in modulated signal
y = fmmod(x,Fc,Fs,dev);
plot(y)
Frequency modulation without fmmod:
Fs = 44100; % Sampling rate of signal
T=1/Fs; % period
t = 0:T:0.01; % sample times
% amplitude of message signal
vm = 5
% amplitude of carrier signal
vc =5
% message frequency
fm =500
% carrier freq
fc = 5e3
% modulation index
m =5
figure
y = vc*sin(2*pi*fc*t+m.*cos(2*pi*fm*t));
plot(t,y);

Low-pass filter in carrier modulation and demodulation

I'm designing a project in which an array is passed through quadrature amplitude modulation (QAM) modulator, and then do carrier modulation, make it playable with the sound() command, then demodulate it back for QAM demodulation.
Firstly, I have used the standard way of QAM modulation:
M = 16;
x = randint(5000, 1, M);
y = modulate(modem.qammod(M), x);
Then, I wrote my own carrier modulation function:
function [out] = carriermodulation(x)
fs = 16000;
T = 1.0 / 4000;
fc = 8000;
Q = real(x);
I = imag(x);
t = 0:T:(size(x))*T;
C1 = zeros(size(x), 1);
C2 = zeros(size(x), 1);
for i = 1:size(x)
C1(i) = I(i)*sin(2*pi*(fc)*t(i));
C2(i) = Q(i)*sin(2*pi*fc*t(i) + pi/2);
end
out = C1 + C2;
No problem so far. But when I was done with my demodulation function, I found that the result is different from the original value (the QAM modulator output).
function [out] = carrierdemodulation(x)
fs = 16000;
T = 1.0 / 4000;
fc = 8000;
t = 0:T:(size(x))*T;
A1 = zeros( size(x), 1);
A2 = zeros( size(x), 1);
for i = 1:size(x)
A1(i) = x(i)*sin( 2*pi*(fc)*t(i));
A2(i) = x(i)*cos( 2*pi*(fc)*t(i));
end
A1 = sqrt(A1);
A2 = sqrt(A2);
out = A1 + A2;
I think my modulation part is right. The only problem I think I have is I don't have a low-pass filter (LPF) for the demodulation. And I should not calculate A1 and A2 directly. How do I to add an LPF to my demodulation code such that the output is the same as the original?
You need a low-pass filter at the receiver after coherent demodulation, that's right. But there's also a problem with your modulation. In your example, the symbol rate Rs is less than the angular carrier frequency w_c which potentially causes overlapping of spectra at the receiver. Consequently, reconstruction of the information signal will be impossible. Additionaly, in your example fc * T = 2. That means that the argument of the sine function is an integer multiple of 2pi and therefore always zero.
What you need is an impulse shaper (can be implemented as a low-pass filter) at the transmitter with bandwidth w_g >= R/2. It should be a so-called Nyquist lowpass. The carrier frequency must satisfy w_c > w_g.
I've written a MATLAB script that does impulse shaping, modulation, demodulation, filtering and sampling, so that the transmitted signal can be reconstructed.
First we define the parameters, create random bits and do the mapping as you've already done. Than a very simple impulse response for impulse shaping is used, namely a rectangular impulse. In the real world we're going from digital to analog domain here, but as this is a computer model, we represent the analog signal by a discrete one with sampling frequency f_s. The impulse shaper is simple, because it just repeats each sample L times.
M = 16; % QAM order
fs = 16000; % Sampling frequency in Hz
Ts = 1/fs; % Sampling interval in s
fc = 1000; % Carrier frequency in Hz (must be < fs/2 and > fg)
Rs = 100; % Symbol rate
Ns = 20; % Number of symbols
x = randint(Ns, 1, M);
y = modulate(modem.qammod(M), x);
L = fs / Rs; % Oversampling factor
% Impulse shaping
y_a = reshape(repmat(y', L, 1), 1, length(y)*L);
Now modulation. I used a carrier frequency that satisfies the above conditions: it's higher than the signal bandwidth and can still be represented with the sampling frequency used.
%% Modulation
I = real(y_a);
Q = imag(y_a);
t = 0 : Ts : (length(y_a) - 1) * Ts;
C1 = I .* sin(2*pi * fc * t);
C2 = Q .* cos(2*pi * fc * t);
s = C1 + C2;
Demodlation is straightforward...
%% Demodulation
r_I = s .* sin(2*pi * fc * t);
r_Q = s .* -cos(2*pi * fc * t);
To remove the spectral tributaries at 2f_c after demodulation a low-pass filter is required. I used the MATLAB FDATool to create the filter and part of the following code. Remember: the signal bandwidth is Rs/2, and the unwanted tributaries begin at 2*fc - Rs/2. This is how Fpass and Fstop are found. (It might be useful to relax these requirements a little bit.)
%% Filter
% Design filter with least-squares method
N = 50; % Order
Fpass = Rs/2; % Passband Frequency
Fstop = 2*fc - Rs/2; % Stopband Frequency
Wpass = 1; % Passband Weight
Wstop = 1; % Stopband Weight
% Calculate the coefficients using the FIRLS function.
b = firls(N, [0 Fpass Fstop fs/2]/(fs/2), [1 1 0 0], [Wpass Wstop]);
% Filtering
w_I = filter(b, 1, r_I);
w_Q = filter(b, 1, r_Q);
After filtering we still have to sample the received signal. Here it's just a downsampling. I used a phase offset of L/2 to avoid the filter transitions.
%% Sampling
u_I = downsample(w_I, L, L/2);
u_Q = downsample(w_Q, L, L/2);
Finally, plot the constellation diagram and get a nice 16-QAM constellation:
plot(u_I, u_Q, '.');
You can find the complete code here.
Your question touched a lot of topics of both DSP and MATLAB programming. I could not go into much detail everywhere. If you have specific questions about 16-QAM modulation and demodulation the place to be is probably the Stack Exchange site Signal Processing.

MATLAB - Using fm demod to decode data

I am trying to extract a sinusoid which itself has a speed which changes sinusiodially. The form of this is approximately sin (a(sin(b*t))), a+b are constant.
This is what I'm currently trying, however it doesnt give me a nice sin graph as I hope for.
Fs = 100; % Sampling rate of signal
Fc = 2*pi; % Carrier frequency
t = [0:(20*(Fs-1))]'/Fs; % Sampling times
s1 = sin(11*sin(t)); % Channel 1, this generates the signal
x = [s1];
dev = 50; % Frequency deviation in modulated signal
z = fmdemod(x,Fc,Fs,fm); % Demodulate both channels.
plot(z);
Thank you for your help.
There is a bug in your code, instead of:
z = fmdemod(x,Fc,Fs,fm);
You should have:
z = fmdemod(x,Fc,Fs,dev);
Also to see a nice sine graph you need to plot s1.
It looks like you are not creating a FM signal that is modulated correctly, so you can not demodulate it correctly as well using fmdemod. Here is an example that does it correctly:
Fs = 8000; % Sampling rate of signal
Fc = 3000; % Carrier frequency
t = [0:Fs]'/Fs; % Sampling times
s1 = sin(2*pi*300*t)+2*sin(2*pi*600*t); % Channel 1
s2 = sin(2*pi*150*t)+2*sin(2*pi*900*t); % Channel 2
x = [s1,s2]; % Two-channel signal
dev = 50; % Frequency deviation in modulated signal
y = fmmod(x,Fc,Fs,dev); % Modulate both channels.
z = fmdemod(y,Fc,Fs,dev); % Demodulate both channels.
If you find thr answers useful you can both up-vote them and accept them, thanks.

Matlab fft function

The code below is from the Matlab 2011a help about fft function.
I think there is a problem here : why do they multiply t(1:50) by Fs, and then say it's time in millisecond ? Certainly, it happens to be true in this very particular case, but change the value of Fs to, say, 2000, and it won't work anymore, obviously because of this factor of 2. Right ? Quite misleading, isn't it ? What do I miss ?
Fs = 1000; % Sampling frequency
T = 1/Fs; % Sample time
L = 1000; % Length of signal
t = (0:L-1)*T; % Time vector
% Sum of a 50 Hz sinusoid and a 120 Hz sinusoid
x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);
y = x + 2*randn(size(t)); % Sinusoids plus noise
plot(Fs*t(1:50),y(1:50))
title('Signal Corrupted with Zero-Mean Random Noise')
xlabel('time (milliseconds)')
Clearer with this :
fs = 2000; % Sampling frequency
T = 1 / fs; % Sample time
L = 1000; % Length of signal
t2 = (0:L-1)*T; % Time vector
f = 50; % signal frequency
s2 = sin(2*pi*f*t2);
figure, plot(fs*t2(1:50),s2(1:50)); % NOT good
figure, plot(t2(1:50),s2(1:50)); % good
You don't miss anything. This is a typical bad practice of not having units as comments for each line. For example,
Fs=1000; % in [Hz]
T=1/Fs; % [sec]
L = 1000; % Length of signal
t = (0:L-1)*T; % Time vector
then, the time vector has units of 1/1000 seconds, or milliseconds... (each element is 1 ms).
In the other case Fs=2000 %[Hz], which makes the time vector to have units of 1/2000 seconds...