⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pesqmod.c

📁 pesq算法
💻 C
📖 第 1 页 / 共 4 页
字号:
                    frame_disturbance [frame] = 0;
                    frame_disturbance_asym_add [frame] = 0;
                }
            } 
        }    
    }
    
    nn = DATAPADDING_MSECS  * (Fs / 1000) + maxNsamples;

    tweaked_deg = (float *) safe_malloc (nn * sizeof (float));

    for (i = 0; i < nn; i++) {
        tweaked_deg [i] = 0;
    } 

    for (i = SEARCHBUFFER * Downsample; i < nn - SEARCHBUFFER * Downsample; i++) {
        int  utt = err_info-> Nutterances - 1;
        long delay, j;

        while ((utt >= 0) && (err_info-> Utt_Start [utt] * Downsample > i)) {
            utt--;
        }
        if (utt >= 0) {
            delay = err_info-> Utt_Delay [utt];
        } else {
            delay = err_info-> Utt_Delay [0];        
        }
            
        j = i + delay;
        if (j < SEARCHBUFFER * Downsample) {
            j = SEARCHBUFFER * Downsample;
        }
        if (j >= nn - SEARCHBUFFER * Downsample) {
            j = nn - SEARCHBUFFER * Downsample - 1;
        }
        tweaked_deg [i] = deg_info-> data [j];
    }

    if (there_is_a_bad_frame) {        
        
        for (frame = 0; frame <= stop_frame; frame++) 
        {  
            frame_is_bad [frame] = (frame_disturbance [frame] > THRESHOLD_BAD_FRAMES);       

            smeared_frame_is_bad [frame] = FALSE;
        }
        frame_is_bad [0] = FALSE;

    #define SMEAR_RANGE 2
        
        for (frame = SMEAR_RANGE; frame < stop_frame - SMEAR_RANGE; frame++) {    
            long max_itself_and_left = frame_is_bad [frame];
            long max_itself_and_right = frame_is_bad [frame];
            long mini, i;

            for (i = -SMEAR_RANGE; i <= 0; i++) {
                if (max_itself_and_left < frame_is_bad [frame  + i]) {
                    max_itself_and_left = frame_is_bad [frame  + i];
                }
            }
        
            for (i = 0; i <= SMEAR_RANGE; i++) {
                if (max_itself_and_right < frame_is_bad [frame + i]) {
                    max_itself_and_right = frame_is_bad [frame + i];
                }
            }

            mini = max_itself_and_left;
            if (mini > max_itself_and_right) {
                mini = max_itself_and_right;
            }

            smeared_frame_is_bad [frame] = mini;
        }
   
#define MINIMUM_NUMBER_OF_BAD_FRAMES_IN_BAD_INTERVAL    5

        number_of_bad_intervals = 0;    
        frame = 0; 
        while (frame <= stop_frame) {

            while ((frame <= stop_frame) && (!smeared_frame_is_bad [frame])) {
                frame++; 
            }

            if (frame <= stop_frame) { 
                start_frame_of_bad_interval [number_of_bad_intervals] = frame;

                while ((frame <= stop_frame) && (smeared_frame_is_bad [frame])) {
                    frame++; 
                }
            
                if (frame <= stop_frame) {
                    stop_frame_of_bad_interval [number_of_bad_intervals] = frame; 

                    if (stop_frame_of_bad_interval [number_of_bad_intervals] - start_frame_of_bad_interval [number_of_bad_intervals] >= MINIMUM_NUMBER_OF_BAD_FRAMES_IN_BAD_INTERVAL) {
                        number_of_bad_intervals++; 
                    }
                }
            }
        }

        for (bad_interval = 0; bad_interval < number_of_bad_intervals; bad_interval++) {
            start_sample_of_bad_interval [bad_interval] =  start_frame_of_bad_interval [bad_interval] * (Nf / 2) + SEARCHBUFFER * Downsample;
            stop_sample_of_bad_interval [bad_interval] =  stop_frame_of_bad_interval [bad_interval] * (Nf / 2) + Nf + SEARCHBUFFER* Downsample;
            if (stop_frame_of_bad_interval [bad_interval] > stop_frame) {
                stop_frame_of_bad_interval [bad_interval] = stop_frame; 
            }

            number_of_samples_in_bad_interval [bad_interval] =  stop_sample_of_bad_interval [bad_interval] - start_sample_of_bad_interval [bad_interval];
        }

        

    #define SEARCH_RANGE_IN_TRANSFORM_LENGTH    4

        search_range_in_samples= SEARCH_RANGE_IN_TRANSFORM_LENGTH * Nf;

        for (bad_interval= 0; bad_interval< number_of_bad_intervals; bad_interval++) {
            float  *ref = (float *) safe_malloc ( (2 * search_range_in_samples + number_of_samples_in_bad_interval [bad_interval]) * sizeof (float));
            float  *deg = (float *) safe_malloc ( (2 * search_range_in_samples + number_of_samples_in_bad_interval [bad_interval]) * sizeof (float));
            int        i;
            float    best_correlation;
            int        delay_in_samples;

            for (i = 0; i < search_range_in_samples; i++) {
                ref[i] = 0.0f;
            }
            for (i = 0; i < number_of_samples_in_bad_interval [bad_interval]; i++) {
                ref [search_range_in_samples + i] = ref_info-> data [start_sample_of_bad_interval [bad_interval] + i];
            }
            for (i = 0; i < search_range_in_samples; i++) {
                ref [search_range_in_samples + number_of_samples_in_bad_interval [bad_interval] + i] = 0.0f;
            }
        
            for (i = 0; 
                 i < 2 * search_range_in_samples + number_of_samples_in_bad_interval [bad_interval];
                 i++) {
                
                int j = start_sample_of_bad_interval [bad_interval] - search_range_in_samples + i;
                int nn = maxNsamples - SEARCHBUFFER * Downsample + DATAPADDING_MSECS  * (Fs / 1000);

                if (j < SEARCHBUFFER * Downsample) {
                    j = SEARCHBUFFER * Downsample;
                }
                if (j >= nn) {
                    j = nn - 1;
                }
                deg [i] = tweaked_deg [j]; 
            }

            delay_in_samples= compute_delay (0, 
                                             2 * search_range_in_samples + number_of_samples_in_bad_interval [bad_interval], 
                                             search_range_in_samples,
                                             ref, 
                                             deg,
                                             &best_correlation);

            delay_in_samples_in_bad_interval [bad_interval] =  delay_in_samples;

            if (best_correlation < 0.5) {
                delay_in_samples_in_bad_interval  [bad_interval] = 0;
            } 

            safe_free (ref);
            safe_free (deg);
        }

        if (number_of_bad_intervals > 0) {
            doubly_tweaked_deg = (float *) safe_malloc ((maxNsamples + DATAPADDING_MSECS  * (Fs / 1000)) * sizeof (float));

            for (i = 0; i < maxNsamples + DATAPADDING_MSECS  * (Fs / 1000); i++) {
                doubly_tweaked_deg [i] = tweaked_deg [i];
            }
        
            for (bad_interval= 0; bad_interval< number_of_bad_intervals; bad_interval++) {
                int delay = delay_in_samples_in_bad_interval  [bad_interval];
                int i;
    
                for (i = start_sample_of_bad_interval [bad_interval]; i < stop_sample_of_bad_interval [bad_interval]; i++) {
                    float h;
                    int j = i + delay;
                    if (j < 0) {
                        j = 0;
                    }
                    if (j >= maxNsamples) {
                        j = maxNsamples - 1;
    
                    }
                    doubly_tweaked_deg [i] = h = tweaked_deg [j];        
                }
            }
    
            untweaked_deg = deg_info-> data;
            deg_info-> data = doubly_tweaked_deg;
    
            for (bad_interval= 0; bad_interval < number_of_bad_intervals; bad_interval++) {
    
                 for (frame = start_frame_of_bad_interval [bad_interval]; 
                     frame < stop_frame_of_bad_interval [bad_interval]; 
                     frame++) {
    
                     int start_sample_ref = SEARCHBUFFER * Downsample + frame * Nf / 2;
                    int start_sample_deg = start_sample_ref;
                    
                    short_term_fft (Nf, deg_info, Whanning, start_sample_deg, hz_spectrum_deg, fft_tmp);            
    
                    freq_warping (Nf / 2, hz_spectrum_deg, Nb, pitch_pow_dens_deg, frame);
                }    
    
                oldScale = 1;
                for (frame = start_frame_of_bad_interval [bad_interval]; 
                     frame < stop_frame_of_bad_interval [bad_interval]; 
                     frame++) {
                    int band;
    
                    total_audible_pow_ref = total_audible (frame, pitch_pow_dens_ref, 1);
                    total_audible_pow_deg = total_audible (frame, pitch_pow_dens_deg, 1);        
    
                    scale = (total_audible_pow_ref + (float) 5E3) / (total_audible_pow_deg + (float) 5E3);
                    
                    if (frame > 0) {
                        scale = (float) 0.2 * oldScale + (float) 0.8*scale;
                    }
                    oldScale = scale;
    
                    if (scale > (float) MAX_SCALE) scale = (float) MAX_SCALE;
    
                    if (scale < (float) MIN_SCALE) {
                        scale = (float) MIN_SCALE;            
                    }
    
                    for (band = 0; band < Nb; band++) {
                        pitch_pow_dens_deg [frame * Nb + band] *= scale;
                    }
    
                    intensity_warping_of (loudness_dens_ref, frame, pitch_pow_dens_ref); 
                    intensity_warping_of (loudness_dens_deg, frame, pitch_pow_dens_deg); 
        
                    for (band = 0; band < Nb; band++) {
                        disturbance_dens [band] = loudness_dens_deg [band] - loudness_dens_ref [band];
                    }
    
                    for (band = 0; band < Nb; band++) {
                        deadzone [band] = min (loudness_dens_deg [band], loudness_dens_ref [band]);    
                        deadzone [band] *= 0.25;
                    }
                    
                    for (band = 0; band < Nb; band++) {
                        float d = disturbance_dens [band];
                        float m = deadzone [band];
                    
                        if (d > m) {
                            disturbance_dens [band] -= m;
                        } else {
                            if (d < -m) {
                                disturbance_dens [band] += m;
                            } else {
                                disturbance_dens [band] = 0;
                            }
                        }
                    }    
    
                    frame_disturbance [frame] = min (frame_disturbance [frame] , pseudo_Lp (Nb, disturbance_dens, D_POW_F));    
    
                    multiply_with_asymmetry_factor (disturbance_dens, frame, pitch_pow_dens_ref, pitch_pow_dens_deg);
        
                    frame_disturbance_asym_add [frame] = min (frame_disturbance_asym_add [frame], pseudo_Lp (Nb, disturbance_dens, A_POW_F));    
                }
            }    
            safe_free (doubly_tweaked_deg);
            deg_info->data = untweaked_deg;
        }
    }
    

    for (frame = 0; frame <= stop_frame; frame++) {
        float h = 1;
        
        if (stop_frame + 1 > 1000) {
            long n = (maxNsamples - 2 * SEARCHBUFFER * Downsample) / (Nf / 2) - 1;
            double timeWeightFactor = (n - (float) 1000) / (float) 5500;
            if (timeWeightFactor > (float) 0.5) timeWeightFactor = (float) 0.5;
            h = (float) (((float) 1.0 - timeWeightFactor) + timeWeightFactor * (float) frame / (float) n);
        }

        time_weight [frame] = h;
    }

    for (frame = 0; frame <= stop_frame; frame++) {

        float h = (float) pow ((total_power_ref [frame] + 1E5) / 1E7, 0.04); 

        frame_disturbance [frame] /= h;
        frame_disturbance_asym_add [frame] /= h;

        if (frame_disturbance [frame] > 45) {
            frame_disturbance [frame] = 45;
        }
        if (frame_disturbance_asym_add [frame] > 45) {
            frame_disturbance_asym_add [frame] = 45;
        }            
    }
        
    d_indicator = Lpq_weight (start_frame, stop_frame, D_POW_S, D_POW_T, frame_disturbance, time_weight);    
    a_indicator = Lpq_weight (start_frame, stop_frame, A_POW_S, A_POW_T, frame_disturbance_asym_add, time_weight);       
    
    err_info-> pesq_mos = (float) (4.5 - D_WEIGHT * d_indicator - A_WEIGHT * a_indicator); 

    FFTFree();
    safe_free (fft_tmp);
    safe_free (hz_spectrum_ref);
    safe_free (hz_spectrum_deg);
    safe_free (silent);
    safe_free (pitch_pow_dens_ref);
    safe_free (pitch_pow_dens_deg);
    safe_free (frame_was_skipped);
    safe_free (avg_pitch_pow_dens_ref);
    safe_free (avg_pitch_pow_dens_deg);
    safe_free (loudness_dens_ref);
    safe_free (loudness_dens_deg);
    safe_free (deadzone);
    safe_free (disturbance_dens);
    safe_free (disturbance_dens_asym_add);
    safe_free (total_power_ref);

    safe_free (frame_is_bad);
    safe_free (smeared_frame_is_bad);
    
    safe_free (time_weight);
    safe_free (frame_disturbance);
    safe_free (frame_disturbance_asym_add);
    safe_free (tweaked_deg);

    return;
}

/* END OF FILE */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -