[SCM] xwax/master: Imported Upstream version 1.6~beta1

alessio at users.alioth.debian.org alessio at users.alioth.debian.org
Wed Jun 10 11:55:16 UTC 2015


The following commit has been merged in the master branch:
commit 7bcff24cce7e1b9ad03351fbdfe8b04bbaa5f270
Author: Alessio Treglia <alessio.treglia at smartodds.co.uk>
Date:   Wed Jun 10 12:24:10 2015 +0100

    Imported Upstream version 1.6~beta1

diff --git a/.gitignore b/.gitignore
index 1771606..c0f7d26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 TAGS
 xwax
+mktimecode
 *.o
 *.d
 .config
@@ -7,10 +8,11 @@ xwax
 dist
 
 tests/cues
+tests/external
 tests/library
 tests/midi
+tests/observer
 tests/scan-bpm
-tests/status
 tests/timecoder
 tests/track
 tests/ttf
diff --git a/.version b/.version
index c239c60..c0c1d5c 100644
--- a/.version
+++ b/.version
@@ -1 +1 @@
-1.5
+1.6-beta1
diff --git a/CHANGES b/CHANGES
index e47e813..1351e34 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+v1.6 (work in progress)
+-----------------------
+
+* Added timecode creator (for the adventurous)
+* Correct interpretation of ALSA's buffer size
+
 v1.5 (2014-02-09)
 -----------------
 
diff --git a/Makefile b/Makefile
index 5b5fcc6..a136d85 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 2014 Mark Hills <mark at xwax.org>
+# Copyright (C) 2015 Mark Hills <mark at xwax.org>
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License version 2, as
@@ -50,6 +50,7 @@ OBJS = controller.o \
 	cues.o \
 	deck.o \
 	device.o \
+	dummy.o \
 	excrate.o \
 	external.o \
 	index.o \
@@ -98,12 +99,12 @@ DEVICE_CPPFLAGS += -DWITH_OSS
 endif
 
 TEST_OBJS = $(addsuffix .o,$(TESTS))
-DEPS = $(OBJS:.o=.d) $(TEST_OBJS:.o=.d)
+DEPS = $(OBJS:.o=.d) $(TEST_OBJS:.o=.d) mktimecode.d
 
 # Rules
 
 .PHONY:		all
-all:		xwax tests
+all:		xwax mktimecode tests
 
 # Dynamic versioning
 
@@ -126,6 +127,11 @@ xwax.o:		CPPFLAGS += $(DEVICE_CPPFLAGS)
 xwax.o:		CPPFLAGS += -DEXECDIR=\"$(EXECDIR)\" -DVERSION=\"$(VERSION)\"
 xwax.o:		.version
 
+# Supporting programs
+
+mktimecode:	mktimecode.o
+mktimecode:	LDLIBS  += -lm
+
 # Install to system
 
 .PHONY:		install
@@ -185,6 +191,7 @@ clean:
 		rm -f xwax \
 			$(OBJS) $(DEPS) \
 			$(TESTS) $(TEST_OBJS) \
+			mktimecode mktimecode.o \
 			TAGS
 
 -include $(DEPS)
diff --git a/README b/README
index 3e0a539..829f22f 100644
--- a/README
+++ b/README
@@ -1,11 +1,11 @@
 xwax: Digital vinyl on Linux
 
-(C) Copyright 2012 Mark Hills <mark at pogo.org.uk>
+(C) Copyright 2015 Mark Hills <mark at xwax.org>
 
 For installation instructions, see the INSTALL file. Instructions can
 be found in the xwax(1) man page and http://xwax.org/
 
-xwax is vinyl emulation software for Linux. It allows DJs and
+xwax is a digital vinyl system (DVS) for Linux. It allows DJs and
 turntablists to playback digital audio files (MP3, Ogg Vorbis, FLAC,
 AAC and more), controlled using a normal pair of turntables via
 timecoded vinyls.
