You are on page 1of 16

Appendix A

Matlab code examples


In this appendix, various simple code fragments are provided. All can be viewed as prototypes for physical modeling sound synthesis. The coding style reects something of a compromise between efciency, on the one hand, and brevity and intelligibility, on the other. The choice of Matlab as a programming environment denitely reects the latter sensibility, though the use of Matlab as an actual synthesis engine is not recommended. Some of these examples make use of constructs and features which need not appear in a code fragment intended for synthesis, including various calls to plotting functions, as well as the demonstration of energy conservation in some cases. It should be clear, in all cases, which elements of these examples may be neglected in an actual implementation. For the sake of brevity, these examples are too crude for actual synthesis purposes, but many features, discussed at various points in the texts and exercises, may be added.

A.1

The simple harmonic oscillator

% matlab script sho.m % finite difference scheme for simple harmonic oscillator %%%%%% begin global parameters SR f0 TF u0 v0 = = = = = 44100; 1000; 1.0; 0.3; 0.0; % % % % % sample rate (Hz) fundamental frequency (Hz) duration of simulation (s) initial displacement initial velocity

%%%%%% end global parameters % check that stability condition is satisfied if(SR<=pi*f0) error(Stability condition violated); end

Numerical Sound Synthesis: Finite Difference Schemes and Simulation in Musical Acoustics 2009 John Wiley & Sons, Ltd. ISBN: 978-0-470-51046-9

Stefan Bilbao

392

APPENDIX A

% derived parameters k = 1/SR; coef = 2-k^2*(2*pi*f0)^2; NF = floor(TF*SR); % initialize state of scheme u1 = u0+k*v0; u2 = u0; % initialize readout out = zeros(NF,1); out(1) = u2; out(2) = u1; %%%%%% start main loop for n=3:NF u=coef*u1-u2; out(n) = u; u2 = u1; u1 = u; end %%%%%% end main loop % play sound soundsc(out,SR); % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(SHO: Scheme Output); axis tight % last value of time series % one before last value of time series % time step % scheme update coefficient % duration of simulation (samples)

% difference scheme calculation % read value to output vector % update state of difference scheme

A.2

Hammer collision with massspring system

% matlab script hammermass.m % hammer collision with a mass-spring system %%%%%% begin global parameters SR = 44100; xH0 = -0.001; vH0 = 2; TF = 0.05; w0 = 2000; MR = 10; wH = 1000; alpha = 2; %%%%%% end global parameters % derived parameters k = 1/SR; NF = floor(TF*SR); % % % % % % % sample rate (Hz) initial conditions of hammer duration of simulation (s) angular frequency of mass-spring system hammer/target mass ratio stiffness parameter for hammer hammer stiffness nonlinearity exponent

APPENDIX A
% initialization uH2 = xH0; uH1 = xH0+k*vH0; % hammer u2 = 0; u1 = 0; % mass-spring system out = zeros(NF,1); f = zeros(NF,1); out(1) = u2; out(2) = u1; %%%%%% start main loop for n=3:NF if(uH1>u1) f(n-1) = wH^(1+alpha)*(uH1-u1)^alpha; else f(n-1) = 0; end uH = 2*uH1-uH2-k^2*f(n-1); u = 2*u1-u2-w0^2*k^2*u1+MR*k^2*f(n-1); out(n) = u; u2 = u1; u1 = u; uH2 = uH1; uH1 = uH; end %%%%%% end main loop % plots of displacement of target mass and force subplot(2,1,1) plot([0:NF-1]*k, out, k); title(Position of Target Mass); xlabel(t); axis tight subplot(2,1,2) plot([0:NF-1]*k, f, k); title(Hammer Force/Mass); xlabel(t); axis tight

393

A.3

Bowed massspring system

% matlab script bowmass.m % finite difference scheme for a bowed mass-spring system % soft friction characteristic w/iterative Newton-Raphson method %%%%%% begin global parameters SR = 44100; f0 = 200; FB = 500; TF = 0.1; vB = 0.2; sig = 100; tol = 1e-4; % % % % % % % sample rate (Hz) oscillator frequency (Hz) bow force/mass (m/s^2) simulation duration (s) bow velocity (m/s) friction law free parameter (1/m^2) tolerance for Newton-Raphson method

