/***************************************************************************/ /* Part of speech segregation program for the 1999 IEEE Trans. Neural Net. */ /* paper by D.L. Wang and G.J. Brown. */ /* It takes the PITCHMASK produced earlier, does segmentation, and */ /* performs conformation and trimming by the longest segment. */ /* Its output will be read by the program "stream.c", and the */ /* latter produces the outcome of speech segregation (two streams). */ /***************************************************************************/ #include #include #define MAX_CHANNEL 127 #define MAX_DELAY 200 #define MIN_DELAY 32 #define MAX_FRAME 300 #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; int numChannels, numFrames; short channels[MAX_FRAME][MAX_CHANNEL]; short pitchmask[MAX_FRAME][MAX_CHANNEL]; short mask[MAX_FRAME][MAX_CHANNEL]; group segment[MAX_SEGMENT]; short groupsize[MAX_SEGMENT]; short sourcemask[MAX_FRAME][MAX_CHANNEL]; void clearSourceMask() { int frame, chan; for (frame=0; frameoneCount[frame]=0; g->twoCount[frame]=0; } g->first=numFrames; g->last=0; g->size=0; g->head=NULL; g->group_id=0; } void initChannels() { int frame, chan; for (frame=MIN_FRAME; framenext=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 update(int s, point *p) { int frame, chan; if (p!=NULL) { if (segment[s].oneCount[p->frame]>segment[s].twoCount[p->frame]) pitchmask[p->frame][p->chan]=1; else pitchmask[p->frame][p->chan]=2; update(s,p->next); } } void writeGroup(int n, int numFrames) { 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=0; frameoneCount[frame]++; if (channels[frame][chan]==2) g->twoCount[frame]++; channels[frame][chan]=0; if (chan0) searchGroup(g,frame,chan-1,numFrames,numChannels); if (frame>0) searchGroup(g,frame-1,chan,numFrames,numChannels); if (frame= segment[n1].twoCount[frame]); test2=(segment[n2].oneCount[frame] >= segment[n2].twoCount[frame]); return (test1 && test2) | (!test1 && !test2); } int min(int x1, int x2) { return (x1x2) ? x1 : x2; } int matchSegment(int n1, int n2) { int st, fn, cnt, frame; cnt=0; st=max(segment[n1].first,segment[n2].first); fn=min(segment[n1].last,segment[n2].last); for (frame=st; frame<=fn; frame++) cnt+=matchPitch(n1,n2,frame); //fprintf(stderr,"SEED=%d TARGET=%d ST=%d FN=%d CNT=%d\n",n2,n1,st,fn,cnt); if (((float)cnt/((float)fn-(float)st))>0.5) return TRUE; else return FALSE; } int overlap(int n1, int n2) /* do segments n1 and n2 overlap? */ { int s1, s2, f1, f2; s1=segment[n1].first; f1=segment[n1].last; s2=segment[n2].first; f2=segment[n2].last; return ((s1>=s2)&&(f1<=f2)) | ((s2>=s1)&&(f2<=f1)) | ((s2>s1)&&(f1s2)) | ((s1>s2)&&(f2s1)); } main(int argc, char **argv) { int opt; extern char *optarg; int ok = TRUE; char path[100]; char fname[150]; int frame, chan, dummy; short pg[MAX_DELAY]; int numSegment; group newSegment; int seed, s, MaxSize, groupNum; FILE *ofp1, *ofp2, *ifp; while ((opt=getopt(argc,argv,"n:")) != EOF) switch(opt) { case 'n': numFrames=atoi(optarg); break; case '?': ok = FALSE; } if (ok==FALSE) exit(0); numChannels=127; for (frame=0; frame=2) { 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 biggest segment to seed the search */ seed=0; MaxSize=0; for (s=0; s MaxSize) { MaxSize=(segment[s].last-segment[s].first); seed=s; } } /* TEMPORARY CODE */ /* create a pitch mask with /* trim the pitch mask */ /* for (s=0; s