/* RECENG.C Sound record/playback application engine */ #include #include #include #include #include #include #include #include #include #define RECENG_ENVNAME "REC$PREF" #define RECENG_ENVNAMELEN 8 GLREF_D PR_HWIMMAN * const w_am; LOCAL_C UINT ConvDurationTo2Ks(UINT tenths) /* Convert 10ths of a second to 2Kbyte units */ { return((tenths*25+0x3f)>>6); } LOCAL_C INT IsDeviceSuitable(INT device) { P_DINFO dinfo; TEXT dspec[16]; if (device!='M') { p_scpy(&dspec[0],"LOC::M:"); dspec[P_FSYSNAMESIZE]=device; p_dinfo(&dspec[0],&dinfo); return((dinfo.mediatype&0xff)==P_FMEDIA_RAM); } return(TRUE); } LOCAL_C INT DiskToDevice(INT disk) { if (disk==0) return('A'); if (disk==1) return('M'); if (disk==2) return('B'); } LOCAL_C VOID CheckSoundCompletion(INT stat) { if (stat==E_GEN_FAIL) hInfoPrint(-SYS_SOUND_DISABLED); else f_leave(stat); } #pragma METHOD_CALL METHOD VOID receng_eng_init(PR_RECENG *self,PR_ROOT *hview,UINT mupdate,UINT msound) { self->receng.prefs.duration=20; /* two seconds */ self->receng.prefs.disk=1; /* Internal (M:) */ self->receng.hview=hview; self->receng.mupdate=mupdate; self->receng.msound=msound; self->receng.wvefile=f_new(CAT_RECORD_RECORD,C_WVEFILE); self->receng.waveao=f_newsend(CAT_RECORD_RECORD,C_WAVEAO,O_AO_INIT,self,O_ENG_DONE_RECORD,O_ENG_DONE_PLAY); } METHOD TEXT *receng_eng_sense_file(PR_RECENG *self) { return((TEXT *)p_send2(self->receng.wvefile,O_WVE_SENSE_FNAME)); } METHOD INT receng_eng_default_disk(PR_RECENG *self) /* Returns the default device letter for new recordings. Based on the "dialog" local disk number (0:A, 1:M, 2:B). Guaranteed to return a suitable disk. */ { INT device; TEXT fspec[P_FNAMESIZE]; p_send2(self,O_ENG_SENSE_PREFS); device=DiskToDevice(self->receng.prefs.disk); /* try user-specified preference first */ if (!IsDeviceSuitable(device)) { /* preference is unsuitable */ device='M'; /* fallback if the default device is unsuitable */ p_getpth(&fspec[0]); if (IsDeviceSuitable(fspec[P_FSYSNAMESIZE])) device=fspec[P_FSYSNAMESIZE]; } return(device); } METHOD VOID receng_eng_view_update(PR_RECENG *self) { p_send2(self->receng.hview,self->receng.mupdate); } METHOD INT receng_eng_new_file(PR_RECENG *self,TEXT *pname) { return(p_send3(self->receng.wvefile,O_WVE_NEW,pname)); } METHOD VOID receng_eng_open_file(PR_RECENG *self,TEXT *pname) { p_send3(self->receng.wvefile,O_WVE_OPEN,pname); p_send3(w_am,O_AM_NEW_FILENAME,receng_eng_sense_file(self)); receng_eng_view_update(self); } METHOD VOID receng_eng_done_record(PR_RECENG *self,INT stat) { CheckSoundCompletion(stat); receng_eng_open_file(self,NULL); } METHOD VOID receng_eng_done_play(PR_RECENG *self,INT stat) { CheckSoundCompletion(stat); receng_eng_view_update(self); } METHOD VOID receng_eng_sound_play(PR_RECENG *self) { INT v; WVEFILE_INFO info; p_send2(self,O_ENG_SENSE_PREFS); v=0; /* loud */ if (self->receng.prefs.volume==1) v=2; /* medium */ else if (self->receng.prefs.volume==2) v=5; /* quiet */ p_send3(self->receng.wvefile,O_WVE_SENSE_INFO,&info); if (info.duration==0) { hInfoPrint(NO_DATA_NO_PLAY); return; } p_send4(self->receng.waveao,O_WV_PLAY,p_send2(self->receng.wvefile,O_WVE_SENSE_FNAME),v); p_send3(self->receng.hview,self->receng.msound,&info.total); } METHOD VOID receng_eng_sound_record(PR_RECENG *self,UINT duration) { UINT num2Ks; ULONG tenths; TEXT *name; num2Ks=ConvDurationTo2Ks(duration); tenths=num2Ks; tenths=(tenths<<6)/25; name=(TEXT *)p_send2(self->receng.wvefile,O_WVE_SENSE_FNAME); if (name[P_FSYSNAMESIZE]=='M') p_delete(name); /* free space for the sound server */ p_send4(self->receng.waveao,O_WV_RECORD,name,num2Ks); p_send3(self->receng.hview,self->receng.msound,&tenths); } METHOD VOID receng_eng_sound_stop(PR_RECENG *self) { p_send2(self->receng.waveao,O_WV_STOP); } METHOD VOID receng_eng_set_repeats(PR_RECENG *self,UINT repeats,UINT tenths) { p_send4(self->receng.wvefile,O_WVE_SET_REPEATS,repeats,tenths); receng_eng_view_update(self); } METHOD VOID receng_eng_file_info(PR_RECENG *self,WVEFILE_INFO *pi) { p_send3(self->receng.wvefile,O_WVE_SENSE_INFO,pi); } METHOD RECENG_PREFS *receng_eng_sense_prefs(PR_RECENG *self) { INT len; TEXT bb[P_ENVMAX]; len=p_getenviron(RECENG_ENVNAME,RECENG_ENVNAMELEN,&bb[0]); if (len==sizeof(RECENG_PREFS)) self->receng.prefs=*(RECENG_PREFS *)&bb[0]; return(&self->receng.prefs); } METHOD VOID receng_eng_set_prefs(PR_RECENG *self,RECENG_PREFS *new) { if (!p_bcmp(&self->receng.prefs,sizeof(RECENG_PREFS),new,sizeof(RECENG_PREFS))) return; /* no change */ self->receng.prefs=*new; f_leave(p_setenviron(RECENG_ENVNAME,RECENG_ENVNAMELEN,&self->receng.prefs,sizeof(RECENG_PREFS))); }