%%%%%% end global parameters % derived parameters NF = floor(TF*SR); k = 1/SR; A = exp(1/2)*sqrt(2*sig);

394

APPENDIX A

% initialize time series/iterative method u = zeros(NF,1); f = zeros(NF,1); vr = zeros(NF,1); qlast = 0; % time step restrictions if(k>min(1/(pi*f0),exp(1)/(FB*sqrt(2*sig)))) error(Time step too large); end %%%%%% start main loop for n=3:NF % Newton-Raphson method to determine relative velocity b = (2*pi*f0)^2*u(n-1)-(2/k^2)*(u(n-1)-u(n-2))+(2/k)*vB; eps = 1; while eps>tol q=qlast-(FB*A*qlast*exp(-sig*qlast^2)+2*qlast/k+b)/... (FB*A*(1-2*sig*qlast^2)*exp(-sig*qlast^2)+2/k); eps = abs(q-qlast); qlast = q; end % update position of mass and relative bow velocity u(n) = 2*k*(q+vB)+u(n-2); vr(n-1) = q; end %%%%%% end main loop % plot mass displacement and relative bow velocity tax = [0:NF-1]*k; subplot(2,1,1); plot(tax, u, k); title(Displacement of Mass); xlabel(time (s)); subplot(2,1,2); plot(tax, vr, k); title(Relative Bow Velocity); xlabel(time (s));

A.4
% % % %

The 1D wave equation: nite difference scheme

matlab script waveeq1dfd.m finite difference scheme for the 1D wave equation fixed boundary conditions raised cosine initial conditions

%%%%%% begin global parameters SR = 44100; f0 = 330; TF = 1; ctr = 0.7; wid = 0.1; u0 = 1; v0 = 0; rp = 0.3; lambda = 1; %%%%%% end global parameters % % % % % % % sample rate (Hz) fundamental frequency (Hz) duration of simulation (s) center location/width of excitation maximum initial displacement/velocity position of readout (0-1) Courant number

APPENDIX A
% begin derived parameters gamma = 2*f0; k = 1/SR; NF = floor(SR*TF); % wave equation free parameter % time step % duration of simulation (samples)

395

% stability condition/scheme parameters h = gamma*k/lambda; N = floor(1/h); h = 1/N; lambda = gamma*k/h; s0 = 2*(1-lambda^2); s1 = lambda^2; % readout interpolation parameters rp_int = 1+floor(N*rp); rp_frac = 1+rp/h-rp_int; % create raised cosine xax = [0:N]*h; ind = sign(max(-(xax-ctr-wid/2).*(xax-ctr+wid/2),0)); rc = 0.5*ind.*(1+cos(2*pi*(xax-ctr)/wid)); % initialize grid functions and output u2 = u0*rc; u1 = (u0+k*v0)*rc; u = zeros(N+1,1); out = zeros(NF,1); %%%%%% start main loop for n=3:NF u(2:N) = -u2(2:N)+s0*u1(2:N)+s1*(u1(1:N-1)+u1(3:N+1)); % scheme calculation out(n) = (1-rp_frac)*u(rp_int)+rp_frac*u(rp_int+1); % readout u2 = u1; u1 = u; % update of grid variables end %%%%%% end main loop % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(1D Wave Equation: FD Output); axis tight % play sound soundsc(out,SR); % rounded grid index for readout % fractional part of readout location

A.5
% % % %

The 1D wave equation: digital waveguide synthesis

matlab script waveeq1ddw.m digital waveguide method for the 1D wave equation fixed boundary conditions raised cosine initial conditions

%%%%%% begin global parameters SR = 44100; f0 = 441; % sample rate (Hz) % fundamental frequency (Hz)

396

APPENDIX A
% % % % duration of simulation (s) center location/width of excitation maximum initial displacement/velocity position of readout (0-1)

TF = 1; ctr = 0.7; wid = 0.1; u0 = 1; v0 = 0; rp = 0.3; %%%%%% end global parameters % begin derived parameters k = 1/SR; NF = floor(SR*TF); N = floor(0.5*SR/f0); rp_int = 1+floor(N*rp); rp_frac = 1+rp*N-rp_int;

% % % % %

time step duration of simulation (samples) length of delay lines rounded grid index for readout fractional part of readout location