diff --git a/alsa.c b/alsa.c
index 0a410f4..d7d2be3 100644
--- a/alsa.c
+++ b/alsa.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -111,8 +111,8 @@ static int pcm_open(struct alsa_pcm *alsa, const char *device_name,
 
     p = buffer_time * 1000; /* microseconds */
     dir = -1;
-    r = snd_pcm_hw_params_set_buffer_time_max(alsa->pcm, hw_params, &p, &dir);
-    if (!chk("hw_params_set_buffer_time_max", r)) {
+    r = snd_pcm_hw_params_set_buffer_time_near(alsa->pcm, hw_params, &p, &dir);
+    if (!chk("hw_params_set_buffer_time_near", r)) {
         fprintf(stderr, "Buffer of %dms may be too small for this hardware.\n",
                 buffer_time);
         return -1;
diff --git a/alsa.h b/alsa.h
index ce97b3b..7bf2dc2 100644
--- a/alsa.h
+++ b/alsa.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/controller.c b/controller.c
index 174e4b7..222fd8d 100644
--- a/controller.c
+++ b/controller.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/controller.h b/controller.h
index 5181cfa..938d8a5 100644
--- a/controller.h
+++ b/controller.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/cues.c b/cues.c
index 0a51168..dc3a77d 100644
--- a/cues.c
+++ b/cues.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/cues.h b/cues.h
index a5f3211..50778bd 100644
--- a/cues.h
+++ b/cues.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/debug.h b/debug.h
index dcd8087..a8a7e26 100644
--- a/debug.h
+++ b/debug.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/deck.c b/deck.c
index 090efce..258c21c 100644
--- a/deck.c
+++ b/deck.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -41,82 +41,87 @@ static const struct record no_record = {
  * A deck is a logical grouping of the various components which
  * reflects the user's view on a deck in the system.
  *
- * Pre: deck->device, deck->timecoder, deck->importer are valid
+ * Pre: deck->device is valid
  */
 
-int deck_init(struct deck *deck, struct rt *rt)
+int deck_init(struct deck *d, struct rt *rt,
+              struct timecode_def *timecode, const char *importer,
+              double speed, bool phono, bool protect)
 {
     unsigned int rate;
 
-    assert(deck->importer != NULL);
-
-    if (rt_add_device(rt, &deck->device) == -1)
+    if (rt_add_device(rt, &d->device) == -1)
         return -1;
 
-    deck->ncontrol = 0;
-    deck->record = &no_record;
-    deck->punch = NO_PUNCH;
-    rate = device_sample_rate(&deck->device);
-    player_init(&deck->player, rate, track_acquire_empty(), &deck->timecoder);
-    cues_reset(&deck->cues);
+    d->ncontrol = 0;
+    d->record = &no_record;
+    d->punch = NO_PUNCH;
+    d->protect = protect;
+    assert(importer != NULL);
+    d->importer = importer;
+    rate = device_sample_rate(&d->device);
+    assert(timecode != NULL);
+    timecoder_init(&d->timecoder, timecode, speed, rate, phono);
+    player_init(&d->player, rate, track_acquire_empty(), &d->timecoder);
+    cues_reset(&d->cues);
 
     /* The timecoder and player are driven by requests from
      * the audio device */
 
-    device_connect_timecoder(&deck->device, &deck->timecoder);
-    device_connect_player(&deck->device, &deck->player);
+    device_connect_timecoder(&d->device, &d->timecoder);
+    device_connect_player(&d->device, &d->player);
 
     return 0;
 }
 
-void deck_clear(struct deck *deck)
+void deck_clear(struct deck *d)
 {
     /* FIXME: remove from rig and rt */
-    player_clear(&deck->player);
-    timecoder_clear(&deck->timecoder);
-    device_clear(&deck->device);
+    player_clear(&d->player);
+    timecoder_clear(&d->timecoder);
+    device_clear(&d->device);
 }
 
-bool deck_is_locked(const struct deck *deck)
+bool deck_is_locked(const struct deck *d)
 {
-    return (deck->protect && player_is_active(&deck->player));
+    return (d->protect && player_is_active(&d->player));
 }
 
 /*
  * Load a record from the library to a deck
  */
 
-void deck_load(struct deck *deck, struct record *record)
+void deck_load(struct deck *d, struct record *record)
 {
     struct track *t;
 
-    if (deck_is_locked(deck)) {
+    if (deck_is_locked(d)) {
         status_printf(STATUS_WARN, "Stop deck to load a different track");
         return;
     }
 
-    t = track_acquire_by_import(deck->importer, record->pathname);
+    t = track_acquire_by_import(d->importer, record->pathname);
     if (t == NULL)
         return;
 
-    deck->record = record;
-    player_set_track(&deck->player, t); /* passes reference */
+    d->record = record;
+    player_set_track(&d->player, t); /* passes reference */
 }
 
-void deck_recue(struct deck *deck)
+void deck_recue(struct deck *d)
 {
-    if (deck_is_locked(deck)) {
+    if (deck_is_locked(d)) {
         status_printf(STATUS_WARN, "Stop deck to recue");
         return;
     }
 
-    player_recue(&deck->player);
+    player_recue(&d->player);
 }
 
-void deck_clone(struct deck *deck, const struct deck *from)
+void deck_clone(struct deck *d, const struct deck *from)
 {
-    deck->record = from->record;
-    player_clone(&deck->player, &from->player);
+    d->record = from->record;
+    player_clone(&d->player, &from->player);
 }
 
 /*
diff --git a/deck.h b/deck.h
index 44eb0d2..cd5a2e4 100644
--- a/deck.h
+++ b/deck.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -51,7 +51,9 @@ struct deck {
     struct controller *control[4];
 };
 
-int deck_init(struct deck *deck, struct rt *rt);
+int deck_init(struct deck *deck, struct rt *rt,
+              struct timecode_def *timecode, const char *importer,
+              double speed, bool phono, bool protect);
 void deck_clear(struct deck *deck);
 
 bool deck_is_locked(const struct deck *deck);
diff --git a/device.c b/device.c
index 3098f95..2d4b888 100644
--- a/device.c
+++ b/device.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/device.h b/device.h
index 90d580b..727192b 100644
--- a/device.h
+++ b/device.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/dicer.c b/dicer.c
index dcb0b86..f3a303d 100644
--- a/dicer.c
+++ b/dicer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/dicer.h b/dicer.h
index 23a4648..7076e0d 100644
--- a/dicer.h
+++ b/dicer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/interface.h b/dummy.c
similarity index 70%
copy from interface.h
copy to dummy.c
index 9b856a0..0a564e9 100644
--- a/interface.h
+++ b/dummy.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -17,13 +17,18 @@
  *
  */
 
-#ifndef INTERFACE_H
-#define INTERFACE_H
+#include "dummy.h"
 
-#include "deck.h"
-#include "library.h"
+static unsigned int sample_rate(struct device *d)
+{
+    return 48000;
+}
 
-int interface_start(struct library *lib, const char *geo);
-void interface_stop();
+static struct device_ops dummy_ops = {
+    .sample_rate = sample_rate,
+};
 
-#endif
+void dummy_init(struct device *d)
+{
+    device_init(d, &dummy_ops);
+}
diff --git a/jack.h b/dummy.h
similarity index 84%
copy from jack.h
copy to dummy.h
index 15ca5f3..46832fa 100644
--- a/jack.h
+++ b/dummy.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -17,11 +17,11 @@
  *
  */
 
-#ifndef JACK_H
-#define JACK_H
+#ifndef DUMMY_H
+#define DUMMY_H
 
 #include "device.h"
 
-int jack_init(struct device *dv, const char *name);
+void dummy_init(struct device *d);
 
 #endif
diff --git a/excrate.c b/excrate.c
index f076770..6dc5690 100644
--- a/excrate.c
+++ b/excrate.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/excrate.h b/excrate.h
index c12c142..dd61a7d 100644
--- a/excrate.h
+++ b/excrate.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/external.c b/external.c
index 3ce3bf0..f2f7157 100644
--- a/external.c
+++ b/external.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -17,7 +17,7 @@
  *
  */
 
-#define _BSD_SOURCE /* vfork() */
+#define _DEFAULT_SOURCE /* vfork() */
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
diff --git a/external.h b/external.h
index 0a1e2dd..6e1e585 100644
--- a/external.h
+++ b/external.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/index.c b/index.c
index e3bdac5..fa0d7b8 100644
--- a/index.c
+++ b/index.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/index.h b/index.h
index 282bf1b..f71b9b0 100644
--- a/index.h
+++ b/index.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/interface.c b/interface.c
index a84ba3c..80d9cc1 100644
--- a/interface.c
+++ b/interface.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/interface.h b/interface.h
index 9b856a0..6b787ec 100644
--- a/interface.h
+++ b/interface.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/jack.c b/jack.c
index 218265b..07ca9d3 100644
--- a/jack.c
+++ b/jack.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/jack.h b/jack.h
index 15ca5f3..82478a8 100644
--- a/jack.h
+++ b/jack.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/layout.h b/layout.h
index ac66719..c4c4971 100644
--- a/layout.h
+++ b/layout.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/library.c b/library.c
index ed09da0..4c35161 100644
--- a/library.c
+++ b/library.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/library.h b/library.h
index 657589e..98805be 100644
--- a/library.h
+++ b/library.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/list.h b/list.h
index d7a0167..a775d67 100644
--- a/list.h
+++ b/list.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/listbox.c b/listbox.c
index 03b616b..4e861d7 100644
--- a/listbox.c
+++ b/listbox.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/listbox.h b/listbox.h
index 2c6c0cf..0d20556 100644
--- a/listbox.h
+++ b/listbox.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/lut.c b/lut.c
index de2482f..d84f89a 100644
--- a/lut.c
+++ b/lut.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/lut.h b/lut.h
index ff92d87..87a179e 100644
--- a/lut.h
+++ b/lut.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/midi.c b/midi.c
index b7c445b..8d637d0 100644
--- a/midi.c
+++ b/midi.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/midi.h b/midi.h
index 3cfd555..54ec9a1 100644
--- a/midi.h
+++ b/midi.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/mktimecode.c b/mktimecode.c
new file mode 100644
index 0000000..1df31b5
--- /dev/null
+++ b/mktimecode.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * Experimental program to generate a timecode signal for use
+ * with xwax.
+ */
+
+#define _GNU_SOURCE /* sincos() */
+#include <assert.h>
+#include <limits.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define BANNER "xwax timecode generator " \
+    "(C) Copyright 2015 Mark Hills <mark at xwax.org>"
+
+#define RATE 44100
+#define RESOLUTION 4000
+#define SEED 0x00001
+#define TAPS 0x00002
+#define BITS 22
+
+#define MAX(x,y) ((x)>(y)?(x):(y))
+
+typedef unsigned int bits_t;
+
+/*
+ * Calculate the next bit in the LFSR sequence
+ */
+
+static inline bits_t lfsr(bits_t code, bits_t taps)
+{
+    bits_t taken;
+    int xrs;
+
+    taken = code & taps;
+    xrs = 0;
+    while (taken != 0x0) {
+        xrs += taken & 0x1;
+        taken >>= 1;
+    }
+
+    return xrs & 0x1;
+}
+
+/*
+ * LFSR in the forward direction
+ */
+
+static inline bits_t fwd(bits_t current, bits_t taps, unsigned int nbits)
+{
+    bits_t l;
+
+    /* New bits are added at the MSB; shift right by one */
+
+    l = lfsr(current, taps | 0x1);
+    return (current >> 1) | (l << (nbits - 1));
+}
+
+static inline double dither(void)
+{
+    return (double)(rand() % 32768) / 32768.0 - 0.5;
+}
+
+int main(int argc, char *argv[])
+{
+    unsigned int s;
+    bits_t b;
+    int length;
+
+    fputs(BANNER, stderr);
+    fputc('\n', stderr);
+
+    fprintf(stderr, "Generating %d-bit %dHz timecode sampled at %dKhz\n",
+            BITS, RESOLUTION, RATE);
+
+    b = SEED;
+    length = 0;
+
+    for (s = 0; ; s++) {
+        double time, cycle, angle, modulate, x, y;
+        signed short c[2];
+
+        time = (double)s / RATE;
+        cycle = time * RESOLUTION;
+        angle = cycle * M_PI * 2;
+
+        sincos(angle, &x, &y);
+
+        /* Modulate the waveform according to the bitstream */
+
+        modulate = 1.0 - (-cos(angle) + 1.0) * 0.25 * ((b & 0x1) == 0);
+        x *= modulate;
+        y *= modulate;
+
+        /* Write out 16-bit PCM data */
+
+        c[0] = -y * SHRT_MAX * 0.5 + dither();
+        c[1] = x * SHRT_MAX * 0.5 + dither();
+
+        fwrite(c, sizeof(signed short), 2, stdout);
+
+        /* Advance the bitstream if required */
+
+        if ((int)cycle > length) {
+            assert((int)cycle - length == 1);
+            b = fwd(b, TAPS, BITS);
+            if (b == SEED) /* LFSR period reached */
+                break;
+            length = cycle;
+        }
+    }
+
+    fprintf(stderr, "Generated %0.1f seconds of timecode\n",
+            (double)length / RESOLUTION);
+
+    fprintf(stderr, "\n");
+    fprintf(stderr, "    {\n");
+    fprintf(stderr, "        .resolution = %d,\n", RESOLUTION);
+    fprintf(stderr, "        .bits = %d,\n", BITS);
+    fprintf(stderr, "        .seed = 0x%08x,\n", SEED);
+    fprintf(stderr, "        .taps = 0x%08x,\n", TAPS);
+    fprintf(stderr, "        .length = %d,\n", length);
+    fprintf(stderr, "        .safe = %d,\n", MAX(0, length - 4 * RESOLUTION));
+    fprintf(stderr, "    }\n");
+
+    return 0;
+}
diff --git a/mutex.h b/mutex.h
index 0aca247..7710edf 100644
--- a/mutex.h
+++ b/mutex.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/observer.h b/observer.h
index 7d2f527..96552c1 100644
--- a/observer.h
+++ b/observer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/oss.c b/oss.c
index 6fc7069..0eb7e0a 100644
--- a/oss.c
+++ b/oss.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/oss.h b/oss.h
index 05e091b..0edcd7b 100644
--- a/oss.h
+++ b/oss.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/pitch.h b/pitch.h
index 4f0af6b..2a34142 100644
--- a/pitch.h
+++ b/pitch.h
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/player.c b/player.c
index eec7b20..27f9d09 100644
--- a/player.c
+++ b/player.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/player.h b/player.h
index 2968d30..560fb17 100644
--- a/player.h
+++ b/player.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/realtime.c b/realtime.c
index 48277eb..cb8827c 100644
--- a/realtime.c
+++ b/realtime.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/realtime.h b/realtime.h
index da5ab32..3d708f0 100644
--- a/realtime.h
+++ b/realtime.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/rig.c b/rig.c
index 845a2bb..836fd11 100644
--- a/rig.c
+++ b/rig.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/rig.h b/rig.h
index fcaadae..f34e5b4 100644
--- a/rig.h
+++ b/rig.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/selector.c b/selector.c
index 9756ac0..ea63449 100644
--- a/selector.c
+++ b/selector.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>,
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>,
  *                    Yves Adler <yves.adler at googlemail.com>
  *
  * This program is free software; you can redistribute it and/or
diff --git a/selector.h b/selector.h
index 6b76246..1ed9ded 100644
--- a/selector.h
+++ b/selector.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>,
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>,
  *                    Yves Adler <yves.adler at googlemail.com>
  *
  * This program is free software; you can redistribute it and/or
diff --git a/spin.h b/spin.h
index 584b0b7..6c6ff38 100644
--- a/spin.h
+++ b/spin.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/status.c b/status.c
index cd3bb08..46c357a 100644
--- a/status.c
+++ b/status.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/status.h b/status.h
index 7d1f3de..88f8c12 100644
--- a/status.h
+++ b/status.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/thread.c b/thread.c
index 3fcbde7..1e32df6 100644
--- a/thread.c
+++ b/thread.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/thread.h b/thread.h
index 611c4b2..1217ad7 100644
--- a/thread.h
+++ b/thread.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/timecoder.c b/timecoder.c
index 9a90e04..67546cc 100644
--- a/timecoder.c
+++ b/timecoder.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -55,37 +55,31 @@ static struct timecode_def timecodes[] = {
         .name = "serato_2a",
         .desc = "Serato 2nd Ed., side A",
         .resolution = 1000,
-        .flags = 0,
         .bits = 20,
         .seed = 0x59017,
         .taps = 0x361e4,
         .length = 712000,
         .safe = 707000,
-        .lookup = false
     },
     {
         .name = "serato_2b",
         .desc = "Serato 2nd Ed., side B",
         .resolution = 1000,
-        .flags = 0,
         .bits = 20,
         .seed = 0x8f3c6,
         .taps = 0x4f0d8, /* reverse of side A */
         .length = 922000,
         .safe = 917000,
-        .lookup = false
     },
     {
         .name = "serato_cd",
         .desc = "Serato CD",
         .resolution = 1000,
-        .flags = 0,
         .bits = 20,
         .seed = 0xd8b40,
         .taps = 0x34d54,
         .length = 950000,
         .safe = 940000,
-        .lookup = false
     },
     {
         .name = "traktor_a",
@@ -97,7 +91,6 @@ static struct timecode_def timecodes[] = {
         .taps = 0x041040,
         .length = 1500000,
         .safe = 1480000,
-        .lookup = false
     },
     {
         .name = "traktor_b",
@@ -109,7 +102,6 @@ static struct timecode_def timecodes[] = {
         .taps = 0x041040, /* same as side A */
         .length = 2110000,
         .safe = 2090000,
-        .lookup = false
     },
     {
         .name = "mixvibes_v2",
@@ -121,7 +113,6 @@ static struct timecode_def timecodes[] = {
         .taps = 0x00008,
         .length = 950000,
         .safe = 923000,
-        .lookup = false
     },
     {
         .name = "mixvibes_7inch",
@@ -133,7 +124,6 @@ static struct timecode_def timecodes[] = {
         .taps = 0x00008,
         .length = 312000,
         .safe = 310000,
-        .lookup = false
     },
 };
 
diff --git a/timecoder.h b/timecoder.h
index 5762b90..bd58e01 100644
--- a/timecoder.h
+++ b/timecoder.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/track.c b/track.c
index 4a3c344..8fa2c6b 100644
--- a/track.c
+++ b/track.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/track.h b/track.h
index 276060a..4a562a2 100644
--- a/track.h
+++ b/track.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
diff --git a/xwax.1 b/xwax.1
index cf0bcb5..52cfcde 100644
--- a/xwax.1
+++ b/xwax.1
@@ -1,61 +1,48 @@
 .TH XWAX "1"
-
 .SH NAME
 xwax \- Digital vinyl on Linux
-
 .SH SYNOPSIS
 .B xwax
 [\fIoptions\fR]
-
 .SH DESCRIPTION
-
 .P
 xwax is vinyl emulation software for Linux. It allows DJs and
 turntablists to playback digital audio files (MP3, Ogg Vorbis, FLAC,
 AAC and more), controlled using a normal pair of turntables via
 timecoded vinyls.
-
 .SH OPTIONS
-
 .P
 The ordering of options is important. Most options apply to
 subsequent music libraries or decks, which can be given multiple times.
 See the
 .B EXAMPLES
 below.
-
 .TP
 .B \-l \fIpath\fR
 Scan the music library or playlist at the given path.
-
 .TP
 .B \-t \fIname\fR
 Use the named timecode for subsequent decks. See \-h for a list of
 valid timecodes. You will need the corresponding timecode signal on
 vinyl to control playback.
-
 .TP
 .B \-33
 Set the reference playback speed for subsequent decks to 33 and one
 third revolutions per minute. This is the default.
-
 .TP
 .B \-45
 Set the reference playback speed for subsequent decks to 45
 revolutions per minute.
-
 .TP
 .B \-c
 Protect subsequent decks against certain operations during
 playback.
-
 .TP
 .B \-u
 Allow all operations on a deck during playback. This is the inverse
 of the
 .B \-c
 option, and is the default.
-
 .TP
 .B \-\-phono
 Adjust the noise thresholds of subsequent decks to tolerate a
@@ -63,22 +50,22 @@ cartridge-level signal connected to a line-level audio interface. This
 is a 'software pre-amp'. Unless your audio path has low noise, this
 will give worse results or may not work at all; a true phono
 pre-amplifier is always preferred.
-
 .TP
 .B \-\-line
 Set noise thresholds of subsequent decks to standard audio levels.
 This reverses the effect of the
 .B \-\-phono
 option, and is the default.
-
 .TP
 .B \-i \fIpath\fR
 Use the given importer executable for subsequent decks.
-
 .TP
 .B \-s \fIpath\fR
 Use the given scanner executable to scan subsequent music libraries.
-
+.TP
+.B \-\-dummy
+Create a deck which is not connected to any audio device, used
+for testing.
 .TP
 .B \-k
 Lock into RAM any memory required for real-time use.
@@ -86,12 +73,10 @@ This includes audio tracks held in memory which can be large.
 Use
 .B ulimit \-l
 to raise the kernel's memory limit to allow this.
-
 .TP
 .B \-q \fIn\fR
 Change the real-time priority of the process. A priority of 0 gives
 the process no priority, and is used for testing only.
-
 .TP
 .B \-g [\fIn\fRx\fIn\fR][+\fIn\fR+\fIn\fR][/\fIf\fR]
 Change the geometry of the display in size, position and scale (zoom)
@@ -100,131 +85,98 @@ The size and position is passed
 to SDL, which may use it to set the display mode, or size of an X window.
 See the
 .B EXAMPLES.
-
 .TP
 .B \-h
 Display the help message and default values.
-
 .SH "ALSA DEVICE OPTIONS"
-
 .P
 The following options are available only when xwax is compiled with
 ALSA support.
-
 .TP
 .B \-a \fIdevice\fR
 Create a deck which uses the given ALSA device (eg. plughw:0).
-
 .TP
 .B \-r \fIhz\fR
 Set the sample rate for subsequent decks.
-
 .TP
 .B \-m \fImilliseconds\fR
 Set the ALSA buffer time for subsequent decks.
-
 .SH "JACK DEVICE OPTIONS"
-
 .P
 The following options are available only when xwax is compiled with
 JACK support.
-
 .TP
 .B \-j \fIname\fR
 Create a deck which connects to JACK and registers under the given
 name.
-
 .P
 xwax does not set the sample rate for JACK devices; it uses the sample
 rate given in the global JACK configuration.
-
 .SH "OSS DEVICE OPTIONS"
-
 .P
 The following options are available only when xwax is compiled with
 OSS support.
-
 .TP
 .B \-d \fIpathname\fR
 Create a deck which uses the given OSS device (eg. /dev/dsp).
-
 .TP
 .B \-r \fIhz\fR
 Set the sample rate for subsequent decks.
-
 .TP
 .B \-b \fIn\fR
 Set the number of OSS buffers for subsequent decks.
-
 .TP
 .B \-f \fIn\fR
 Set the OSS buffer size (2^n bytes).
-
 .SH HARDWARE CONTROLLER OPTIONS
-
 .P
 The following options are available only when xwax is compiled
 with ALSA support.
-
 .TP
 .B \-\-dicer \fIdevice\fR
 Use one or two Dicer controllers connected as the given ALSA device
 (eg. hw:Dicer). See the section
 .B NOVATION DICER CONTROLS
 for more information.
-
 .P
 Adding a hardware controller results in control over subsequent decks,
 up to the limit of the hardware.
-
 .SH KEYBOARD CONTROLS
-
 .P
 The playback of each deck (direction, speed and position) is
 controlled via the incoming timecode signal from the turntables.
 The keyboard provides additional controls.
-
 .P
 "C-" and "S-" means a keypress is combined with
-the 'Control' and 'Shift' keys, respectively.
-
+the 'Control' or 'Shift' key, respectively.
 .P
 Record selection controls:
-
 .TP
 cursor up, cursor down
 Move highlighted record up/down by one.
-
 .TP
 page up, page down
 Scroll the record listing up/down by one page.
-
 .TP
 left cursor, right cursor
 Switch to the previous/next crate of records.
-
 .TP
 tab
 Toggle between the current crate and the 'All records' crate.
-
 .TP
 C-tab
 Toggle sort mode between: artist/track name, BPM and 'playlist'
 order. Playlist order is the order in which records were returned
 from the scanner.
-
 .TP
 C-S-tab
 Re-scan the currently selected crate.
-
 .P
 To filter the current list of records type a portion of a record
 name. Separate multiple searches with a space, and use backspace to
 delete.
-
 .P
 Deck-specific controls:
-
 .TS
 l l l l.
 Deck 0	Deck 1	Deck 2
@@ -233,122 +185,99 @@ F2	F6	F10	Reset start of track to the current position
 F3	F7	F11	Toggle timecode control on/off
 C-F3	C-F7	C-F11	Cycle between available timecodes
 .TE
-
 .P
 The "available timecodes" are those which have been the subject of any
 .B \-t
 flag on the command line.
-
 Audio display controls:
-
 .TP
 +, \-
 Zoom in/out the close-up audio meters for all decks.
-
 .SH NOVATION DICER CONTROLS
-
 .P
 The Novation Dicer provides hardware control of cue points. The controls
 are:
-
 .TP
 cue mode: dice button (1-5)
 Jump to the specified cue point, or set it if unset.
-
 .TP
 loop-roll mode: dicer button (1-5)
 "Punch" to the specified cue point, or set it if unset. Returns playback
 to normal when the button is released.
-
 .TP
 mode button + dice button (1-5)
 Clear the specified cue point.
-
 .P
 The dice buttons are lit to show that the corresponding cue point is
 set.
-
 .SH EXAMPLES
-
 .P
 2-deck setup using one directory of music and OSS devices:
 .sp
 .RS
 xwax \-l ~/music \-d /dev/dsp \-d /dev/dsp1
 .RE
-
 .P
 As above, but using ALSA devices:
 .sp
 .RS
 xwax \-l ~/music \-d hw:0 \-d hw:1
 .RE
-
 .P
 2-deck setup using a different timecode on each deck:
 .sp
 .RS
 xwax \-l ~/music \-t serato_2a \-d hw:0 \-t mixvibes_v2 \-d hw:1
 .RE
-
 .P
 As above, but with the second deck at 45 RPM:
 .sp
 .RS
 xwax \-l ~/music \-t serato_2a \-d hw:0 \-t mixvibes_v2 \-45 \-d hw:1
 .RE
-
 .P
 Default to the same timecode, but allow switching at runtime:
 .sp
 .RS
 xwax \-l ~/music \-t serato_2a \-t mixvibes_v2 \-d hw:0 \-d hw:1
 .RE
-
 .P
 3-deck setup with the third deck at a higher sample rate:
 .sp
 .RS
 xwax \-l ~/music \-r 48000 \-a hw:0 \-a hw:1 \-r 96000 \-a hw:2
 .RE
-
 .P
 Using all three device types simultaneously, one deck on each:
 .sp
 .RS
 xwax \-l ~/music \-a hw:0 \-d /dev/dsp1 \-j jack0
 .RE
-
 .P
 Scan multiple music libraries:
 .sp
 .RS
 xwax \-l ~/music \-l ~/sounds \-l ~/mixes \-a hw:0
 .RE
-
 .P
 Scan a second music library using a custom script:
 .sp
 .RS
 xwax \-l ~/music \-i ./custom-scan \-l ~/sounds \-a hw:0
 .RE
-
 .P
 Control two decks with Dicer hardware:
 .sp
 .RS
-xwax \-dicer hw:Dicer \-a hw:0 \-a hw:1
+xwax \-\-dicer hw:Dicer \-a hw:0 \-a hw:1
 .RE
-
 .P
 Use a high resolution and enlarge the user interface:
 .sp
 .RS
 xwax -g 1920x1200/1.8 -a hw:0
 .RE
-
 .SH HOMEPAGE
 http://xwax.org/
-
 .SH AUTHOR
 Mark Hills <mark at xwax.org>
diff --git a/xwax.c b/xwax.c
index c282476..d4bd8e9 100644
--- a/xwax.c
+++ b/xwax.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
 #include "controller.h"
 #include "device.h"
 #include "dicer.h"
+#include "dummy.h"
 #include "interface.h"
 #include "jack.h"
 #include "library.h"
@@ -56,11 +57,21 @@
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*x))
 
 char *banner = "xwax " VERSION \
-    " (C) Copyright 2014 Mark Hills <mark at xwax.org>";
+    " (C) Copyright 2015 Mark Hills <mark at xwax.org>";
 
 size_t ndeck;
 struct deck deck[3];
 
+static size_t nctl;
+static struct controller ctl[2];
+
+static struct rt rt;
+
+static double speed;
+static bool protect, phono;
+static const char *importer;
+static struct timecode_def *timecode;
+
 static void usage(FILE *fd)
 {
     fprintf(fd, "Usage: xwax [<options>]\n\n");
@@ -85,7 +96,8 @@ static void usage(FILE *fd)
       "  -u             Allow all operations when playing\n"
       "  --line         Line level signal (default)\n"
       "  --phono        Tolerate cartridge level signal ('software pre-amp')\n"
-      "  -i <program>   Importer (default '%s')\n\n",
+      "  -i <program>   Importer (default '%s')\n"
+      "  --dummy        Build a dummy deck with no audio device\n\n",
       DEFAULT_IMPORTER);
 
 #ifdef WITH_OSS
@@ -125,18 +137,55 @@ static void usage(FILE *fd)
       "See the xwax(1) man page for full information and examples.\n");
 }
 
+static struct device* start_deck(const char *desc)
+{
+    fprintf(stderr, "Initialising deck %zd (%s)...\n", ndeck, desc);
+
+    if (ndeck == ARRAY_SIZE(deck)) {
+        fprintf(stderr, "Too many decks.\n");
+        return NULL;
+    }
+
+    return &deck[ndeck].device;
+}
+
+static int commit_deck(void)
+{
+    int r;
+    struct deck *d;
+    size_t n;
+
+    /* Fallback to a default timecode. Don't initialise this at the
+     * front of the program to avoid buildling unnecessary LUTs */
+
+    if (timecode == NULL) {
+        timecode = timecoder_find_definition(DEFAULT_TIMECODE);
+        assert(timecode != NULL);
+    }
+
+    d = &deck[ndeck];
+
+    r = deck_init(d, &rt, timecode, importer, speed, phono, protect);
+    if (r == -1)
+        return -1;
+
+    /* Connect this deck to available controllers */
+
+    for (n = 0; n < nctl; n++)
+        controller_add_deck(&ctl[n], d);
+
+    ndeck++;
+
+    return 0;
+}
+
 int main(int argc, char *argv[])
 {
     int rc = -1, n, priority;
-    const char *importer, *scanner, *geo;
+    const char *scanner, *geo;
     char *endptr;
-    size_t nctl;
-    double speed;
-    struct timecode_def *timecode;
-    bool protect, use_mlock, phono;
+    bool use_mlock;
 
-    struct controller ctl[2];
-    struct rt rt;
     struct library library;
 
 #if defined WITH_OSS || WITH_ALSA
@@ -288,10 +337,7 @@ int main(int argc, char *argv[])
 		  !strcmp(argv[0], "-j"))
 	{
             int r;
-            unsigned int sample_rate;
-            struct deck *ld;
             struct device *device;
-            struct timecoder *timecoder;
 
             /* Create a deck */
 
@@ -301,18 +347,9 @@ int main(int argc, char *argv[])
                 return -1;
             }
 
-            if (ndeck == ARRAY_SIZE(deck)) {
-                fprintf(stderr, "Too many decks; aborting.\n");
+            device = start_deck(argv[1]);
+            if (device == NULL)
                 return -1;
-            }
-
-            fprintf(stderr, "Initialising deck %zd (%s)...\n", ndeck, argv[1]);
-
-            ld = &deck[ndeck];
-            device = &ld->device;
-            timecoder = &ld->timecoder;
-            ld->importer = importer;
-            ld->protect = protect;
 
             /* Work out which device type we are using, and initialise
              * an appropriate device. */
@@ -343,32 +380,24 @@ int main(int argc, char *argv[])
             if (r == -1)
                 return -1;
 
-	    sample_rate = device_sample_rate(device);
-
-            /* Default timecode decoder where none is specified */
+            commit_deck();
 
-            if (timecode == NULL) {
-                timecode = timecoder_find_definition(DEFAULT_TIMECODE);
-                assert(timecode != NULL);
-            }
+            argv += 2;
+            argc -= 2;
 
-            timecoder_init(timecoder, timecode, speed, sample_rate, phono);
+        } else if (!strcmp(argv[0], "--dummy")) {
 
-            /* Connect up the elements to make an operational deck */
+            struct device *v;
 
-            r = deck_init(ld, &rt);
-            if (r == -1)
+            v = start_deck("dummy");
+            if (v == NULL)
                 return -1;
 
-            /* Connect this deck to available controllers */
-
-            for (n = 0; n < nctl; n++)
-                controller_add_deck(&ctl[n], &deck[ndeck]);
+            dummy_init(v);
+            commit_deck();
 
-            ndeck++;
-
-            argv += 2;
-            argc -= 2;
+            argv++;
+            argc--;
 
         } else if (!strcmp(argv[0], "-t")) {
 
@@ -507,8 +536,7 @@ int main(int argc, char *argv[])
             /* Load in a music library */
 
             if (argc < 2) {
-                fprintf(stderr, "-%c requires a pathname as an argument.\n",
-                        argv[0][1]);
+                fprintf(stderr, "-l requires a pathname as an argument.\n");
                 return -1;
             }
 
diff --git a/xwax.h b/xwax.h
index 52e7ad3..a47f7b7 100644
--- a/xwax.h
+++ b/xwax.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Mark Hills <mark at xwax.org>
+ * Copyright (C) 2015 Mark Hills <mark at xwax.org>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License

-- 
xwax packaging



More information about the pkg-multimedia-commits mailing list