📄 hslab.c
字号:
/* ----------------------------------------------------------- *//* *//* ___ *//* |_| | |_/ SPEECH *//* | | | | \ RECOGNITION *//* ========= SOFTWARE */ /* *//* *//* ----------------------------------------------------------- *//* developed at: *//* *//* Speech Vision and Robotics group *//* Cambridge University Engineering Department *//* http://svr-www.eng.cam.ac.uk/ *//* *//* Entropic Cambridge Research Laboratory *//* (now part of Microsoft) *//* *//* ----------------------------------------------------------- *//* Copyright: Microsoft Corporation *//* 1995-2000 Redmond, Washington USA *//* http://www.microsoft.com *//* *//* 2001 Cambridge University *//* Engineering Department *//* *//* Use of this software is governed by a License Agreement *//* ** See the file License for the Conditions of Use ** *//* ** This banner notice must not be removed ** *//* *//* ----------------------------------------------------------- *//* File: HSLab.c: The Speech Label Editor *//* ----------------------------------------------------------- */char *hslab_version = "!HVER!HSLab: 3.3 [CUED 28/04/05]";char *hslab_vc_id = "$Id: HSLab.c,v 1.2 2005/05/12 15:51:29 jal58 Exp $";/* -------------------------------------------------------------- In order to compile this program, you may need to use different compiler options. For example, under HP-UX 8.07 you would add -D_HPUX_SOURCE to the compiler flags. Also the environment variable LPATH will need to be set to "/lib:/usr/lib:/usr/lib/X11R4" --------------------------------------------------------------*//* Enable use of stat calls to reload files changed by another process - e.g. label files generated by a recogniser #define USE_STAT*/#define USE_STAT#include "HShell.h"#include "HMem.h"#include "HMath.h"#include "HWave.h"#include "HAudio.h"#include "HLabel.h"#include "HGraf.h"#define WINNAME "HSLab"#define HSLAB_INFO "HSLab V2.0 by Valtcho Valtchev and Steve Young"#define SLEN 256 /* string length for various buffers */#define MAX_ZOOM 100 /* maximum level of zooming */#define INIT_XPOS 10 /* initial x-position of the HSLab window */#define INIT_YPOS 10 /* initial y-position of the HSLab window */#define WIDTH 700 /* window width */#define HEIGHT 500 /* window height */#define MAX_LAB_LEN 128 /* maximum length of a string representing a label */#define LAB_BUF_LEN 256 /* string length for buffers used to store labels *//* define 16-bit resolution, assume that shorts are 16-bit */#define MIN_AMPL SHRT_MIN #define MAX_AMPL SHRT_MAX#define AMPL_RANGE USHRT_MAX/* button configuration relative to the main window size */#define BTN_AREA_W 1.00 /* area width as fraction of main window width */#define BTN_AREA_H 0.25 /* area height as fraction of main window height */#define BTN_AREA_X 0.0 /* top left corner x of button area as fraction of main win width */#define BTN_AREA_Y 0.75 /* top left corner y of button area as fraction of main win height */#define BTN_PER_ROW 10.0 /* how many buttons in a single row in button area */#define BTN_PER_COL 3.0 /* how many buttons in a column in button area */#define BTN_H_SPC 0.20 /* vertical spacing between rows of buttons as fraction of btn_width */#define BTN_V_SPC 0.33 /* horizontal spacing between cols of buttons as fraction of btn_height */#define SCROLL_PT 20#define NUM_OF_SCALES 6 /* the number of different amplitude scales */#define VOLUME_STEPS 10 /* volume control button steps */#define TIMES_LABELLED 2 /* maximum number of times a frame can be labelled *//* -------------------------- Global Types ------------------------ */typedef enum { WAVE_WIN, LAB_WIN, IO_WIN, NO_WIN } WinKind;typedef enum { BT_NONE, BT_LOAD, BT_SAVE, BT_SCRLL, BT_SCRLR, BT_ZOOM_IN, BT_ZOOM_OUT, BT_RESTORE, BT_PLAY, BT_PLAY_VOL, BT_SCALE, BT_MARK, BT_UNMARK, BT_LABSTR, BT_LABEL, BT_LABELAS, BT_LDELETE, BT_LEDIT, BT_LSELECT, BT_ABOUT, BT_ADJUST, BT_LABSET, BT_NEWSET, BT_UNDO, BT_SPCL, BT_REC, BT_PAUSE, BT_STOP, BT_QUIT} BtnId;typedef struct { /* used to record different levels of zooming */ long st, en; /* start and end sample of the previous zoom level */ int regA, regB; /* marked regions on the screen (if any) */} ZoomRecord;typedef enum { CREATE_OP, DELETE_OP, CHANGE_OP} OpType;typedef struct { /* used to keep track of tha last operation carried out */ OpType op; /* the operation carried out */ int lset; /* label set */ Label lab; /* the label prior to change */ LLink ptr; /* pointer to the label last modified (if any) */} UndoRecord; typedef struct{ /* the structure describing the various windows on the main window */ int x, y, w, h, bw; /* x-pos, y-pos, width, height, fg and bg colours */ HColour fg, bg;} RectWin;/* ----------------------- Global Variables ---------------------------- */#define STACKSIZE 100000 /* assume ~100K wave files */static MemHeap tmpStack; /* temporary storage with reset */static MemHeap tmpCHeap; /* storage allocated once */static MemHeap wavStack; /* storage for waveforms */static MemHeap labStack; /* storage for label objects */static MemHeap audStack;static short *data; /* the data samples */static long nSamples; /* number of samples */static HTime sampPeriod; /* the sample period */static Wave wave; /* the input waveform */static Boolean newData=FALSE;static FileFormat ifmt=UNDEFF; /* Label input file format */static FileFormat ofmt=UNDEFF; /* Label output file format */static FileFormat wfmt=UNDEFF; /* wave file format */static HButton *btnList; /* the list of buttons displayed on the HSLab window */static RectWin waveWin; /* the waveform window */static RectWin fileWin; /* the window for file names and other info */static RectWin labWin1; /* the label window */static RectWin io_Win; /* the I/O window used for messages and inputing strings */static int trace = 0; /* trace level */static int nParm = 0; /* total num params */static ConfParam *cParm[MAXGLOBS]; /* configuration parameters */static char labstr[LAB_BUF_LEN] = "Speech";static HButton *labstr_btn;static char volStr[10]; /* the string displayed in the volume button */static short playVol = 0; /* the volume for playing samples */static HButton *vol_btn; /* pointer to the volume button */static HButton *lev_btn; /* the level button */static char levStr[10]; /* the level button string */static int btn_v_spc; /* calculated button vertical spacing */static int btn_h_spc; /* calculated button horizontal spacing */static int btn_w; /* calculated button width */static int btn_h; /* calculated button height */static int *plotBuf; /* buffer to store waveform samples to plot */static int zoomLev; /* the current zoom level - ptr in the zoom record */static ZoomRecord zoomRec[MAX_ZOOM]; /* the zoom record */static float samplesPt; /* samples per point of the graphics screen */static long T; /* number of samples */ /* waveform scaling */static float scValues[NUM_OF_SCALES] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0};static char *scString[NUM_OF_SCALES] = {"x1", "x2", "x4", "x8", "x16", "x32"};static short scIndex = 0; /* initial scaling index == 1.0*/static HButton *scale_btn; /* pointer to the amplitude scale button */static Boolean wavePtrOn = FALSE; /* keeps track of the state of the waveform pointer */static int thisWpos, lastWpos; /* the positions of the waveform pointer */static char labfn[SLEN]; /* the label file name */static char spfn[SLEN] = "noname.wav"; /* the speech (waveform) file name */static char *ospfn = "noname.wav"; /* the speech file name on the command line */static char *labDir = NULL; /* directory for label files */static char *labExt = "lab"; /* label file extension */static long sStart, sEnd; /* the start and end sample currently visible on the screen */static Transcription *trans; /* the transcriptions */static LabList *llist; /* the current label list edited */static int labSet; /* the number of the current label list */static int numSet; /* number of alternative transcriptions */static Boolean labsModified = FALSE; /* tracks any changes made to the labels */static Boolean newLabFile = FALSE; /* forcing the creation of a new (empty) label file */static Boolean incLab = FALSE; /* increment global label */static Boolean regnMarked = FALSE; /* region marked */static int markA, markB; /* boundaries of a marked region */static UndoRecord undo; /* the undo record variable */static Boolean undoEmpty; /* shows the status of the record */static HButton *spcl_btn; /* pointer to special button */static char spcl_str[SLEN] = "Command"; /* special button string *//* ---------------- Process Command Line ------------------------- */void ReportUsage(void){ printf("\nUSAGE: HSLab [options] waveformFile\n\n"); printf(" Option Default\n\n"); printf(" -a auto-increment global label off\n"); printf(" -i s Output transcriptions to MLF s off\n"); printf(" -n Create new transcription off\n"); printf(" -s str Set special button label command\n"); PrintStdOpts("FGILPX");}int main(int argc, char *argv[]){ char *s; void Initialise(void); void LoadFiles(void); void hRedrawWindow(void); void DecodeCommands(void); void CloseAudio(void); if(InitShell(argc,argv, hslab_version, hslab_vc_id)<SUCCESS) HError(1500,"HSLab: InitShell failed"); InitMem(); InitMath(); InitWave(); InitLabel(); InitAudio(); InitGraf(); if (!InfoPrinted() && NumArgs() == 0) ReportUsage(); if (NumArgs() == 0) Exit(0); while (NextArg() == SWITCHARG) { s = GetSwtArg(); if (strlen(s)!=1) HError(1519,"HSLab: Bad switch %s; must be single letter",s); switch(s[0]){ case 'a': incLab = TRUE; break; case 'i': if (NextArg()!=STRINGARG) HError(1519,"HSLab: Output MLF file name expected"); if(SaveToMasterfile(GetStrArg())<SUCCESS) HError(1514,"HCopy: Cannot write to MLF"); break; case 'n': newLabFile = TRUE; break; case 's': if (NextArg() != STRINGARG) HError(1519,"HSLab: Button label expected"); strcpy(spcl_str, GetStrArg()); break; case 'F': if (NextArg() != STRINGARG) HError(1519,"HSLab: HSLab: Data File format expected"); if((wfmt = Str2Format(GetStrArg())) == ALIEN) HError(-1589,"HSLab: Warning ALIEN Data file format set"); break; case 'G': if (NextArg() != STRINGARG) HError(1519,"HSLab: Label File format expected"); if((ifmt = Str2Format(GetStrArg())) == ALIEN) HError(-1589,"HSLab: Warning ALIEN Label input file format set"); break; case 'I': if (NextArg() != STRINGARG) HError(1519,"HSLab: Input MLF file name expected"); LoadMasterFile(GetStrArg()); break; case 'L': if (NextArg()!=STRINGARG) HError(1519,"HSLab: HSLab: Label file directory expected"); labDir = GetStrArg(); break; case 'P': if (NextArg() != STRINGARG) HError(1519,"HSLab: Label File format expected"); if((ofmt = Str2Format(GetStrArg())) == ALIEN) HError(-1589,"Warning ALIEN Label output file format set"); break; case 'T': trace = GetChkedInt(0,65535,s); break; case 'X': if (NextArg()!=STRINGARG) HError(1519,"HSLab: Label file extension expected"); labExt = GetStrArg(); break; default: HError(1519,"HSLab: Unknown switch %s",s); } } if (NextArg()==STRINGARG) strcpy(spfn, ospfn=GetStrArg()); Initialise(); LoadFiles(); hRedrawWindow(); DecodeCommands(); TermHGraf(); Exit(0); return (0); /* never reached -- make compiler happy */}/* ------------------------- Bar handling ------------------------- */#define BAR_WIDTH 200#define BAR_HEIGHT 15#define BAR_BORDER 2typedef struct { int x, y; HColour fg; float step;} BarType;static void InitBar(BarType *bar, int x_ofs, HColour fg, int range, char *str){ bar->x = io_Win.x + x_ofs + HTextWidth(str) + 10; bar->y = io_Win.y + (io_Win.h - BAR_HEIGHT)/2; bar->fg = fg; bar->step = (float) (BAR_WIDTH - 2*BAR_BORDER)/(float) range; HSetColour(BLACK); HPrintf(io_Win.x+x_ofs, io_Win.y+(io_Win.h/2)+HTextHeight(str)/2, "%s", str); HSetGrey(30); HFillRectangle(bar->x, bar->y, bar->x+BAR_WIDTH, bar->y+BAR_HEIGHT);}static void StepBar(BarType *bar, int pos){ int x0, y0, x1, y1; HSetGrey(30); HFillRectangle(bar->x, bar->y, bar->x+BAR_WIDTH, bar->y+BAR_HEIGHT); x0 = bar->x + BAR_BORDER; y0 = bar->y + BAR_BORDER; x1 = x0 + ((int) bar->step*pos); y1 = bar->y + BAR_HEIGHT-BAR_BORDER; HSetColour(bar->fg); HFillRectangle(x0, y0, x1, y1); }/* ------------------------- Audio Drivers -------------------------- */#define REC_BUF_SIZE 1920000typedef signed short SampleType;BtnId DoPause(void);short ClipSample(short sample, float sampleScale);/* Record: record signal from audio device */Wave Record(long *nSamples, HTime *sampPeriod){ Wave w; AudioIn ain; float bufDur; HButton *btn; Boolean done; HEventRec hev; BarType tm, vu; char sbuf[256]; long i, chunk; long nWaiting, nToRecord; SampleType *buf, smin, smax; long nEmpty, nTotal, nToFlush; SampleType *recbuf; ResetHeap(&tmpStack); recbuf=(SampleType *) New(&tmpStack,sizeof(SampleType)*REC_BUF_SIZE); /* initialise parameters */ *sampPeriod = 0; ain = OpenAudioInput(&tmpStack, sampPeriod, 0.0, 0.0); i = (long) (1.0E+07 / (*sampPeriod)); chunk = (long) (i / 20.0); bufDur = (float) REC_BUF_SIZE / (double) i; sprintf(sbuf, "rec buffer (0 - %.2fsec)", bufDur); InitBar(&tm, 10, RED, REC_BUF_SIZE, sbuf); InitBar(&vu, 400, DARK_GREEN, 65536, "VU:"); buf = recbuf; done = FALSE; nEmpty = REC_BUF_SIZE; nTotal =0; /* start audio input */ StartAudioInput(ain, NULLSIG); while (nEmpty > 0){ nWaiting = SamplesInAudio(ain); nToRecord = (nWaiting > chunk) ? nWaiting : chunk; if (nEmpty < nToRecord) nToRecord = nEmpty; GetRawAudio(ain, nToRecord, buf); /* get min/max samples and update display*/ smin = 32767; smax = -smin; for (i=0; i<nToRecord; i++){ if (buf[i]<smin) smin=buf[i]; if (buf[i]>smax) smax=buf[i]; } StepBar(&tm, nTotal); StepBar(&vu, smax-smin); buf += nToRecord; nEmpty -= nToRecord; nTotal += nToRecord; if(HEventsPending() > 0){ /* break loop if mouse button pressed */ hev = HGetEvent(FALSE,NULL); if(hev.event == HMOUSEDOWN){ btn = CheckButtonList(btnList, hev.x, hev.y); if(btn != NULL){ switch(btn->id){ case BT_REC:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -