Main: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
argv: CommandTool.ArgumentVector;
intFrequency, intPower, intPhase, intAmplitude: INT;
frequency, phaseIncrement, phase, power, amplitude: REAL;
muValue: INTEGER;
sineTotal, squareTotal, amiTotal: INT;
sineSum, squareSum, amiSum: ARRAY [0..6) OF INT;
sqsineTotal, sqsquareTotal, sqamiTotal: INT;
sqsineSum, sqsquareSum, sqamiSum: ARRAY [0..6) OF INT;
sineGain, squareGain, amiDutyCycle: REAL;
argv ← CommandTool.Parse[cmd ! CommandTool.Failed => { msg ← errorMsg; CONTINUE; }];
IF argv = NIL THEN RETURN[$Failure, msg];
[] ← Random.Init[range: 0, seed: -1];
find frequency
IF argv.argc < 2
THEN {
out.PutRope["Usage LarkSilenceTest frequency\n"];
RETURN;
};
intFrequency ← Convert.IntFromRope[argv[1] ! Convert.Error => GOTO BadArgs];
frequency ← intFrequency;
phaseIncrement ← (frequency * TwoPi) / 8000.0;
out.PutF["Frequency %d\n", IO.int[intFrequency]];
out.PutRope["dBm square sine ami\n"];
FOR intPower
IN [-50..10]
DO
power ← intPower;
an amplitude of 1 will correspond to codec clipping level
Codec clipping level corresponds to a 3.16 dBm sine wave.
sineGain ← RealFns.Power[base: 10.0, exponent: (power - 3.16) / 20.0];
Codec clipping level corresponds to a 6.18 dBm square wave.
squareGain ← RealFns.Power[base: 10.0, exponent: (power - 6.18) / 20.0];
A 100% duty cycle AMI wave is 6.18 dBm
amiDutyCycle ← RealFns.Power[base: 10.0, exponent: (power - 6.18) / 10.0];
initialize phase
intPhase ← Random.Choose[min: 0, max: 359];
phase ← intPhase;
phase ← phase / TwoPi;
sineSum ← squareSum ← amiSum ← ALL[0];
sineTotal ← squareTotal ← amiTotal ← 0;
sqsineSum ← sqsquareSum ← sqamiSum ← ALL[0];
sqsineTotal ← sqsquareTotal ← sqamiTotal ← 0;
FOR trial:
NAT
IN [0..6)
DO
FOR i:
NAT
IN [0..160)
DO
phase ← phase + phaseIncrement;
WHILE phase < 0 DO phase ← phase + TwoPi; ENDLOOP;
WHILE phase >= TwoPi DO phase ← phase - TwoPi; ENDLOOP;
Sine wave
amplitude ← RealFns.Sin[radians: phase];
amplitude ← amplitude * sineGain * 32767.0;
IF amplitude > 32767.0 THEN amplitude ← 32767.0;
IF amplitude < -32767.0 THEN amplitude ← -32767.0;
intAmplitude ← Real.FixI[amplitude];
TRUSTED {
muValue ← U255.Encode[intAmplitude];
};
muValue ← Basics.BITAND[muValue, 177B]; -- mask off sign bit
sineSum[trial] ← sineSum[trial] + muValue;
sqsineSum[trial] ← sqsineSum[trial] + NewSilence[muValue];
Square wave
amplitude ← squareGain * 32767.0;
IF amplitude > 32767.0 THEN amplitude ← 32767.0;
IF amplitude < -32767.0 THEN amplitude ← -32767.0;
intAmplitude ← Real.FixI[amplitude];
TRUSTED {
muValue ← U255.Encode[intAmplitude];
};
muValue ← Basics.BITAND[muValue, 177B]; -- mask off sign bit
squareSum[trial] ← squareSum[trial] + muValue;
sqsquareSum[trial] ← sqsquareSum[trial] + NewSilence[muValue];
AMI wave
IF phase < (TwoPi * amiDutyCycle) THEN amplitude ← 32767.0
ELSE amplitude ← 0.0;
intAmplitude ← Real.FixI[amplitude];
TRUSTED {
muValue ← U255.Encode[intAmplitude];
};
muValue ← Basics.BITAND[muValue, 177B]; -- mask off sign bit
amiSum[trial] ← amiSum[trial] + muValue;
sqamiSum[trial] ← sqamiSum[trial] + NewSilence[muValue];
ENDLOOP;
sineTotal ← sineTotal + sineSum[trial];
squareTotal ← squareTotal + squareSum[trial];
amiTotal ← amiTotal + amiSum[trial];
sqsineTotal ← sqsineTotal + sqsineSum[trial];
sqsquareTotal ← sqsquareTotal + sqsquareSum[trial];
sqamiTotal ← sqamiTotal + sqamiSum[trial];
ENDLOOP;
sineTotal ← sineTotal / 6;
squareTotal ← squareTotal / 6;
amiTotal ← amiTotal / 6;
sqsineTotal ← sqsineTotal / 6;
sqsquareTotal ← sqsquareTotal / 6;
sqamiTotal ← sqamiTotal / 6;
out.PutF["%3d: %8d %8d %8d", IO.int[intPower], IO.int[squareTotal], IO.int[sineTotal], IO.int[amiTotal]];
out.PutF[" %8d %8d %8d\n", IO.int[sqsquareTotal], IO.int[sqsineTotal], IO.int[sqamiTotal]];
ENDLOOP;
EXITS
BadArgs => NULL;
};
}.