[SCM] calf/master: + Only builds LADSPA and/or JACK versions when prerequisites are met+other configure fixes (unfortunately, still uses -O2) + Better GUI in JACK version + Command-line handling fixes (copy-pasting too fast!) + First attempt at benchmarking framework, more will follow! + Fixed bugs in direct II form of biquad filters
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:36:42 UTC 2013
The following commit has been merged in the master branch:
commit e12a572cac768608787ccb8e82184c7f68858dc1
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date: Sun Dec 2 22:18:37 2007 +0000
+ Only builds LADSPA and/or JACK versions when prerequisites are met+other configure fixes (unfortunately, still uses -O2)
+ Better GUI in JACK version
+ Command-line handling fixes (copy-pasting too fast!)
+ First attempt at benchmarking framework, more will follow!
+ Fixed bugs in direct II form of biquad filters
git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@5 78b06b96-2940-0410-b7fc-879d825d01d8
diff --git a/config.h.in b/config.h.in
index 5e08aed..6f38196 100644
--- a/config.h.in
+++ b/config.h.in
@@ -9,18 +9,21 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the <jack/jack.h> header file. */
+#undef HAVE_JACK_JACK_H
+
/* Define to 1 if you have the <ladspa.h> header file. */
#undef HAVE_LADSPA_H
-/* Define to 1 if you have the `jack' library (-ljack). */
-#undef HAVE_LIBJACK
-
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
+/* Define to 1 if you have the <phat/phatknob.h> header file. */
+#undef HAVE_PHAT_PHATKNOB_H
+
/* Define to 1 if you have the `pow' function. */
#undef HAVE_POW
@@ -45,6 +48,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
diff --git a/configure.in b/configure.in
index f65ab9b..59fa169 100644
--- a/configure.in
+++ b/configure.in
@@ -2,32 +2,64 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.61)
-AC_INIT([calf],[0.0.4],[wdev at foltman.com])
+AC_INIT([calf],[0.0.5],[wdev at foltman.com])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADER([config.h])
-AM_INIT_AUTOMAKE([std-options])
+AM_INIT_AUTOMAKE(1.8)
+
+if test "x$prefix" = "xNONE"; then
+ prefix=$ac_default_prefix
+fi
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
+AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_LIBTOOL
# Checks for libraries.
PKG_PROG_PKG_CONFIG
-PKG_CHECK_MODULES(GUI_DEPS, glib-2.0 >= 2.10.0 gtk+-2.0 >= 2.12.0 phat >= 0.4.1 jack >= 0.103.0)
-AC_CHECK_LIB([jack], [jack_port_new])
-CXXFLAGS="$CXXFLAGS -ffast-math $GUI_DEPS_CFLAGS"
-LDFLAGS="$LDFLAGS $GUI_DEPS_LIBS"
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([memory.h stdint.h stdlib.h ladspa.h time.h])
+
+AC_CHECK_HEADER(ladspa.h, LADSPA_FOUND="yes", LADSPA_FOUND="no")
+
+AC_CHECK_HEADERS([jack/jack.h], have_jack_header=yes, have_jack_header=no)
+
+if test "$have_jack_header" = "yes"; then
+ PKG_CHECK_MODULES(JACK_DEPS, jack >= 0.103.0,
+ AC_CHECK_LIB([jack], [jack_port_new], JACK_FOUND="yes", JACK_FOUND="no"),
+ JACK_FOUND="no")
+else
+ JACK_FOUND="no"
+fi
AC_SUBST(GUI_DEPS_CFLAGS)
AC_SUBST(GUI_DEPS_LIBS)
+AC_SUBST(JACK_DEPS_CFLAGS)
+AC_SUBST(JACK_DEPS_LIBS)
-# Checks for header files.
-AC_HEADER_STDC
-AC_CHECK_HEADERS([memory.h stdint.h stdlib.h ladspa.h])
+if test "$JACK_FOUND" = "yes"; then
+ PKG_CHECK_MODULES(GUI_DEPS, gtk+-2.0 >= 2.4.0 phat >= 0.4.1,
+ [
+ CFLAGS="$CFLAGS $GUI_DEPS_CFLAGS $JACK_DEPS_CFLAGS"
+ CPPFLAGS="$CPPFLAGS $GUI_DEPS_CFLAGS $JACK_DEPS_CFLAGS"
+ AC_CHECK_HEADERS([phat/phatknob.h],
+ JACK_ENABLED="yes",
+ JACK_ENABLED="no (phat library is too old, SVN version required)")
+ ],
+ JACK_ENABLED="no (GTK+ or phat is missing or too old)"
+ )
+else
+ JACK_ENABLED="no"
+fi
+
+AM_CONDITIONAL(USE_LADSPA, test "$LADSPA_FOUND" = "yes")
+AM_CONDITIONAL(USE_JACK, test "$JACK_ENABLED" = "yes")
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
@@ -64,4 +96,12 @@ AC_CHECK_FUNCS([floor memset pow])
AC_CONFIG_FILES([Makefile
src/Makefile
src/calf/Makefile])
+AC_MSG_RESULT([
+ Calf configured
+
+ LADSPA enabled: $LADSPA_FOUND
+ JACK host enabled: $JACK_ENABLED
+
+ Installation prefix: $prefix
+])
AC_OUTPUT
diff --git a/src/Makefile.am b/src/Makefile.am
index f5bfc19..a298e41 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,15 +6,29 @@ SUBDIRS = calf
ladspadir = $(with_ladspa_dir)
-bin_PROGRAMS = calfjackhost calfmakerdf
+bin_PROGRAMS =
+noinst_PROGRAMS = calfbenchmark
+noinst_LTLIBRARIES = libcalf.la libcalfstatic.la
+
+AM_CXXFLAGS = -O3 -ffast-math -march=pentium4 -finline-limit=8
+
+if USE_JACK
+AM_CXXFLAGS += -DUSE_JACK=1
+bin_PROGRAMS += calfjackhost
calfjackhost_SOURCES = jackhost.cpp
-calfjackhost_LDADD = libcalfstatic.la
+calfjackhost_LDADD = libcalfstatic.la $(JACK_DEPS_LIBS) $(GUI_DEPS_LIBS)
+endif
+if USE_LADSPA
+AM_CXXFLAGS += -DUSE_LADSPA=1
+bin_PROGRAMS += calfmakerdf
calfmakerdf_SOURCES = makerdf.cpp
calfmakerdf_LDADD = libcalfstatic.la
+endif
-noinst_LTLIBRARIES = libcalf.la libcalfstatic.la
+calfbenchmark_SOURCES = benchmark.cpp
+calfbenchmark_LDADD =
libcalf_la_SOURCES = modules.cpp giface.cpp
libcalf_la_LDFLAGS = -rpath $(ladspadir) -version-info 0:0:0
@@ -26,16 +40,20 @@ clean-local:
$(RM) -f calfjackhost *~
install-data-hook:
+if USE_LADSPA
install -d -m 755 $(DESTDIR)$(with_ladspa_dir)
install -d -m 755 $(DESTDIR)$(with_ladspa_rdf_dir)
install -c -m 755 $(top_builddir)/src/.libs/libcalf.so.0.0.0 $(DESTDIR)$(with_ladspa_dir)/calf.so
$(DESTDIR)$(bindir)/calfmakerdf > $(DESTDIR)$(with_ladspa_rdf_dir)/calf.rdf
+endif
#remove calf.so, calf.rdf and - if empty - ladspa dir in usr/share
uninstall-hook:
+if USE_LADSPA
$(RM) -f $(DESTDIR)$(with_ladspa_dir)/calf.so
$(RM) -f $(DESTDIR)$(with_ladspa_rdf_dir)/calf.rdf
rmdir $(DESTDIR)$(with_ladspa_rdf_dir)
+endif
#install:
# $(INSTALL) calfjackhost $(bindir)
diff --git a/src/benchmark.cpp b/src/benchmark.cpp
new file mode 100644
index 0000000..071f5c9
--- /dev/null
+++ b/src/benchmark.cpp
@@ -0,0 +1,189 @@
+#include <getopt.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <config.h>
+#include <calf/giface.h>
+#include <calf/modules.h>
+#include <calf/benchmark.h>
+
+using namespace std;
+using namespace dsp;
+
+template<int BUF_SIZE>
+struct empty_benchmark
+{
+ void prepare()
+ {
+ }
+ void cleanup()
+ {
+ }
+ double scaler() { return BUF_SIZE; }
+};
+
+struct filter_lp24dB_benchmark
+{
+ enum { BUF_SIZE = 256 };
+ float buffer[BUF_SIZE];
+ float result;
+ dsp::biquad<float> biquad, biquad2;
+ void prepare()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = i;
+ biquad.set_lp_rbj(2000, 0.7, 44100);
+ biquad2.set_lp_rbj(2000, 0.7, 44100);
+ result = 0;
+ }
+ void cleanup() { result = buffer[BUF_SIZE - 1]; }
+ double scaler() { return BUF_SIZE; }
+};
+
+struct filter_24dB_lp_twopass_d1: public filter_lp24dB_benchmark
+{
+ void run()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad.process_d1(buffer[i]);
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad2.process_d1(buffer[i]);
+ }
+};
+
+struct filter_24dB_lp_onepass_d1: public filter_lp24dB_benchmark
+{
+ void run()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad2.process_d1(biquad.process_d2(buffer[i]));
+ }
+};
+
+struct filter_12dB_lp_d1: public filter_lp24dB_benchmark
+{
+ void run()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad.process_d1(buffer[i]);
+ }
+};
+
+struct filter_24dB_lp_twopass_d2: public filter_lp24dB_benchmark
+{
+ void run()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad.process_d1(buffer[i]);
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad2.process_d1(buffer[i]);
+ }
+};
+
+struct filter_24dB_lp_onepass_d2: public filter_lp24dB_benchmark
+{
+ void run()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad2.process_d2(biquad.process_d2(buffer[i]));
+ }
+};
+
+struct filter_12dB_lp_d2: public filter_lp24dB_benchmark
+{
+ void run()
+ {
+ for (int i = 0; i < BUF_SIZE; i++)
+ buffer[i] = biquad.process_d2(buffer[i]);
+ }
+};
+
+#define ALIGN_TEST_RUN 1024
+
+struct __attribute__((aligned(8))) alignment_test: public empty_benchmark<ALIGN_TEST_RUN>
+{
+ char __attribute__((aligned(8))) data[ALIGN_TEST_RUN * sizeof(double) + sizeof(double)];
+ float result;
+
+ virtual double *get_ptr()=0;
+ void prepare()
+ {
+ memset(data, 0, sizeof(data));
+ result = 0;
+ }
+ void cleanup()
+ {
+ result = 0;
+ double *p = get_ptr();
+ for (int i=0; i < ALIGN_TEST_RUN; i++)
+ result += p[i];
+ }
+};
+
+struct aligned_double: public alignment_test
+{
+ virtual double *get_ptr() { return (double *)data; }
+ void run()
+ {
+ double *ptr = (double *)data;
+ for (int i=0; i < ALIGN_TEST_RUN; i++)
+ ptr[i] += 1 + i;
+ }
+};
+
+struct __attribute__((aligned(8))) misaligned_double: public alignment_test
+{
+ virtual double *get_ptr() { return (double *)(data+4); }
+ void run()
+ {
+ double *ptr = (double *)(data + 4);
+ for (int i=0; i < ALIGN_TEST_RUN; i++)
+ ptr[i] += 1 + i;
+ }
+};
+
+const char *unit = NULL;
+
+static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {"unit", 1, 0, 'u'},
+ {0,0,0,0},
+};
+
+int main(int argc, char *argv[])
+{
+ while(1) {
+ int option_index;
+ int c = getopt_long(argc, argv, "u:hv", long_options, &option_index);
+ if (c == -1)
+ break;
+ switch(c) {
+ case 'h':
+ case '?':
+ printf("Benchmark suite Calf plugin pack\nSyntax: %s [--help] [--version] [--unit biquad|alignment]\n", argv[0]);
+ return 0;
+ case 'v':
+ printf("%s\n", PACKAGE_STRING);
+ return 0;
+ case 'u':
+ unit = optarg;
+ break;
+ }
+ }
+
+ if (!unit || !strcmp(unit, "biquad")) {
+ do_simple_benchmark<filter_24dB_lp_twopass_d1>();
+ do_simple_benchmark<filter_24dB_lp_onepass_d1>();
+ do_simple_benchmark<filter_12dB_lp_d1>();
+ do_simple_benchmark<filter_24dB_lp_twopass_d2>();
+ do_simple_benchmark<filter_24dB_lp_onepass_d2>();
+ do_simple_benchmark<filter_12dB_lp_d2>();
+ }
+
+ if (!unit || !strcmp(unit, "alignment")) {
+ do_simple_benchmark<misaligned_double>();
+ do_simple_benchmark<aligned_double>();
+ }
+
+ return 0;
+}
diff --git a/src/calf/Makefile.am b/src/calf/Makefile.am
index 2508e0f..68ef4b6 100644
--- a/src/calf/Makefile.am
+++ b/src/calf/Makefile.am
@@ -1,3 +1,3 @@
calfdir = $(includedir)/calf
-calf_HEADERS = audio_fx.h biquad.h buffer.h delay.h fixed_point.h giface.h inertia.h modules.h onepole.h primitives.h wave.h
+calf_HEADERS = audio_fx.h benchmark.h biquad.h buffer.h delay.h fixed_point.h giface.h inertia.h modules.h onepole.h primitives.h wave.h
diff --git a/src/calf/benchmark.h b/src/calf/benchmark.h
new file mode 100644
index 0000000..e6835d1
--- /dev/null
+++ b/src/calf/benchmark.h
@@ -0,0 +1,156 @@
+/* Calf DSP Library
+ * Reusable performance measurement classes.
+ *
+ * Copyright (C) 2007 Krzysztof Foltman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CALF_BENCHMARK_H
+#define __CALF_BENCHMAR_H
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include "primitives.h"
+#include <algorithm>
+#include <typeinfo>
+
+namespace dsp {
+#if 0
+}; to keep editor happy
+#endif
+
+
+class median_stat
+{
+public:
+ double *data;
+ unsigned int pos, count;
+ bool sorted;
+
+ median_stat() {
+ data = NULL;
+ pos = 0;
+ count = 0;
+ sorted = false;
+ }
+ void start(int items) {
+ if (data)
+ delete []data;
+ data = new double[items];
+ pos = 0;
+ count = items;
+ sorted = false;
+ }
+ void add(double value)
+ {
+ assert(pos < count);
+ data[pos++] = value;
+ }
+ void end()
+ {
+ std::sort(&data[0], &data[count]);
+ sorted = true;
+ }
+ float get()
+ {
+ assert(sorted);
+ return data[count >> 1];
+ }
+};
+
+// USE_RDTSC is for testing on my own machine, a crappy 1.6GHz Pentium 4 - it gives less headaches than clock() based measurements
+#define USE_RDTSC 0
+#define CLOCK_SPEED (1.6 * 1000.0 * 1000.0 * 1000.0)
+
+#if USE_RDTSC
+inline uint64_t rdtsc()
+{
+ unsigned long long int x;
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+ return x;
+}
+#endif
+
+template<typename Target, class Stat>
+class simple_benchmark
+{
+public:
+ Target target;
+ Stat &stat;
+
+ simple_benchmark(const Target &_target, Stat &_stat)
+ : target(_target)
+ , stat(_stat)
+ {
+ }
+
+ int measure(int runs, int repeats)
+ {
+ int priority = getpriority(PRIO_PROCESS, getpid());
+ stat.start(runs);
+ if (setpriority(PRIO_PROCESS, getpid(), -20) < 0)
+ fprintf(stderr, "Warning: could not set process priority, measurements can be worthless\n");
+ for (int i = 0; i < runs; i++) {
+ target.prepare();
+ // XXXKF measuring CPU time with clock() sucks,
+#if USE_RDTSC
+ uint64_t start = rdtsc();
+#else
+ clock_t start = ::clock();
+#endif
+ for (int j = 0; j < repeats; j++) {
+ target.run();
+ }
+#if USE_RDTSC
+ uint64_t end = rdtsc();
+ double elapsed = double(end - start) / (CLOCK_SPEED * repeats * target.scaler());
+#else
+ clock_t end = ::clock();
+ double elapsed = double(end - start) / (double(CLOCKS_PER_SEC) * repeats * target.scaler());
+#endif
+ stat.add(elapsed);
+ target.cleanup();
+ // printf("elapsed = %f start = %d end = %d diff = %d\n", elapsed, start, end, end - start);
+ }
+ setpriority(PRIO_PROCESS, getpid(), priority);
+ stat.end();
+ }
+
+ float get_stat()
+ {
+ return stat.get();
+ }
+};
+
+template<class T>
+void do_simple_benchmark(int runs = 5, int repeats = 50000)
+{
+ dsp::median_stat stat;
+ dsp::simple_benchmark<T, dsp::median_stat> benchmark(T(), stat);
+
+ benchmark.measure(runs, repeats);
+
+ printf("%-30s: %f/sec, %f/CDsr, value = %f\n", typeid(T).name(), 1.0 / stat.get(), 1.0 / (44100 * stat.get()), benchmark.target.result);
+}
+
+
+#if 0
+{ to keep editor happy
+#endif
+}
+
+#endif
diff --git a/src/calf/biquad.h b/src/calf/biquad.h
index b597583..4c13e28 100644
--- a/src/calf/biquad.h
+++ b/src/calf/biquad.h
@@ -217,7 +217,7 @@ public:
// direct II form with two state variables
inline T process_d2(T in)
{
- T tmp = in - y1 * b1 - y2 * b2;
+ T tmp = in - w1 * b1 - w2 * b2;
T out = tmp * a0 + w1 * a1 + w2 * a2;
w2 = w1;
w1 = tmp;
@@ -225,9 +225,10 @@ public:
}
// direct II form with two state variables, lowpass version
+ // interesting fact: this is actually slower than the general version!
inline T process_d2_lp(T in)
{
- T tmp = in - y1 * b1 - y2 * b2;
+ T tmp = in - w1 * b1 - w2 * b2;
T out = (tmp + w1 + w1 + w2) * a0;
w2 = w1;
w1 = tmp;
diff --git a/src/calf/giface.h b/src/calf/giface.h
index b88cc71..5a38774 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -23,8 +23,12 @@
#include <stdint.h>
#include <stdlib.h>
+#if USE_LADSPA
#include <ladspa.h>
+#endif
+#if USE_JACK
#include <jack/jack.h>
+#endif
#include <exception>
#include <string>
@@ -58,7 +62,7 @@ enum parameter_flags
PF_CTLO_HORIZ = 0x010000,
PF_CTLO_VERT = 0x020000,
- PF_UNITS = 0xFF000000,
+ PF_UNITMASK = 0xFF000000,
PF_UNIT_DB = 0x01000000,
PF_UNIT_COEF = 0x02000000,
PF_UNIT_HZ = 0x03000000,
@@ -68,11 +72,12 @@ enum parameter_flags
struct parameter_properties
{
- float def_value, min, max, step;
- uint32_t flags;
- const char **choices;
- float from_01(float value01);
- float to_01(float value);
+ float def_value, min, max, step;
+ uint32_t flags;
+ const char **choices;
+ float from_01(float value01) const;
+ float to_01(float value) const;
+ std::string to_string(float value) const;
};
struct midi_event {
@@ -111,6 +116,8 @@ struct ladspa_info
const char *plugin_type;
};
+#if USE_LADSPA
+
extern std::string generate_ladspa_rdf(const ladspa_info &info, parameter_properties *params, const char *param_names[], unsigned int count, unsigned int ctl_ofs);
template<class Module>
@@ -242,6 +249,8 @@ struct ladspa_wrapper
};
};
+#endif
+
struct audio_exception: public std::exception
{
const char *text;
@@ -253,6 +262,8 @@ public:
virtual ~audio_exception() throw () {}
};
+#if USE_JACK
+
class jack_host_base {
public:
typedef int (*process_func)(jack_nframes_t nframes, void *p);
@@ -419,6 +430,8 @@ public:
virtual parameter_properties* get_param_props() { return Module::param_props; }
};
+#endif
+
};
#endif
diff --git a/src/giface.cpp b/src/giface.cpp
index e589356..3eddd2d 100644
--- a/src/giface.cpp
+++ b/src/giface.cpp
@@ -18,16 +18,16 @@
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
+#include <config.h>
#include <assert.h>
#include <memory.h>
-#include <jack/jack.h>
#include <calf/giface.h>
#include <calf/modules.h>
using namespace synth;
using namespace std;
-float parameter_properties::from_01(float value01)
+float parameter_properties::from_01(float value01) const
{
switch(flags & PF_SCALEMASK)
{
@@ -46,7 +46,7 @@ float parameter_properties::from_01(float value01)
}
}
-float parameter_properties::to_01(float value)
+float parameter_properties::to_01(float value) const
{
switch(flags & PF_SCALEMASK)
{
@@ -67,11 +67,30 @@ float parameter_properties::to_01(float value)
}
}
+std::string parameter_properties::to_string(float value) const
+{
+ char buf[32];
+ if ((flags & PF_SCALEMASK) == PF_SCALE_PERC) {
+ sprintf(buf, "%g%%", 99.0 * value);
+ return string(buf);
+ }
+ sprintf(buf, "%g", value);
+
+ switch(flags & PF_UNITMASK) {
+ case PF_UNIT_DB: return string(buf) + " dB";
+ case PF_UNIT_HZ: return string(buf) + " Hz";
+ case PF_UNIT_SEC: return string(buf) + " s";
+ case PF_UNIT_MSEC: return string(buf) + " ms";
+ }
+ return string(buf);
+}
+
static std::string i2s(int value)
{
char buf[32];
sprintf(buf, "%d", value);
- return buf;
+
+ return string(buf);
}
static string f2s(double value)
@@ -95,9 +114,11 @@ static string rdf_escape(const string &src)
return dest;
}
+#if USE_LADSPA
+
static std::string unit_to_string(parameter_properties &props)
{
- uint32_t flags = props.flags & PF_UNITS;
+ uint32_t flags = props.flags & PF_UNITMASK;
switch(flags) {
case PF_UNIT_DB:
@@ -164,3 +185,5 @@ std::string synth::generate_ladspa_rdf(const ladspa_info &info, parameter_proper
rdf += " </ladspa:" + plugin_type + ">\n";
return rdf;
}
+
+#endif
diff --git a/src/jackhost.cpp b/src/jackhost.cpp
index fc48978..f6481f6 100644
--- a/src/jackhost.cpp
+++ b/src/jackhost.cpp
@@ -35,6 +35,7 @@ struct jack_host_param
{
jack_host_gui *gui;
int param_no;
+ GtkWidget *label;
};
class jack_host_gui
@@ -48,7 +49,7 @@ public:
jack_host_param *params;
jack_host_gui(GtkWidget *_toplevel);
- void create(synth::jack_host_base *_host);
+ void create(synth::jack_host_base *_host, const char *title);
static void knob_value_changed(PhatKnob *widget, gpointer value);
static void combo_value_changed(GtkComboBox *widget, gpointer value);
};
@@ -63,11 +64,13 @@ void jack_host_gui::knob_value_changed(PhatKnob *widget, gpointer value)
{
jack_host_param *jhp = (jack_host_param *)value;
jack_host_base &jh = *jhp->gui->host;
+ const parameter_properties &props = jh.get_param_props()[jhp->param_no];
int nparam = jhp->param_no;
- float cvalue = jh.get_param_props()[jhp->param_no].from_01 (phat_knob_get_value (widget));
+ float cvalue = props.from_01 (phat_knob_get_value (widget));
jh.get_params()[nparam] = cvalue;
// printf("%d -> %f\n", nparam, cvalue);
jh.set_params();
+ gtk_label_set_text (GTK_LABEL (jhp->label), props.to_string(cvalue).c_str());
}
void jack_host_gui::combo_value_changed(GtkComboBox *widget, gpointer value)
@@ -79,7 +82,7 @@ void jack_host_gui::combo_value_changed(GtkComboBox *widget, gpointer value)
jh.set_params();
}
-void jack_host_gui::create(synth::jack_host_base *_host)
+void jack_host_gui::create(synth::jack_host_base *_host, const char *title)
{
host = _host;
param_count = host->get_param_count();
@@ -90,11 +93,16 @@ void jack_host_gui::create(synth::jack_host_base *_host)
params[i].param_no = i;
}
- table = gtk_table_new (param_count, 2, FALSE);
+ table = gtk_table_new (param_count + 1, 3, FALSE);
+ GtkWidget *title_label = gtk_label_new ("");
+ gtk_label_set_markup (GTK_LABEL (title_label), (string("<b>")+title+"</b>").c_str());
+ gtk_table_attach (GTK_TABLE (table), title_label, 0, 3, 0, 1, GTK_EXPAND, GTK_EXPAND, 2, 2);
+
for (int i = 0; i < param_count; i++) {
GtkWidget *label = gtk_label_new (host->get_param_names()[host->get_input_count() + host->get_output_count() + i]);
- gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i + 1, GTK_EXPAND, GTK_EXPAND, 2, 2);
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, i + 1, i + 2, GTK_FILL, GTK_EXPAND, 2, 2);
parameter_properties &props = host->get_param_props()[i];
@@ -108,15 +116,25 @@ void jack_host_gui::create(synth::jack_host_base *_host)
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), props.choices[j]);
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), (int)host->get_params()[i] - (int)props.min);
gtk_signal_connect (GTK_OBJECT (widget), "changed", G_CALLBACK (combo_value_changed), (gpointer)¶ms[i]);
+ gtk_table_attach (GTK_TABLE (table), widget, 1, 3, i + 1, i + 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
}
else
{
- widget = phat_knob_new_with_range (host->get_param_props()[i].to_01 (host->get_params()[i]), 0, 1, 0.01);
- gtk_signal_connect (GTK_OBJECT (widget), "value-changed", G_CALLBACK (knob_value_changed), (gpointer)¶ms[i]);
+ GtkWidget *knob = phat_knob_new_with_range (host->get_param_props()[i].to_01 (host->get_params()[i]), 0, 1, 0.01);
+ gtk_signal_connect (GTK_OBJECT (knob), "value-changed", G_CALLBACK (knob_value_changed), (gpointer)¶ms[i]);
+ gtk_table_attach (GTK_TABLE (table), knob, 1, 2, i + 1, i + 2, GTK_EXPAND, GTK_EXPAND, 0, 0);
+
+ widget = gtk_label_new ("");
+ gtk_label_set_width_chars (GTK_LABEL (widget), 12);
+ gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), widget, 2, 3, i + 1, i + 2, GTK_FILL, GTK_EXPAND, 0, 0);
+ params[i].label = widget;
+ // gtk_widget_set_size_request (widget, widget->allocation.width, widget->allocation.height);
+ // gtk_widget_set_size_request (widget, 100, 10);
+
+ knob_value_changed (PHAT_KNOB (knob), (gpointer)¶ms[i]);
}
- gtk_table_attach (GTK_TABLE (table), widget, 1, 2, i, i + 1, GTK_EXPAND, GTK_EXPAND, 0, 0);
}
-
gtk_container_add (GTK_CONTAINER (toplevel), table);
}
@@ -130,12 +148,13 @@ void destroy(GtkWindow *window, gpointer data)
gtk_main_quit();
}
-void make_gui(jack_host_base *jh)
+void make_gui(jack_host_base *jh, const char *title, const char *effect)
{
GtkWidget *toplevel = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (toplevel), title);
gui = new jack_host_gui(toplevel);
- gui->create(jh);
+ gui->create(jh, effect);
gtk_signal_connect (GTK_OBJECT(toplevel), "destroy", G_CALLBACK(destroy), NULL);
gtk_widget_show_all(toplevel);
@@ -152,10 +171,10 @@ static struct option long_options[] = {
{0,0,0,0},
};
-char *effect_name = "flanger";
-char *client_name = "calfhost";
-char *input_name = "input";
-char *output_name = "output";
+const char *effect_name = "flanger";
+const char *client_name = "calfhost";
+const char *input_name = "input";
+const char *output_name = "output";
int main(int argc, char *argv[])
{
@@ -167,7 +186,10 @@ int main(int argc, char *argv[])
break;
switch(c) {
case 'h':
- printf("Syntax: %s [--effect reverb|flanger|filter] [--client <name>] [--input <name>] [--output <name>] [--help] [--version]\n", argv[0]);
+ case '?':
+ printf("JACK host for Calf effects\n"
+ "Syntax: %s [--effect reverb|flanger|filter] [--client <name>] [--input <name>] [--output <name>] [--help] [--version]\n",
+ argv[0]);
return 0;
case 'v':
printf("%s\n", PACKAGE_STRING);
@@ -199,7 +221,7 @@ int main(int argc, char *argv[])
return 1;
}
jh->open(client_name, input_name, output_name);
- make_gui(jh);
+ make_gui(jh, client_name, effect_name);
gtk_main();
delete gui;
jh->close();
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index d01b6d3..729a622 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -2,7 +2,6 @@
#include <stdint.h>
#include <stdlib.h>
#include <config.h>
-#include <jack/jack.h>
#include <calf/giface.h>
#include <calf/modules.h>
@@ -11,10 +10,6 @@ using namespace std;
static struct option long_options[] = {
{"help", 0, 0, 'h'},
{"version", 0, 0, 'v'},
- {"client", 1, 0, 'c'},
- {"effect", 1, 0, 'e'},
- {"input", 1, 0, 'i'},
- {"output", 1, 0, 'o'},
{0,0,0,0},
};
@@ -22,11 +17,12 @@ int main(int argc, char *argv[])
{
while(1) {
int option_index;
- int c = getopt_long(argc, argv, "c:e:i:o:hv", long_options, &option_index);
+ int c = getopt_long(argc, argv, "hv", long_options, &option_index);
if (c == -1)
break;
switch(c) {
case 'h':
+ case '?':
printf("LADSPA RDF generator for Calf plugin pack\nSyntax: %s [--help] [--version]\n", argv[0]);
return 0;
case 'v':
diff --git a/src/modules.cpp b/src/modules.cpp
index 7365502..bd55a3c 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -20,7 +20,9 @@
*/
#include <assert.h>
#include <memory.h>
+#if USE_JACK
#include <jack/jack.h>
+#endif
#include <calf/giface.h>
#include <calf/modules.h>
@@ -36,11 +38,13 @@ parameter_properties amp_audio_module::param_props[] = {
static synth::ladspa_info amp_info = { 0x847c, "Amp", "Calf Const Amp", "Krzysztof Foltman", copyright, "AmplifierPlugin" };
+#if USE_LADSPA
synth::ladspa_wrapper<amp_audio_module> amp(amp_info);
+#endif
////////////////////////////////////////////////////////////////////////////
-const char *flanger_audio_module::param_names[] = {"In L", "In R", "Out L", "Out R", "Min. delay", "Mod. depth", "Mod. rate", "Feedback", "Amount"};
+const char *flanger_audio_module::param_names[] = {"In L", "In R", "Out L", "Out R", "Minimum delay", "Modulation depth", "Modulation rate", "Feedback", "Amount"};
parameter_properties flanger_audio_module::param_props[] = {
{ 0.1, 0.1, 10, 1.01, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL },
@@ -52,11 +56,13 @@ parameter_properties flanger_audio_module::param_props[] = {
static synth::ladspa_info flanger_info = { 0x847d, "Flanger", "Calf Flanger", "Krzysztof Foltman", copyright, "FlangerPlugin" };
+#if USE_LADSPA
synth::ladspa_wrapper<flanger_audio_module> flanger(flanger_info);
+#endif
////////////////////////////////////////////////////////////////////////////
-const char *reverb_audio_module::param_names[] = {"In L", "In R", "Out L", "Out R", "Dec. time", "HF Damp", "Amount"};
+const char *reverb_audio_module::param_names[] = {"In L", "In R", "Out L", "Out R", "Decay time", "HF Damp", "Amount"};
parameter_properties reverb_audio_module::param_props[] = {
{ 1.5, 1.0, 4.0, 1.01, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_SEC, NULL },
@@ -66,11 +72,13 @@ parameter_properties reverb_audio_module::param_props[] = {
static synth::ladspa_info reverb_info = { 0x847e, "Reverb", "Calf Reverb", "Krzysztof Foltman", copyright, "ReverbPlugin" };
+#if USE_LADSPA
synth::ladspa_wrapper<reverb_audio_module> reverb(reverb_info);
+#endif
////////////////////////////////////////////////////////////////////////////
-const char *filter_audio_module::param_names[] = {"In L", "In R", "Out L", "Out R", "Cutoff", "Resonance", "Mode", "Inertia"};
+const char *filter_audio_module::param_names[] = {"In L", "In R", "Out L", "Out R", "Frequency", "Resonance", "Mode", "Inertia"};
const char *filter_choices[] = {
"12dB/oct Lowpass",
@@ -83,17 +91,20 @@ const char *filter_choices[] = {
parameter_properties filter_audio_module::param_props[] = {
{ 2000, 10,20000, 1.01, PF_FLOAT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_HZ, NULL },
- { 0.707, 0.707, 20, 1.1, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_DB, NULL },
+ { 0.707, 0.707, 20, 1.1, PF_FLOAT | PF_SCALE_GAIN | PF_CTL_KNOB | PF_UNIT_COEF, NULL },
{ 0, 0, 5, 1, PF_ENUM | PF_CTL_COMBO, filter_choices },
- { 20, 5, 100, 1, PF_INT | PF_SCALE_LOG | PF_CTL_KNOB, NULL},
+ { 20, 5, 100, 1, PF_INT | PF_SCALE_LOG | PF_CTL_KNOB | PF_UNIT_MSEC, NULL},
};
static synth::ladspa_info filter_info = { 0x847f, "Filter", "Calf Filter", "Krzysztof Foltman", copyright, "FilterPlugin" };
+#if USE_LADSPA
synth::ladspa_wrapper<filter_audio_module> filter(filter_info);
+#endif
////////////////////////////////////////////////////////////////////////////
+#if USE_LADSPA
extern "C" {
const LADSPA_Descriptor *ladspa_descriptor(unsigned long Index)
@@ -118,3 +129,4 @@ std::string synth::get_builtin_modules_rdf()
return rdf;
}
+#endif
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list