📄 hslab.c
字号:
done = TRUE; break; case BT_PAUSE: if(DoPause() == BT_REC) /* wait for next button press */ done = TRUE; else { nWaiting = SamplesInAudio(ain); /* flush accumulated samples */ do { nToFlush = (nWaiting > nEmpty) ? nEmpty : nWaiting; GetRawAudio(ain, nToFlush, buf); nWaiting -= nToFlush; } while (nWaiting > 0); } break; } } } } if( nEmpty==0 || done) break; } /* shutdown audio and tranfer data into wave structure */ StopAudioInput(ain); CloseAudioInput(ain); *nSamples = nTotal; w = OpenWaveOutput(&tmpStack, sampPeriod, *nSamples); PutWaveSample(w, *nSamples, recbuf); return w;}/* Playback: playback part of DataFile with given volume and scale */void Playback(Wave w, long sampA, long sampB, int vol, int scale, Boolean *newData){ long i; AudioOut aout; short *data, *p; HTime sampP = sampPeriod; static long nSamples; static short *playBuf; static int c_scale = -1; int volmap[10] = {0,10,20,30,40,50,60,70,85,100}; ResetHeap(&tmpStack); /* Reload buffer if new data or scale changed */ if ((*newData) || (scale!=c_scale)) { data = GetWaveDirect(w, &nSamples); ResetHeap(&audStack); playBuf = (short *) New(&audStack, nSamples*sizeof(short)); for (p=data, i=0; i<nSamples; i++, p++) playBuf[i] = ClipSample(*p, scale); *newData = FALSE; c_scale = scale; } aout = OpenAudioOutput(&tmpStack, &sampP); SetVolume(aout, volmap[vol]); /* Set up play buffer */ if (sampA < 0) sampA = 0; if (sampB > nSamples) sampB = nSamples; i = sampB - sampA; if (i>0) /* play segment of sound */ StartAudioOutput(aout, i, playBuf+sampA); while(SamplesToPlay(aout)>0); CloseAudioOutput(aout);}/* ---------------------- Command Processing ------------------------ */static char *command_map[] = { "HSLABCMD", "HSLABRUN"};typedef enum { HSLabCmd, HSLabRun} HSlabCmdType;/* CommandSet: returns true and puts cmd in s if envvar set */Boolean CommandSet(HSlabCmdType hcmd, char *s){ char *env; if ((env = getenv(command_map[hcmd])) != NULL){ strcpy(s,env); return TRUE; } else return FALSE;}/* ----------------------- Rectangular Windows ----------------------- *//* InitRectWin: create and initialise a RectWin structure */void InitRectWin(RectWin *win, float x, float y, float w, float h, int bw, HColour fg, HColour bg){ win->w = (int) (WIDTH * w); win->h = (int) (HEIGHT *h); win->x = (int) (WIDTH * x); win->y = (int) (HEIGHT * y); win->bw = bw; win->fg = fg; win->bg = bg;}/* DrawRectWin: draw a rect window on the screen */void DrawRectWin(RectWin *win){ HSetColour(win->bg); HFillRectangle(win->x, win->y, win->x + win->w, win->y + win->h); HSetColour(win->fg); HSetLineWidth(win->bw); HDrawRectangle(win->x, win->y, win->x + win->w, win->y + win->h);}/* IsInRectWin: check if (x, y) is in w */Boolean IsInRectWin(RectWin *w, int x, int y){ return IsInRect(x, y, w->x, w->y, w->x + w->w, w->y + w->h);}/* IsInWin: check if (x, y) is in w */Boolean IsInWin(RectWin *w, int x, int y){ return IsInRect(x, y, w->x, w->y, w->x + w->w, w->y + w->h);}/* GetWinKind: return window kind associated with given event */WinKind GetWinKind(HEventRec hev){ if (IsInWin(&waveWin,hev.x,hev.y)) return WAVE_WIN; if (IsInWin(&labWin1,hev.x,hev.y)) return LAB_WIN; if (IsInWin(&io_Win,hev.x,hev.y)) return IO_WIN; return NO_WIN;} /* Point2Sample: converts a point from the wave form window into a sample number */long Point2Sample(RectWin *win, int pt){ int t; t=(int) (sStart + (float) (pt - (win->x))*samplesPt); if (t<sStart) t=sStart;if (t>sEnd) t=sEnd; return t;}/* ------------------------- Wave Ptr Handling --------------------------- *//* PlotWaveWinPtr: plot the waveform window pointer in inverted colour */void PlotWaveWinPtr(int pos){ HSetXMode(GINVERT); HDrawLine(pos, waveWin.y + 1, pos, waveWin.y + waveWin.h); HDrawLine(pos, labWin1.y + 1, pos, labWin1.y + labWin1.h); HSetXMode(GCOPY);}/* WPtrOff: turn the waveform window pointer off */void WPtrOff(void){ if (wavePtrOn){ PlotWaveWinPtr(thisWpos); wavePtrOn = FALSE; }}/* WPtrOn: turn the waveform window pointer on */void WPtrOn(void){ if (!wavePtrOn){ PlotWaveWinPtr(thisWpos); wavePtrOn = TRUE; }}/* ----------------------- Misc Plot Routines ---------------------------- *//* PlotGStripes: create and draw a grey scale image for about box */void PlotGStripes(int x, int y, int width, int height){ int i, j; unsigned char *pix; static unsigned char *gimage = NULL; if (gimage==NULL){ gimage = (unsigned char *) New(&tmpCHeap,width*height*sizeof(unsigned char)); pix = gimage; for (j = 0; j < height; j++) for (i = 0; i < width; i++) *pix++ = (unsigned char) (i % MAX_GREYS); } HDrawImage(gimage, x, y, width, height);}/* PrintMsg: print a message in the io_window */void PrintMsg(RectWin *win, char *msg){ int sx, sy, pos, pad = 4; char sbuf[256]; HSetXMode(GCOPY); DrawRectWin(win); if (msg==NULL) return; strcpy(sbuf, msg); pos = strlen(sbuf); while(HTextWidth(sbuf) > (win->w - 2*pad)) sbuf[--pos]='\0'; HSetColour(win->fg); sx = win->x + pad; sy = CentreY(win->y + win->h/2, sbuf); HPrintf(sx, sy, "%s", sbuf);}/* ----------------------- LabList Processing ------------------------------ *//* CreateLabObj: create and insert a Label into a sorted LabList */Label *CreateLabObj(LabList *ll, LabId labid, long st, long en){ LLink p, q; q = CreateLabel(&labStack, 10); q->start = st; q->end = en; q->labid = labid; q->score = 0.0; q->succ = NULL; q->pred = NULL; for (p=ll->head->succ; p->succ!=NULL; p=p->succ) if (p->start > st) break; q->succ = p; q->pred = p->pred; q->pred->succ = q; p->pred = q; return q;}/* TimesLabelled: returns the number of times frame pos is labelled */int TimesLabelled(LabList *ll, long pos){ int c; LLink p; c = 0; for (p=ll->head->succ; p->succ!=NULL; p=p->succ) if (pos >= p->start && pos <= p->end) c++; return c;}/* MaxTimesLabelled: find frame with max number of labels and returns that number */int MaxTimesLabelled(LabList *ll, long st, long en){ long t; int a, max; for (max=0, t=st; t<en; t++){ a = TimesLabelled(ll, t); if (a > max) max = a; } return max;}/* DeleteLabObj: deletes q from LabList ll, q must be in lablst */ void DeleteLabObj(LabList *ll, LLink q){ LLink p; if (ll->head==q || ll->tail==q) HError(1590, "DeleteLabObj: attempt to delete sentinel"); for (p=ll->head; p->succ!=NULL; p=p->succ) if (p==q) break; if (p!=NULL) { p->pred->succ = p->succ; p->succ->pred = p->pred; }}/* GetLabDistance: return a pointer to a label whose start or end point are within minimum distance of t. The code takes care of exact boundaries i.e. the end of the current label matches the start of it's successor by taking (start + eps) and (end - eps) where eps is a small number. */LLink GetLabDistance(LabList *ll, long t, long st, long en, Boolean *isStart){ long pos; LLink p, bp; float eps = 0.005; float d, min_d, fpos; bp=NULL; min_d=INT_MAX; for (p=ll->head->succ; p->succ!=NULL; p=p->succ){ fpos = p->start; pos = (long) fpos; if ((pos >= st) && (pos < en)){ fpos += eps; d = fabs((float) t - fpos); if (d < min_d) { bp = p; min_d = d; *isStart = TRUE; } } fpos = p->end; pos = (long) fpos; if ((pos >= st) && (pos < en)){ fpos -= eps; d = fabs((float) t - fpos); if (d < min_d) { bp = p; min_d = d; *isStart = FALSE; } } } return bp;}/* GetLabT: returns a pointer to the first Label in the ll which contains t */LLink GetLabT(LabList *ll, long t){ LLink p; for (p=ll->head->succ; p->succ!=NULL; p=p->succ) if ((t > p->start) && (t < p->end)) return p; return NULL;}/* Intersect: returns TRUE if the regions (a,b):{a<=b} and (a1,b1):{a1<=b1} intersect */Boolean Intersect(long a, long b, long a1, long b1){ return !(((a1 < a) && (b1 < a)) || ((a1 >= b) && (b1 >= b)));}/* PlotLabels: draws the labels on the screen. This routine assumes that no frame is labelled more than twice. The display is split into two levels for improved clarity. If a label text is too large to fit in the corrsponding box on the screen the code attempts to print a single dot, if there is still no room nothing is printed. Also `..` are added to the start or the end of the label text if the labelled region continues off the screen. */void PlotLabels(RectWin *win, LabList *ll, long sStart, long sEnd){ LLink p; float spt; long nSamples; HTime st, en, p_en; char sbuf[SLEN]; short shift, p_shift; Boolean no_st_bar, no_en_bar; char *dot = ".", *dot2 = "..", *str; int x, y, h, w, yy, b1, b2, bb, h2, nPoints; nPoints = win->w - 1; nSamples = sEnd - sStart; spt = (float)nSamples/(float)nPoints; x = win->x; y = win->y; w = win->w; h = win->h; h2 = h/2; shift = 0; p_en = 0; p_shift = 0; HDrawLine(x, y+h2, x+w, y+h2); /* traverse the list and plot visible labels on the screen */ for (p=ll->head->succ; p->succ!=NULL; p=p->succ){ st = p->start; en = p->end; if (!Intersect(sStart, sEnd, (long) st, (long) en)) continue; no_st_bar = no_en_bar = FALSE; str = p->labid->name; if (st < sStart) { st = sStart; no_st_bar = TRUE; } b1 =(int) (x + (float)(st - sStart)/spt); if (en >= sEnd){ en = sEnd-1; no_en_bar = TRUE; } b2 = (int) (x + (float)(en - sStart)/spt); sbuf[0]='\0'; shift = (st < p_en) ? (p_shift + 1) % 2 : 0; yy = y + shift*h2; if (no_st_bar) strcat(sbuf, dot2); else HDrawLine(b1, yy+1, b1, yy+h2); strcat(sbuf, str); if (no_en_bar) strcat(sbuf, dot2); else HDrawLine(b2, yy+1, b2, yy+h2); bb = (b2 - b1); if (HTextWidth(sbuf) < bb) HPrintf(CentreX(b1 + bb/2, sbuf), CentreY(yy + h2/2, sbuf), "%s", sbuf); else if (HTextWidth(dot) < bb) HPrintf(CentreX(b1 + bb/2, dot), CentreY(yy + h2/2, dot), "%", dot); if (en >= p_en){ p_en = en; p_shift = shift; } }}/* PlotLabWin: plot the label window */ void PlotLabWin(void){ WPtrOff(); HSetXMode(GCOPY); DrawRectWin(&labWin1); HSetColour(labWin1.fg); HSetLineWidth(0); PlotLabels(&labWin1, llist, sStart, sEnd);}/* ------------------------- WaveForm Processing --------------------------- *//* ClipSample: scale a sample, apply clipping if necessary */short ClipSample(short sample, float sampleScale){ int intSample; intSample = (int) (sample * sampleScale); if (intSample > MAX_AMPL) intSample = MAX_AMPL; if (intSample < MIN_AMPL) intSample = MIN_AMPL; return (short) intSample;}/* AdjustBounds: adjust the sStart & sEnd such that there are at least 1.0 samples per pixel */void AdjustBounds(RectWin *win){ long np, ns, st, en; float p; np = win->w - 1; ns = sEnd - sStart; p = (float)ns/(float)np; if (p > 1.0) return; en = sStart + np; if (en <= T) { sEnd = en; return; } st = sEnd - np; if (st >= 0) { sStart = st; return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -