// *********************************************************************************************************************

// 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.