// --------------------------------------------------------------------------- // buildPartials // --------------------------------------------------------------------------- // Append spectral peaks, extracted from a reassigned time-frequency // spectrum, to eligible Partials, where possible. Peaks that cannot // be used to extend eliglble Partials spawn new Partials. // // This is similar to the basic MQ partial formation strategy, except that // before matching, all frequencies are normalized by the value of the // warping envelope at the time of the current frame. This means that // the frequency envelopes of all the Partials are warped, and need to // be un-normalized by calling finishBuilding at the end of the building // process. // void PartialBuilder::buildPartials( Peaks & peaks, double frameTime ) { mNewlyEligible.clear(); unsigned int matchCount = 0; // for debugging // frequency-sort the spectral peaks: // (the eligible partials are always sorted by // increasing frequency if we always sort the // peaks this way) std::sort( peaks.begin(), peaks.end(), SpectralPeak::sort_increasing_freq ); PartialPtrs::iterator eligible = mEligiblePartials.begin(); for ( Peaks::iterator bpIter = peaks.begin(); bpIter != peaks.end(); ++bpIter ) { //const Breakpoint & bp = bpIter->breakpoint; const double peakTime = frameTime + bpIter->time(); // find the Partial that is nearest in frequency to the Peak: PartialPtrs::iterator nextEligible = eligible; if ( eligible != mEligiblePartials.end() && end_frequency( **eligible ) < bpIter->frequency() ) { ++nextEligible; while ( nextEligible != mEligiblePartials.end() && end_frequency( **nextEligible ) < bpIter->frequency() ) { ++nextEligible; ++eligible; } if ( nextEligible != mEligiblePartials.end() && better_match( **nextEligible, **eligible, *bpIter ) ) { eligible = nextEligible; } } // INVARIANT: // // eligible is the position of the nearest (in frequency) // eligible Partial (pointer) or it is mEligiblePartials.end(). // // nextEligible is the eligible Partial with frequency // greater than bp, or it is mEligiblePartials.end(). #if defined(Debug_Loris) && Debug_Loris /* if ( nextEligible != mEligiblePartials.end() ) { debugger << matchFrequency << "( " << end_frequency( **eligible ) << ", " << end_frequency( **nextEligible ) << ")" << endl; } */ #endif // create a new Partial if there is no eligible Partial, // or the frequency difference to the eligible Partial is // too great, or the next peak is a better match for the // eligible Partial, otherwise add this peak to the eligible // Partial: Peaks::iterator nextPeak = //Peaks::iterator( bpIter ); ++nextPeak; ++Peaks::iterator( bpIter ); // some compilers choke on this? // decide whether this match should be made: // - can only make the match if eligible is not the end of the list // - the match is only good if it is close enough in frequency // - even if the match is good, only match if the next one is not better bool makeMatch = false; if ( eligible != mEligiblePartials.end() ) { bool matchIsGood = mFreqDrift > std::fabs( end_frequency( **eligible ) - bpIter->frequency() ); if ( matchIsGood ) { bool nextIsBetter = ( nextPeak != peaks.end() && better_match( **eligible, *nextPeak, *bpIter ) ); if ( ! nextIsBetter ) { makeMatch = true; } } } Breakpoint bp = bpIter->createBreakpoint(); if ( makeMatch ) { // invariant: // if makeMatch is true, then eligible is the position of a valid Partial (*eligible)->insert( peakTime, bp ); mNewlyEligible.push_back( *eligible ); ++matchCount; } else { Partial p; p.insert( peakTime, bp ); mCollectedPartials.push_back( p ); mNewlyEligible.push_back( & mCollectedPartials.back() ); } // update eligible, nextEligible is the eligible Partial // with frequency greater than bp, or it is mEligiblePartials.end(): eligible = nextEligible; } mEligiblePartials = mNewlyEligible; /* debugger << "PartialBuilder::buildPartials: matched " << matchCount << endl; debugger << "PartialBuilder::buildPartials: " << mNewlyEligible.size() << " newly eligible partials" << endl; */ }
static void check_match(struct bigram_list *bigram, struct body *bp, char *ptr, int max_msgnum, String_Match * match_info, const char *match_start_ptr, const char *exact_line) { int match_len = 1; int alloc_len = 0; int match_len_bytes; struct body *bp2 = bp; struct body *bp3 = NULL; char *ptr2 = ptr; const char *last_ptr = ptr; char *ptr3; char token2[MAXLINE]; char token3[MAXLINE]; int b2_index = 0; int b_index = 0; int msgnum = bigram->bp->msgnum; bp3 = bigram->bp; if (msgnum < max_msgnum && bp3) { ptr3 = bp3->line + bigram->offset; while (1) { bp2 = tokenize_body(bp2, token2, &ptr2, &b2_index, TRUE); bp3 = tokenize_body(bp3, token3, &ptr3, &b_index, TRUE); if (0) printf("compare_match: %d %s, %20.20s\n", match_len, token3, ptr3); if (!bp2 || !bp3) break; if (ENCODE_TOKEN(token2) != ENCODE_TOKEN(token3)) break; ++match_len; last_ptr = ptr2; } { const char *p = match_start_ptr; match_len_bytes = 0; while (p != last_ptr) { ++match_len_bytes; ++p; if (!*p && p != last_ptr) { bp = bp->next; p = bp->line; } } ++match_len_bytes; } if (0) printf("compare_match: %d %d msgnum %d\n", match_len, match_info->match_len_tokens, msgnum); if (match_len > match_info->match_len_tokens || (match_len == match_info->match_len_tokens && better_match(bp, exact_line, match_info->last_matched_string))) { match_info->match_len_tokens = match_len; match_info->match_len_bytes = match_len_bytes; match_info->msgnum = msgnum; match_info->start_match = bigram->bp->line + bigram->offset; match_info->stop_match = ptr3; if (match_info->last_matched_string) free(match_info->last_matched_string); match_len = strlen(bigram->bp->line); alloc_len = match_len + 1000; match_info->last_matched_string = (char *)emalloc(alloc_len); strcpy(match_info->last_matched_string, bigram->bp->line); if (!strchr(match_info->last_matched_string, '\n')) { strcat(match_info->last_matched_string + match_len, "\n"); ++match_len; } for (bp3 = bigram->bp->next; bp3; bp3 = bp3->next) { char *p = match_info->last_matched_string; int add_len = strlen(bp3->line); if (match_len + add_len + 2 > alloc_len) { alloc_len = 2 * (match_len + add_len + 2); match_info->last_matched_string = (char *)realloc(p, alloc_len); } strcat(match_info->last_matched_string + match_len, bp3->line); match_len += add_len; if (add_len > 0 && bp3->line[add_len - 1] != '\n') strcat(match_info->last_matched_string + match_len++, "\n"); } if (0) printf("%d +++ %s; %s\nbp->line %s\n", bigram->bp->msgnum, match_info->last_matched_string, match_info->stop_match, bp->line); } } }
/* Create a Content Type filter stack ** ---------------------------------- ** If a wildcard match is made, a temporary HTPresentation ** structure is made to hold the destination format while the ** new stack is generated. This is just to pass the out format to ** MIME so far. Storing the format of a stream in the stream might ** be a lot neater. ** ** The star/star format is special, in that if you can take ** that you can take anything. */ PUBLIC HTStream * HTStreamStack (HTFormat rep_in, HTFormat rep_out, HTStream * output_stream, HTRequest * request, BOOL guess) { HTList * conversion[2]; int which_list; double best_quality = -1e30; /* Pretty bad! */ HTPresentation *pres, *best_match=NULL; if (rep_out == WWW_RAW) { HTTRACE(CORE_TRACE, "StreamStack. Raw output...\n"); return output_stream ? output_stream : HTErrorStream(); } if (rep_out == rep_in) { HTTRACE(CORE_TRACE, "StreamStack. Identical input/output format (%s)\n" _ HTAtom_name(rep_out)); return output_stream ? output_stream : HTErrorStream(); } #ifdef HTDEBUG if (CORE_TRACE) { const char *p = HTAtom_name(rep_in); const char *q = HTAtom_name(rep_out); HTTRACE(CORE_TRACE, "StreamStack. Constructing stream stack for %s to %s\n" _ p ? p : "<NULL>" _ q ? q : "<NULL>"); } #endif /* HTDEBUG */ conversion[0] = HTRequest_conversion(request); conversion[1] = HTConversions; for(which_list = 0; which_list<2; which_list++) { HTList * cur = conversion[which_list]; while ((pres = (HTPresentation*)HTList_nextObject(cur))) { if ((pres->rep==rep_in || HTMIMEMatch(pres->rep, rep_in)) && (pres->rep_out==rep_out || HTMIMEMatch(pres->rep_out,rep_out))){ if (!best_match || better_match(pres->rep, best_match->rep) || (!better_match(best_match->rep, pres->rep) && pres->quality > best_quality)) { #ifdef HAVE_SYSTEM int result=0; if (pres->test_command) { result = system(pres->test_command); HTTRACE(CORE_TRACE, "StreamStack. system(%s) returns %d\n" _ pres->test_command _ result); } if (!result) { best_match = pres; best_quality = pres->quality; } #else best_match = pres; best_quality = pres->quality; #endif /* HAVE_SYSTEM */ } } } } if (best_match) { if (rep_out == WWW_SOURCE && best_match->rep_out != WWW_SOURCE) { HTTRACE(CORE_TRACE, "StreamStack. Source output\n"); return output_stream ? output_stream : HTErrorStream(); } return (*best_match->converter)(request, best_match->command, rep_in, rep_out, output_stream); } if (rep_out == WWW_SOURCE) { HTTRACE(CORE_TRACE, "StreamStack. Source output\n"); return output_stream ? output_stream : HTErrorStream(); } HTTRACE(CORE_TRACE, "StreamStack. NOT FOUND - error!\n"); return HTBlackHole(); }