static void gmStage1(SECTION_INFO * sectionInfo, Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const Word16 maxSfb, const Word16 *sideInfoTab) { SECTION_INFO * sectionInfo_s; SECTION_INFO * sectionInfo_e; Word32 mergeStart, mergeEnd; mergeStart = 0; do { sectionInfo_s = sectionInfo + mergeStart; for (mergeEnd=mergeStart+1; mergeEnd<maxSfb; mergeEnd++) { sectionInfo_e = sectionInfo + mergeEnd; if (sectionInfo_s->codeBook != sectionInfo_e->codeBook) break; sectionInfo_s->sfbCnt += 1; sectionInfo_s->sectionBits += sectionInfo_e->sectionBits; mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]); } sectionInfo_s->sectionBits += sideInfoTab[sectionInfo_s->sfbCnt]; sectionInfo[mergeEnd - 1].sfbStart = sectionInfo_s->sfbStart; /* speed up prev search */ mergeStart = mergeEnd; } while (mergeStart - maxSfb < 0); }
/* sectioning Stage 2:greedy merge algorithm, merge connected sections with maximum bit gain until no more gain is possible */ static void gmStage2(SECTION_INFO *sectionInfo, Word16 mergeGainLookUp[MAX_SFB_LONG], Word16 bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const Word16 maxSfb, const Word16 *sideInfoTab) { Word16 i; for (i=0; i+sectionInfo[i].sfbCnt<maxSfb; i+=sectionInfo[i].sfbCnt) { mergeGainLookUp[i] = CalcMergeGain(sectionInfo, bitLookUp, sideInfoTab, i, (i + sectionInfo[i].sfbCnt)); } while (TRUE) { Word16 maxMergeGain, maxNdx, maxNdxNext, maxNdxLast; maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx); if (maxMergeGain <= 0) break; maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt; sectionInfo[maxNdx].sfbCnt = sectionInfo[maxNdx].sfbCnt + sectionInfo[maxNdxNext].sfbCnt; sectionInfo[maxNdx].sectionBits = sectionInfo[maxNdx].sectionBits + (sectionInfo[maxNdxNext].sectionBits - maxMergeGain); mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]); if (maxNdx != 0) { maxNdxLast = sectionInfo[maxNdx - 1].sfbStart; mergeGainLookUp[maxNdxLast] = CalcMergeGain(sectionInfo, bitLookUp, sideInfoTab, maxNdxLast, maxNdx); } maxNdxNext = maxNdx + sectionInfo[maxNdx].sfbCnt; sectionInfo[maxNdxNext - 1].sfbStart = sectionInfo[maxNdx].sfbStart; if (maxNdxNext - maxSfb < 0) { mergeGainLookUp[maxNdx] = CalcMergeGain(sectionInfo, bitLookUp, sideInfoTab, maxNdx, maxNdxNext); } } }
static void gmStage1(SECTION_INFO * section, int bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const int maxSfb, const int *sideInfoTab) { int mergeStart = 0, mergeEnd; COUNT_sub_start("gmStage1"); MOVE(1); /* counting previous operations */ LOOP(1); do { PTR_INIT(4); /* pointers for section[mergeStart] section[mergeEnd] bitLookUp[mergeStart] bitLookUp[mergeEnd] */ ADD(1); LOOP(1); for (mergeEnd = mergeStart + 1; mergeEnd < maxSfb; mergeEnd++) { ADD(1); BRANCH(1); if (section[mergeStart].codeBook != section[mergeEnd].codeBook) break; ADD(1); STORE(1); section[mergeStart].sfbCnt++; ADD(1); STORE(1); section[mergeStart].sectionBits += section[mergeEnd].sectionBits; FUNC(2); mergeBitLookUp(bitLookUp[mergeStart], bitLookUp[mergeEnd]); } INDIRECT(1); ADD(1); STORE(1); section[mergeStart].sectionBits += sideInfoTab[section[mergeStart].sfbCnt]; MOVE(1); section[mergeEnd - 1].sfbStart = section[mergeStart].sfbStart; MOVE(1); mergeStart = mergeEnd; } while (mergeStart < maxSfb); COUNT_sub_end(); }
static void gmStage2(SECTION_INFO * section, int mergeGainLookUp[MAX_SFB_LONG], int bitLookUp[MAX_SFB_LONG][CODE_BOOK_ESC_NDX + 1], const int maxSfb, const int *sideInfoTab) { int i; COUNT_sub_start("gmStage2"); PTR_INIT(2); /* pointers for section[], mergeGainLookUp[] */ LOOP(1); for (i = 0; i + section[i].sfbCnt < maxSfb; i += section[i].sfbCnt) { ADD(1); FUNC(5); STORE(1); mergeGainLookUp[i] = CalcMergeGain(section, bitLookUp, sideInfoTab, i, i + section[i].sfbCnt); } LOOP(1); while (TRUE) { int maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast; PTR_INIT(1); FUNC(4); maxMergeGain = findMaxMerge(mergeGainLookUp, section, maxSfb, &maxNdx); /* exit while loop if no more gain is possible */ BRANCH(1); if (maxMergeGain <= 0) break; PTR_INIT(3); /* pointers for section[maxNdx], bitLookUp[maxNdx], mergeGainLookUp[maxNdx] */ ADD(1); maxNdxNext = maxNdx + section[maxNdx].sfbCnt; PTR_INIT(2); /* pointers for section[maxNdxNext], bitLookUp[maxNdxNext] */ ADD(1); section[maxNdx].sfbCnt += section[maxNdxNext].sfbCnt; ADD(2); section[maxNdx].sectionBits += section[maxNdxNext].sectionBits - maxMergeGain; FUNC(2); mergeBitLookUp(bitLookUp[maxNdx], bitLookUp[maxNdxNext]); BRANCH(1); if (maxNdx != 0) { MOVE(1); maxNdxLast = section[maxNdx - 1].sfbStart; FUNC(5); INDIRECT(1); STORE(1); mergeGainLookUp[maxNdxLast] = CalcMergeGain(section, bitLookUp, sideInfoTab, maxNdxLast, maxNdx); } ADD(1); maxNdxNext = maxNdx + section[maxNdx].sfbCnt; PTR_INIT(1); /* pointers for section[maxNdxNext] */ MOVE(1); section[maxNdxNext - 1].sfbStart = section[maxNdx].sfbStart; ADD(1); BRANCH(1); if (maxNdxNext < maxSfb) { FUNC(5); STORE(1); mergeGainLookUp[maxNdx] = CalcMergeGain(section, bitLookUp, sideInfoTab, maxNdx, maxNdxNext); } } COUNT_sub_end(); }