I have a vector with many frequencies. Now I try to program a sine-wave, which generates for each frequency one period and put it into one vector... (similar like a sweep signal)
Finally I want to plot this...
I already tried this, but it doesn't work correctly..
%fr = Frequency-Vector with 784 Elements from 2.0118e+04 to 1.9883e+04 Hz
fs = 48000; %Sampling frequency [Hz]
tstart = 0;
tstep = 1/fs;
tend = (length(fr))*(1/min(fr))-tstep;
t3 = tstart3:tstep3:tend3;
sin3 = [];
for i = 1:length(fr)/2
sin3 = [sin3 sin(2*pi*fr(i)*t3)];
end
tstart4 = 0;
tstep4 = 1/fs2;
tend4 = tstep4*length(sin3);
t4 = tstart4:tstep4:tend4-tstep4;
figure;
plot(t4,sin3)
Could you please help me?
Thanks!
If reversed engineer your codes correctly, it seems like you wanted to generate a chirp frequency. It could be more efficient if you do it as follows
fr = linspace(2.0118e4, 1.9883e4, 784); % Frequency content
%fr = linspace(2e4, 1e4, 784); % Try this for a wider chirp
fs = 48e3;
phi = cumsum(2*pi*fr/fs);
s1 = sin(phi);
spectrogram(s1, 128, 120, 128, fs); % View the signal in time vs frequency
Related
I have an array containing the Fourier transform of an input audio signal (the amplitudes corresponding to various frequencies). I wish to select specific ranges of the signal without using the inbuilt functions. I have performed the following simple operations for the same :
[audio_in,audio_freq_sampl]=audioread('F:\Signals and Systems\Take Me Home Country Roads (John Denver Cover).wav');
Length_audio=length(audio_in);
df=audio_freq_sampl/Length_audio;
frequency_audio=-audio_freq_sampl/2:df:audio_freq_sampl/2-df;
figure
FFT_audio_in=fft(audio_in);
n = length(FFT_audio_in);
init = 30000;
fin = 40000;
conji= mod((n-init+2),n) ;
conjf= mod((n-fin+2),n) ;
fs_1(1:n) = 0.0 ;
fs_1(init:fin) = FFT_audio_in(init:fin);
fs_1(conji:conjf) = FFT_audio_in(conji:conjf);
plot(frequency_audio,abs(fs_1));
As we can see here, there is only one peak. the other one should be visible at the other end of the plot in the range.
The song can be found here - https://www.youtube.com/watch?v=WF046Z5tPJE
The song must be converted to a .wav file before reading it.
The above code should give me a plot containing two small peaks corresponding to the ranges of frequencies - (init , fin) and (conji , conjf). However, I am getting a peak only corresponding to the 1st range. Both these ranges are within the size of the array - FFT_audio_in.
The error lies in the following lines of code :
n = length(FFT_audio_in);
init = 30000;
fin = 40000;
conji= mod((n-init+2),n) ;
conjf= mod((n-fin+2),n) ;
fs_1(1:n) = 0.0 ;
fs_1(init:fin) = FFT_audio_in(init:fin);
fs_1(conji:conjf) = FFT_audio_in(conji:conjf);
Turns out that in the above lines of code, conji < conjf. So in the last line of the code, I am spanning through the vector with the initial point being larger than the final point. However, with the following lines of code, this issue is resolved :
n = length(FFT_audio_in);
init = n/4;
fin = n/4 + 10000;
conji= mod((n-init+2),n) ;
conjf= mod((n-fin+2),n) ;
init_2 = min(conji , conjf);
fin_2 = max(conji , conjf);
fs_1(1:n) = 0.0 ;
fs_1(init:fin) = FFT_audio_in(init:fin);
fs_1(init_2:fin_2) = FFT_audio_in(init_2:fin_2);
bits = [1,0,1,1,0,0,0,1];
for a=1:length(bits)
if bits(a) == 1
bit(a) = 5;
else
bit(a) = -5;
end
end
i = 1;
t = 0:0.01:length(bits);
for b=1:length(t)
if t(b) <= i
y(b) = bit(i);
else
y(b) = bit(i);
i = i+1;
end
end
plot(t,y);
I am plotting y at t from 0 to 8.
I need to change the time scale to 0 to 8us with each bit lasting 1us and a step of 10ns.
Simply changing the time scale will only plot the first value as length of array is 8. Any ideas on how to approach this problem?
I'm confused with the method of calculating DAC output as decimal value. I'm using DAC7741. The voltage I need to estimate is called Vint. The below code is a sample I refer. But I don't know why voltage = DAC_buf *3052 ?? I checked the DAC7741 datasheet but didn't see any clue of 3052. Please explain to me how we can get that formula. Thank you!
unsigned long DAC_buf =0x0000;
unsigned char idata Vint_H _at_ 0xB3;
unsigned char idata Vint_L _at_ 0xB4;
DAC_buf += Vint_H;
DAC_buf = DAC_buf << 8;
DAC_buf += Vint_L;
if(Vint_H<0x80)
{
DAC_buf = 0x8000-DAC_buf;
voltage = DAC_buf *3052;
voltage_ten_thousand = (voltage%100000000)/10000000;
voltage_thousand = (voltage%10000000)/1000000;
voltage_hundred = (voltage%1000000)/100000 ;
voltage_ten = (voltage%100000)/10000 ;
voltage_unit = (voltage%10000)/1000;
}
else
{
DAC_buf = DAC_buf- 0x8000;
voltage = DAC_buf *3052;
voltage_ten_thousand = (voltage%100000000)/10000000;
voltage_thousand = (voltage%10000000)/1000000;
voltage_hundred = (voltage%1000000)/100000 ;
voltage_ten = (voltage%100000)/10000 ;
voltage_unit = (voltage%10000)/1000;
}
Another voltage I need to calculate from a power IC (LTC2606).
voltage = 13050- OVSS_buf*100; // OVSS_buf is the hex value assigned to the power IC
I got that formula after tried & error several times. Even though I got correct result to display on the monitor, I still don't know how to get the correct formula. I checked LTC2606 the formula of Vout = (k/2^16)*Vcc. Vcc = 3V
I would appreciate if someone can explain to me the way of calculating both voltages I mentioned above.
I have a problem where i can't add values to my 1 x 250 matrix directly from a variable. This is the code.
COMPORT = 'COM4';
BAUDRATE = 115200;
s1 = serial(COMPORT, 'baudrate', BAUDRATE);
set(s1, 'Terminator', 10);
fopen(s1);
adc = 0;
N = 250;
values = zeros(1, N);
for n = 1:N
adc = fscanf(s1);
values(n) = adc;
flushinput(s1);
flushoutput(s1);
end
x = linspace(0, 250);
plot(x, n);
The values(n) = adc does not seem to work and i don't know how to work my way around it.
This doesn't work because values(n) is a single element and the output from fscanf(s1) consist of several elements.
Maybe you want to use cells?
values{n} = adc;
Substitute the pre-allocation: n = zeros(1, N) with n = cell(1,N);.
Notice that you need to do some changes later in your code. I'll leave that uo to you.
I am trying to compute 3D convolution of a 3D array using Intel MKL. Could someone kindly give me some hints how I can do that? Is it achievable using MKL? Thanks in advance.
Intel has an example on their page of a 3D FFT, which should be helpful for performing convolution by multiplication in frequency space. Sorry I don't have a full solution:
Three-Dimensional REAL FFT (C Interface)
#include "mkl_dfti.h"
float x[32][100][19];
float _Complex y[32][100][10]; /* 10 = 19/2 + 1 */
DFTI_DESCRIPTOR_HANDLE my_desc_handle;
MKL_LONG status, l[3];
MKL_LONG strides_out[4];
//...put input data into x[j][k][s] 0<=j<=31, 0<=k<=99, 0<=s<=18
l[0] = 32; l[1] = 100; l[2] = 19;
strides_out[0] = 0; strides_out[1] = 1000;
strides_out[2] = 10; strides_out[3] = 1;
status = DftiCreateDescriptor( &my_desc_handle, DFTI_SINGLE,
DFTI_REAL, 3, l );
status = DftiSetValue(my_desc_handle,
DFTI_CONJUGATE_EVEN_STORAGE, DFTI_COMPLEX_COMPLEX);
status = DftiSetValue( my_desc_handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE );
status = DftiSetValue(my_desc_handle,
DFTI_OUTPUT_STRIDES, strides_out);
status = DftiCommitDescriptor(my_desc_handle);
status = DftiComputeForward(my_desc_handle, x, y);
status = DftiFreeDescriptor(&my_desc_handle);
/* result is the complex value z(j,k,s) 0<=j<=31; 0<=k<=99, 0<=s<=9
and is stored in complex matrix y in CCE format. */
The next steps would be do perform the same transform for a padded kernel, point-wise multiplication of the two complex arrays, and inverse FFT.