// *********************************************************************************************************************
// This delphi program creates an open tube with a side hole and calculates its input impedance with
// open, semiclosed and closed side hole.
//
// It assumes that knowledge about built-in models and their usage has been already obtained. This
// kind of information is shown in red colour. Library calls are shown in black.
//
// Note: Pointers and name strings can be interchanged freely.
// Parameter values can be expressions of other parameters.
// Common units are recognized
//
*********************************************************************************************************************
program SideHole();
var psim, pimp, parr,
pref, p0, p1, p2, p3: pointer;
pfrq, pcpx: ^double;
i, alen: integer;
begin
// Create Simulator
psim := SimCreate(‘MySimulator‘);
// Create the Models
SimCreateModel(psim,
‘MyFirstTube‘,‘CylindricalTube‘);
SimCreateModel(psim,
‘MyToneHole‘,‘SideHole‘);
// Save pointers to the tone hole termination models for later use.
p1 := SimCreateModel(psim, ‘MyOpenToneHole‘,‘RadiationImpedance‘);
p2 := SimCreateModel(psim,
‘MyClosedToneHole‘,‘PerfectReflection‘);
p3 := SimCreateModel(psim, ‘MySemiClosedToneHole‘,‘ComplexTermination‘);
SimCreateModel(psim,
‘MySecondTube‘,‘CylindricalTube‘);
SimCreateModel(psim,
‘MyOpenEnd‘,‘RadiationImpedance‘);
// Supply Model Parameters
SimSetParameter(psim,
‘MyFirstTube.Length=100mm‘);
SimSetParameter(psim,
‘MyFirstTube.Bore=12mm‘);
SimSetParameter(psim,
‘MyToneHole.Bore=[MyFirstTube.Bore]‘);
SimSetParameter(psim,
‘MyToneHole.HoleDiameter=8mm‘);
SimSetParameter(psim,
‘MyToneHole.WallThickness=3mm‘);
SimSetParameter(psim,
‘MyToneHole.HoleAngle=10mm‘);
SimSetParameter(psim,
‘MyOpenToneHole.Diameter=[MyToneHole.HoleDiameter]‘);
SimSetParameter(psim,
‘MyClosedToneHole.Diameter=[MyToneHole.HoleDiameter]‘);
SimSetParameter(psim,
‘MySemiClosedToneHole.Filename=data\ZTerm.txt‘);
SimSetParameter(psim,
‘MySecondTube.Length=100mm‘);
SimSetParameter(psim,
‘MySecondTube.Bore=[MyFirstTube.Bore]‘);
SimSetParameter(psim,
‘MyOpenEnd.Diameter=[MyFirstTube.Bore]‘);
// Arrange Model References to Create Acoustical Tree
parr := SimCreateArrangement(psim,
‘MyInstrument‘,‘FrequencyDomain‘);
SimAppendReference(psim, parr, ‘Ref1‘, ‘MyFirstTube‘);
// Save a pointer to the reference of the tone hole model for later use.
p0 := SimAppendReference(psim, parr, ‘Ref2‘,
‘MyToneHole‘);
SimAppendReference(psim, parr, ‘Ref3‘, ‘MySecondTube‘);
SimAppendReference(psim, parr, ‘Ref4‘, ‘MyOpenEnd‘);
// The SideHole ‘MyToneHole‘ at p0 is a branch with three terminals.
// It can be treated as the root of a side tree.
// We have pointers so we can do it more efficient.
// Let us save a pointer for changing models efficiently later on.
pref := SimAppendReference(psim, p0, ‘Ref2.1‘,
p1);
// Calculate Input Impedance
SimEvaluate;
// Get Pointer to Resulting Object
pimp := SimInputImpedance(psim, parr);
// Retrieve Impedance Information in Text Format
ptxt := SimGetInfo(pimp, nil);
while ptxt <>
nil do begin
writeln(ptxt);
ptxt := SimGetInfo(pimp,
ptxt);
end;
// Retrieve Frequency/Magnitude/Phase as Triples of Double
pfrq := SimGetDouble(pimp, nil, cFreq);
pcpx := SimGetComplex(pimp, nil, cMagArg+cDeg);
while pfrq <>
nil do begin
writeln(pfrq^, pcpx^, (pcpx+1)^);
pfrq := SimGetDouble(pimp,
pfrq, cFreq);
pcpx := SimGetComplex(pimp,
pcpx, cMagArg);
end;
// Close tone hole by changing the reference of the termination model
SimChangeReference(psim, pref, p2);
// Alternatively (replaces p1 by p2 in all references of list p0):
// SimReplaceReferences(psim, p0, p1, p2);
// Alternatively (much less efficient, replace in whole tree):
// SimReplaceReferences(psim,‘MyInstrument‘,‘MyOpenToneHole‘,‘MyClosedToneHole‘);
// Recalculate Input Impedance
// Note: memory is reused, previously obtained pointer pimp still valid!
SimEvaluate;
// Retrieve Frequency/Magnitude/Phase this time as Double and Complex Vector
alen := SimGetArrayLen(pimp);
pfrq := SimGetArray(pimp, cFreq);
pcpx := SimGetArray(pimp, cMagArg+cDeg);
for i := 0 to alen-1
do
writeln((pfrq+i)^, (pcpx+2*i)^,
(pcpx+2*i+1)^);
// Select semi-closed termination model
SimChangeReference(psim, pref, p3);
// Recalculate Input Impedance
// Note: all previously obtained pointers are still valid!
SimEvaluate;
// Retrieve Frequency/Magnitude/Phase once more as Double and Complex Vector
for i := 0 to alen-1
do
writeln((pfrq+i)^, (pcpx+2*i)^,
(pcpx+2*i+1)^);
SimDestroy(psim);
end.