/* peak_tracking * ============= * connects peaks from one analysis frame to tracks * returns a pointer to two frames of orphaned peaks. * tracks: pointer to the tracks * tracks_size: numeber of tracks * peaks: peaks to connect * peaks_size: number of peaks * frq_dev: frequency deviation from tracks * SMR_cont: contribution of SMR to tracking * n_partials: pointer to the number of partials before tracking */ ATS_FRAME *peak_tracking(ATS_PEAK *tracks, int *tracks_size, ATS_PEAK *peaks, int *peaks_size, float frq_dev, float SMR_cont, int *n_partials) { ATS_CANDS *track_candidates = (ATS_CANDS *)malloc(*peaks_size*sizeof(ATS_CANDS)); double lo, hi; int k, j, used, goback; ATS_FRAME *returned_peaks = (ATS_FRAME *)malloc(2*sizeof(ATS_FRAME)); returned_peaks[0].peaks = returned_peaks[1].peaks = NULL; returned_peaks[0].n_peaks = returned_peaks[1].n_peaks = 0; /* sort data to prepare for matching */ qsort(tracks, *tracks_size, sizeof(ATS_PEAK), peak_frq_inc); qsort(peaks, *peaks_size, sizeof(ATS_PEAK), peak_frq_inc); /* find candidates for each peak and set each peak to best candidate */ for (k=0; k<*peaks_size; k++) { /* find frq limits for candidates */ lo = peaks[k].frq - (.5 * peaks[k].frq * frq_dev); hi = peaks[k].frq + (.5 * peaks[k].frq * frq_dev); /* get possible candidates */ track_candidates[k].size = 0; track_candidates[k].cands = find_candidates(tracks, *tracks_size, lo, hi, &track_candidates[k].size); if(track_candidates[k].size) { sort_candidates(&track_candidates[k], peaks[k], SMR_cont); peaks[k].track = track_candidates[k].cands[0].track; } } /* compare adjacent peaks track numbers to insure unique track numbers */ do { goback = 0; for (j=0; j<(*peaks_size - 1); j++) if((peaks[j].track == peaks[j+1].track) && (peaks[j].track > -1)) { if(track_candidates[j].cands[0].amp > track_candidates[j+1].cands[0].amp) { track_candidates[j].cands[0].amp = ATSA_HFREQ; qsort(track_candidates[j].cands, track_candidates[j].size, sizeof(ATS_PEAK), peak_amp_inc); if(track_candidates[j].cands[0].amp < ATSA_HFREQ) { peaks[j].track = track_candidates[j].cands[0].track; goback = 1; } else peaks[j].track = -1; } else { track_candidates[j+1].cands[0].amp = ATSA_HFREQ; qsort(track_candidates[j+1].cands, track_candidates[j+1].size, sizeof(ATS_PEAK), peak_amp_inc); if(track_candidates[j+1].cands[0].amp < ATSA_HFREQ) peaks[j+1].track = track_candidates[j+1].cands[0].track; else peaks[j+1].track = -1; } } } while (goback); /* by this point, all peaks will either have a unique track number, or -1 now we need to take care of those left behind */ for(k=0; k<*peaks_size; k++) if(peaks[k].track == -1) { peaks[k].track = (*n_partials)++; returned_peaks[1].peaks = push_peak(&peaks[k], returned_peaks[1].peaks, &returned_peaks[1].n_peaks); } /* check for tracks that didnt get assigned */ for(k=0; k<*tracks_size; k++) { used = 0; for(j=0; j<*peaks_size; j++) if(tracks[k].track == peaks[j].track) { used = 1; break; } if(!used) returned_peaks[0].peaks = push_peak(&tracks[k], returned_peaks[0].peaks, &returned_peaks[0].n_peaks); } for (k=0; k<*peaks_size; k++) free(track_candidates[k].cands); free(track_candidates); return(returned_peaks); }
/* Performs a multiple dispatch using the candidates held in the passed * DispatcherSub and using the arguments in the passed capture. */ PMC *nqp_multi_dispatch(PARROT_INTERP, PMC *dispatcher, PMC *capture) { /* Get list and number of dispatchees. */ PMC *dispatchees = PARROT_DISPATCHERSUB(dispatcher)->dispatchees; const INTVAL num_candidates = VTABLE_elements(interp, dispatchees); /* Count arguments. */ const INTVAL num_args = VTABLE_elements(interp, capture); /* Initialize dispatcher state. */ INTVAL type_mismatch; INTVAL possibles_count = 0; candidate_info **possibles = mem_allocate_n_typed(num_candidates, candidate_info *); INTVAL type_check_count; /* Get sorted candidate list. * XXX We'll cache this in the future. */ candidate_info** candidates = sort_candidates(interp, dispatchees); candidate_info** cur_candidate = candidates; /* Ensure we know what is a 6model object and what is not. */ if (!smo_id) smo_id = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "SixModelObject", 0)); /* Iterate over the candidates and collect best ones; terminate * when we see two nulls (may break out earlier). */ while (1) { INTVAL i; if (*cur_candidate == NULL) { /* If we have some possible candidate(s), we're done in this loop. */ if (possibles_count) break; /* Otherwise, we keep looping and looking, unless we really hit the end. */ if (cur_candidate[1]) { cur_candidate++; continue; } else { break; } } /* Check if it's admissable by arity. */ if (num_args < (*cur_candidate)->min_arity || num_args > (*cur_candidate)->max_arity) { cur_candidate++; continue; } /* Check if it's admissable by type. */ type_check_count = (*cur_candidate)->num_types > num_args ? num_args : (*cur_candidate)->num_types; type_mismatch = 0; for (i = 0; i < type_check_count; i++) { PMC * const param = VTABLE_get_pmc_keyed_int(interp, capture, i); PMC * const param_type = param->vtable->base_type == smo_id ? STABLE(param)->WHAT : PMCNULL; PMC * const type_obj = (*cur_candidate)->types[i]; INTVAL const definedness = (*cur_candidate)->definednesses[i]; if (param_type != type_obj && !is_narrower_type(interp, param_type, type_obj)) { type_mismatch = 1; break; } if (definedness) { /* Have a constraint on the definedness. */ INTVAL defined = param->vtable->base_type == smo_id ? IS_CONCRETE(param) : VTABLE_defined(interp, param); if ((!defined && definedness == DEFINED_ONLY) || (defined && definedness == UNDEFINED_ONLY)) { type_mismatch = 1; break; } } } if (type_mismatch) { cur_candidate++; continue; } /* If we get here, it's an admissable candidate; add to list. */ possibles[possibles_count] = *cur_candidate; possibles_count++; cur_candidate++; } /* Cache the result if there's a single chosen one. */ if (possibles_count == 1) { /* XXX TODO: Cache entry. */ } /* Need a unique candidate. */ if (possibles_count == 1) { PMC *result = possibles[0]->sub; mem_sys_free(possibles); return result; } else if (possibles_count == 0) { /* Get signatures of all possible candidates. We dump them in the * order in which we search for them. */ STRING *signatures = Parrot_str_new(interp, "", 0); cur_candidate = candidates; while (1) { if (!cur_candidate[0] && !cur_candidate[1]) break; /* XXX TODO: add sig dumping. if (cur_candidate[0]) signatures = dump_signature(interp, signatures, (*cur_candidate)->sub); */ cur_candidate++; } mem_sys_free(possibles); Parrot_ex_throw_from_c_args(interp, NULL, 1, "No applicable candidates found to dispatch to for '%Ss'. Available candidates are:\n%Ss", VTABLE_get_string(interp, candidates[0]->sub), signatures); } else { /* Get signatures of ambiguous candidates. */ STRING *signatures = Parrot_str_new(interp, "", 0); INTVAL i; /* XXX TODO: sig dumping for (i = 0; i < possibles_count; i++) signatures = dump_signature(interp, signatures, possibles[i]->sub); */ mem_sys_free(possibles); Parrot_ex_throw_from_c_args(interp, NULL, 1, "Ambiguous dispatch to multi '%Ss'. Ambiguous candidates had signatures:\n%Ss", VTABLE_get_string(interp, candidates[0]->sub), signatures); } }