% initialize delay lines and output wleft = zeros(N,1); wright = zeros(N,1); out = zeros(NF,1); % create raised cosine and integral xax = ([1:N]-1/2)/N; ind = sign(max(-(xax-ctr-wid/2).*(xax-ctr+wid/2),0)); rc = 0.5*ind.*(1+cos(2*pi*(xax-ctr)/wid)); rcint = zeros(N,1); for qq=2:N rcint(qq) = rcint(qq-1)+rc(qq)/N; end % set initial conditions wleft = 0.5*(u0*rc+v0*rcint/(2*f0)); wright = 0.5*(u0*rc-v0*rcint/(2*f0)); %%%%%% start main loop for n=3:NF temp1 = wright(N); temp2 = wleft(1); wright(2:N) = wright(1:N-1); wleft(1:N-1) = wleft(2:N); wright(1) = -temp2; wleft(N) = -temp1; % readout out(n) = (1-rp_frac)*(wleft(rp_int)+wright(rp_int))... +rp_frac*(wleft(rp_int+1)+wright(rp_int+1)); end %%%%%% end main loop % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(1D Wave Equation: Digital Waveguide Synthesis Output); axis tight % play sound soundsc(out,SR);

APPENDIX A

397

A.6
% % % %

The 1D wave equation: modal synthesis

matlab script waveeq1dmod.m modal synthesis method for the 1D wave equation fixed boundary conditions raised cosine initial conditions

%%%%%% begin global parameters SR = 44100; f0 = 441; TF = 1; ctr = 0.7; wid = 0.1; u0 = 1; v0 = 0; rp = 0.3; %%%%%% end global parameters % begin derived parameters/temporary storage k = 1/SR; NF = floor(SR*TF); N = floor(0.5*SR/f0); temp = 2*pi*[1:N]*f0/SR; coeff = % time step % duration of simulation (samples) % number of modes 2*cos(temp); outexp = sin([1:N]*pi*rp); % % % % % % sample rate (Hz) fundamental frequency (Hz) duration of simulation (s) center location/width of excitation maximum initial displacement/velocity position of readout (0-1)

% initialize grid functions and output U = zeros(N,1); U1 = zeros(N,1); U2 = zeros(N,1); out2 = zeros(NF,1); % create raised cosine and find Fourier coefficients xax = [0:N-1]/N; ind = sign(max(-(xax-ctr-wid/2).*(xax-ctr+wid/2),0)); rc = 0.5*ind.*(1+cos(2*pi*(xax-ctr)/wid)); rcfs = -imag(fft([rc; zeros(N,1)])); rcfs = 2*rcfs(2:N+1)/N; % set initial conditions U2(1:N) = u0*rcfs; U1(1:N) = (u0*cos(temp)+v0*sin(temp)./(2*pi*[1:N]*f0)).*rcfs; %%%%%% start main loop for n=3:NF U = -U2+coeff.*U1; out(n) = outexp*U; U2 = U1; U1 = U; end %%%%%% end main loop % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(1D Wave Equation: Modal Synthesis Output); axis tight

% scheme calculation % readout % update of modal weights

398

APPENDIX A

% play sound soundsc(out,SR);

A.7
% % % %

The ideal bar

matlab script idealbarfd.m finite difference scheme for the ideal bar equation clamped/pivoting boundary conditions raised cosine initial conditions

%%%%%% begin global parameters SR = 44100; K = 10; TF = 1; ctr = 0.7; wid = 0.1; u0 = 1; v0 = 0; mu = 0.5; rp = 0.85; bc = [2 2]; sample rate (Hz) stiffness parameter duration of simulation (s) center location/width of excitation maximum initial displacement/velocity scheme free parameter position of readout (0-1) boundary condition type, [left right] with % 1: clamped, 2: pivoting % % % % % % % %

%%%%%% end global parameters % begin derived parameters k = 1/SR; NF = floor(SR*TF); % time step % duration of simulation (samples)

