Use the matrix multiplication method of Kalotas and Lee (K&L) to investigate the spectrum of nonuniform strings. In this version, each string has three segments: unwound, wound, and unwound. The first two sliders adjust the percent of the string that is of each type. These set the first unwound length and the wound length. The final segment is calculated so that the total length of the string remains constant.

addSynth[dur_,sr_,freqs_,amps_,decay_]:=Module[{},tVec=Range[0.,dur,1/sr];
env=Exp[-decay*tVec];
envRise=ConstantArray[1,Length[tVec]];
envRise[[1;;8000]]=Range[0,0.9999,1/8000];
env envRise Total[Table[amps[[i]] Sin[2 Pi freqs[[i]] tVec],{i,1,Length[freqs]}]]];ratio2cents[x_]:=(1200 Log[10,x])/Log[10,2];
cents2ratio[x_]:=10^((Log[10,2] x)/1200);
mat[ki_,wi_]:={{Cos[ki wi],-Sin[ki wi]/(ki)},{ki Sin[ki wi],Cos[ki wi]}};
k[www_,mu_,t_]:=www Sqrt[mu/t];
f[ww_,mu1_,mu2_,t_]:=(mat[k[ww,mu1,t],w1].mat[k[ww,mu2,t],w2].mat[k[ww,mu1,t],w3])[[1,2]];
findSpec100[lam_,lam2_,mu1_,mu2_]:=Module[{},w1=lam 0.9144;w2=lam2*0.9144;w3=(1-lam-lam2)*0.9144;
sol=FindRoot[f[w,mu1,mu2,15]==0,{w,Range[100,highF,10]}];
posSol=Select[sol[[1,2]],#>20&];
posSol100=100 posSol/posSol[[1]];
Select[Union[Round[100*posSol100/100.]],highF>#>0&]];
d[f1_,f2_]:=Exp[-3.5 Abs[f2-f1] s[Min[f1,f2]]]-Exp[-5.75 Abs[f2-f1] s[Min[f1,f2]]];
s[freq_]:=0.22/(0.021 freq+19);
dissAmp[spec1_,spec2_,amp1_,amp2_]:=Total[Table[Min[amp1[[i]],amp2[[j]]] d[spec1[[i]],spec2[[j]]],{i,1,Length[spec1]},{j,1,Length[spec2]}],2];
logSpace[a_,b_,n_]:=2.0^Range[a,b,(b-a)/(n-1)];
highF=2000;mu2=0.0275591;mu1=0.00721785;
Manipulate[If[lam+lam2≥1,lam=lam-0.1;lam2=lam2-0.1;];
If[lam<0,lam=0];If[lam2<0,lam2=0;];
amp=0.95^Range[numLines];spectrum=4 Take[findSpec100[lam,lam2,mu1,mu2],numLines];
alphas=cents2ratio[#]&/@Range[0,range,1]//N;
dissAll=Table[dissAmp[spectrum,alpha spectrum,amp,amp],{alpha,alphas}];
fig=ListLinePlot[Transpose[{ratio2cents[alphas],dissAll}],PlotRange->All,ImageSize->size*600,AxesLabel->{"cents","sensory dissonance"},Ticks->{Automatic,None}];
allMins=ratio2cents@alphas[[First@Transpose@FindPeaks[-dissAll]]];
label="spectrum: "<>ToString[N[spectrum/spectrum[[1]]]]<>"\nminima:"<>ToString[allMins]<>"\nstring: unwound "<>ToString[100 lam]<>"%, wound "<>ToString[100 lam2]<>"%, unwound "<>ToString[100 (1-lam-lam2)]<>"%";
Column[{EventHandler[fig,{"MouseClicked":>(ptClick=MousePosition["Graphics"];sndWav1=addSynth[1,44100, spectrum/2,RandomReal[{-1,1},numLines],2];sndWav2=addSynth[1,44100,cents2ratio[First@ptClick] spectrum/2,RandomReal[{-1,1},numLines],2];
EmitSound@SampledSoundList[sndWav1,44100];
EmitSound@SampledSoundList[sndWav2,44100];
EmitSound@SampledSoundList[sndWav1+sndWav2,44100];)}],Text[label]}],
Control[{{lam,0.24,"first segment unwound"},0,1,Appearance->"Labeled"}],Control[{{lam2,0.426,"second segment wound"},0,1,Appearance->"Labeled"}],Row[{Control[{{numLines,7,"number of spectral lines"},3,10,1,Appearance->"Labeled"}],Spacer[10],Control[{{size,1},{1/2,3/4,1,2,3,4}}],Spacer[10],Control[{{range,1500},{700,1200,1500,1800,2400,2700}}]}],FrameLabel->Dynamic[MousePosition["Graphics"]],SynchronousUpdating->False,SaveDefinitions->False]