1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 /**************************************************************************************** 19 Portions of this file are derived from the following 3GPP standard: 20 21 3GPP TS 26.073 22 ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec 23 Available from http://www.3gpp.org 24 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 ****************************************************************************************/ 29 /* 30 Pathname: ./audio/gsm-amr/c/src/q_plsf_5.c 31 Funtions: 32 33 ------------------------------------------------------------------------------ 34 REVISION HISTORY 35 36 Description: Placed code in the PV standard template format. 37 Updated to accept new parameter, Flag *pOverflow. 38 39 Description: 40 Eliminated unused include files. 41 For Vq_subvec() 42 1. Eliminated math operations that unnecessary checked for 43 saturation (number are bounded to 2^12) 44 2. Eliminated access to (slow) memory by using axiliar variables 45 3. Because this routine is looking for the minimum distance, 46 introduced 3 check conditions inside the loop, so when the 47 partial distance is bigger than the minimun distance, the 48 loop is not completed and process continue with next iteration 49 For Vq_subvec_s() 50 1. Eliminated math operations that unnecessary checked for 51 saturation (number are bounded to 2^12) 52 2. Combined increasing and decreasing loops to avoid double 53 accesses to the same table element 54 3. Eliminated access to (slow) memory by using axiliar variables 55 4. Because this routine is looking for the minimum distance, 56 introduced 2 check conditions inside the loop, so when the 57 partial distance is bigger than the minimun distance, the 58 loop is not completed and process continue with next iteration 59 For Q_plsf_5() 60 1. Eliminated math operations that unnecessary checked for 61 saturation (number are bounded to 2^12) 62 2. Replaced array addressing by pointers 63 64 Description: Replaced OSCL mem type functions and eliminated include 65 files that now are chosen by OSCL definitions 66 67 Description: Replaced "int" and/or "char" with OSCL defined types. 68 69 70 Description: Added #ifdef __cplusplus around extern'ed table. 71 72 Who: Date: 73 Description: 74 75 ------------------------------------------------------------------------------ 76 MODULE DESCRIPTION 77 78 79 ------------------------------------------------------------------------------ 80 */ 81 82 /*---------------------------------------------------------------------------- 83 ; INCLUDES 84 ----------------------------------------------------------------------------*/ 85 #include "q_plsf.h" 86 #include "typedef.h" 87 #include "basic_op.h" 88 #include "lsp_lsf.h" 89 #include "reorder.h" 90 #include "lsfwt.h" 91 92 /*--------------------------------------------------------------------------*/ 93 #ifdef __cplusplus 94 extern "C" 95 { 96 #endif 97 98 /*---------------------------------------------------------------------------- 99 ; MACROS 100 ; Define module specific macros here 101 ----------------------------------------------------------------------------*/ 102 103 /*---------------------------------------------------------------------------- 104 ; DEFINES 105 ; Include all pre-processor statements here. Include conditional 106 ; compile variables also. 107 ----------------------------------------------------------------------------*/ 108 109 /*---------------------------------------------------------------------------- 110 ; LOCAL FUNCTION DEFINITIONS 111 ; Function Prototype declaration 112 ----------------------------------------------------------------------------*/ 113 114 /*---------------------------------------------------------------------------- 115 ; LOCAL VARIABLE DEFINITIONS 116 ; Variable declaration - defined here and used outside this module 117 ----------------------------------------------------------------------------*/ 118 119 /*---------------------------------------------------------------------------- 120 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES 121 ; Declare variables used in this module but defined elsewhere 122 ----------------------------------------------------------------------------*/ 123 /* Codebooks of LSF prediction residual */ 124 extern const Word16 mean_lsf_5[]; 125 126 extern const Word16 dico1_lsf_5[]; 127 extern const Word16 dico2_lsf_5[]; 128 extern const Word16 dico3_lsf_5[]; 129 extern const Word16 dico4_lsf_5[]; 130 extern const Word16 dico5_lsf_5[]; 131 132 /*--------------------------------------------------------------------------*/ 133 #ifdef __cplusplus 134 } 135 #endif 136 137 /* 138 ------------------------------------------------------------------------------ 139 FUNCTION NAME: Vq_subvec 140 ------------------------------------------------------------------------------ 141 INPUT AND OUTPUT DEFINITIONS 142 143 Inputs: 144 lsf_r1 -- array of type Word16 -- 1st LSF residual vector, Q15 145 lsf_r2 -- array of type Word16 -- 2nd LSF residual vector, Q15 146 dico -- pointer to const Word16 -- quantization codebook, Q15 147 wf1 -- array of type Word16 -- 1st LSF weighting factors, Q13 148 wf2 -- array of type Word16 -- 2nd LSF weighting factors, Q13 149 dico_size -- Word16 -- size of quantization codebook, Q0 150 Outputs: 151 pOverflow -- pointer to type Flag -- overflow indicator 152 153 Returns: 154 Word16 -- quantization index, Q0 155 156 Global Variables Used: 157 None 158 159 Local Variables Needed: 160 None 161 162 ------------------------------------------------------------------------------ 163 FUNCTION DESCRIPTION 164 165 This function performs the quantization of a 4-dimensional subvector. 166 167 ------------------------------------------------------------------------------ 168 REQUIREMENTS 169 170 None 171 172 ------------------------------------------------------------------------------ 173 REFERENCES 174 175 q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 176 177 ------------------------------------------------------------------------------ 178 PSEUDO-CODE 179 180 181 ------------------------------------------------------------------------------ 182 RESOURCES USED [optional] 183 184 When the code is written for a specific target processor the 185 the resources used should be documented below. 186 187 HEAP MEMORY USED: x bytes 188 189 STACK MEMORY USED: x bytes 190 191 CLOCK CYCLES: (cycle count equation for this function) + (variable 192 used to represent cycle count for each subroutine 193 called) 194 where: (cycle count variable) = cycle count for [subroutine 195 name] 196 197 ------------------------------------------------------------------------------ 198 CAUTION [optional] 199 [State any special notes, constraints or cautions for users of this function] 200 201 ------------------------------------------------------------------------------ 202 */ 203 /* Quantization of a 4 dimensional subvector */ 204 205 static Word16 Vq_subvec( /* o : quantization index, Q0 */ 206 Word16 *lsf_r1, /* i : 1st LSF residual vector, Q15 */ 207 Word16 *lsf_r2, /* i : 2nd LSF residual vector, Q15 */ 208 const Word16 *dico, /* i : quantization codebook, Q15 */ 209 Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ 210 Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ 211 Word16 dico_size, /* i : size of quantization codebook, Q0 */ 212 Flag *pOverflow /* o : overflow indicator */ 213 ) 214 { 215 Word16 index = 0; /* initialization only needed to keep gcc silent */ 216 Word16 i; 217 Word16 temp; 218 const Word16 *p_dico; 219 Word32 dist_min; 220 Word32 dist; 221 Word16 wf1_0; 222 Word16 wf1_1; 223 Word16 wf2_0; 224 Word16 wf2_1; 225 Word32 aux1; 226 Word32 aux2; 227 Word32 aux3; 228 Word32 aux4; 229 230 OSCL_UNUSED_ARG(pOverflow); 231 232 dist_min = MAX_32; 233 p_dico = dico; 234 235 wf1_0 = wf1[0]; 236 wf1_1 = wf1[1]; 237 wf2_0 = wf2[0]; 238 wf2_1 = wf2[1]; 239 240 aux1 = ((Word32) lsf_r1[0] * wf1_0); 241 aux2 = ((Word32) lsf_r1[1] * wf1_1); 242 aux3 = ((Word32) lsf_r2[0] * wf2_0); 243 aux4 = ((Word32) lsf_r2[1] * wf2_1); 244 245 for (i = 0; i < dico_size; i++) 246 { 247 temp = (aux1 - ((Word32)wf1_0 * *(p_dico++))) >> 15; 248 dist = ((Word32)temp * temp); 249 250 if (dist >= dist_min) 251 { 252 p_dico += 3; 253 continue; 254 } 255 256 temp = (aux2 - ((Word32)wf1_1 * *(p_dico++))) >> 15; 257 dist += ((Word32)temp * temp); 258 259 if (dist >= dist_min) 260 { 261 p_dico += 2; 262 continue; 263 } 264 265 temp = (aux3 - ((Word32)wf2_0 * *(p_dico++))) >> 15; 266 dist += ((Word32)temp * temp); 267 268 if (dist >= dist_min) 269 { 270 p_dico += 1; 271 continue; 272 } 273 274 temp = (aux4 - ((Word32)wf2_1 * *(p_dico++))) >> 15; 275 dist += ((Word32)temp * temp); 276 277 278 if (dist < dist_min) 279 { 280 dist_min = dist; 281 index = i; 282 } 283 } 284 285 286 287 /* Reading the selected vector */ 288 289 p_dico = &dico[ index<<2]; 290 lsf_r1[0] = *p_dico++; 291 lsf_r1[1] = *p_dico++; 292 lsf_r2[0] = *p_dico++; 293 lsf_r2[1] = *p_dico; 294 295 return index; 296 297 } 298 299 300 /* 301 ------------------------------------------------------------------------------ 302 FUNCTION NAME: Vq_subvec_s 303 ------------------------------------------------------------------------------ 304 INPUT AND OUTPUT DEFINITIONS 305 306 Inputs: 307 lsf_r1 -- array of type Word16 -- 1st LSF residual vector, Q15 308 lsf_r2 -- array of type Word16 -- 2nd LSF residual vector, Q15 309 dico -- pointer to const Word16 -- quantization codebook, Q15 310 wf1 -- array of type Word16 -- 1st LSF weighting factors, Q13 311 wf2 -- array of type Word16 -- 2nd LSF weighting factors, Q13 312 dico_size -- Word16 -- size of quantization codebook, Q0 313 314 Outputs: 315 pOverflow -- pointer to type Flag -- overflow indicator 316 317 Returns: 318 Word16 -- quantization index, Q0 319 320 Global Variables Used: 321 None 322 323 Local Variables Needed: 324 None 325 326 ------------------------------------------------------------------------------ 327 FUNCTION DESCRIPTION 328 329 This function performs the quantization of a 4-dimensional subvector. 330 331 ------------------------------------------------------------------------------ 332 REQUIREMENTS 333 334 None 335 336 ------------------------------------------------------------------------------ 337 REFERENCES 338 339 q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 340 341 ------------------------------------------------------------------------------ 342 PSEUDO-CODE 343 344 345 ------------------------------------------------------------------------------ 346 RESOURCES USED [optional] 347 348 When the code is written for a specific target processor the 349 the resources used should be documented below. 350 351 HEAP MEMORY USED: x bytes 352 353 STACK MEMORY USED: x bytes 354 355 CLOCK CYCLES: (cycle count equation for this function) + (variable 356 used to represent cycle count for each subroutine 357 called) 358 where: (cycle count variable) = cycle count for [subroutine 359 name] 360 361 ------------------------------------------------------------------------------ 362 CAUTION [optional] 363 [State any special notes, constraints or cautions for users of this function] 364 365 ------------------------------------------------------------------------------ 366 */ 367 368 369 /* Quantization of a 4 dimensional subvector with a signed codebook */ 370 371 static Word16 Vq_subvec_s( /* o : quantization index Q0 */ 372 Word16 *lsf_r1, /* i : 1st LSF residual vector Q15 */ 373 Word16 *lsf_r2, /* i : and LSF residual vector Q15 */ 374 const Word16 *dico, /* i : quantization codebook Q15 */ 375 Word16 *wf1, /* i : 1st LSF weighting factors Q13 */ 376 Word16 *wf2, /* i : 2nd LSF weighting factors Q13 */ 377 Word16 dico_size, /* i : size of quantization codebook Q0 */ 378 Flag *pOverflow) /* o : overflow indicator */ 379 { 380 Word16 index = 0; /* initialization only needed to keep gcc silent */ 381 Word16 sign = 0; /* initialization only needed to keep gcc silent */ 382 Word16 i; 383 Word16 temp; 384 Word16 temp1; 385 Word16 temp2; 386 const Word16 *p_dico; 387 Word32 dist_min; 388 Word32 dist1; 389 Word32 dist2; 390 391 Word16 lsf_r1_0; 392 Word16 lsf_r1_1; 393 Word16 lsf_r2_0; 394 Word16 lsf_r2_1; 395 396 Word16 wf1_0; 397 Word16 wf1_1; 398 Word16 wf2_0; 399 Word16 wf2_1; 400 401 OSCL_UNUSED_ARG(pOverflow); 402 403 dist_min = MAX_32; 404 p_dico = dico; 405 406 407 lsf_r1_0 = lsf_r1[0]; 408 lsf_r1_1 = lsf_r1[1]; 409 lsf_r2_0 = lsf_r2[0]; 410 lsf_r2_1 = lsf_r2[1]; 411 412 wf1_0 = wf1[0]; 413 wf1_1 = wf1[1]; 414 wf2_0 = wf2[0]; 415 wf2_1 = wf2[1]; 416 417 for (i = 0; i < dico_size; i++) 418 { 419 /* test positive */ 420 temp = *p_dico++; 421 temp1 = lsf_r1_0 - temp; 422 temp2 = lsf_r1_0 + temp; 423 temp1 = ((Word32)wf1_0 * temp1) >> 15; 424 temp2 = ((Word32)wf1_0 * temp2) >> 15; 425 dist1 = ((Word32)temp1 * temp1); 426 dist2 = ((Word32)temp2 * temp2); 427 428 temp = *p_dico++; 429 temp1 = lsf_r1_1 - temp; 430 temp2 = lsf_r1_1 + temp; 431 temp1 = ((Word32)wf1_1 * temp1) >> 15; 432 temp2 = ((Word32)wf1_1 * temp2) >> 15; 433 dist1 += ((Word32)temp1 * temp1); 434 dist2 += ((Word32)temp2 * temp2); 435 436 if ((dist1 >= dist_min) && (dist2 >= dist_min)) 437 { 438 p_dico += 2; 439 continue; 440 } 441 442 temp = *p_dico++; 443 temp1 = lsf_r2_0 - temp; 444 temp2 = lsf_r2_0 + temp; 445 temp1 = ((Word32)wf2_0 * temp1) >> 15; 446 temp2 = ((Word32)wf2_0 * temp2) >> 15; 447 dist1 += ((Word32)temp1 * temp1); 448 dist2 += ((Word32)temp2 * temp2); 449 450 temp = *p_dico++; 451 temp1 = lsf_r2_1 - temp; 452 temp2 = lsf_r2_1 + temp; 453 temp1 = ((Word32)wf2_1 * temp1) >> 15; 454 temp2 = ((Word32)wf2_1 * temp2) >> 15; 455 dist1 += ((Word32)temp1 * temp1); 456 dist2 += ((Word32)temp2 * temp2); 457 458 if (dist1 < dist_min) 459 { 460 dist_min = dist1; 461 index = i; 462 sign = 0; 463 } 464 465 /* test negative */ 466 467 if (dist2 < dist_min) 468 { 469 dist_min = dist2; 470 index = i; 471 sign = 1; 472 } 473 } 474 475 /* Reading the selected vector */ 476 477 p_dico = &dico[index<<2]; 478 index <<= 1; 479 if (sign) 480 { 481 lsf_r1[0] = - (*p_dico++); 482 lsf_r1[1] = - (*p_dico++); 483 lsf_r2[0] = - (*p_dico++); 484 lsf_r2[1] = - (*p_dico); 485 index += 1; 486 } 487 else 488 { 489 lsf_r1[0] = *p_dico++; 490 lsf_r1[1] = *p_dico++; 491 lsf_r2[0] = *p_dico++; 492 lsf_r2[1] = *p_dico; 493 } 494 495 return index; 496 497 } 498 499 /* 500 ------------------------------------------------------------------------------ 501 FUNCTION NAME: Q_plsf_5 502 ------------------------------------------------------------------------------ 503 INPUT AND OUTPUT DEFINITIONS 504 505 506 Inputs: 507 st -- pointer to Q_plsfState -- state information 508 lsp1 -- array of type Word16 -- 1st LSP vector, Q15 509 lsp2 -- array of type Word16 -- 2nd LSP vector, Q15 510 511 Outputs: 512 lps1_q -- array of type Word16 -- quantized 1st LSP vector, Q15 513 lps2_q -- array of type Word16 -- quantized 2nd LSP vector, Q15 514 indices -- array of type Word16 -- quantization indices of 5 matrics, Q0 515 pOverflow -- pointer to type Flag -- overflow indicator 516 517 Returns: 518 None 519 520 Global Variables Used: 521 mean_lsf_5[]; 522 523 dico1_lsf_5[]; 524 dico2_lsf_5[]; 525 dico3_lsf_5[]; 526 dico4_lsf_5[]; 527 dico5_lsf_5[]; 528 529 Local Variables Needed: 530 None 531 532 ------------------------------------------------------------------------------ 533 FUNCTION DESCRIPTION 534 535 PURPOSE: Quantization of 2 sets of LSF parameters using 1st order MA 536 prediction and split by 5 matrix quantization (split-MQ) 537 538 DESCRIPTION: 539 540 p[i] = pred_factor*past_rq[i]; i=0,...,m-1 541 r1[i]= lsf1[i] - p[i]; i=0,...,m-1 542 r2[i]= lsf2[i] - p[i]; i=0,...,m-1 543 where: 544 lsf1[i] 1st mean-removed LSF vector. 545 lsf2[i] 2nd mean-removed LSF vector. 546 r1[i] 1st residual prediction vector. 547 r2[i] 2nd residual prediction vector. 548 past_r2q[i] Past quantized residual (2nd vector). 549 550 The residual vectors r1[i] and r2[i] are jointly quantized using 551 split-MQ with 5 codebooks. Each 4th dimension submatrix contains 2 552 elements from each residual vector. The 5 submatrices are as follows: 553 {r1[0], r1[1], r2[0], r2[1]}; {r1[2], r1[3], r2[2], r2[3]}; 554 {r1[4], r1[5], r2[4], r2[5]}; {r1[6], r1[7], r2[6], r2[7]}; 555 {r1[8], r1[9], r2[8], r2[9]} 556 557 ------------------------------------------------------------------------------ 558 REQUIREMENTS 559 560 None 561 562 ------------------------------------------------------------------------------ 563 REFERENCES 564 565 q_plsf_5.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001 566 567 ------------------------------------------------------------------------------ 568 PSEUDO-CODE 569 570 571 ------------------------------------------------------------------------------ 572 RESOURCES USED [optional] 573 574 When the code is written for a specific target processor the 575 the resources used should be documented below. 576 577 HEAP MEMORY USED: x bytes 578 579 STACK MEMORY USED: x bytes 580 581 CLOCK CYCLES: (cycle count equation for this function) + (variable 582 used to represent cycle count for each subroutine 583 called) 584 where: (cycle count variable) = cycle count for [subroutine 585 name] 586 587 ------------------------------------------------------------------------------ 588 CAUTION [optional] 589 [State any special notes, constraints or cautions for users of this function] 590 591 ------------------------------------------------------------------------------ 592 */ 593 594 void Q_plsf_5( 595 Q_plsfState *st, 596 Word16 *lsp1, /* i : 1st LSP vector, Q15 */ 597 Word16 *lsp2, /* i : 2nd LSP vector, Q15 */ 598 Word16 *lsp1_q, /* o : quantized 1st LSP vector, Q15 */ 599 Word16 *lsp2_q, /* o : quantized 2nd LSP vector, Q15 */ 600 Word16 *indice, /* o : quantization indices of 5 matrices, Q0 */ 601 Flag *pOverflow /* o : overflow indicator */ 602 ) 603 { 604 Word16 i; 605 Word16 lsf1[M]; 606 Word16 lsf2[M]; 607 Word16 wf1[M]; 608 Word16 wf2[M]; 609 Word16 lsf_p[M]; 610 Word16 lsf_r1[M]; 611 Word16 lsf_r2[M]; 612 Word16 lsf1_q[M]; 613 Word16 lsf2_q[M]; 614 615 Word16 *p_lsf_p; 616 Word16 *p_lsf1; 617 Word16 *p_lsf2; 618 Word16 *p_lsf_r1; 619 Word16 *p_lsf_r2; 620 621 /* convert LSFs to normalize frequency domain 0..16384 */ 622 623 Lsp_lsf(lsp1, lsf1, M, pOverflow); 624 Lsp_lsf(lsp2, lsf2, M, pOverflow); 625 626 /* Compute LSF weighting factors (Q13) */ 627 628 Lsf_wt(lsf1, wf1, pOverflow); 629 Lsf_wt(lsf2, wf2, pOverflow); 630 631 /* Compute predicted LSF and prediction error */ 632 633 p_lsf_p = &lsf_p[0]; 634 p_lsf1 = &lsf1[0]; 635 p_lsf2 = &lsf2[0]; 636 p_lsf_r1 = &lsf_r1[0]; 637 p_lsf_r2 = &lsf_r2[0]; 638 639 for (i = 0; i < M; i++) 640 { 641 *(p_lsf_p) = mean_lsf_5[i] + 642 (((Word32)st->past_rq[i] * LSP_PRED_FAC_MR122) >> 15); 643 644 *(p_lsf_r1++) = *(p_lsf1++) - *(p_lsf_p); 645 *(p_lsf_r2++) = *(p_lsf2++) - *(p_lsf_p++); 646 } 647 648 /*---- Split-MQ of prediction error ----*/ 649 650 indice[0] = Vq_subvec(&lsf_r1[0], &lsf_r2[0], dico1_lsf_5, 651 &wf1[0], &wf2[0], DICO1_5_SIZE, pOverflow); 652 653 indice[1] = Vq_subvec(&lsf_r1[2], &lsf_r2[2], dico2_lsf_5, 654 &wf1[2], &wf2[2], DICO2_5_SIZE, pOverflow); 655 656 indice[2] = Vq_subvec_s(&lsf_r1[4], &lsf_r2[4], dico3_lsf_5, 657 &wf1[4], &wf2[4], DICO3_5_SIZE, pOverflow); 658 659 indice[3] = Vq_subvec(&lsf_r1[6], &lsf_r2[6], dico4_lsf_5, 660 &wf1[6], &wf2[6], DICO4_5_SIZE, pOverflow); 661 662 indice[4] = Vq_subvec(&lsf_r1[8], &lsf_r2[8], dico5_lsf_5, 663 &wf1[8], &wf2[8], DICO5_5_SIZE, pOverflow); 664 665 /* Compute quantized LSFs and update the past quantized residual */ 666 667 p_lsf_r1 = &lsf_r1[0]; 668 p_lsf_r2 = &lsf_r2[0]; 669 p_lsf_p = &lsf_p[0]; 670 p_lsf1 = &lsf1_q[0]; 671 p_lsf2 = &lsf2_q[0]; 672 673 674 for (i = 0; i < M; i++) 675 { 676 *(p_lsf1++) = *(p_lsf_r1++) + *(p_lsf_p); 677 *(p_lsf2++) = *(p_lsf_r2) + *(p_lsf_p++); 678 st->past_rq[i] = *(p_lsf_r2++); 679 } 680 681 /* verification that LSFs has minimum distance of LSF_GAP */ 682 683 Reorder_lsf(lsf1_q, LSF_GAP, M, pOverflow); 684 Reorder_lsf(lsf2_q, LSF_GAP, M, pOverflow); 685 686 /* convert LSFs to the cosine domain */ 687 688 Lsf_lsp(lsf1_q, lsp1_q, M, pOverflow); 689 Lsf_lsp(lsf2_q, lsp2_q, M, pOverflow); 690 } 691 692