% stability condition/scheme parameters h = sqrt(K*k/mu); N = floor(1/h); h = 1/N; mu = K*k/h^2; s0 = 2*(1-3*mu^2); s1 = 4*mu^2; s2 = -mu^2; % readout interpolation parameters rp_int = 1+floor(N*rp); rp_frac = 1+rp/h-rp_int; % create raised cosine xax = [0:N]*h; ind = sign(max(-(xax-ctr-wid/2).*(xax-ctr+wid/2),0)); rc = 0.5*ind.*(1+cos(2*pi*(xax-ctr)/wid)); % initialize grid functions and output u2 = u0*rc; u1 = (u0+k*v0)*rc; u = zeros(N+1,1); out = zeros(NF,1); %%%%%% start main loop for n=3:NF % scheme calculation (interior) u(3:N-1) = -u2(3:N-1)+s0*u1(3:N-1)+s1*(u1(2:N-2)+u1(4:N))... % rounded grid index for readout % fractional part of readout location

APPENDIX A
+s2*(u1(1:N-3)+u1(5:N+1)); % calculations at boundary points if(bc(1)==2) u(2) = -u2(2)+(s0-s2)*u1(2)+s1*u1(3)+s2*u1(4); end if(bc(2)==2) u(N) = -u2(N)+(s0-s2)*u1(N)+s1*u1(N-1)+s2*u1(N-2); end out(n) = (1-rp_frac)*u(rp_int)+rp_frac*u(rp_int+1); u2 = u1; u1 = u; end %%%%% end main loop % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(Ideal Bar Equation: FD Output); axis tight % play sound soundsc(out,SR);

399

% readout % update

A.8
% % % % % % %

The stiff string

matlab script ssfd.m finite difference scheme for the stiff string clamped boundary conditions raised cosine initial conditions stereo output implicit scheme: matrix update form two-parameter frequency-dependent loss

%%%%%% begin global parameters SR = 44100; B = 0.001; f0 = 100; TF = 2; ctr = 0.1; wid = 0.05; u0 = 1; v0 = 0; rp = [0.3 0.7]; loss = [100, 10; 1000, 8]; theta = 1.0; %%%%%% end global parameters % begin derived parameters k = 1/SR; % time step NF = floor(SR*TF); % duration of simulation (samples) gamma = 2*f0; K = sqrt(B)*(gamma/pi); % set parameters % stability conditions % % % % % % % % % sample rate(Hz) inharmonicity parameter (>0) fundamental(Hz) duration of simulation(s) center location/width of excitation maximum initial displacement/velocity positions of readout(0-1) loss [freq.(Hz), T60(s), freq.(Hz), T60(s)] implicit scheme free parameter (>0.5)

400

APPENDIX A

h = sqrt((gamma^2*k^2+sqrt(gamma^4*k^4+16*K^2*k^2*(2*theta-1)))/ (2*(2*theta-1))); N = floor(1/h); h = 1/N; mu = K*k/h^2; lambda = gamma*k/h; % readout interpolation parameters rp_int = 1+floor(N*rp); rp_frac = 1+rp/h-rp_int; % set scheme loss parameters zeta1 = (-gamma^2+sqrt(gamma^4+4*K^2*(2*pi*loss(1,1))^2))/(2*K^2); zeta2 = (-gamma^2+sqrt(gamma^4+4*K^2*(2*pi*loss(2,1))^2))/(2*K^2); sig0 = 6*log(10)*(-zeta2/loss(1,2)+zeta1/loss(2,2))/(zeta1-zeta2); sig1 = 6*log(10)*(1/loss(1,2)-1/loss(2,2))/(zeta1-zeta2); % create update matrices M A C B = = = = sparse(toeplitz([theta (1-theta)/2 zeros(1,N-3)])); M+sparse(toeplitz([sig1*k/(h^2)+sig0*k/2 -sig1*k/(2*h^2) zeros(1,N-3)])); M+sparse(toeplitz([-sig1*k/(h^2)-sig0*k/2 sig1*k/(2*h^2) zeros(1,N-3)])); 2*M+sparse(toeplitz([-2*lambda^2-6*mu^2 lambda^2+4*mu^2 -mu^2... zeros(1,N-4)])); % rounded grid index for readout % fractional part of readout location

