hist.c

来自「speech signal process tools」· C语言 代码 · 共 635 行 · 第 1/2 页

C
635
字号
    fflush(fp);    fclose(fp);}/*****************************************************************//* DOC-P:   half_cosine_hist()                                   *//* DOC-PS:  store the values of cos(3pi/2) to cos(5PI/2) in hist */half_cosine_hist(hist,num_bins,begin_bin,end_bin,height)HIST **hist;int num_bins, begin_bin, end_bin, height;{    int i;    float factor, heightby2;    factor = 1.0 / (float)(end_bin-begin_bin+1);    heightby2 = (float)height / 2.0;    for (i=begin_bin;(i<num_bins) && (i <= end_bin);i++){        hist[i]->count = heightby2 * (1.0+cos((float)(i-begin_bin)*factor*M_PI+M_PI));    }}/****************************************************************//* DOC-P:   full_cosine_hist()                                  *//* DOC-PS:  store the values of cos(pi/2) to cos(5pi/2) in hist */full_cosine_hist(hist,num_bins,begin_bin,end_bin,height)HIST **hist;int num_bins, begin_bin, end_bin, height;{    int i;    float factor, heightby2;    factor = 1.0 / (float)(end_bin-begin_bin+1);    heightby2 = (float)height / 2.0;    for (i=begin_bin;(i<num_bins) && (i <= end_bin+(end_bin-begin_bin));i++){        hist[i]->count = heightby2 * (1.0+cos((float)(i-begin_bin)*factor*M_PI+M_PI));    }}/*************************************************************//* DOC-P:   hist_area()                                      *//* DOC-PS:  return the area of the HIST                      */hist_area(hist,num_bins)HIST **hist;int num_bins;{    int i, sum=0;    for (i=0; i<num_bins; i++)        sum+=hist[i]->count;    return(sum);}/*************************************************************//* DOC-P:   hist_character()                                 *//* DOC-PS:  compute the mean, variance and area of a HIST    */hist_character(hist,num_bins,mean,vari,area)HIST **hist;int num_bins, *area;float *mean, *vari;{    int i;    float sum=0.0, ave;    *area = hist_area(hist,num_bins);    for (i=0; i<num_bins; i++)        sum+=(hist[i]->from+(hist[i]->to - hist[i]->from)/2.0) * hist[i]->count;    *mean = sum/(float)*area;    sum=0.0;    for (i=0; i<num_bins; i++){        if (hist[i]->count > 0){            ave = hist[i]->from + (hist[i]->to - hist[i]->from)/2.0 ;            sum+= (ave - *mean) * (ave - *mean) * hist[i]->count;            printf(" var %f ave %f mean %f\n",sum,ave,*mean);        }    }    *vari = sum / (float)*area;}/*************************************************************//* DOC-P:   max_hist()                                       *//* DOC-PS:  return the maximum value in a HIST               */max_hist(hist,num_bins)HIST **hist;int num_bins;{    int i, max=0;    for (i=0; i<num_bins; i++)        if (max<hist[i]->count)            max=hist[i]->count;    return(max);}/*********************************************************************//* DOC-P:   average_hieght_hist()                                    *//* DOC-PS:  return tge average hieght in a the center of this window */average_hieght_hist(hist,num_bins,center,window)HIST **hist;int num_bins, center, window;{    int i, sum=0;    for (i=center-window; i<=center+window; i++)        if ((i>=0) && (i<num_bins))	  sum+=hist[i]->count;    return(sum/(window*2+1));}/*************************************************************//* DOC-P:   smooth_hist()                                    *//* DOC-PS:  compute the average hieghts of the histogram     */smooth_hist(from,to,num_bins,window)HIST **from, **to;int num_bins, window;{    int i, value=0,window2=window*2;    for (value=0,i=(-window); i<(num_bins+window); i++){        if (i-window>=0)           value -= from[i-window]->count;        if (i+window<num_bins)           value += from[i+window]->count;        if ((i>=0) && (i<num_bins))           to[i]->count = value/window2;    }}int comp(a,b)int *a,*b;{  return (*a-*b);}median_filter(h,out,num_bins,size)  /* size must be ODD */HIST **h,**out;                     /* h and out may be the same */int num_bins,size;{  int bin,*out_vals,*temp,i,half_size,index,median;  int comp(); /* comparison function for sorting */    half_size=size/2;  out_vals = (int *) malloc (num_bins * sizeof (int));  temp = (int *) malloc (size * sizeof (int));  for (bin=0; bin <= num_bins; bin++) { /* loop through all the bins */    /* update analysis window */    for (i=0; i<size; i++) {      index=bin-half_size+i;      temp[i]=((index >= 0) && (index < num_bins)) ? h[index]->count : 0;    }          /* find median of window */    qsort(temp,size,sizeof(int),comp);    median = temp[half_size];    out_vals[bin]=median;  }  /* write filtered values back into output histogram */  for (i=0; i<num_bins; i++)    out[i]->count = out_vals[i];  free(out_vals);  free(temp);}    int locate_extremum(h,from,to,type)HIST **h;int from,to,type;{  int i,j,extremum,swing_loc,k,next_swing_loc,diff1,diff2,pre_swing,post_swing;  for (i=from+PEAK_WIDTH; i<to-PEAK_WIDTH; i++) {    if (h[i]->count==0) continue; /* not interested in extrema at 0 */    extremum=1; /* assume it's an extremum to begin with */    pre_swing=post_swing=0;    swing_loc=i-PEAK_WIDTH;    for (j=i-PEAK_WIDTH; j<i; j++) /* check the preceding samples */      if (type==PEAK) {	if (h[j]->count > h[j+1]->count) {	  extremum=0;	  break;	}	if (h[j]->count != h[j+1]->count) {	  pre_swing=1;	}      }	else { /* type == TROUGH */	if (h[j]->count < h[j+1]->count) {	  extremum=0;	  break;	}	if (h[j]->count != h[j+1]->count) {	  pre_swing=1;	}      }    if (!extremum) continue;    for (j=i; j<i+PEAK_WIDTH; j++) /* check the subsequent samples */      if (type==PEAK) {	if (h[j]->count < h[j+1]->count) {	  extremum=0;	  break;	}	if (h[j]->count != h[j+1]->count) {	  post_swing=1;	}      }	else { /* type == TROUGH */	if (h[j]->count > h[j+1]->count) {	  extremum=0;	  break;	}	if (h[j]->count != h[j+1]->count) {	  post_swing=1;	}      }    /* check to make sure it isn't a step function */    /* this kind of check is necessary if the peak is wider than the window */    if (((pre_swing+post_swing)<=1)&&(extremum)) {      for (k=i; k>from; k--)	if ((diff1 = (h[k-1]->count - h[k]->count)) != 0)	  break;      swing_loc=k;      for (k=i; (k<to-1); k++)  /* find next swing */	if ((diff2 = (h[k]->count - h[k+1]->count)) != 0)	  break;      next_swing_loc=k;      if ((type==PEAK)&&((diff1>0)||(diff2<0))) continue;   /* no dice */      if ((type==TROUGH)&&((diff1<0)||(diff2>0))) continue; /* ditto   */      /* otherwise, the peak is at the mid-point of this plateau */      return (int) (swing_loc+next_swing_loc)/2;    }    if (extremum) return i;  }  return to;}/*************************************************************//* DOC-P:   build_normal_hist()                              *//* DOC-PS:  store the the HIST a normal distribution         */build_normal_hist(hist,num_bins,mean,variance,total_area)HIST **hist;int num_bins;float mean, variance, total_area;{    int i;    float x, value, con, e;    printf("Building a histogram for a normal distribution\n");    printf("       mean %f,  variance %f, area %f\n",mean,variance,total_area);    con = (1.0 / sqrt(2.0*M_PI*variance));    /* first generate a N(mean,variance) dist scaled to 10000*/    for (i=0; i<num_bins; i++){        x = hist[i]->from + (hist[i]->to - hist[i]->from)/2.0;        e = exp(-( (x-mean)*(x-mean) / (2*variance)));        value = 10000.0 * con * e;        hist[i]->count = value;    }    /* now normalize it to the total_area */    { float scale; int area;      area = hist_area(hist,num_bins);      scale = (float)total_area/(float)area;      for (i=0; i<num_bins; i++)          hist[i]->count *= scale;    }}/*************************************************************//* DOC-P:   hist_slope()       *//* DOC-PS:  return the slope of histogram the center  */hist_slope(hist,num_bins,center,factor)HIST **hist;int num_bins,center,factor;{    int ind, cnt;    for (ind=0,cnt=0; ind < factor; ind++)        if (center-ind < 0)             cnt -= hist[center+ind]->count;        else if (ind+center>=num_bins)            cnt += hist[center-ind]->count;        else            cnt += hist[center-ind]->count - hist[center+ind]->count;    return((int)-(((float)cnt/(float)factor)*1000.0));}/*************************************************************//* DOC-P:   do_hist()       *//* DOC-PS:  using an input array, compute a historgram */do_hist(hist,num_bins,arr,arr_cnt)HIST **hist;int num_bins, arr_cnt;float *arr;{    int i, index, out_of_range=0;    float dist, from;    from = hist[0]->from;    dist = hist[num_bins-1]->to - hist[0]->from;    for (i=0; i<arr_cnt; i++){        index = (int)((float)num_bins * (*(arr+i) - from) / dist);        if ((index>=0) && (index<num_bins)) hist[index]->count++;        else            out_of_range++;    }}

⌨️ 快捷键说明

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