function [y] = signal_mute(x, index, duration, Fs)
% Return the input vector with a mute that occurs at a specific
% index and with an exponential ramp-down to reduce "pop" sounds.
% The output will start off at 0dB gain and end at -100dB gain.
%
% Usage: y = SIGNAL_MUTE(x, index, duration, Fs);
%
% X is your one-dimensional input array
% INDEX is where in the input signal you want the mute to begin
% DURATION is how long (in seconds) to exponentially ramp down the
% input signal. 100ms is recommended.
% FS is the sample rate
%
% Example:
% You want to mute your signal at 0.5sec with a duration of 100ms
% and with a 48k Fs. (mute complete at 0.6sec)
% y = signal_mute(x, 24000, 0.1, 48000);
%
% Author: sparafucile17 7/29/2003
% Input must have some length
if(length(x) == 1)
error('ERROR: input signal must have more than one element');
end
% This function only supports one-dimensional arrays
if((size(x, 2) ~= 1) && (size(x, 1) ~= 1))
error('ERROR: Input must be one-dimensional');
end
% Make sure there are enough samples to complete the mute
if(length(x) < (index + duration*Fs))
error(['There are not enough samples in X to complete the mute. ' ...
'Either change the mute duration or move the index back.' ]);
end
% Flip vector (temporarily)
if((size(x, 2) ~= 1))
x = x';
flip_back = true;
else
flip_back = false;
end
% Calculate exponential coefficient
dB_atten = -100; %How much attenuation will be at time: index + duration
decayrate = -dB_atten / duration;
coeff = 1.0 - 10^(-decayrate/(20.0*Fs));
% Build the Gain array
gain = [ones(index, 1); zeros((length(x)-index), 1);];
b = [ coeff 0];
a = [ 1 (-1*(1-coeff))];
gain = filter(b,a,gain, [1]);
% Remove minor overshoot at the beginning of gain vector
gain(find(gain > 1)) = 1;
% Apply Mute (gain) to the input signal
y = gain .* x;
% Flip the vector (if required)
if(flip_back == true);
y = y';
end
Jordan ● November 30, 2010 ● Coded in ASM for the ARM
/*
* fixedp lowpass_iir(fixedp *w, fixedp x);
*
* Fixed point IIR filtering routine for ARM. Computes output y for
* input x. The output will have the same fracbits as the input.
* w: caller-allocated array for state storage. Should be length 2*L.
* x: sample to filter
*
* Required data:
* LENGTH: number of sections
* .sos: sos matrix
* SOS_FRACBITS: sos fracbits
* .gain: scale values array
* G_FRACBITS: scale values fracbits
*
* Register usage:
* r0: address of internal state array (w)
* r1: x
* r2: address of SOS array
* r3: address of gain array
* r4: w0
* r5: w1
* r6: y
* r7: long multiply lo word
* r8: long multiply hi word
* r9: B1
* r10: B2
* r11: A1
* r12: A2
* r14: loop counter
*/
.set LENGTH, 3
.set SOS_FRACBITS, 30
.set G_FRACBITS, 31
.section .rodata
.align 4
.sos:
.word 0x49be7eaf, 0x40000000, 0xc4c9d93a, 0x251f228c
.word 0x1d81c8a5, 0x40000000, 0xdaa0b600, 0x37cef3c1
.word 0x40000000, 0x00000000, 0xd87b730c, 0x00000000
.gain:
.word 0x06b1dbb5, 0x42fe27a0, 0x613d5d5a
.text
.arm
.global lowpass_iir
.func lowpass_iir
lowpass_iir:
push {r4-r11, lr}
mov r14, #0 /* i = 0 */
ldr r2, =.sos /* load address of SOS matrix */
ldr r3, =.gain /* load address of gain coefficient array */
cmp r14, #LENGTH
bge .endloop
.loop:
/* load all the SOS coefficients we need into r8-r12 and increment the SOS pointer */
ldmia r2!, {r9-r12} /* B1, B2, A1, A2 */
/* x = gain[i]*x */
ldr r6, [r3], #4 /* load current element of gain array into r6 and increment by 4 */
smull r7, r8, r1, r6 /* 64-bit multiply: r5:r4 = x*gain[i]; */
mov r1, r7, lsr#G_FRACBITS /* shift lo word to the right by G_FRACBITS */
orr r1, r1, r8, lsl#(32 - G_FRACBITS) /* shift hi word to the right by G_FRACBITS and OR with lo word*/
/* load w0 and w1 into r4, r5, but do NOT increment */
ldm r0, {r4-r5}
/* y(r6) = x(r1) + w[W0](r4)*/
add r6, r1, r4
/* w0(r4) = .sos[B1](r9)*x(r1) - .sos[A1](r11)*y(r6) + w[W1](r5); */
rsb r11, r11, #0 /* .sos[A1] = -sos[A1] */
smull r7, r8, r9, r1 /* r8:r7 = sos[B1]*x */
smlal r7, r8, r11, r6 /* r8:r7 += -sos[A1]*y */
mov r4, r7, lsr#SOS_FRACBITS /* shift lo word to the right by SOS_FRACBITS */
orr r4, r4, r8, lsl#(32 - SOS_FRACBITS) /* shift hi word to the right by SOS_FRACBITS and OR with lo word*/
add r4, r4, r5 /* add w1 */
/* w2 = sos[B2]*x(r1) - .sos[A2](r12)*y(r6); */
rsb r12, r12, #0 /* .sos[A2] = -sos[A2] */
smull r7, r8, r10, r1 /* r8:r7 = sos[B2](r10)*x(r1) */
smlal r7, r8, r12, r6 /* r8:r7 += -sos[A2](r12)*y(r6) */
mov r5, r7, lsr#SOS_FRACBITS /* shift lo word to the right by SOS_FRACBITS */
orr r5, r5, r8, lsl#(32 - SOS_FRACBITS) /* shift hi word to the right by SOS_FRACBITS and OR with lo word*/
/* need to store w0, w1 back to memory and increment */
stmia r0!, {r4-r5}
/* x = y */
mov r1, r6
/* increment pointer and branch to top of loop */
add r14, r14, #1
cmp r14, #LENGTH
blt .loop
.endloop:
/* set return val, restore stack, and return */
mov r0, r6
pop {r4-r11, lr}
bx lr
.endfunc
.end
clc
clear all
close all
fs=20e7;
T=1/fs;
t=0:T:0.0000002;
f=10e6;
scanagle_deg=60;
step_deg=6;
theta=-deg2rad(scanagle_deg):deg2rad(step_deg):deg2rad(scanagle_deg);
for i=1:length(theta);
ant1=2*sin(2*pi*f*t);
ant2=2*sin(2*pi*f*t+theta(i));
[my,mx]=max(ant1);
sum_ant(i)=ant1(mx)+ant2(mx);
diff_ant(i)=ant1(mx)-ant2(mx);
ratio_ant(i)=diff_ant(i)/sum_ant(i);
% if diff_ant(i)==0
% diff_ant(i)=0.1;
% end
% ratio1_ant(i)=sum_ant(i)/diff_ant(i);
end
% subplot(311)
% plot(t,ant1,t,ant2)
subplot(211)
plot(rad2deg(theta),sum_ant,rad2deg(theta),diff_ant)
subplot(212)
plot(rad2deg(theta),ratio_ant)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sim_ant1=2*sin(2*pi*f*t);
sim_ant2=2*sin(2*pi*f*t+deg2rad(30));
[smy,smx]=max(sim_ant1);
%%%%also take for same sample value of data
sim_sum_ant=sim_ant1(mx)+sim_ant2(mx);
sim_diff_ant=sim_ant1(mx)-sim_ant2(mx);
sim_ratio_ant=sim_diff_ant/sim_sum_ant
% ------------------------------------------------------
% Title: formfilter.m
%
% Author: David Valencia
%
% Institution: UPIITA-IPN 2010
%
% for DSPrelated.com
%
% Published in: http://www.dsprelated.com/showcode/12.php
%
% Description: This program receives 2 basic ortogonal
% filters (one is high-pass and one is low-pass)
% the filtering level and the branch number.
% As a result it returns the equivalent filter
% of the specified branch.
%
% Dependencies: upsample2.m
% http://www.dsprelated.com/showcode/10.php
%
% Revision: v1.0a
% - Commented and translated in English
%
% For more details on this code and its implementation
% see the following blog posts:
%
% http://www.dsprelated.com/showarticle/115.php
% http://www.dsprelated.com/showarticle/116.php
%
% ------------------------------------------------------
function [hx] = formfilter(n_stages,branch,h0,h1)
p = branch;
% Seed vector
hx = 0;
hx(1) = 1;
switch n_stages
case 1
% If it is a single stage filter
% the branches are just the base filters
if mod(branch,2) ~= 0
hx = h0;
else
hx = h1;
end
case 2
% For a 2 stage filter bank, the
% equivalent filters are simply
% the convolution between the corresponding
% base filters, and one of them is upsampled
% The use of upsample2 is needed to avoid having
% a large quantitiy of zeros at the end of the vector
% which certainly difficults its usage to build a
% convolution matrix.
switch branch
case 1
hx = conv(h0,upsample2(h0,2));
case 2
hx = conv(h0,upsample2(h1,2));
case 3
hx = conv(h1,upsample2(h0,2));
case 4
hx = conv(h1,upsample2(h1,2));
otherwise
beep;
fprintf('\nFor a 2 stage filter bank there can not be a fifth branch');
end
otherwise
% For a n>2 stages filter bank, a more ellaborated
% process must be made. A series of upsamplings and convolutions
% are needed to get an equivalent vector.
for i=0:n_stages-2
q = floor(p /(2^(n_stages-1-i)));
if (q == 1)
hx = conv(hx,upsample2(h1,2^i));
else
hx = conv(hx,upsample2(h0,2^i));
end
p = mod(p,2^(n_stages-1-i));
end
% Depending on the parity of the branch number, the filter
% goes through a last convolution
t = mod(branch,2);
if(t == 1)
hx = conv(hx,upsample2(h0,2^(n_stages-1)));
else
hx = conv(hx,upsample2(h1,2^(n_stages-1)));
end
end
function T = bishrink2(CD,CY)
sigman = (median(median(abs(CD))))/0.6745;
[m,n] = size(CY);
sigmay = 0;
for i =1:m
for j = 1:n
sigmay = sigmay+((CY(i,j))^2);
end
end
sigmay = sqrt(2)*sigmay/(m*n);
sigma = sqrt(max((((sigmay))-((sigman)^2)),0)); % Variance calculation
if sigma~=0
T = sqrt(3)*(sigman^2)/sigma; %Threshold
else
T = max(max(abs(CY)));
end
function Demo
%Author: J. Selva.
%Date: May 2011.
%The interpolation method in this snippet has been published in
%
% [1] J. Selva, "Functionally weighted Lagrange interpolation of bandlimited
% signals from nonuniform samples," IEEE Transactions on Signal Processing,
% vol. 57, no. 1, pp. 168-181, Jan 2009.
%
% Also, the barycentric implementation of the interpolator appears in
%
% [2] J. Selva, "Design of barycentric interpolator for uniform and nonuniform
% sampling grids", IEEE Trans. on Signal Processing, vol. 58, n. 3,
% pp. 1618-1627, March 2010.
T = 1; %Sampling period
B = 0.7; %Two-sided signal bandwidth. It must be B*T < 1.
P = 12; %Truncation index. The number of samples taken is 2*P+1. The error
%decreases EXPONENTIALLY with P as exp(-pi*(1-B*T)*P).
%(Try different values of P like 3, 7, 20, and 30.)
int = [-30,30]*T; %Plot x limits.
JitMax = 0.4; %Maximum jitter. This must be between 0 and 0.5*T. The samples
%are taken at instants p*T+d[p], -P<=p<=P and
%-JitMax <= d[p] <= JitMax.
while 1
st = TestSignal(int,ceil(60/B),B); %This defines a test signal formed
%by a random sum of sincs of bandwidth B.
d = 2*(rand(1,2*P+1)-0.5)*JitMax; %Vector of random jitter.
disp('Sampling instants (t_k/T):')
disp((-P:P)*T+d)
sg = TestSignal(st,(-P:P)*T+d); %Sample signal at jittered instants
t = int(1):0.1*T:int(2); %Time grid for figure.
sRef = TestSignal(st,t); %Exact signal samples in grid t.
sInt = NonuniformInterp(t,sg,d,B,T); %Signal samples interpolated from
%d (jitter values) and sg (values at jittered
%instants).
subplot(2,1,1)
plot(t,sRef,t,sInt) %Plot exact and interpolated signals
xlabel('Normalized time (t/T)')
title('Signal (blue) and interpolator (green)')
grid on
subplot(2,1,2)
plot(t,20*log10(abs(sRef-sInt))) %Plot interpolation error in dB.
xlabel('Normalized time (t/T)')
ylabel('Interpolation error (dB)')
grid on
R = input('Press Enter for a new trial, q to quit: ','s');
if any(strcmp(R,{'q','Q'}))
break
end
end
function v = NonuniformInterp(u,sg,d,B,T)
%Performs interpolation from nonuniform samples.
% T is the period of the reference grid (instants (-P:P)*T).
% d is the vector of jitter values relative to the reference grid. It must have an odd ...
% number of elements.
% B: signal's two-sided bandwidth. It must be B*T<1. The error decreases exponentially as
% exp(-pi*(1-B*T)P).
% u: Vector of instants where the signal is to be interpolated.
% sg: Sample values at instants (-P:P)*T+d.
if mod(length(d),2) ~= 1
error('The number of samples must be odd')
end
P = (length(d)-1)/2;
tg = (-P:P)*T+d(:).';
w = baryWeights(tg,T,B,P);
v = DerBarycentricInterp3tVecV1(w,sg,tg,u,0);
function v = APPulse(t,B,TSL)
v = real(sinc(B*sqrt(t.^2-TSL^2)))/real(sinc(1i*pi*B*TSL));
function w = baryWeights(vt,T,B,P)
%Barycentric weights. See Eq. (23) and sequel in [2].
g = APPulse(vt,1/T-B,T*(P+1));
gam = gamma(vt/T+P+1) .* gamma(-vt/T+P+1) .* g;
N = length(vt);
LD = ones(1,N);
for k = 1:N
LD(k) = prod(vt(k)-vt(1:k-1))* prod(vt(k)-vt(k+1:N));
end
w = gam ./ LD;
w = w / max(abs(w));
function out = DerBarycentricInterp3tVecV1(alpha,s,t,tau,nd)
%Vectorized implementation of barycentric interpolator in [2, Sec. IV].
s = s(:).';
t = t(:).';
sztau = size(tau);
tau = tau(:);
Nt = numel(t);
Ntau = numel(tau);
vD = zeros(Ntau,1);
LF = [ones(Ntau,1),zeros(Ntau,Nt-1)];
out = zeros(Ntau,nd+1);
for k = 1:Nt-1
vD = vD .* (tau-t(k))+alpha(k)*LF(:,k);
LF(:,k+1) = LF(:,k) .* (tau-t(k));
end
vD = vD .* (tau-t(Nt)) + alpha(Nt) * LF(:,Nt);
z = s(ones(Ntau,1),:);
for kd = 0:nd
pr = z(:,end);
z1 = z-pr(:,ones(1,Nt)); cN = zeros(Ntau,1);
for k = 1:Nt-1
cN = cN .* (tau-t(k))+z1(:,k)*alpha(k) .* LF(:,k);
end
cN = cN ./ vD;
ztau = z(:,end)+(tau-t(end)) .* cN;
out(:,kd+1) = ztau;
if kd < nd
z = [ (z(:,1:end-1)-ztau)./(t(ones(Nt,1),1:end-1)-tau(:,ones(1,Nt))) , ...
cN ] * (kd+1);
end
end
out = reshape(out,sztau);
function varargout = TestSignal(varargin)
%Test signal formed by a random sum of sincs.
if nargin == 3
[int,Nsinc,B] = deal(varargin{:});
st = [];
st.B = B;
st.Ampl = (rand(1,Nsinc)-0.5)*2;
st.Del = int(1)+(int(2)-int(1))*rand(1,Nsinc);
varargout = {st};
else
[st,t] = deal(varargin{:});
v = zeros(size(t));
for k = 1:numel(t)
v(k) = st.Ampl * sinc(st.B*(t(k)-st.Del)).';
end
varargout = {v};
end
/*******************FLANGER.C******************************/
#include "Delay.h"
#include "Flanger.h"
static short samp_freq;
static double var_delay;
static short counter;
static short counter_limit;
static short control;
static short max_delay;
static short min_delay;
static double mix_vol;
static double delay_step;
/*
This is the initialization function, basically
it passes the initialization parameters to the delay block
and initializes the flanger control variables.
*/
void Flanger_init(short effect_rate,short sampling,short maxd,short mind,double fwv,double stepd,double fbv) {
Delay_Init(2,fbv,fwv,1);
samp_freq = sampling;
counter = effect_rate;
control = 1;
var_delay = mind;
//User Parameters
counter_limit = effect_rate;
max_delay = maxd;
min_delay = mind;
mix_vol = 1;
delay_step = stepd;
}
/*This is the flanging process task
that uses the delay task inside*/
double Flanger_process(double xin) {
double yout;
yout = Delay_task(xin);
return yout;
}
/*
This sweep function creates a slow frequency
ramp that will go up and down changing the
delay value at the same time. The counter
variable is a counter of amount of samples that
the function waits before it can change the delay.
*/
void Flanger_sweep(void) {
if (!--counter) {
var_delay+=control*delay_step;
if (var_delay > max_delay) {
control = -1;
}
if (var_delay < min_delay) {
control = 1;
}
Delay_set_delay(var_delay);
counter = counter_limit;
}
}
/*****************FLANGER.H********************************/
#ifndef __FLANGER_H__
#define __FLANGER_H__
extern void Flanger_init(short effect_rate,short sampling,short maxd,short mind,double fwv,double stepd,double fbv);
extern double Flanger_process(double xin);
extern void Flanger_sweep(void);
#endif
/*****USAGE EXAMPLE****************************************/
#include "Flanger.h"
void main(void) {
double xin;
double yout;
Flanger_init(500,16000,70,2,0.3,1,0.3);
while(1) {
if (new_sample_flag()) {
/*When there's new sample at your ADC or CODEC input*/
/*Read the sample*/
xin = read_sample();
/*Apply the Flanger_process function to the sample*/
yout = Flanger_process(0.7*xin);
/*Send the output value to your DAC or codec output*/
write_output(yout);
/*Makes the delay vary*/
Flanger_sweep();
}
}
}
function Demo(L)
%Author: J. Selva.
%Date: April 2011.
%This demo constructs trials of an undamped exponential plus noise, and then computes the
%maximum likelihood estimate of its frequency, amplitude, and phase. Only one FFT of size
%2^ceil(log2(st.M)+1) is computed, plus a few operations. The complexity is that given by
%the FFT. The algoritm is explained in
%
% http://arxiv.org/abs/1104.3069
%
format long g
format compact
M = 1024; %Number of samples.
gdB = 20; %SNR at matched filter output.
ARef = 1.3; %Amplitude.
fRef = 0.372; %Frequency in [-0.5,0.5[.
PhiRef = 0.43; %Phase (rad).
if nargin > 0
for k = 1:2:length(L)
eval([L{k} '=L{k+1};']);
end
end
%Define a random vector with 1024 elements.
SNRdB = gdB - 10*log10(M); %Signal-to-noise ratio (dB).
%Complex sinusoidal amplitude, frequency, and phase.
NVar = ARef^2*10.^(-SNRdB/10); %Noise variance.
m1 = -ceil(M/2);
while 1
disp(' ')
disp(['M = ', num2str(M), ', gdB = ', num2str(gdB), ' dB, ARef = ', num2str(ARef), ...
', fRef = ', num2str(fRef), ', PhiRef = ', num2str(PhiRef), ' rad'])
disp(' ')
%Set up a trial.
a = ARef*exp(1i*2*pi*fRef*(m1:m1+M-1).'+1i*PhiRef)+(randn(M,1)+1i*randn(M,1))*sqrt(NVar/2);
%Call the nufft function. The output is a struct with some variables for later use.
st = nufft(a);
%Compute the DFT peak.
[f1,A1,Phi1,L1,Deg,nIt] = MLEstimate(st);
%The output is the following,
%
% f1, A1, and Phi1 are the ML estimates of frequency, amplitude and phase, respectively.
%
% L1 is the ML cost function value at f1 and its first two derivatives. L1(1) should be
% large since it is the square value of the peak amplitude. L1(2) is the cost
% function derivative, and it should be small since we are at a critical
% point. Finally L1(2) should be a negative number with large amplitude since f1 is
% the abcissa of a maximum (second derivative).
%
% Deg: If Deg==1 then the Newton iteration was cut too many times.
% nIt: Number of Newton iterations.
disp('Exact and estimated frequency, amplitude, and phase:')
disp([fRef,ARef,PhiRef;f1,A1,Phi1])
disp(['Number of iterations: ' num2str(nIt)])
%
%Plot the spectrum close to the ML estimate
%
f = fRef+(-10:.05:10)/st.K;
sp = nufft(st,f);
plot(f,20*log10(abs(sp)/M))
hold on
stem(f1,20*log10(A1),'r')
hold off
grid on
set(gca,'YLim',[-40,10])
xlabel('f')
ylabel('Amplitude (dB)')
text(fRef+2/st.K,5,{['Freq. ' num2str(f1)],['Ampl. ' num2str(A1)],...
['Phase. (rad) ' num2str(Phi1)]})
%
R = input('Press Enter for a new trial, q to quit: ','s');
if any(strcmp(R,{'q','Q'}))
break
end
end
%------------------------------------------------------
%------------------------------------------------------
function [f1,A1,Phi1,L1,Deg,nIt] = MLEstimate(st)
%This function finds out the peak of a DFT. Its input is the struct produced by the nufft function.
%Find the spectral peak in the frequency grid.
[pr11,ind] = max(abs(st.aF).^2);
%Compute its frequency.
f0 = (ind-1)/st.K;
f0 = f0+ceil(-0.5-f0);
%L0 contains the differentials of the ML cost function of orders 0,1, 2 ...
%at f0.
L0 = LDiff(nufft(st,f0,2));
nItMax = 20;
err = 10.^-12;
nIt = 0;
%Call Iter (Newton iteration) until there is no change or the solution is degenerate.
while 1
[Deg,pr11,f1,L1] = Iter(st,f0,L0);
if Deg || abs(f1-f0) <= err || nIt >= nItMax
break
end
f0 = f1;
L0 = L1;
nIt = nIt+1;
end
pr = nufft(st,f1);
A1 = abs(pr)/st.M;
Phi1 = angle(pr);
function L = LDiff(c)
%Computes the differentials of the ML cost function from the nufft differentials.
L = [real(c(1)*conj(c(1))); 2*real(conj(c(1))*c(2)); ...
2*real(conj(c(2))*c(2)+conj(c(1))*c(3))];
function [Deg,nCut,f1,L1] = Iter(st,f0,L0)
%Performs the Newton iteration, cutting the Newton direction if necessary.
f1 = f0-L0(2)/L0(3); %Newton iteration.
f1 = f1+ceil(-0.5-f1); %Make it fall in [-0.5,0.5].
L1 = LDiff(nufft(st,f1,2)); %Compute the differentials at f1.
nCutMax = 20; %The difference f1-f0 will be reduced in the sequel if there is no ...
%improvement in the cost function
nCut = 0;
d = 1;
%In this loop the difference f1-f0 is halved a maximum of nCutMax times until there is ...
%an increase in the cost function
while L1(1) < L0(1) && nCut < nCutMax
d = d/2;
f1 = f0-d*L0(2)/L0(3);
f1 = f1+ceil(-0.5-f1);
L1 = LDiff(nufft(st,f1,2));
nCut = nCut+1;
end
Deg = nCut >= nCutMax;
%----------------------------------------------------------------
%----------------------------------------------------------------
%Non-uniform FFT function. This code is discussed in
% http://www.dsprelated.com/showcode/159.php
function varargout = nufft(varargin)
%Author: J. Selva
%Date: April 2011.
%
%nufft computes the FFT at arbitrary frequencies using barycentric interpolation.
%
%For the interpolation method, see
%
%J. Selva, 'Design of barycentric interpolator for uniform and nonuniform sampling
% grids', IEEE Trans. on Signal Processing, vol. 58, n. 3, pp. 1618-1627, March 2010.
%
%Usage:
%
% -First call nufft with the vector of samples as argument,
%
% st = nufft(a); %a is the vector of samples.
%
% The output is an struct. The field st.aF is the DFT of vector a, sampled with spacing
% 1/st.K.
%
% The DFT is defined using
%
% A_k = \sum_{n=m_1}^{m_1+M-1} a_n e^{-j 2 \pi n f}
%
% where m_1=-ceil(M/2) and M the number of samples.
%
% -Then call nufft with sintax
%
% out = nufft(st,f,nd,method)
%
% where
%
% f: Vector of frequencies where the DFT is evaluated. Its elements must follow
% abs(f(k))<=0.5
%
% nd: Derivative order. nufft computes derivatives up to order nd. At the output
% out(p,q) is the (q-1)-order derivative of the DFT at frequency f(p). The first
% column of out contains the zero-order derivatives, i.e, the values of the DFT at
% frequencies in vector f.
% method: If omitted, it is 'baryVec'. Four methods have been implemented:
%
% +'baryLoop': The output is interpolated using the barycentric method and a loop
% implementation.
%
% +'baryVec': The output is interpolated using the barycentric method and a
% vectorized implementation.
%
% +'directLoop': The output is computed using the DFT sum directly and a loop
% implementation.
%
% +'directVec': The output is computed using the DFT sum directly and a vectorized
% implementation.
if ~isstruct(varargin{1})
st = [];
st.a = varargin{1};
st.a = st.a(:);
st.M = length(st.a);
st.m1 = -ceil(st.M/2);
st.K = 2^ceil(log2(st.M)+1);
st.aF = fft([st.a(-st.m1+1:st.M); zeros(st.K-st.M,1); st.a(1:-st.m1)]);
errb = 10.^-13; %This is the interpolation accuracy. You can set any larger value, and ...
%this would reduce st.P. The number of interpolation samples is 2*st.P+1.
st.T = 1/st.K;
st.B = -2*st.m1;
st.P = ceil(acsch(errb)/(pi*(1-st.B*st.T)));
st.vt = MidElementToEnd((-st.P:st.P)*st.T);
st.alpha = MidElementToEnd(baryWeights(st.T,st.B,st.P));
varargout = {st};
return
end
[st,f] = deal(varargin{1:2});
nd = 0;
if nargin > 2
nd = varargin{3};
end
method = 'baryVec';
if nargin > 3
method = varargin{4};
end
Nf = length(f);
out = zeros(Nf,nd+1);
switch method
case 'baryLoop' %Interpolated method using loops
for k = 1:length(f)
x = f(k);
n = floor(x/st.T+0.5);
u = x - n * st.T;
da = MidElementToEnd(st.aF(1+mod(n-st.P:n+st.P,st.K)).');
out(k,:) = DerBarycentricInterp3(st.alpha,da,st.vt,u,nd);
end
case 'baryVec' %Vectorized interpolated method
f = f(:);
Nf = length(f);
n = floor(f/st.T+0.5);
u = f - n * st.T;
pr = [-st.P:-1 , 1:st.P , 0];
ms = st.aF(1+mod(n(:,ones(1,2*st.P+1)) + pr(ones(Nf,1),:),st.K));
if length(f) == 1
ms = ms.';
end
out = DerBarycentricInterp3Vec(st.alpha,ms,st.vt,u,nd);
case 'directLoop' % Direct method using loops
for k = 1:length(f)
out(k,1) = 0;
for r = st.m1:st.m1+st.M-1
out(k,1) = out(k,1)+exp(-1i*2*pi*r*f(k))*st.a(r-st.m1+1);
end
for kd = 1:nd
out(k,kd+1) = 0;
for r = st.m1:st.m1+st.M-1
out(k,kd+1) = out(k,kd+1) + ...
((-1i*2*pi*r).^kd .* exp(-1i*2*pi*r*f(k)))*st.a(r-st.m1+1);
end
end
end
case 'directVec' %Vectorized direct method
for k = 1:length(f)
out(k,1) = exp(-1i*2*pi*(st.m1:st.m1+st.M-1)*f(k))*st.a;
for kd = 1:nd
out(k,kd+1) = ...
((-1i*2*pi*(st.m1:st.m1+st.M-1)).^kd .* ...
exp(-1i*2*pi*(st.m1:st.m1+st.M-1)*f(k)))*st.a;
end
end
end
varargout = {out};
function v = MidElementToEnd(v)
ind = ceil(length(v)/2);
v = [v(1:ind-1),v(ind+1:end),v(ind)];
function v = APPulse(t,B,TSL)
v = real(sinc(B*sqrt(t.^2-TSL^2)))/real(sinc(1i*pi*B*TSL));
function w = baryWeights(T,B,P)
vt = (-P:P)*T;
g = APPulse(vt,1/T-B,T*(P+1));
gam = gamma(vt/T+P+1) .* gamma(-vt/T+P+1) .* g;
N = length(vt);
LD = ones(1,N);
for k = 1:N
LD(k) = prod(vt(k)-vt(1:k-1))* prod(vt(k)-vt(k+1:N));
end
w = gam ./ LD;
w = w / max(abs(w));
function out = DerBarycentricInterp3(alpha,s,t,tau,nd)
vD = 0;
Nt = length(t);
LF = [1,zeros(1,Nt-1)];
out = zeros(1,nd+1);
for k = 1:Nt-1
vD = vD*(tau-t(k))+alpha(k)*LF(k);
LF(k+1) = LF(k)*(tau-t(k));
end
vD = vD * (tau-t(Nt)) + alpha(Nt) * LF(Nt);
z = s;
for kd = 0:nd
z1 = z-z(end); cN = 0;
for k = 1:Nt-1
cN = cN * (tau-t(k))+z1(k)*alpha(k)*LF(k);
end
cN = cN/vD;
ztau = z(end)+(tau-t(end))*cN;
out(kd+1) = ztau;
if kd < nd
z = [ (z(1:end-1)-ztau)./(t(1:end-1)-tau) , cN ] * (kd+1);
end
end
function out = DerBarycentricInterp3Vec(alpha,zL,t,tauL,nd)
NtauL = size(tauL,1);
LBtau = 200; %Block size for vectorized processing. Change this to adjust the memory
%usage.
NBlock = 1+floor(NtauL/LBtau);
Nt = length(t);
out = zeros(NtauL,nd+1);
for r = 0:NBlock-1
ind1 = 1+r*LBtau;
ind2 = min([(r+1)*LBtau,NtauL]);
Ntau = ind2-ind1+1;
z = zL(ind1:ind2,:);
tau = tauL(ind1:ind2);
vD = zeros(Ntau,1);
LF = [1,zeros(1,Nt-1)];
LF = LF(ones(Ntau,1),:);
for k = 1:Nt-1
vD = vD .* (tau-t(k))+alpha(k)*LF(:,k);
LF(:,k+1) = LF(:,k) .* (tau-t(k));
end
vD = vD .* (tau-t(Nt)) + alpha(Nt) * LF(:,Nt);
for kd = 0:nd
pr = z(:,end); z1 = z-pr(:,ones(1,Nt)); cN = zeros(Ntau,1);
for k = 1:Nt-1
cN = cN .* (tau-t(k)) + z1(:,k) .* alpha(k) .* LF(:,k);
end
cN = cN ./ vD;
ztau = z(:,end)+(tau-t(end)) .* cN;
out(ind1:ind2,kd+1) = ztau;
if kd < nd
pr1 = ztau;
pr1 = z(:,1:end-1) - pr1(:,ones(1,Nt-1));
pr2 = t(1:end-1);
pr2 = pr2(ones(Ntau,1),:)-tau(:,ones(1,Nt-1));
z = [pr1 ./ pr2, cN] * (kd+1);
end
end
end
function [Sdct] = matrix_dct(P) %where P is the vector to apply the dct
N=length(P);
Cf=[1/sqrt(2),ones(1,N-1)];
S=zeros(1,N);
for f=0: N-1;
for x=0: N-1;
W(f+1, x+1)=cos((2*x+1)*pi*f/(2*N)); %matrix kernel
end
end
Sdct=W*P';
Sdct=sqrt(2/N)*Sdct.*Cf'; %constant product
function [S] = dct_2d(P) %where P is the matrix to apply the dct
N=length(P);
Cu=[1/sqrt(2),ones(1,N-1)]; %Constant coeficients d1
Cv=[1/sqrt(2),ones(1,N-1)]; %Constant coeficients d2
S=zeros(N,N);
for v=0: N-1;
for y=0: N-1;
for u=0: N-1;
for x=0: N-1; %serial processing
S(u+1,v+1)=S(u+1,v+1)+Cu(u+1)*Cv(v+1)*P(x+1,y+1)*cos((2*x+1)*pi*u/(2*N))*cos((2*y+1)*pi*v/(2*N));
end;
end;
end;
end;
S=(2/N)*S; %final result
[header, s] = hdrload('data_file.txt');
num = 2;
x = zeros(ceil(44100/num),1); %channel 1
y = zeros(ceil(44100/num),1); %channel 2
Fs = 44100; % Sampling frequency
T = 1/Fs; % Sample time
L = Fs/num; % Length of window
g = floor(num*length(s)/Fs); % number of windows
H = 0;
count = 50;
max_index = 1; % pointer for max value
max = 0; % max value
max_index2 = 1; % pointer for max value
max2 = 0; % max value
z = zeros(g,2);
z2 = zeros(g,2);
for i = 1:1:g-3
% creating windows for channel one and two
for j = 1:1:L
k = j + L*i;
x(j,1) = s(k+i,1);
y(j,1) = s(k+i,2);
end
NFFT = 2^nextpow2(L); % Next power of 2 from length of y
YY = fft(y,NFFT)/L;
Y = fft(x,NFFT)/L;
f = Fs/2*linspace(0,1,NFFT/2+1); % creating frequency vector
Y2 = 2*abs(Y(1:NFFT/2+1));
YY2 = 2*abs(YY(1:NFFT/2+1));
%%channel 1
max = Y(max_index,1);
%%channel 2
if(max_index2 < length(YY2))
max2 = YY(max_index2,1);
b = length(YY2) - max_index2 - 2*count;
if b > 0
a = max_index2 + 2*count;
else
a = length(YY2);
end
for j = max_index2:1:(a-1)
if max2 < YY2(j+1,1)
max2 = YY2(j+1,1);
max = Y2(j+1,1);
max_index2 = j+1;
end
end
end
z2(i+1,1) = abs(max2);
z2(i+1,2) = f(1,max_index2);
z(i+1,1) = abs(max);
z(i+1,2) = f(1,max_index2);
if(max_index2 > 4*count)
max_index2 = max_index2 - count;
end
% RECORD MOVIE
% semilogy(z2(:,2),z2(:,1),f,YY2,z(:,2),z(:,1),f,Y2);
% axis([0 20000 10^-3 Inf]);
end
semilogy(z2(:,2),z2(:,1),z(:,2),z(:,1));
axis([0 20000 0.00001 Inf]);