% create raised cosine xax = [1:N-1]*h; ind = sign(max(-(xax-ctr-wid/2).*(xax-ctr+wid/2),0)); rc = 0.5*ind.*(1+cos(2*pi*(xax-ctr)/wid)); % set initial conditions u2 = u0*rc; u1 = (u0+k*v0)*rc; u = zeros(N+1,1); out = zeros(NF,2); %%%%%% start main loop for n=3:NF u = A\(B*u1-C*u2); out(n,:) = (1-rp_frac).*u(rp_int)+rp_frac.*u(rp_int+1); % readout u2 = u1; u1 = u; % update end %%%%%% end main loop % plot output waveform subplot(2,1,1); plot([0:NF-1]*k, out(:,1), k); xlabel(t); ylabel(u); title(Stiff String Equation: FD Output (left)); subplot(2,1,2); plot([0:NF-1]*k, out(:,2), k); xlabel(t); ylabel(u); title(Stiff String Equation: FD Output (right)); axis tight % play sound soundsc(out,SR);

APPENDIX A

401

A.9
% % % %

The KirchhoffCarrier equation

matlab script kcfd.m finite difference scheme for the Kirchhoff-Carrier equation fixed boundary conditions triangular initial conditions

%%%%%% begin global parameters SR = 44100; f0 = 200; alpha = 10; TF = 0.03; ctr = 0.5; u0 = 0.05; rp = 0.5; lambda = 0.7; %%%%%% end global parameters % begin derived parameters gamma = 2*f0; k = 1/SR; NF = floor(SR*TF); % stability condition h = gamma*k/lambda; N = floor(1/h); h = 1/N; lambda = gamma*k/h; % readout interpolation parameters rp_int = 1+floor(N*rp); rp_frac = 1+rp/h-rp_int; % create triangular function xax = [0:N]*h; tri = min(xax/ctr-1,0)+1+min((1-xax)/(1-ctr)-1,0); % initialize grid functions and output u2 = u0*tri; u1 = u2; u = zeros(N+1,1); out = zeros(NF,1); %%%%%% start main loop for n=1:NF % calculate nonlinearity g u1x = (u1(2:N+1)-u1(1:N))/h; u1xx = (u1x(2:N)-u1x(1:N-1))/h; g = (1+0.5*alpha^2*h*sum(u1x.*u1x))/... (1+0.25*alpha^2*k^2*gamma^2*h*sum(u1xx.*u1xx)); % scheme update u(2:N) = 2*u1(2:N)-u2(2:N)+g*gamma^2*k^2*u1xx(1:N-1); % calculation out(n) = (1-rp_frac)*u(rp_int)+rp_frac*u(rp_int+1); % readout % rounded grid index for readout % fractional part of readout location % wave equation free parameter % time step % duration of simulation (samples) % % % % % sample rate (Hz) fundamental frequency (Hz) nonlinear string parameter duration of simulation (s) center location of excitation (0-1) % maximum initial displacement % position of readout (0-1) % Courant number

402

APPENDIX A
% update

u2 = u1; u1 = u; end %%%%% end main loop % plot output waveform

plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(Kirchhoff-Carrier Equation: FD Output); axis tight

A.10
% % % % %

Vocal synthesis

matlab script vocalfd.m finite difference vocal tract simulation radiation loss included simple glottal source waveform static pitch

%%%%%% begin global parameters SR = 44100; % sample rate (Hz) L = 0.17; % tract length (m) S0 = 0.00025; % vocal tract surface area, left end (m^2) c = 340; % wave speed (m/s) f0 = 120; % fundamental frequency (Hz) TF = 1; % simulation duration (s) % vocal tract profile, non-dimensional [pos S] pairs % /E/ S = [0 1;0.09 0.4;0.11 2.4;0.24 2.4;0.26 3.2;0.29 3.2;0.32 4.2;... 0.41 4.2;0.47 3.2;0.59 1.8;0.65 1.6;0.71 1.6;0.74 1;0.76 0.8;... 0.82 0.8;0.88 2;0.91 2;0.94 3.2;1 3.2]; % /A/ % S = [0 1;0.03 0.60;0.09 0.4;0.12 1.6;0.18 0.6;0.29 0.2;0.35 0.4;... % 0.41 0.8;0.47 1;0.50 0.6;0.59 2;0.65 3.2;0.85 3.2;0.94 2;1 2]; %%%%% end global parameters % begin derived parameters k = 1/SR; NF = floor(TF*SR); gamma = c/L; % stability condition/scheme parameters h = gamma*k; N = floor(1/h); h = 1/N; lambda = gamma*k/h; S = interp1(S(:,1),S(:,2),[0:h:1]); % interpolate vocal tract profile alf = 2.0881*L*sqrt(1/(S0*S(N+1))); % radiation parameter bet = 0.7407/gamma; % radiation parameter Sav = [S(1); 0.25*(S(3:N+1)+2*S(2:N)+S(1:N-1)); S(N+1)]; Sr = 1.5*S(N+1)-0.5*S(N); sr = 0.5*lambda^2*((S(2:N)+S(3:N+1))./Sav(2:N)); sl = 0.5*lambda^2*((S(2:N)+S(1:N-1))./Sav(2:N)); s0 = 2*(1-lambda^2); % time step % sample duration

