diff --git a/aucat/aucat.1 b/aucat/aucat.1 index 446311d..94b658e 100644 --- a/aucat/aucat.1 +++ b/aucat/aucat.1 @@ -27,10 +27,12 @@ .Op Fl c Ar min : Ns Ar max .Op Fl e Ar enc .Op Fl f Ar device +.Op Fl g Ar position .Op Fl h Ar fmt .Op Fl i Ar file .Op Fl j Ar flag .Op Fl o Ar file +.Op Fl p Ar position .Op Fl q Ar port .Op Fl r Ar rate .Op Fl v Ar volume @@ -117,6 +119,10 @@ audio device. Device mode and parameters are determined from audio files. Default is .Pa default . +.It Fl g Ar position +Go to the given time position and start playback or recording there. +This option is equivalent to an incoming MMC relocate message +with the same position. .It Fl h Ar fmt Audio file type. The following file types are supported: @@ -169,6 +175,10 @@ Record into this audio file. If the option argument is .Sq - then standard output will be used. +.It Fl p Ar position +Time offset where the beginning of the file belongs. +The first sample of the file will be played or recorded when the current +position reaches the given postion. .It Fl q Ar port Control audio device properties through this MIDI port. This includes per-stream volumes and the ability to diff --git a/aucat/aucat.c b/aucat/aucat.c index 308bcef..7a5e2f6 100644 --- a/aucat/aucat.c +++ b/aucat/aucat.c @@ -103,7 +103,7 @@ unsigned int dev_round; /* device block size */ int dev_rate; /* device sample rate (Hz) */ unsigned int dev_pchan, dev_rchan; /* play & rec channels count */ adata_t *dev_pbuf, *dev_rbuf; /* play & rec buffers */ -long long dev_pos; /* last MMC position in frames */ +unsigned int dev_mmcpos; /* last MMC position */ #define DEV_STOP 0 /* stopped */ #define DEV_START 1 /* started */ unsigned int dev_pstate; /* one of above */ @@ -351,8 +351,10 @@ slot_init(struct slot *s) } static void -slot_start(struct slot *s, long long pos) +slot_start(struct slot *s, unsigned int mmc) { + off_t mmcpos; + #ifdef DEBUG if (s->pstate != SLOT_INIT) { slot_log(s); @@ -360,15 +362,8 @@ slot_start(struct slot *s, long long pos) panic(); } #endif - /* - * convert pos to slot sample rate - * - * At this stage, we could adjust s->resamp.diff to get - * sub-frame accuracy. - */ - pos = pos * s->afile.rate / dev_rate; - - if (!afile_seek(&s->afile, pos * s->bpf)) { + mmcpos = ((off_t)mmc * s->afile.rate / MTC_SEC) * s->bpf; + if (!afile_seek(&s->afile, mmcpos)) { s->pstate = SLOT_INIT; return; } @@ -667,7 +662,7 @@ dev_open(char *dev, int mode, int bufsz, char *port) dev_rchan = par.rchan; dev_rbuf = xmalloc(sizeof(adata_t) * dev_rchan * dev_round); } - dev_pos = 0; + dev_mmcpos = 0; dev_pstate = DEV_STOP; if (log_level >= 2) { log_puts(dev_name); @@ -758,7 +753,7 @@ dev_mmcstart(void) if (dev_pstate == DEV_STOP) { dev_pstate = DEV_START; for (s = slot_list; s != NULL; s = s->next) - slot_start(s, dev_pos); + slot_start(s, dev_mmcpos); dev_prime = (dev_mode & SIO_PLAY) ? dev_bufsz / dev_round : 0; sio_start(dev_sh); if (log_level >= 2) @@ -798,35 +793,20 @@ dev_mmcstop(void) * relocate all slots simultaneously */ static void -dev_mmcloc(int hr, int min, int sec, int fr, int cent, int fps) +dev_mmcloc(unsigned int mmc) { - long long pos; - - pos = dev_rate * hr * 3600 + - dev_rate * min * 60 + - dev_rate * sec + - dev_rate * fr / fps + - dev_rate * cent / (100 * fps); - if (dev_pos == pos) + if (dev_mmcpos == mmc) return; - dev_pos = pos; + dev_mmcpos = mmc; if (log_level >= 2) { log_puts("relocated to "); - log_putu(hr); + log_putu((dev_mmcpos / (MTC_SEC * 3600)) % 24); log_puts(":"); - log_putu(min); + log_putu((dev_mmcpos / (MTC_SEC * 60)) % 60); log_puts(":"); - log_putu(sec); + log_putu((dev_mmcpos / (MTC_SEC)) % 60); log_puts("."); - log_putu(fr); - log_puts("."); - log_putu(cent); - log_puts(" at "); - log_putu(fps); - log_puts("fps\n"); - - log_puts("pos: "); - log_putu(pos); + log_putu((dev_mmcpos / (MTC_SEC / 100)) % 100); log_puts("\n"); } if (dev_pstate == DEV_START) { @@ -890,12 +870,11 @@ dev_imsg(unsigned char *msg, unsigned int len) dev_mmcstop(); return; } - dev_mmcloc(x->u.loc.hr & 0x1f, - x->u.loc.min, - x->u.loc.sec, - x->u.loc.fr, - x->u.loc.cent, - fps); + dev_mmcloc((x->u.loc.hr & 0x1f) * 3600 * MTC_SEC + + x->u.loc.min * 60 * MTC_SEC + + x->u.loc.sec * MTC_SEC + + x->u.loc.fr * (MTC_SEC / fps) + + x->u.loc.cent * (MTC_SEC / 100 / fps)); break; } } @@ -1031,7 +1010,7 @@ offline(void) dev_pchan = dev_rchan = cmax + 1; dev_pbuf = dev_rbuf = xmalloc(sizeof(adata_t) * dev_pchan * dev_round); dev_pstate = DEV_STOP; - dev_pos = 0; + dev_mmcpos = 0; for (s = slot_list; s != NULL; s = s->next) slot_init(s); for (s = slot_list; s != NULL; s = s->next) diff --git a/aucat/defs.h b/aucat/defs.h index 6cfc877..0820cf5 100644 --- a/aucat/defs.h +++ b/aucat/defs.h @@ -17,6 +17,11 @@ #ifndef DEFS_H #define DEFS_H +/* + * units used for MTC clock. + */ +#define MTC_SEC 2400 /* 1 second is 2400 ticks */ + /* * limits */