summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2016-06-07 06:26:25 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2016-06-07 06:26:25 +0000
commit1dd226a08b4d876846585f80b2a92a01bf92b8c0 (patch)
tree3cf343643947e1d3ec39815ee3594f993dc76777
parent18fe27a4440d3619d5364d76e216fac1e5368c4f (diff)
Add -g and -p options to control device and file start position.
-rw-r--r--usr.bin/aucat/aucat.116
-rw-r--r--usr.bin/aucat/aucat.c75
2 files changed, 79 insertions, 12 deletions
diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1
index 7d8fae1ba90..ab056fd6440 100644
--- a/usr.bin/aucat/aucat.1
+++ b/usr.bin/aucat/aucat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: aucat.1,v 1.112 2016/01/07 07:41:01 ratchov Exp $
+.\" $OpenBSD: aucat.1,v 1.113 2016/06/07 06:26:24 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: January 7 2016 $
+.Dd $Mdocdate: June 7 2016 $
.Dt AUCAT 1
.Os
.Sh NAME
@@ -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,11 @@ 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.
+The position is expressed as the number of samples (at device sample rate).
.It Fl h Ar fmt
Audio file type.
The following file types are supported:
@@ -169,6 +176,11 @@ 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 device
+reaches the given postion.
+The position is expressed as the number of samples (at device sample rate).
.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/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c
index 33aad5a2d4c..9014dd90d88 100644
--- a/usr.bin/aucat/aucat.c
+++ b/usr.bin/aucat/aucat.c
@@ -16,6 +16,7 @@
#include <fcntl.h>
#include <errno.h>
+#include <limits.h>
#include <poll.h>
#include <signal.h>
#include <sndio.h>
@@ -90,6 +91,8 @@ struct slot {
#define SLOT_RUN 2 /* playing/recording */
#define SLOT_STOP 3 /* draining (play only) */
int pstate; /* one of above */
+ long long skip; /* frames to skip at the beginning */
+ long long pos; /* start position (at device rate) */
struct afile afile; /* file desc & friends */
};
@@ -134,8 +137,9 @@ unsigned int voice_len[] = { 3, 3, 3, 3, 2, 2, 3 };
unsigned int common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 };
char usagestr[] = "usage: aucat [-dn] [-b size] "
- "[-c min:max] [-e enc] [-f device] [-h fmt]\n\t"
- "[-i file] [-j flag] [-o file] [-q port] [-r rate] [-v volume]\n";
+ "[-c min:max] [-e enc] [-f device] [-g position]\n\t"
+ "[-h fmt] [-i file] [-j flag] [-o file] [-p position] [-q port]\n\t"
+ "[-r rate] [-v volume]\n";
static void
slot_log(struct slot *s)
@@ -202,7 +206,7 @@ slot_fill(struct slot *s)
static int
slot_new(char *path, int mode, struct aparams *par, int hdr,
- int cmin, int cmax, int rate, int dup, int vol)
+ int cmin, int cmax, int rate, int dup, int vol, long long pos)
{
struct slot *s;
@@ -219,6 +223,7 @@ slot_new(char *path, int mode, struct aparams *par, int hdr,
s->vol = MIDI_TO_ADATA(vol);
s->mode = mode;
s->pstate = SLOT_CFG;
+ s->pos = pos;
if (log_level >= 2) {
slot_log(s);
log_puts(": ");
@@ -359,6 +364,13 @@ slot_start(struct slot *s, long long pos)
panic();
}
#endif
+ pos -= s->pos;
+ if (pos < 0) {
+ s->skip = -pos;
+ pos = 0;
+ } else
+ s->skip = 0;
+
/*
* convert pos to slot sample rate
*
@@ -415,8 +427,10 @@ slot_del(struct slot *s)
}
#endif
abuf_done(&s->buf);
- free(s->resampbuf);
- free(s->convbuf);
+ if (s->resampbuf)
+ free(s->resampbuf);
+ if (s->convbuf)
+ free(s->convbuf);
}
for (ps = &slot_list; *ps != s; ps = &(*ps)->next)
; /* nothing */
@@ -505,6 +519,15 @@ slot_mix_badd(struct slot *s, adata_t *odata)
odone = 0;
otodo = dev_round;
+ if (s->skip > 0) {
+ ocnt = otodo;
+ if (ocnt > s->skip)
+ ocnt = s->skip;
+ s->skip -= ocnt;
+ odata += dev_pchan * ocnt;
+ otodo -= ocnt;
+ odone += ocnt;
+ }
while (otodo > 0) {
idata = (adata_t *)abuf_rgetblk(&s->buf, &len);
icnt = len / s->bpf;
@@ -570,6 +593,15 @@ slot_sub_bcopy(struct slot *s, adata_t *idata, int itodo)
adata_t *odata;
int len, icnt, ocnt;
+ if (s->skip > 0) {
+ icnt = itodo;
+ if (icnt > s->skip)
+ icnt = s->skip;
+ s->skip -= icnt;
+ idata += dev_rchan * icnt;
+ itodo -= icnt;
+ }
+
while (itodo > 0) {
odata = (adata_t *)abuf_wgetblk(&s->buf, &len);
ocnt = len / s->bpf;
@@ -658,7 +690,6 @@ 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_pstate = DEV_STOP;
if (log_level >= 2) {
log_puts(dev_name);
@@ -1018,7 +1049,6 @@ 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;
for (s = slot_list; s != NULL; s = s->next)
slot_init(s);
for (s = slot_list; s != NULL; s = s->next)
@@ -1287,6 +1317,20 @@ opt_num(char *s, int min, int max, int *num)
return 1;
}
+static int
+opt_pos(char *s, long long *pos)
+{
+ const char *errstr;
+
+ *pos = strtonum(s, 0, LLONG_MAX, &errstr);
+ if (errstr) {
+ log_puts(s);
+ log_puts(": positive number of samples expected\n");
+ return 0;
+ }
+ return 1;
+}
+
int
main(int argc, char **argv)
{
@@ -1294,6 +1338,7 @@ main(int argc, char **argv)
char *port, *dev;
struct aparams par;
int n_flag, c;
+ long long pos;
vol = 127;
dup = 0;
@@ -1307,8 +1352,10 @@ main(int argc, char **argv)
port = NULL;
dev = NULL;
mode = 0;
+ pos = 0;
- while ((c = getopt(argc, argv, "b:c:de:f:h:i:j:no:q:r:t:v:")) != -1) {
+ while ((c = getopt(argc, argv,
+ "b:c:de:f:g:h:i:j:no:p:q:r:t:v:")) != -1) {
switch (c) {
case 'b':
if (!opt_num(optarg, 1, RATE_MAX, &bufsz))
@@ -1328,13 +1375,17 @@ main(int argc, char **argv)
case 'f':
dev = optarg;
break;
+ case 'g':
+ if (!opt_pos(optarg, &dev_pos))
+ return 1;
+ break;
case 'h':
if (!opt_hdr(optarg, &hdr))
return 1;
break;
case 'i':
if (!slot_new(optarg, SIO_PLAY,
- &par, hdr, cmin, cmax, rate, dup, vol))
+ &par, hdr, cmin, cmax, rate, dup, vol, pos))
return 1;
mode |= SIO_PLAY;
break;
@@ -1347,10 +1398,14 @@ main(int argc, char **argv)
break;
case 'o':
if (!slot_new(optarg, SIO_REC,
- &par, hdr, cmin, cmax, rate, dup, 0))
+ &par, hdr, cmin, cmax, rate, dup, 0, pos))
return 1;
mode |= SIO_REC;
break;
+ case 'p':
+ if (!opt_pos(optarg, &pos))
+ return 1;
+ break;
case 'q':
port = optarg;
break;