APPENDIX A
q1 = alf*gamma^2*k^2*Sr/(Sav(N+1)*h); q2 = bet*gamma^2*k*Sr/(Sav(N+1)*h); r1 = 2*lambda^2/(1+q1+q2); r2 = -(1+q1-q2)/(1+q1+q2); g1 = -(k^2*gamma^2/h/S(1))*(3*S(1)-S(2)); % initialize grid functions and output, generate glottal waveform Psi = zeros(N+1,1); Psi1 = zeros(N+1,1); Psi2 = zeros(N+1,1); uin = sin(2*pi*[0:NF-1]*k*f0); uin = 0.5*(uin+abs(uin)); out = zeros(NF,1); %%%%%% begin main loop for n=1:NF; Psi(2:N) = s0*Psi1(2:N)+sl.*Psi1(1:N-1)+sr.*Psi1(3:N+1)-Psi2(2:N); Psi(N+1) = r1*Psi1(N)+r2*Psi2(N+1); Psi(1) = s0*Psi1(1)+2*lambda^2*Psi1(2)-Psi2(1)+g1*uin(n); out(n) = SR*(Psi(N+1)-Psi1(N+1)); Psi2 = Psi1; Psi1 = Psi; end %%%%%% end main loop % plot vocal tract profile and output spectrum subplot(2,1,1); plot([0:h:1], sqrt(S),k, [0:h:1], -sqrt(S),k) title(Vocal Tract Profile); xlabel(x); ylabel(sqrt(S)); subplot(2,1,2); plot([0:NF-1]*SR/NF, 10*log10(abs(fft(out))), k); title(Output Spectrum); xlabel(f);ylabel(pressure (dB)); % play sound soundsc(out, SR);

403

A.11
% % % % %

The 2D wave equation

matlab script waveeq2dloss.m finite difference scheme for the 2D wave equation with loss fixed boundary conditions raised cosine initial conditions bilinear interpolation

%%%%%% begin global parameters SR = 16000; gamma = 200 T60 = 8; epsilon = 1.3; TF = 2; ctr = [0.3 0.5]; wid = 0.15; u0 = 0; v0 = 1; rp = [0.5 0.6]; lambda = 1/sqrt(2); %%%%%% end global parameters % % % % % % % % % sample rate(Hz) wave speed (1/s) 60 dB decay time (s) domain aspect ratio duration of simulation(s) center location/width of excitation maximum initial displacement/velocity position of readout([0-1,0-1]) Courant number

404

APPENDIX A

