1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
23 Available from http://www.3gpp.org
25 (C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
30 ------------------------------------------------------------------------------
35 Functions: code_2i40_9bits
41 ------------------------------------------------------------------------------
44 This file contains the functions that search a 9 bit algebraic codebook
45 containing 2 pulses in a frame of 40 samples.
47 ------------------------------------------------------------------------------
50 /*----------------------------------------------------------------------------
52 ----------------------------------------------------------------------------*/
62 /*--------------------------------------------------------------------------*/
68 /*----------------------------------------------------------------------------
70 ; Define module specific macros here
71 ----------------------------------------------------------------------------*/
73 /*----------------------------------------------------------------------------
75 ; Include all pre-processor statements here. Include conditional
76 ; compile variables also.
77 ----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------
81 ; LOCAL FUNCTION DEFINITIONS
82 ; Function Prototype declaration
83 ----------------------------------------------------------------------------*/
84 static void search_2i40(
85 Word16 subNr, /* i : subframe number */
86 Word16 dn[], /* i : correlation between target and h[] */
87 Word16 rr[][L_CODE],/* i : matrix of autocorrelation */
88 const Word16* startPos_ptr, /* i: ptr to read only table */
89 Word16 codvec[], /* o : algebraic codebook vector */
90 Flag * pOverflow /* o : Flag set when overflow occurs */
93 static Word16 build_code(
94 Word16 subNr, /* i : subframe number */
95 Word16 codvec[], /* i : algebraic codebook vector */
96 Word16 dn_sign[], /* i : sign of dn[] */
97 Word16 cod[], /* o : algebraic (fixed) codebook excitation */
98 Word16 h[], /* i : impulse response of weighted synthesis filter */
99 Word16 y[], /* o : filtered fixed codebook excitation */
100 Word16 sign[], /* o : sign of 2 pulses */
101 Flag * pOverflow /* o : Flag set when overflow occurs */
104 /*----------------------------------------------------------------------------
105 ; LOCAL VARIABLE DEFINITIONS
106 ; Variable declaration - defined here and used outside this module
107 ----------------------------------------------------------------------------*/
109 const Word16 trackTable[4*5] =
111 0, 1, 0, 1, -1, /* subframe 1; track to code;
112 * -1 do not code this position
114 0, -1, 1, 0, 1, /* subframe 2 */
115 0, 1, 0, -1, 1, /* subframe 3 */
120 /*----------------------------------------------------------------------------
121 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
122 ; Declare variables used in this module but defined elsewhere
123 ----------------------------------------------------------------------------*/
126 ------------------------------------------------------------------------------
127 FUNCTION NAME: code_2i40_9bits
128 ------------------------------------------------------------------------------
129 INPUT AND OUTPUT DEFINITIONS
132 subNr = subframe number (Word16)
133 x = target buffer (Word16)
134 h = buffer containing the impulse response of the
135 weighted synthesis filter; h[-L_subfr .. -1] must be
137 T0 = pitch lag (Word16)
138 pitch_sharp = last quantized pitch gain (Word16)
139 code = buffer containing the innovative codebook (Word16)
140 y = buffer containing the filtered fixed codebook excitation (Word16)
141 sign = pointer to the signs of 2 pulses (Word16)
144 code buffer contains the new innovation vector gains
147 index = code index (Word16)
149 Global Variables Used:
150 Overflow = overflow flag (Flag)
152 Local Variables Needed:
155 ------------------------------------------------------------------------------
158 This function searches a 9 bit algebraic codebook containing 2 pulses in a
161 The code length is 40, containing 2 nonzero pulses: i0...i1. All pulses can
162 have two possible amplitudes: +1 or -1. Pulse i0 can have 8 possible positions,
163 pulse i1 can have 8 positions. Also coded is which track pair should be used,
164 i.e. first or second pair. Where each pair contains 2 tracks.
167 first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
168 i1 : 2, 7, 12, 17, 22, 27, 32, 37.
169 second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
170 i1 : 3, 8, 13, 18, 23, 28, 33, 38.
173 first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
174 i1 : 3, 8, 13, 18, 23, 28, 33, 38.
175 second i0 : 2, 7, 12, 17, 22, 27, 32, 37.
176 i1 : 4, 9, 14, 19, 24, 29, 34, 39.
179 first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
180 i1 : 2, 7, 12, 17, 22, 27, 32, 37.
181 second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
182 i1 : 4, 9, 14, 19, 24, 29, 34, 39.
185 first i0 : 0, 5, 10, 15, 20, 25, 30, 35.
186 i1 : 3, 8, 13, 18, 23, 28, 33, 38.
187 second i0 : 1, 6, 11, 16, 21, 26, 31, 36.
188 i1 : 4, 9, 14, 19, 24, 29, 34, 39.
190 ------------------------------------------------------------------------------
195 ------------------------------------------------------------------------------
198 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
200 ------------------------------------------------------------------------------
203 Word16 code_2i40_9bits(
204 Word16 subNr, // i : subframe number
205 Word16 x[], // i : target vector
206 Word16 h[], // i : impulse response of weighted synthesis filter
207 // h[-L_subfr..-1] must be set to zero.
208 Word16 T0, // i : Pitch lag
209 Word16 pitch_sharp, // i : Last quantized pitch gain
210 Word16 code[], // o : Innovative codebook
211 Word16 y[], // o : filtered fixed codebook excitation
212 Word16 * sign // o : Signs of 2 pulses
215 Word16 codvec[NB_PULSE];
216 Word16 dn[L_CODE], dn2[L_CODE], dn_sign[L_CODE];
217 Word16 rr[L_CODE][L_CODE];
218 Word16 i, index, sharp;
220 sharp = shl(pitch_sharp, 1);
221 if (sub(T0, L_CODE) < 0)
222 for (i = T0; i < L_CODE; i++) {
223 h[i] = add(h[i], mult(h[i - T0], sharp));
225 cor_h_x(h, x, dn, 1);
226 set_sign(dn, dn_sign, dn2, 8); // dn2[] not used in this codebook search
227 cor_h(h, dn_sign, rr);
228 search_2i40(subNr, dn, rr, codvec);
229 index = build_code(subNr, codvec, dn_sign, code, h, y, sign);
231 *-----------------------------------------------------------------*
232 * Compute innovation vector gain. *
233 * Include fixed-gain pitch contribution into code[]. *
234 *-----------------------------------------------------------------*
236 if (sub(T0, L_CODE) < 0)
237 for (i = T0; i < L_CODE; i++) {
238 code[i] = add(code[i], mult(code[i - T0], sharp));
243 ------------------------------------------------------------------------------
245 [State any special notes, constraints or cautions for users of this function]
247 ------------------------------------------------------------------------------
250 Word16 code_2i40_9bits(
251 Word16 subNr, /* i : subframe number */
252 Word16 x[], /* i : target vector */
253 Word16 h[], /* i : impulse response of weighted synthesis */
254 /* filter h[-L_subfr..-1] must be set to 0. */
255 Word16 T0, /* i : Pitch lag */
256 Word16 pitch_sharp, /* i : Last quantized pitch gain */
257 Word16 code[], /* o : Innovative codebook */
258 Word16 y[], /* o : filtered fixed codebook excitation */
259 Word16 * sign, /* o : Signs of 2 pulses */
260 const Word16* startPos_ptr, /* ptr to read-only table */
261 Flag * pOverflow /* o : Flag set when overflow occurs */
264 Word16 codvec[NB_PULSE];
267 Word16 dn_sign[L_CODE];
268 Word16 rr[L_CODE][L_CODE];
277 L_temp = ((Word32) pitch_sharp) << 1;
279 /* Check for overflow condition */
280 if (L_temp != (Word32)((Word16) L_temp))
283 sharp = (pitch_sharp > 0) ? MAX_16 : MIN_16;
287 sharp = (Word16) L_temp;
292 for (i = T0; i < L_CODE; i++)
315 /* dn2[] not used in this codebook search */
348 /*-----------------------------------------------------------------*
349 * Compute innovation vector gain. *
350 * Include fixed-gain pitch contribution into code[]. *
351 *-----------------------------------------------------------------*/
355 for (i = T0; i < L_CODE; i++)
374 /****************************************************************************/
378 ------------------------------------------------------------------------------
379 FUNCTION NAME: search_2i40
380 ------------------------------------------------------------------------------
381 INPUT AND OUTPUT DEFINITIONS
384 subNr = subframe number (Word16)
385 dn = vector containing the correlation between target and the impulse
386 response of the weighted synthesis filter (Word16)
387 rr = autocorrelation matrix (Word16)
388 codvec = algebraic codebook vector (Word16)
391 codvec contains the newly calculated codevectors
396 Global Variables Used:
399 Local Variables Needed:
400 startPos = table containing the start positions used by fixed codebook
401 routines (const Word16)
403 ------------------------------------------------------------------------------
406 This function searches the best codevector and determines the positions of
407 the 2 pulses in the 40-sample frame.
409 ------------------------------------------------------------------------------
414 ------------------------------------------------------------------------------
417 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
419 ------------------------------------------------------------------------------
422 static void search_2i40(
423 Word16 subNr, // i : subframe number
424 Word16 dn[], // i : correlation between target and h[]
425 Word16 rr[][L_CODE], // i : matrix of autocorrelation
426 Word16 codvec[] // o : algebraic codebook vector
430 Word16 ix = 0; // initialization only needed to keep gcc silent
431 Word16 track1, ipos[NB_PULSE];
432 Word16 psk, ps0, ps1, sq, sq1;
433 Word16 alpk, alp, alp_16;
434 Word32 s, alp0, alp1;
439 for (i = 0; i < NB_PULSE; i++)
444 for (track1 = 0; track1 < 2; track1++) {
445 // fix starting position
447 ipos[0] = startPos[subNr*2+8*track1];
448 ipos[1] = startPos[subNr*2+1+8*track1];
451 *----------------------------------------------------------------*
452 * i0 loop: try 8 positions. *
453 *----------------------------------------------------------------*
455 for (i0 = ipos[0]; i0 < L_CODE; i0 += STEP) {
458 alp0 = L_mult(rr[i0][i0], _1_4);
460 *----------------------------------------------------------------*
461 * i1 loop: 8 positions. *
462 *----------------------------------------------------------------*
468 *-------------------------------------------------------------------*
469 * These index have low complexity address computation because *
470 * they are, in fact, pointers with fixed increment. For example, *
471 * "rr[i0][i2]" is a pointer initialized to "&rr[i0][ipos[2]]" *
472 * and incremented by "STEP". *
473 *-------------------------------------------------------------------*
475 for (i1 = ipos[1]; i1 < L_CODE; i1 += STEP) {
476 ps1 = add(ps0, dn[i1]); // idx increment = STEP
478 // alp1 = alp0 + rr[i0][i1] + 1/2*rr[i1][i1];
480 alp1 = L_mac(alp0, rr[i1][i1], _1_4); // idx incr = STEP
481 alp1 = L_mac(alp1, rr[i0][i1], _1_2); // idx incr = STEP
483 sq1 = mult(ps1, ps1);
485 alp_16 = pv_round(alp1);
487 s = L_msu(L_mult(alp, sq1), sq, alp_16);
496 *----------------------------------------------------------------*
497 * memorise codevector if this one is better than the last one. *
498 *----------------------------------------------------------------*
500 s = L_msu(L_mult(alpk, sq), psk, alp);
514 ------------------------------------------------------------------------------
516 [State any special notes, constraints or cautions for users of this function]
518 ------------------------------------------------------------------------------
521 static void search_2i40(
522 Word16 subNr, /* i : subframe number */
523 Word16 dn[], /* i : correlation between target and h[] */
524 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
525 const Word16* startPos_ptr, /* i: ptr to read only table */
526 Word16 codvec[], /* o : algebraic codebook vector */
527 Flag * pOverflow /* o : Flag set when overflow occurs */
532 Word16 ix = 0; /* initialization only needed to keep gcc silent */
533 register Word16 track1;
534 Word16 ipos[NB_PULSE];
548 Word16 *p_codvec = &codvec[0];
550 OSCL_UNUSED_ARG(pOverflow);
555 /* Unrolled the following FOR loop to save MIPS */
556 /* for (i = 0; i < NB_PULSE; i++) */
558 /* *(codvec + i) = i; */
564 for (track1 = 0; track1 < 2; track1++)
566 /* fix starting position */
568 i = (subNr << 1) + (track1 << 3);
569 *ipos = *(startPos_ptr + i);
570 *(ipos + 1) = *(startPos_ptr + i + 1);
573 /*----------------------------------------------------------*
574 * i0 loop: try 8 positions. *
575 *----------------------------------------------------------*/
577 for (i0 = *ipos; i0 < L_CODE; i0 += STEP)
581 /* Left shift by 1 converts integer product to */
582 /* fractional product. */
583 alp0 = (Word32) rr[i0][i0] << 14;
585 /*--------------------------------------------------*
586 * i1 loop: 8 positions. *
587 *--------------------------------------------------*/
593 /*--------------------------------------------------*
594 * These index have low complexity address *
595 * computation because they are, in fact, pointers *
596 * with fixed increment. For example, "rr[i0][i2]" *
597 * is a pointer initialized to "&rr[i0][ipos[2]]" *
598 * and incremented by "STEP". *
599 *---------------------------------------------------*/
601 for (i1 = *(ipos + 1); i1 < L_CODE; i1 += STEP)
603 /* idx increment = STEP */
604 /* ps1 = add(ps0, *(dn + i1), pOverflow); */
607 /* alp1 = alp0+rr[i0][i1]+1/2*rr[i1][i1]; */
609 /* idx incr = STEP */
610 /* Extra left shift by 1 converts integer */
611 /* product to fractional product */
612 /* alp1 = L_add(alp0, s, pOverflow); */
613 alp1 = alp0 + ((Word32) rr[i1][i1] << 14);
615 /* idx incr = STEP */
616 /* Extra left shift by 1 converts integer */
617 /* product to fractional product */
618 /* alp1 = L_add(alp1, s, pOverflow); */
619 alp1 += (Word32) rr[i0][i1] << 15;
621 /* sq1 = mult(ps1, ps1, pOverflow); */
622 sq1 = (Word16)(((Word32) ps1 * ps1) >> 15);
624 /* alp_16 = pv_round(alp1, pOverflow); */
625 alp_16 = (Word16)((alp1 + (Word32) 0x00008000L) >> 16);
627 /* L_temp = L_mult(alp, sq1, pOverflow); */
628 L_temp = ((Word32) alp * sq1) << 1;
630 /* s = L_msu(L_temp, sq, alp_16, pOverflow); */
631 s = L_temp - (((Word32) sq * alp_16) << 1);
641 /* memorize codevector if this one is better than the last one. */
643 /* L_temp = L_mult(alpk, sq, pOverflow); */
644 L_temp = ((Word32) alpk * sq) << 1;
646 /* s = L_msu(L_temp, psk, alp, pOverflow); */
647 s = L_temp - (((Word32) psk * alp) << 1);
653 p_codvec = &codvec[0];
663 /****************************************************************************/
666 ------------------------------------------------------------------------------
667 FUNCTION NAME: Test_search_2i40
668 ------------------------------------------------------------------------------
669 INPUT AND OUTPUT DEFINITIONS
672 subNr = subframe number (Word16)
673 dn = vector containing the correlation between target and the impulse
674 response of the weighted synthesis filter (Word16)
675 rr = autocorrelation matrix (Word16)
676 codvec = algebraic codebook vector (Word16)
679 codvec contains the newly calculated codevectors
684 Global Variables Used:
687 Local Variables Needed:
688 startPos = table containing the start positions used by fixed codebook
689 routines (const Word16)
691 ------------------------------------------------------------------------------
694 This function provides external access to the local function search_2i40.
696 ------------------------------------------------------------------------------
701 ------------------------------------------------------------------------------
704 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
706 ------------------------------------------------------------------------------
709 CALL search_2i40 ( subNr = subNr
716 ------------------------------------------------------------------------------
718 [State any special notes, constraints or cautions for users of this function]
720 ------------------------------------------------------------------------------
723 void Test_search_2i40(
724 Word16 subNr, /* i : subframe number */
725 Word16 dn[], /* i : correlation between target and h[] */
726 Word16 rr[][L_CODE], /* i : matrix of autocorrelation */
727 const Word16* startPos_ptr, /* i : ptr to read-only table */
728 Word16 codvec[], /* o : algebraic codebook vector */
729 Flag * pOverflow /* o : Flag set when overflow occurs */
732 /*----------------------------------------------------------------------------
733 CALL search_2i40 ( subNr = subNr
739 ----------------------------------------------------------------------------*/
751 /****************************************************************************/
754 ------------------------------------------------------------------------------
755 FUNCTION NAME: build_code
756 ------------------------------------------------------------------------------
757 INPUT AND OUTPUT DEFINITIONS
760 subNr = subframe number (Word16)
761 codvec = vector containing the position of pulses (Word16)
762 dn_sign = vector containing the sign of pulses (Word16)
763 cod = innovative code vector (Word16)
764 h = vector containing the impulse response of the weighted
765 synthesis filter (Word16)
766 y = vector containing the filtered innovative code (Word16)
767 sign = vector containing the sign of 2 pulses (Word16)
770 cod vector contains the new innovative code
771 y vector contains the new filtered innovative code
772 sign vector contains the sign of 2 pulses
775 indx = codebook index (Word16)
777 Global Variables Used:
780 Local Variables Needed:
781 trackTable = table used for tracking codewords (Word16)
783 ------------------------------------------------------------------------------
786 This function builds the codeword, the filtered codeword and index of the
787 codevector, based on the signs and positions of 2 pulses.
789 ------------------------------------------------------------------------------
794 ------------------------------------------------------------------------------
797 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
799 ------------------------------------------------------------------------------
802 static Word16 build_code(
803 Word16 subNr, // i : subframe number
804 Word16 codvec[], // i : position of pulses
805 Word16 dn_sign[], // i : sign of pulses
806 Word16 cod[], // o : innovative code vector
807 Word16 h[], // i : impulse response of weighted synthesis filter
808 Word16 y[], // o : filtered innovative code
809 Word16 sign[] // o : sign of 2 pulses
812 Word16 i, j, k, track, first, index, _sign[NB_PULSE], indx, rsign;
813 Word16 *p0, *p1, *pt;
815 static Word16 trackTable[4*5] = {
816 0, 1, 0, 1, -1, // subframe 1; track to code; -1 do not code this position
817 0, -1, 1, 0, 1, // subframe 2
818 0, 1, 0, -1, 1, // subframe 3
819 0, 1, -1, 0, 1};// subframe 4
821 pt = &trackTable[add(subNr, shl(subNr, 2))];
823 for (i = 0; i < L_CODE; i++) {
829 for (k = 0; k < NB_PULSE; k++) {
830 i = codvec[k]; // read pulse position
831 j = dn_sign[i]; // read sign
833 index = mult(i, 6554); // index = pos/5
835 track = sub(i, extract_l(L_shr(L_mult(index, 5), 1)));
844 index = shl(index, 3);
849 index = add(index, 64); // table bit is MSB
852 index = shl(index, 3);
859 rsign = add(rsign, shl(1, track));
862 _sign[k] = (Word16) - 32768L;
865 indx = add(indx, index);
872 for (i = 0; i < L_CODE; i++) {
874 s = L_mac(s, *p0++, _sign[0]);
875 s = L_mac(s, *p1++, _sign[1]);
882 ------------------------------------------------------------------------------
884 [State any special notes, constraints or cautions for users of this function]
886 ------------------------------------------------------------------------------
889 static Word16 build_code(
890 Word16 subNr, /* i : subframe number */
891 Word16 codvec[], /* i : position of pulses */
892 Word16 dn_sign[], /* i : sign of pulses */
893 Word16 cod[], /* o : innovative code vector */
894 Word16 h[], /* i : impulse response of weighted synthesis */
896 Word16 y[], /* o : filtered innovative code */
897 Word16 sign[], /* o : sign of 2 pulses */
898 Flag *pOverflow /* o : Flag set when overflow occurs */
904 register Word16 track;
905 register Word16 first;
906 register Word16 index;
907 register Word16 rsign;
909 Word16 _sign[NB_PULSE];
917 pt = trackTable + subNr + (subNr << 2);
919 for (i = 0; i < L_CODE; i++)
927 for (k = 0; k < NB_PULSE; k++)
929 i = *(codvec + k); /* read pulse position */
930 j = *(dn_sign + i); /* read sign */
932 s = ((Word32)(i * 6554)) >> 15;
933 index = (Word16) s; /* index = pos/5 */
935 track = i - (5 * index); /* track = pos%5 */
937 first = *(pt + track);
946 index += 64; /* table bit is MSB */
958 *(_sign + k) = 32767;
959 rsign += (1 << track);
963 *(cod + i) = ~(8192) + 1;
964 *(_sign + k) = (Word16)(~(32768) + 1);
973 p1 = h - *(codvec + 1);
975 for (i = 0; i < L_CODE; i++)
1000 /****************************************************************************/
1003 ------------------------------------------------------------------------------
1004 FUNCTION NAME: Test_build_code
1005 ------------------------------------------------------------------------------
1006 INPUT AND OUTPUT DEFINITIONS
1009 subNr = subframe number (Word16)
1010 codvec = vector containing the position of pulses (Word16)
1011 dn_sign = vector containing the sign of pulses (Word16)
1012 cod = innovative code vector (Word16)
1013 h = vector containing the impulse response of the weighted
1014 synthesis filter (Word16)
1015 y = vector containing the filtered innovative code (Word16)
1016 sign = vector containing the sign of 2 pulses (Word16)
1019 cod vector contains the new innovative code
1020 y vector contains the new filtered innovative code
1021 sign vector contains the sign of 2 pulses
1024 indx = codebook index (Word16)
1026 Global Variables Used:
1029 Local Variables Needed:
1030 trackTable = table used for tracking codewords (Word16)
1032 ------------------------------------------------------------------------------
1033 FUNCTION DESCRIPTION
1035 This function provides external access to the local function build_code.
1037 ------------------------------------------------------------------------------
1042 ------------------------------------------------------------------------------
1045 [1] c2_9pf.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001
1047 ------------------------------------------------------------------------------
1050 CALL build_code ( subNr = subNr
1060 ------------------------------------------------------------------------------
1062 [State any special notes, constraints or cautions for users of this function]
1064 ------------------------------------------------------------------------------
1067 Word16 Test_build_code(
1068 Word16 subNr, /* i : subframe number */
1069 Word16 codvec[], /* i : position of pulses */
1070 Word16 dn_sign[], /* i : sign of pulses */
1071 Word16 cod[], /* o : innovative code vector */
1072 Word16 h[], /* i : impulse response of weighted synthesis */
1074 Word16 y[], /* o : filtered innovative code */
1075 Word16 sign[], /* o : sign of 2 pulses */
1076 Flag * pOverflow /* o : Flag set when overflow occurs */
1081 /*----------------------------------------------------------------------------
1082 CALL build_code ( subNr = subNr
1091 ----------------------------------------------------------------------------*/