Skip to content

Commit 44cb132

Browse files
committed
Create single_stiff_string.m
1 parent 5086a0b commit 44cb132

1 file changed

Lines changed: 254 additions & 0 deletions

File tree

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
clearvars,
2+
close all
3+
4+
%%%%% flags
5+
6+
plot_on = 0; % in-loop plotting on (1) or off (0)
7+
itype = 1; % type of input: 1: struck, 2: plucked
8+
bctype = 1; % boundary condition type: 1: simply supported, 2: clamped
9+
outtype = 1; % output type: 1: string displacement, 2: string velocity
10+
11+
%%%%% parameters
12+
13+
% physical string parameters (see Q7a)
14+
L(1:6) = 0.648; % guitar scale length(m)
15+
rho(1:6)= 7750; % Density of steel (kg/m^3)
16+
% Strings: E B G D A E
17+
% gauges: .046 .036 .026 .017 .013 .01
18+
r = [1.1684e-3 9.144e-4 6.604e-4 4.3e-4 3.3e-4 2.5e-4]; % string radius (m)
19+
20+
% Young's modulus (Pa) taken from
21+
% http://srjcstaff.santarosa.edu/~yataiiya/E45/PROJECTS/guitar%20strings.pdf
22+
% considering the lowest three strings to be wound and the top three
23+
% single-wire
24+
E = [6.4e10 6.4e10 6.4e10 1.88e11 1.88e11 1.88e11] ;
25+
freq= [82.41 110 146.83 196 246.94 329.63]; % Note frequencies
26+
27+
28+
29+
% T60 (s) was left to 5 s. Although longer T60 were found by analysing
30+
% decays of plucked guitar strings, 5 s produced nicer sound.
31+
T60(1:6) = 5;
32+
33+
% I/O
34+
SR = 44100; % sample rate (Hz)
35+
Tf = 5; % duration of simulation (s)
36+
37+
xi(1:6) = 0.3; % coordinate of excitation (normalised, 0-1)
38+
famp = [1 1 1 1 1 1]; % peak amplitude of excitation (N)
39+
dur = [0.001 0.001 0.001 0.001 0.001 0.001]; % duration of excitation (s)
40+
exc_st = [0 0.5 1 1.5 2 2.5]; % start time of excitation (s)
41+
xo(1:6) = 0.2; % coordinate of output (normalised, 0-1)
42+
window_dur = 0.01; % duration of fade-out window (s). See Q6.
43+
44+
%%%%% Error checking
45+
46+
if any([r, rho, T60, L, SR, Tf, famp, window_dur]<=0)
47+
error('Parameters must be positive');
48+
end
49+
if any(E<0)
50+
error('Young''s modulus must be non-negative');
51+
end
52+
if any(exc_st<0 | exc_st>Tf)
53+
error('Start time of excitation are beyond the simulation time')
54+
end
55+
if any([xi, xo]>=1 | [xi, xo]<=0)
56+
error('Excitation and output coordinates must be between 0 and 1')
57+
end
58+
if any([all(plot_on~=[0 1]) all(itype~=[1 2])...
59+
all(bctype~=[1 2]) all(outtype~=[1 2])])
60+
error('Flag values are incorrect')
61+
end
62+
if any(exc_st+dur>Tf)
63+
error('Excitation duration exceeds simulation duration')
64+
end
65+
66+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67+
68+
%%%%% derived parameters
69+
A = pi*r.^2; % string cross-sectional area
70+
I = 0.25*pi*r.^4; % string moment of intertia
71+
K = sqrt(E.*I./(rho.*A)); % stiffness constant
72+
73+
% Tension (N) using stiff string frequency equation (7.21) from NSS
74+
T = (4*L.^2.*freq.^2+K.^2*pi^2).*rho.*A;
75+
76+
c = sqrt(T./(rho.*A)); % wave speed
77+
78+
sig = 6*log(10)./T60; % loss parameter
79+
80+
%%%%% grid
81+
82+
k = 1/SR; % time step
83+
hmin = sqrt(0.5*(c.^2.*k^2+sqrt(c.^4.*k^4+16*K.^2.*k^2))); % minimal grid spacing
84+
85+
N = floor(L./hmin); % number of segments (N+1 is number of grid points)
86+
87+
%%%%% rest of error checking
88+
if any(N>10000)
89+
error('Too many grid points.')
90+
end
91+
92+
h = L./N; % adjusted grid spacing
93+
94+
lambda = c*k./h; % Courant number
95+
mu = K*k./h.^2; % numerical stiffness constant
96+
97+
%%%%% I/O
98+
99+
Nf = floor(SR*Tf); % number of time steps
100+
101+
li = floor(xi.*N); % grid index of excitation
102+
lo = floor(xo.*N); % grid index of output
103+
104+
Nstr = length(T); % number of strings
105+
106+
107+
%%%% Adjusting li and lo in case they are out of range and calculating
108+
%%%% indeces for I/O in the case of concatenated u
109+
110+
mli=zeros(1,Nstr); % Input for matrix form
111+
mlo=zeros(1,Nstr); % Output for matrix form
112+
113+
for s=1:Nstr
114+
if any([li(s),lo(s)]<2 | [li(s), lo(s)]>N(s))
115+
warning('Param:outRange',...
116+
['Excitation and/or output is outside the range of h to L-h.' ...
117+
'\n Forcing it to the range.'])
118+
end
119+
if li(s)<2
120+
li(s)=2;
121+
elseif li(s)>N(s)
122+
li(s)=N(s);
123+
end
124+
if lo(s)<2
125+
lo(s)=2;
126+
elseif lo(s)>N(s)
127+
lo(s)=N(s);
128+
end
129+
130+
% Adding the summed number of grid points of the previous strings and
131+
% subtracting s number of points, since the 1st point of each string is
132+
% missing
133+
mli(s)=li(s)+sum(N(1:s-1))-s;
134+
mlo(s)=lo(s)+sum(N(1:s-1))-s;
135+
end
136+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
137+
138+
% create force signal
139+
140+
f = zeros(Nf,Nstr); % input force signal
141+
durint = floor(dur*SR); % duration of force signal, in samples
142+
exc_st_int = floor(exc_st*SR)+1; % start time index for excitation
143+
144+
145+
% Computing forcing terms for each string
146+
for s=1:Nstr
147+
f(exc_st_int(s):exc_st_int(s)+durint(s)-1,s)=famp(s)*0.5.*...
148+
(1-cos(2/itype*pi*(0:durint(s)-1)/durint(s)));
149+
end
150+
151+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
152+
153+
%%%%% scheme coefficients
154+
out = zeros(Nf, 1); % output
155+
tic
156+
% loop over the strings
157+
AA=cell(1,Nstr);
158+
BB=cell(1,Nstr);
159+
CC=cell(1,Nstr);
160+
161+
% Finding matrices for each string
162+
for s=1:Nstr
163+
% interior
164+
I = speye(N(s) - 1);
165+
Dxx = fidimat(N(s)-1,'xx', 1);
166+
Dxxxx = fidimat(N(s)-1,'xxxx', 1);
167+
168+
a = 1/(1+sig(s)*k);
169+
BB{s} = a*(2*I + (lambda(s)^2*Dxx) + (-mu(s)^2) * Dxxxx);
170+
CC{s} = a*(-(1-sig(s)*k)*I);
171+
end
172+
173+
% Concatenating them into block diagonal matrices
174+
AA=blkdiag(AA{:});
175+
BB=blkdiag(BB{:});
176+
CC=blkdiag(CC{:});
177+
178+
179+
% input
180+
d0 = 1./(1+sig*k).*(k^2./(h.*rho.*A));
181+
182+
%%%%% initialise scheme variables
183+
184+
u2 = zeros(sum(N)-Nstr,1); % state
185+
u1 = u2; % state
186+
u = u2; % state
187+
188+
% plot
189+
if(plot_on==1)
190+
% draw current state
191+
fig=figure;
192+
for s=1:Nstr
193+
subplot(Nstr,1,s)
194+
pl(s)=plot((0:N(s)-2)'*h(s), u(1-s+1+sum(N(1:s-1)):sum(N(1:s))-s), 'k');
195+
axis([0 L(s)-h(s) -0.0005 0.0005])
196+
% set data source (to be later used for refreshing data)
197+
set(pl(s),'YDataSource',['u(' num2str(1-s+1+sum(N(1:s-1)))...
198+
':' num2str(sum(N(1:s))-s) ')'])
199+
ylabel(['String ' num2str(s)])
200+
end
201+
drawnow
202+
end
203+
204+
%%%%% main loop
205+
for n=1:Nf
206+
207+
u=(BB*u1+CC*u2);
208+
209+
% send in input
210+
u(mli) = u(mli)+(d0.*f(n,:))';
211+
212+
% read output
213+
if(outtype==1)
214+
out(n)= sum(u(mlo));
215+
end
216+
if(outtype==2)
217+
out(n) = sum((u(mlo)-u1(mlo))/k);
218+
end
219+
220+
% plot
221+
if(plot_on==1)
222+
refreshdata(fig)
223+
drawnow
224+
end
225+
226+
% shift state
227+
u2 = u1;
228+
u1 = u;
229+
230+
end
231+
232+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233+
234+
%%%% windowing the end
235+
nWin=floor(SR*window_dur);
236+
out(end-nWin:end)=0.5*(1+cos(pi*(0:nWin)/nWin))'.*out(end-nWin:end);
237+
238+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239+
240+
toc
241+
%%%%% play sound
242+
soundsc(out,SR);
243+
244+
%%%%% plot spectrum
245+
246+
figure(1)
247+
outfft = 10*log10(abs(fft(out)));
248+
plot((0:SR/Nf:SR*(1-1/Nf))', outfft, 'k')
249+
xlabel('Frequency (Hz)')
250+
ylabel('Magnitude')
251+
title('Frequency Spectrum of Output Signal')
252+
set(gca, 'FontSize', 12)
253+
xlim([0 SR/2])
254+

0 commit comments

Comments
 (0)