How to generate a non-stationary signals - matlab

The code I have in this question I just modified it to generate a non-stationary signals as mentioned below. I just want to know is it the correct way to generate a non-stationary signals?
Code
%% Time specifications:
Fs = 8000; % samples per second
dt = 1/Fs; % seconds per sample
StopTime = 1; % seconds
t = (0:dt:StopTime-dt); % seconds
x = (10)*cos(2*pi*3*(t-.2))...
+ (20)*cos(2*pi*6*(t-.7))...
+ (20)*cos(2*pi*2*(t-.5));

No, its not the correct way because non stationary signal means that the properties of the signal does not remain constant, i.e the properties of the signal changes after some time but in your case at every point the signal is the sum of three cosine wave with same frequencies , amplitudes and phases.

For different time intervals signal contains different frequency components in non stationary signal. The signal you have generated is stationary signal, as at any instance of time you have same frequency components. Speech signal as you record through microphone will have different components and is an example of non stationary signal. Another example of non stationary signal is ultrasonic A scan obtained in pulse echo testing. What Narendra generated can be called as nonstationary signal.

Related

Fundamental Frequency of signal

I have a signal of 100ms. Fs = 8000 Hz. nbits = 16.
fs_orig = 44100;
nbits = 16;
[signal_orig,fs_orig,nbits]=wavread('oo.wav');
y=resample(signal_orig, 8000,44100);
z=y(1:800,1);
t=(0:1/8000:0.1-1/8000);
plot(t,z);xlabel('Time(s)');ylabel('Amplitude');
How many samples there are I calculated this way
N = fs(Hz)*duration(ms)/1000
N = 8000*100/1000 = 800 samples.
Want to know how i can calculate the length of one period in matlab?
How can i see which frequencies are in the signal?
The fundamental frequency of the period I can calculate by 1/Period time?
If your signal is periodic (like a sine wave, a sawtooth pulse, etc), you can use seqperiod. If your signal is not periodic, the simplest method is to apply fourier analysis (via fft) and look for peaks in its spectrum, which correspond to the most dominant frequencies.
You should also look into this question.
Edit: if your signal varies highly with time, but is periodic for small sections (typically < 50milliseconds), like a speech signal, I would look into cepstral analysis.

Drawing sine wave with increasing Amplitude and frequency over time

I am trying to plot a sine wave where the amplitude increases over time and the frequecy increases over time as well. I draw a normal sine wave as shown below but I couldn't change the amplitude and frequency. Any Ideas?
t  = [ 0 : 1 : 40 ];           % Time Samples
f  = 500;                       % Input Signal Frequency
fs = 8000;                    % Sampling Frequency
x = sin(2*pi*f/fs*t);        % Generate Sine Wave  
figure(1);
stem(t,x,'r');                  % View the samples
figure(2);
stem(t*1/fs*1000,x,'r');  % View the samples
hold on;
plot(t*1/fs*1000,x);        %
I believe what you are speaking of is amplitude modulation (AM) and frequency modulation (FM). Basically, AM refers to varying the amplitude of your sinusoidal signal and varying this uses a function that is time-dependent. FM is similar, except the frequency varies instead of the amplitude.
Given a time-varying signal A(t), AM is usually expressed as:
Minor note: The above is actually double sideband suppressed carrier (DSB-SC) modulation but if you want to achieve what you are looking for in your question, we actually need to do it this way instead. Also, the signal customarily uses cos instead of sin to ensure zero-phase shift when transmitting. However, because your original code uses sin, that's what I'll be using as well.
I'm putting this disclaimer here in case any communications theorists want to try and correct me :)
Similarly, FM is usually expressed as:
A(t) is what is known as the message or modulating signal as it is varying the amplitude or frequency of the sinusoid. The sinusoid itself is what is known as the carrier signal. The reason why AM and FM are used is due to communication theory. In analog communication systems, in order to transmit a signal from one point to another, the message needs to be frequency shifted or modulated to a higher range in the frequency spectrum in order to suit the frequency response of the channel or medium that the signal travels in.
As such, all you have to do is specify A(t) to be whichever signal you want, as long as your values of t are used in the same way as your sinusoid. As an example, let's say that you want the amplitude or frequency to increase linearly. In this case, A(t) = t. Bear in mind that you need to specify the frequency of the sinusoid f_c, the sampling period or sampling frequency of your data as well as the time frame that your signal is defined as. Let's call the sampling frequency of your data as f. Also bear in mind that this needs to be sufficiently high if you want the curve to be visualized properly. If you make this too low, what'll happen is that you will be skipping essential peaks and troughs of your signal and the graph will look poor.
Therefore, for AM your code may look something like this:
f = 24; %// Hz
f_c = 8; %// Hz
T = 1 / f; %// Sampling period from f
t = 0 : T : 5; %// Determine time values from 0 to 5 in steps of the sampling period
A = t; %// Define message
%// Define carrier signal
carrier = sin(2*pi*f_c*t);
%// Define AM signal
out = A.*carrier;
%// Plot carrier signal and modulated signal
figure;
plot(t, carrier, 'r', t, out, 'b');
grid;
The above code will plot the carrier as well as the modulated signal together.
This is what I get:
As you can see, the amplitude gets higher as the time increases. You can also see that the carrier signal is being bounded by the message signal A(t) = t. I've placed the original carrier signal in the plot as an aid. You can certainly see that the amplitude of the carrier is getting larger due to the message signal.
Similarly, if you want to do FM, most of the code is the same. The only thing that'll be different is that the message signal will be inside the carrier signal itself. Therefore:
f = 100; %// Hz
f_c = 1; %// Hz
T = 1 / f; %// Sampling period from f
t = 0 : T : 5; %// Determine time values from 0 to 5 in steps of the sampling period
A = t; %// Define message
%// Define FM signal
out = sin(2*pi*(f_c + A).*t);
%// Plot modulated signal
figure;
plot(t, out, 'b');
grid;
Bear in mind that I changed f_c and f in order for you to properly see the changes. I also did not plot the carrier signal so you don't get distracted and you can see the results more clearly.
This is what I get:
You can see that the frequency starts rather low, then starts to gradually increase itself due to the message signal A(t) = t. As time increases, so does the frequency.
You can play around with the different frequencies to get different results, but this should be enough to get you started.
Good luck!

