summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--raul/Atom.h12
-rw-r--r--raul/JackDriver.h2
-rw-r--r--raul/Makefile.am3
-rw-r--r--raul/TimeSlice.h160
-rw-r--r--src/JackDriver.cpp7
-rw-r--r--src/RDFWriter.cpp2
-rw-r--r--src/TimeSlice.cpp54
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/time_test.cpp29
9 files changed, 262 insertions, 11 deletions
diff --git a/raul/Atom.h b/raul/Atom.h
index 41a7fdd..cded253 100644
--- a/raul/Atom.h
+++ b/raul/Atom.h
@@ -23,8 +23,6 @@
#include <cstring>
#include <string>
-using std::string;
-
namespace Raul {
@@ -42,11 +40,11 @@ public:
BLOB
};
- Atom() : _type(NIL), _blob_val(0) {}
- Atom(int32_t val) : _type(INT), _int_val(val) {}
- Atom(float val) : _type(FLOAT), _float_val(val) {}
- Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {}
- Atom(const string& val) : _type(STRING), _string_val(strdup(val.c_str())) {}
+ Atom() : _type(NIL), _blob_val(0) {}
+ Atom(int32_t val) : _type(INT), _int_val(val) {}
+ Atom(float val) : _type(FLOAT), _float_val(val) {}
+ Atom(const char* val) : _type(STRING), _string_val(strdup(val)) {}
+ Atom(const std::string& val) : _type(STRING), _string_val(strdup(val.c_str())) {}
Atom(void* val) : _type(BLOB), _blob_size(sizeof(val)), _blob_val(malloc(_blob_size))
{ memcpy(_blob_val, val, sizeof(_blob_size)); }
diff --git a/raul/JackDriver.h b/raul/JackDriver.h
index e7aa30a..17d7d4c 100644
--- a/raul/JackDriver.h
+++ b/raul/JackDriver.h
@@ -39,7 +39,7 @@ public:
JackDriver();
virtual ~JackDriver();
- void attach(const string& client_name, string server_name="default");
+ void attach(const string& client_name, string server_name="");
void detach();
bool is_attached() const { return (_client != NULL); }
diff --git a/raul/Makefile.am b/raul/Makefile.am
index 359e46f..76c9031 100644
--- a/raul/Makefile.am
+++ b/raul/Makefile.am
@@ -26,7 +26,8 @@ raulinclude_HEADERS = \
Slave.h \
Stateful.h \
Thread.h \
- WeakPtr.h
+ WeakPtr.h \
+ TimeSlice.h
if WITH_LIBLO
raulinclude_HEADERS += AtomLiblo.h
diff --git a/raul/TimeSlice.h b/raul/TimeSlice.h
new file mode 100644
index 0000000..289233c
--- /dev/null
+++ b/raul/TimeSlice.h
@@ -0,0 +1,160 @@
+/* This file is part of Raul.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * Raul is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Raul 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 for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef RAUL_TIMESLICE_H
+#define RAUL_TIMESLICE_H
+
+#include <cassert>
+#include <boost/utility.hpp>
+
+namespace Raul {
+
+
+typedef uint32_t TickTime; ///< absolute time in ticks
+typedef uint32_t TickCount; ///< offset in ticks
+typedef double BeatTime;
+typedef double BeatCount;
+typedef double Seconds;
+
+
+/** A duration of time, with conversion between tick time and beat time.
+ *
+ * This is a slice along a single timeline (ie t=0 in ticks and t=0 in beats
+ * are equal). Relation to an external time base (e.g. Jack frame time) is
+ * represented by frame_offset (the idea is that this holds all the information
+ * necessary for passing to run() methods so they know the current state of
+ * things WRT time).
+ *
+ * This class handles conversion between two units of time: musical
+ * (beat) time, and real (tick) time. Real time is discrete, the smallest
+ * unit of time is the 'tick' (usually audio frames or MIDI ticks). Beat time
+ * is stored as a double (to be independent of any rates or timer precision).
+ *
+ * This caches as many values as possible to make calls less expensive, pass it
+ * around by reference, not value.
+ *
+ * \ingroup raul
+ */
+class TimeSlice : public boost::noncopyable {
+public:
+ TimeSlice(double tick_rate, double bpm)
+ : _tick_rate(tick_rate)
+ , _beat_rate(60.0/bpm)
+ , _start_ticks(0)
+ , _length_ticks(0)
+ , _start_beats(0)
+ , _length_beats(0)
+ , _offset_ticks(0)
+ {}
+
+
+ /** Set the start and length of the slice.
+ *
+ * Note that external offset is not affected by this, don't forget to reset
+ * the offset each cycle!
+ */
+ void set_window(TickTime start, TickCount length) {
+ _start_ticks = start;
+ _length_ticks = length;
+ update_beat_time();
+ }
+
+ void set_start(TickTime time) { _start_ticks = time; update_beat_time(); }
+
+ void set_length(TickCount length) { _length_ticks = length; update_beat_time(); }
+
+ bool contains(TickTime time) {
+ return (time >= start_ticks() && time < start_ticks() + length_ticks());
+ }
+
+ void set_tick_rate(double tick_rate) {
+ _tick_rate = tick_rate;
+ update_beat_time();
+ }
+
+ void set_bpm(double bpm) {
+ _beat_rate = 60.0/bpm;
+ update_beat_time();
+ }
+
+ inline Seconds beats_to_seconds(BeatTime beats) const {
+ return (beats * _beat_rate);
+ }
+
+ inline TickTime beats_to_ticks(BeatTime beats) const {
+ return static_cast<TickTime>(beats_to_seconds(beats) / _tick_rate);
+ }
+
+ inline Seconds ticks_to_seconds(TickTime ticks) const {
+ return (ticks * _tick_rate);
+ }
+
+ inline BeatTime ticks_to_beats(TickTime ticks) const {
+ return ticks_to_seconds(ticks) / _beat_rate;
+ }
+
+ /** Start of current sub-cycle in ticks */
+ inline TickTime start_ticks() const { return _start_ticks; }
+
+ /** Length of current sub-cycle in ticks */
+ inline TickCount length_ticks() const { return _length_ticks; }
+
+ /** Start of current sub-cycle in beats */
+ inline BeatTime start_beats() const { return _start_beats; }
+
+ /** Length of current sub-cycle in beats */
+ inline BeatCount length_beats() const { return _length_beats; }
+
+
+ // Real-time conversion
+/*
+ TickCount ticks_to_offset(TickTime time) {
+ assert(time >= _start_ticks);
+ TickCount ret = time - _start_ticks + _offset_ticks;
+ assert(ret < _offset_ticks + _length_ticks);
+ return ret;
+ }
+*/
+ /** Set the offset between real-time and timeslice-time. */
+ inline void set_offset(TickCount offset) { _offset_ticks = offset; }
+ /** Offset relative to external (e.g Jack) time */
+ inline TickCount offset_ticks() const { return _offset_ticks; }
+
+private:
+
+ inline void update_beat_time() {
+ _start_beats = ticks_to_beats(_start_ticks);
+ _length_beats = ticks_to_beats(_length_ticks);
+ }
+
+ // Rate/Tempo
+ double _tick_rate; ///< Tick rate in Hz (e.g. sample rate)
+ double _beat_rate; ///< Beat rate in Hz
+
+ // Current time
+ TickTime _start_ticks; ///< Current window start in ticks
+ TickCount _length_ticks; ///< Current window length in ticks
+ BeatTime _start_beats; ///< Current window start in beats
+ BeatCount _length_beats; ///< Current window length in beats
+
+ TickCount _offset_ticks; ///< Offset to global time (ie Jack sub-cycle offset)
+};
+
+
+} // namespace Raul
+
+#endif // RAUL_TIMESLICE_H
diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp
index fb529eb..cededca 100644
--- a/src/JackDriver.cpp
+++ b/src/JackDriver.cpp
@@ -58,7 +58,12 @@ JackDriver::attach(const string& client_name, string server_name)
jack_set_error_function(error_cb);
- _client = jack_client_open(client_name.c_str(), JackServerName, NULL, server_name.c_str(), NULL);
+ if (server_name.length() > 0)
+ _client = jack_client_open(client_name.c_str(), JackServerName, NULL,
+ server_name.c_str(), NULL);
+ else
+ _client = jack_client_open(client_name.c_str(), JackNullOption, NULL, NULL);
+
if (_client == NULL) {
//_app->status_message("[JACK] Unable to create client");
_is_activated = false;
diff --git a/src/RDFWriter.cpp b/src/RDFWriter.cpp
index 625d1fc..33bc220 100644
--- a/src/RDFWriter.cpp
+++ b/src/RDFWriter.cpp
@@ -21,6 +21,8 @@
#define U(x) ((const unsigned char*)(x))
+using namespace std;
+
namespace Raul {
diff --git a/src/TimeSlice.cpp b/src/TimeSlice.cpp
new file mode 100644
index 0000000..d6b7fc6
--- /dev/null
+++ b/src/TimeSlice.cpp
@@ -0,0 +1,54 @@
+/* This file is part of Raul.
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *
+ * Raul is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Raul 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 for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <raul/TimeSlice.h>
+
+namespace Raul {
+
+
+TimeSlice::TimeSlice(double tick_rate, double bpm)
+ : _tick_rate(tick_rate)
+ , _beat_rate(60.0/bpm)
+ , _start_ticks(0)
+ , _offset(0)
+ , _length(0)
+ , _start_beats(0)
+{}
+
+
+/** Update beat time to match real (tick) time.
+ */
+void
+TimeSlice::update_beat_time()
+{
+ _start_beats = (start_ticks() * _tick_rate) / _beat_rate;
+}
+
+
+TickTime
+TimeSlice::beats_to_ticks(BeatTime beats)
+{
+ return static_cast<TickTime>(beats_to_seconds(beats) / _tick_rate);
+}
+
+Seconds
+TimeSlice::beats_to_seconds(BeatTime beats)
+{
+ return (beats * _beat_rate);
+}
+
+} // namespace Raul
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 9ae9810..05b0f21 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -3,18 +3,20 @@ if BUILD_TESTS
AM_CXXFLAGS = -I.. -lpthread @RASQAL_CFLAGS@ @GLIBMM_CFLAGS@
ALL_LIBS = @RASQAL_LIBS@ @GLIBMM_LIBS@ ../src/libraul.la
-bin_PROGRAMS = path_test thread_test queue_test atomic_test list_test
+bin_PROGRAMS = path_test thread_test queue_test atomic_test list_test time_test
thread_test_LDADD = $(ALL_LIBS)
path_test_LDADD = $(ALL_LIBS)
queue_test_LDADD = $(ALL_LIBS)
atomic_test_LDADD = $(ALL_LIBS)
list_test_LDADD = $(ALL_LIBS)
+time_test_LDADD = $(ALL_LIBS)
path_test_SOURCES = path_test.cpp
thread_test_SOURCES = thread_test.cpp
queue_test_SOURCES = queue_test.cpp
atomic_test_SOURCES = atomic_test.cpp
list_test_SOURCES = list_test.cpp
+time_test_SOURCES = time_test.cpp
endif
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
new file mode 100644
index 0000000..0eb0a83
--- /dev/null
+++ b/tests/time_test.cpp
@@ -0,0 +1,29 @@
+#include <iostream>
+#include <raul/TimeSlice.h>
+
+using namespace std;
+using namespace Raul;
+
+
+int
+main()
+{
+ TimeSlice ts(1/48000.0, 120);
+
+ string in_string;
+ double in_double = 0;
+
+ cout << "Beats: ";
+ cin >> in_double;
+
+ cout << "\tSeconds: ";
+ cout << ts.beats_to_seconds(in_double);
+ cout << endl;
+
+ cout << "\tTicks: ";
+ cout << ts.beats_to_ticks(in_double);
+ cout << endl;
+
+ return 0;
+}
+