% begin derived parameters k = 1/SR; NF = floor(SR*TF); sig0 = 6*log(10)/T60; % stability condition/scheme parameters h = gamma*k/lambda; Nx = floor(sqrt(epsilon)/h); % find grid spacing % number of x-subdivisions of spatial domain Ny = floor(1/(sqrt(epsilon)*h)); % number of y-subdivisions of spatial domain h = sqrt(epsilon)/Nx; lambda = gamma*k/h; % reset Courant number s0 = (2-4*lambda^2)/(1+sig0*k); s1 = lambda^2/(1+sig0*k); t0 = -(1-sig0*k)/(1+sig0*k); % readout interpolation parameters rp_int = 1+floor([Nx Ny].*rp); rp_frac = 1+rp/h-rp_int; % create 2D raised cosine [X, Y] = meshgrid([0:Nx]*h, [0:Ny]*h); dist = sqrt((X-ctr(1)).^2 +(Y-ctr(2)).^2); ind = sign(max(-dist+wid/2,0)); rc = 0.5*ind.*(1+cos(2*pi*dist/wid)); % set initial conditions u2 = u0*rc; u1 = (u0+k*v0)*rc; u = zeros(Nx+1,Ny+1); out = zeros(NF,2); %%%%%% start main loop for n=3:NF u(2:Nx,2:Ny) = s1*(u1(3:Nx+1,2:Ny)+u1(1:Nx-1,2:Ny)+u1(2:Nx,3:Ny+1)+... u1(2:Nx,1:Ny-1))+s0*u1(2:Nx,2:Ny)+t0*u2(2:Nx,2:Ny); out(n,:) = (1-rp_frac(1))*(1-rp_frac(2))*u(rp_int(1),rp_int(2))+... (1-rp_frac(1))*rp_frac(2)*u(rp_int(1),rp_int(2)+1)+... rp_frac(1)*(1-rp_frac(2))*u(rp_int(1)+1,rp_int(2))+... rp_frac(1)*rp_frac(2)*u(rp_int(1)+1,rp_int(2)+1); u2 = u1; u1 = u; end %%%%% end main loop % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(2D Wave Equation with Loss: FD Output); axis tight % play sound soundsc(out,SR); % time step % duration of simulation (samples) % loss parameter

APPENDIX A

405

A.12
% % % % % %

Thin plate

matlab script plateloss.m finite difference scheme for the thin plate equation with loss simply supported boundary conditions raised cosine initial conditions vector/matrix update form zeroth-order interpolation

%%%%%% begin global parameters SR = 44100; K = 20; T60 = 8; epsilon = 1.2; TF = 2; ctr = [0.8 0.9]; wid = 0.3; u0 = 0; v0 = 1; rp = [0.05 0.7]; mu = 0.25; %%%%%% end global parameters % begin derived parameters k = 1/SR; NF = floor(SR*TF); sig0 = 6*log(10)/T60; % time step % duration of simulation (samples) % loss parameter % % % % % % % % % sample rate(Hz) plate stiffness parameter (1/s) 60 dB decay time (s) domain aspect ratio duration of simulation(s) center location/width of excitation maximum initial displacement/velocity position of readout([0-1,0-1]) scheme free parameter

% stability condition/scheme parameters h = sqrt(K*k/mu); Nx = floor(sqrt(epsilon)/h); Ny = floor(1/(sqrt(epsilon)*h)); h = sqrt(epsilon)/Nx; ss = (Nx-1)*(Ny-1); % find grid spacing % number of x-subdivisions of spatial domain % number of y-subdivisions of spatial domain % total grid size

% generate difference matrix/scheme matrices Dxx Dyy D = B = C = = sparse(toeplitz([-2/h^2;1/h^2;zeros(Nx-3,1)])); = sparse(toeplitz([-2/h^2;1/h^2;zeros(Ny-3,1)])); kron(eye(Nx-1), Dyy)+kron(Dxx, eye(Ny-1)); DD = D*D; sparse((2*eye(ss)-K^2*k^2*DD)/(1+sig0*k)); ((1-sig0*k)/(1+sig0*k))*sparse(eye(ss));

% readout interpolation parameters rp_index = (Ny-1)*floor(rp(1)*Nx)+floor(rp(2)*Ny); % create 2D raised cosine [X, Y] = meshgrid([1:Nx-1]*h, [1:Ny-1]*h); dist = sqrt((X-ctr(1)*sqrt(epsilon)).^2+(Y-ctr(2)/sqrt(epsilon)).^2); ind = sign(max(-dist+wid/2,0)); rc = 0.5*ind.*(1+cos(2*pi*dist/wid)); rc = reshape(rc, ss,1);

406

APPENDIX A

% set initial conditions/initialize output u2 = u0*rc; u1 = (u0+k*v0)*rc; u = zeros(ss,1);out = zeros(NF,1); %%%%%% start main loop for n=3:NF u = B*u1-C*u2; u2 = u1; u1 = u; out(n) = u(rp_index); end %%%%%% end main loop % plot output waveform plot([0:NF-1]*k, out, k); xlabel(t); ylabel(u); title(Thin Plate Equation with Loss: FD Output); axis tight % play sound soundsc(out,SR);

You might also like