MATLAB - Combining .wav files of different length and sampling

This is my first time using Octave/MATLAB for this sort of project. I am also completely new to signal processing, so please excuse my lack of knowledge. The end goal of this project is to create an mfile which will be able to take a wav file which will be recorded from a microphone, add a level of noise distortion to it which will be specified by the user in increments, and also to add variable onset delay to either the right or left channel of the audio for the new wav file that will be generated.
edit 12:29AM 5/13/14
I have a more clear idea of what needs to happen now after discussion with partner on goals and equipment and now need to find out how to solve these blanks. The delay will most likely have to be between 10 and 300 ns max and the intensity of noise should be from 0 to 5 on a scale of silent to heavy static.
clear;
delay=input('Delay in ns: ');
noise=input('Level of distortion: );
[y,Fs,nbits]=wavread(filename);
generate some noise same length and sampling as file
[newy,Fs]=[y+y2,Fs];
shift over wave x many nanoseconds
wavwrite(newy,Fs,'newwave');
Any help with the current goal of combining signals OR if you could help with generating noise to overlay onto any size of .wav recording I would be extremely grateful.
Here's an example of how it might work. I've simplified the problem by limiting the delay to multiples of the sample period. For a 48kHz sample rate, the delay resolution is around 20us. This method is to first convert the delay to a number of samples and prepend it to the samples from the wave file. Second, the noise signal is generated of the same length and then it is added element wise to the first signal.
noiseLevel = input('Level of distortion: '); % between 0 and 1 - 0 means all signal
- 1 means all noise
delaySeconds = input('Delay in seconds: '); % in seconds
[y,fs,nbits] = wavread(filename);
% figure out how many samples to delay. Resolution is 1/fs.
delaySamples = round(delaySeconds * fs);
% signal length
signalLength = length(y) + delaySamples;
% generate noise samples
noiseSignal = gennoise(signalLength); % call your noise generation function.
% prepend zeros to the signal to delay.
delayedSignal = vertcat(zeros(delaySamples,1), y);
combinedSignal = noiseLevel*noiseSignal + (1-noiseLevel)*delayedSignal;
Couple of points:
Unless I'm doing my math wrong (entirely possible), a delay of 10 to 300 ns is not going to be detectable with typical 44 kHz audio sampling rates. You'd need to be in the MHz sampling rate range.
This solution assumes that your signal is one channel (mono). It shouldn't be too difficult to implement more channels using this format.
For adding noise, you can use randn and scale it based on your level of distortion. I'd suggest tinkering with the value that you multiply it by. Alternatively, you can use awgn to add white gaussian noise. I'm sure there are ways to add other kinds of noise, either in Fourier or time domain, but you can look into those.
If you want the noise during the delay, switch the order of the two.
A reminder that you can use sound(newy,Fs) to see if you like your result.
clear;
delay=input('Delay in ns: ');
noise=input('Level of distortion: );
[y,Fs,nbits]=wavread(filename);
% Add random noise to signal
newy = y + noise*0.1*randn(length(y),1);
% shift over wave x many nanoseconds
num = round(delay*1e-9*Fs); % Convert to number of zeros to add to front of data
newy = [zeros(num,1); newy]; % Pad with zeros
wavwrite(newy,Fs,'newwave');

Matlab: Finding dominant frequencies in a frame of audio data

I am pretty new to Matlab and I am trying to write a simple frequency based speech detection algorithm. The end goal is to run the script on a wav file, and have it output start/end times for each speech segment. If use the code:
fr = 128;
[ audio, fs, nbits ] = wavread(audioPath);
spectrogram(audio,fr,120,fr,fs,'yaxis')
I get a useful frequency intensity vs. time graph like this:
By looking at it, it is very easy to see when speech occurs. I could write an algorithm to automate the detection process by looking at each x-axis frame, figuring out which frequencies are dominant (have the highest intensity), testing the dominant frequencies to see if enough of them are above a certain intensity threshold (the difference between yellow and red on the graph), and then labeling that frame as either speech or non-speech. Once the frames are labeled, it would be simple to get start/end times for each speech segment.
My problem is that I don't know how to access that data. I can use the code:
[S,F,T,P] = spectrogram(audio,fr,120,fr,fs);
to get all the features of the spectrogram, but the results of that code don't make any sense to me. The bounds of the S,F,T,P arrays and matrices don't correlate to anything I see on the graph. I've looked through the help files and the API, but I get confused when they start throwing around algorithm names and acronyms - my DSP background is pretty limited.
How could I get an array of the frequency intensity values for each frame of this spectrogram analysis? I can figure the rest out from there, I just need to know how to get the appropriate data.
What you are trying to do is called speech activity detection. There are many approaches to this, the simplest might be a simple band pass filter, that passes frequencies where speech is strongest, this is between 1kHz and 8kHz. You could then compare total signal energy with bandpass limited and if majority of energy is in the speech band, classify frame as speech. That's one option, but there are others too.
To get frequencies at peaks you could use FFT to get spectrum and then use peakdetect.m. But this is a very naïve approach, as you will get a lot of peaks, belonging to harmonic frequencies of a base sine.
Theoretically you should use some sort of cepstrum (also known as spectrum of spectrum), which reduces harmonics' periodicity in spectrum to base frequency and then use that with peakdetect. Or, you could use existing tools, that do that, such as praat.
Be aware, that speech analysis is usually done on a frames of around 30ms, stepping in 10ms. You could further filter out false detection by ensuring formant is detected in N sequential frames.
Why don't you use fft with `fftshift:
%% Time specifications:
Fs = 100; % samples per second
dt = 1/Fs; % seconds per sample
StopTime = 1; % seconds
t = (0:dt:StopTime-dt)';
N = size(t,1);
%% Sine wave:
Fc = 12; % hertz
x = cos(2*pi*Fc*t);
%% Fourier Transform:
X = fftshift(fft(x));
%% Frequency specifications:
dF = Fs/N; % hertz
f = -Fs/2:dF:Fs/2-dF; % hertz
%% Plot the spectrum:
figure;
plot(f,abs(X)/N);
xlabel('Frequency (in hertz)');
title('Magnitude Response');
Why do you want to use complex stuff?
a nice and full solution may found in https://dsp.stackexchange.com/questions/1522/simplest-way-of-detecting-where-audio-envelopes-start-and-stop
Have a look at the STFT (short-time fourier transform) or (even better) the DWT (discrete wavelet transform) which both will estimate the frequency content in blocks (windows) of data, which is what you need if you want to detect sudden changes in amplitude of certain ("speech") frequencies.
Don't use a FFT since it calculates the relative frequency content over the entire duration of the signal, making it impossible to determine when a certain frequency occured in the signal.
If you still use inbuilt STFT function, then to plot the maximum you can use following command
plot(T,(floor(abs(max(S,[],1)))))

Matlab: Analysis of signal

I have a problem with this task:
For free route perform frequency analysis and give parametrs of each signal component:
time of beginning and ending of each component
beginning and ending frequency
amplitude (in time domain) in the beginning and end of each signal's component
level of noise in dB
Assume, that, the parametrs of each component like amplitude, frequency is changing lineary in time. Frequency of sampling is 1000Hz
For example I have signal like this:
Nx=64;
fs=1000;
t=1/fs*(0:Nx-1);
%==========================
A1=1;
A2=4;
f1=500;
f2=1000;
x1=A1*cos(2*pi*f1*t);
x2=A2*sin(2*pi*f2*t);
%==========================
x=x1+x2;
you are horrendously under-sampling your signal. You will be able to see your 500Hz sin wave, but just barely and your 1000Hz sine-wave wont appear where you would like it to. You will have aliasing issues.
You are also not going to see too many samples (64 samples is not enough data)
MaxTime = 1;%second;
fs = 2000; %minimum for shannon-nyquist
t = 0:1/fs:MaxTime; %this ensures that you are getting the correct sampling rate and you can adjust the time range.
Noise Level = -infinity dB (there is no noise component here)