/***************************************************************************/ /* Speech segregation program for the 1999 IEEE Trans. Neural Net. paper */ /* by D.L. Wang and G.J. Brown. */ /* The segments produced by this program have been discarded since an */ /* older version was used. The two useful outputs are: */ /* (1) The file "PITCHMASK"; (2) The file "ENERGY". The latter is a */ /* map (frequency-time) representation of the Meddis hair cell response. */ /***************************************************************************/ #include #include #define MAX_CHANNEL 128 #define MAX_DELAY 200 #define MIN_DELAY 32 #define MAX_FRAME 150 /* 323 or 150 */ #define MIN_FRAME 0 #define MAX_SEGMENT 300 /* threshold WAS 0.95 */ #define THRESHOLD 0.95 #define ENERGY_THRESHOLD 50.0 #define GROUP_THRESHOLD 0.985 #define TRUE 1 #define FALSE 0 #define sqr(x) ((x)*(x)) struct _point { int frame; int chan; struct _point *next; } _point; typedef struct _point point; struct _group { int first; int last; int size; short group_id; point *head; short oneCount[MAX_FRAME]; short twoCount[MAX_FRAME]; } _group; typedef struct _group group; float acg[MAX_DELAY][MAX_CHANNEL]; float norm_acg[MAX_DELAY][MAX_CHANNEL]; float correlation[MAX_FRAME][MAX_CHANNEL]; float summary[MAX_DELAY]; short channels[MAX_FRAME][MAX_CHANNEL]; short energy[MAX_FRAME][MAX_CHANNEL]; /* newly added */ short mask[MAX_FRAME][MAX_CHANNEL]; group segment[MAX_SEGMENT]; short groupsize[MAX_SEGMENT]; short sourcemask[MAX_FRAME][MAX_CHANNEL]; int count_one[MAX_FRAME]; int count_two[MAX_FRAME]; int group_first; int group_last; void clearSourceMask() { int frame, chan; for (frame=0; frameoneCount[frame]=0; g->twoCount[frame]=0; } g->first=MAX_FRAME; g->last=MIN_FRAME; g->size=0; g->head=NULL; g->group_id=0; } void zeroCounts() { int frame; for (frame=MIN_FRAME; framemaxVal) { maxVal=summary[delay]; maxDelay=delay; } return maxDelay; } void selectChannels(int frame, int maxd) { int chan, delay; float maxval; for (chan=0; chanmaxval) maxval=acg[delay][chan]; if ((acg[maxd][chan]/maxval)>THRESHOLD) channels[frame][chan]=1; } } void writeChannels() { int chan, frame; FILE *ofp; ofp=fopen("PITCHMASK","w"); for (frame=MIN_FRAME; frameGROUP_THRESHOLD) && (acg[0][chan]>ENERGY_THRESHOLD)) { mask[frame][chan]=1; } } } void addPoint(group *g, int f, int c) { point *p; //fprintf(stderr,"adding (%d,%d)\n",f,c); p=(point *)malloc(sizeof(point)); p->next=g->head; p->frame=f; p->chan=c; g->size++; g->head=p; if (f < g->first) g->first=f; if (f > g->last) g->last=f; } void traverse(point *p) { if (p!=NULL) { printf("%d %d\n",p->frame,p->chan); traverse(p->next); } } void addToMask(point *p) { if (p!=NULL) { sourcemask[p->frame][p->chan]=1; addToMask(p->next); } } void traverseToFile(point *p, FILE *ofp) { if (p!=NULL) { fprintf(ofp,"%d %d\n",p->frame,p->chan); traverseToFile(p->next,ofp); } } void writeGroup(int n) { char fname[30]; FILE *ofp; int frame; sprintf(fname,"SEGMENT.%03d",n); ofp=fopen(fname,"w"); if (ofp==NULL) { fprintf(stderr,"ARGH!!! CANNOT OPEN FILE\n"); exit(0); } fprintf(ofp,"first=%d last=%d size=%d\n",segment[n].first,segment[n].last,segment[n].size); fprintf(ofp,"Count for group 1:\n"); for (frame=MIN_FRAME; frameoneCount[frame]++; if (channels[frame][chan]==2) g->twoCount[frame]++; if (chan0) searchGroup(g,frame,chan-1); if (frame>0) searchGroup(g,frame-1,chan); if (frame= segment[n].twoCount[frame]); test2=(count_one[frame] >= count_two[frame]); return (test1 && test2) | (!test1 && !test2); } int min(int x1, int x2) { return (x1x2) ? x1 : x2; } int matchSegment(int n) { int st, fn, cnt, frame; cnt=0; st=max(segment[n].first,group_first); fn=min(segment[n].last,group_last); for (frame=st; frame<=fn; frame++) cnt+=matchPitch(n,frame); //fprintf(stderr,"TARGET=%d ST=%d FN=%d CNT=%d\n",n,st,fn,cnt); if (((float)cnt/((float)fn-(float)st))>0.5) return TRUE; else return FALSE; } int overlap(int n) /* does segment n overlap with group? */ { int s1, s2, f1, f2; s1=group_first; f1=group_last; s2=segment[n].first; f2=segment[n].last; return ((s1>=s2)&&(f1<=f2)) | ((s2>=s1)&&(f2<=f1)) | ((s2>s1)&&(f1s2)) | ((s1>s2)&&(f2s1)); } main() { int maxDelay; int frame, chan; char fname[50]; short pg[MAX_DELAY]; int delay; int numSegment; group newSegment; int seed, s, s1, MaxSize, groupNum; FILE *ofp1, *ofp2; int maxval = 0, temp; initChannels(); for (frame=MIN_FRAME; frame maxval) maxval = energy[frame][chan]; fprintf(ofp1, "%d ", energy[frame][chan]); } printf("maximum energy is %d\n", maxval); /* numSegment=0; for (frame=MIN_FRAME; frame2) { writeGroup(numSegment); numSegment++; if (numSegment==MAX_SEGMENT) { fprintf(stderr,"TOO MANY SEGMENTS! TERMINATING THE SEARCH"); exit(0); } } } fprintf(stderr,"Made the elements ... doing the search now.\n"); */ /* find the longest segment to seed the search */ /* zeroCounts(); seed=0; MaxSize=0; for (s=0; s MaxSize) { MaxSize=(segment[s].last-segment[s].first); seed=s; } } fprintf(stderr,"searching from segment %d\n",seed); segment[seed].group_id=1; add_pitch_info(seed); group_first=segment[seed].first; group_last=segment[seed].last; for (s1=0; s1group_last) group_last=segment[s].last; } } */ /* now find the next group */ /* zeroCounts(); seed=0; MaxSize=0; for (s=0; s MaxSize)) { MaxSize=segment[s].last-segment[s].first; seed=s; } } fprintf(stderr,"searching from segment %d\n",seed); segment[seed].group_id=2; add_pitch_info(seed); group_first=segment[seed].first; group_last=segment[seed].last; for (s1=0; s1group_last) group_last=segment[s].last; } } */ /* make the groups */ /* clearSourceMask(); for (s=0; s