Re: DavOrgan C++ port - please review
- From: Tim Janik <timj gtk org>
- To: Stefan Westerfeld <stefan space twc de>
- Cc: Beast Liste <beast beast gtk org>
- Subject: Re: DavOrgan C++ port - please review
- Date: Wed, 15 Nov 2006 02:36:12 +0100 (CET)
On Mon, 23 Oct 2006, Stefan Westerfeld wrote:
Hi!
I just C++ified the DavOrgan module - please review. I'll not post a
diff between the old C code and the C++ code (hardly readable, because
everything is different), but start with the new implementation as-is
and then the rest of the changes I made to SVN to make it work.
thanks, it's great to see some movement on the porting front.
note that in the below review i'm also commenting on non-porting changes.
it's probably best if you simply commit the most straight-foward ported
version and then apply those comments on the resulting .idl/.cc file.
note that for the move, you should "svn copy" davorgan.h -> idl and .c -> .cc.
hm, looking at the changelog, you seem to have done the copying already, but
not applied the changes, leaving SVN with stale files (i.e. not taken care
of by the Makefile etc.). comitting this copy only shortly before the
application of the below changes and removal of the old .c and .h variants
would have been much better.
Cu... Stefan
plugins/davorgan.idl:
========================================================================
/* DavChorus - DAV Chorus Effect -*-mode: c++;-*-
* Copyright (c) 1999, 2000, 2002 David A. Bartold and Tim Janik
* Copyright (c) 2006 Stefan Westerfeld
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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 more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <bse/bse.idl>
namespace Bse {
namespace Dav {
class Organ : Effect {
Info icon = "icons/organ.png";
Info authors = "David A. Bartold";
Info license = _("GNU Lesser General Public License");
Info category = _("/Audio Sources/Organ");
Info blurb = _("DavOrgan is a modifiable additive organ synthesizer");
s/modifiable/versatile/ might sound better here.
IStream freq_in = (_("Freq In"), _("Frequency Input"));
OStream audio_out = (_("Audio Out"), _("Organ output"));
group _("Base Frequency") {
Real base_freq = Freq (_("Frequency"), NULL, BSE_KAMMER_FREQUENCY, STANDARD ":dial");
Int base_note = Note (_("Note"), NULL, BSE_KAMMER_NOTE, GUI);
Int transpose = (_("Transpose"), _("Transposition of the frequency in semitones"),
0, BSE_MIN_TRANSPOSE, BSE_MAX_TRANSPOSE, 12,
STANDARD ":f:dial:skip-default");
huh? :f: for an integer property is pointless...
you'll find the specific hint descriptions here:
http://beast.gtk.org/plugin-devel#section-property-options
Int fine_tune = FineTune (_("Fine Tune"), _("Amount of detuning in cent (hundredth part of a semitone)"),
STANDARD ":f:dial:skip-default");
same here.
};
group _("Harmonics") {
Real harm0 = Perc (_("16th"), _("16th Harmonic"), 100.0, STANDARD ":scale");
Real harm1 = Perc (_("8th"), _("8th Harmonic"), 100. * 36. / 127., STANDARD ":scale");
Real harm2 = Perc (_("5 1/3rd"), _("5 1/3rd Harmonic"), 100. * 100. / 127., STANDARD ":scale");
Real harm3 = Perc (_("4th"), _("4th Harmonic"), 100. * 32. / 127., STANDARD ":scale");
Real harm4 = Perc (_("2 2/3rd"), _("2 2/3rd Harmonic"), 100. * 91. / 127., STANDARD ":scale");
Real harm5 = Perc (_("2nd"), _("2nd Harmonic"), 100. * 55. / 127., STANDARD ":scale");
};
group _("Instrument flavour") {
Bool brass = (_("Brass Sounds"), _("Changes the organ to sound more brassy"), FALSE, STANDARD);
s/Changes/Change/ or s/Changes/Enable/
Bool reed = (_("Reed Sounds"), _("Adds reeds sound"), FALSE, STANDARD);
Bool flute = (_("Flute Sounds"), _("Adds flute sounds"), FALSE, STANDARD);
s/Adds/Add/
and, we should be able to use "true" "false" in .idl files, i.e. the C++
lowercase variant (even in .c files, since we include stdbool.h nowadays).
};
};
} // Dav
} // Bse
plugins/davorgan.cc:
========================================================================
/* DavOrgan - DAV Additive Organ Synthesizer
* Copyright (c) 1999, 2000, 2002 David A. Bartold and Tim Janik
* Copyright (c) 2006 Stefan Westerfeld
*
* This library 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 library 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "davorgan.genidl.hh"
#include <bse/bsemathsignal.h>
#include <bse/bsemain.h>
#include <bse/bseengine.h> /* FIXME: required for bse_engine_sample_freq() */
getting rid of bse_engine_sample_freq() is a *MUST-CHANGE* when porting
to C++. you can use the mix_freq() method which in C++ is optimized to
a global variable access.
#include <vector>
using namespace std;
using namespace Sfi;
using declarations should always be moved to the innermost scope
(like variables) i.e. into Bse::Dav.
namespace Bse {
namespace Dav {
+ using namespace std;
+ using namespace Sfi;
here should be the using decls.
class Organ : public OrganBase {
/* per mix_freq() tables */
struct Tables
{
guint ref_count;
we can use "uint" in C++.
i don't like the notion of a ref counted structure with
a public ref_count though.
if you want ref counting, in C++ this should be a private
field, have ref/unref methods a private destructor, and
no public constrcutor but a factory funciton that hands
out a Tables* pointer.
the C impl also does have clear _ref/_unref functions here,
and no other functions/methods mess around with table
construction/destruciton or its ref_count.
vector<gfloat> sine_table;
vector<gfloat> triangle_table;
vector<gfloat> pulse_table;
we can use "float" and "double" in C++.
Tables (guint rate) :
ref_count (1),
sine_table (rate),
triangle_table (rate),
pulse_table (rate)
{
guint half = rate / 2;
guint slope = rate / 10;
guint i;
/* Initialize sine table. */
for (guint i = 0; i < rate; i++)
sine_table[i] = sin ((double (i) / rate) * 2.0 * PI) / 6.0;
this is introducing new uneccessar casts. casts should be avoided
wherever possible to not blinden the compiler.
you've made rate an uint instead of the float from the C version
which gets you in the need for a cast in the first place, but that
is easily worked around by e.g.
Tables (guint urate)
{
double rate = urate;
/* Initialize triangle table. */
for (i = 0; i < rate / 2; i++)
triangle_table[i] = (4.0 / rate * i - 1.0) / 6.0;
for (; i < rate; i++)
triangle_table[i] = (4.0 / rate * (rate - i) - 1.0) / 6.0;
/* Initialize pulse table. */
for (i = 0; i < slope; i++)
pulse_table[i] = (-double (i) / slope) / 6.0;
for (; i < half - slope; i++)
pulse_table[i] = -1.0 / 6.0;
for (; i < half + slope; i++)
pulse_table[i] = ((double (i) - half) / slope) / 6.0;
for (; i < rate - slope; i++)
pulse_table[i] = 1.0 / 6.0;
for (; i < rate; i++)
pulse_table[i] = ((rate - i) * 1.0 / slope) / 6.0;
}
} *tables;
please don't use a class type declaration + variable declaration
in one statement. adding an extra line for
Tables *tables;
is much more readable.
static map<guint, Tables*> table_map;
this should have a comment on what the uint usually is (rate?).
/* properties (used to pass "global" noise data into the modules) */
struct Properties : public OrganProperties {
const Tables *tables;
extraneous newline. and why is this not m_tables?
Properties (Organ *organ) :
OrganProperties (organ),
tables (organ->tables)
{
}
};
/* actual computation */
class Module : public SynthesisModule {
public:
/* frequency */
double m_transpose_factor;
double m_fine_tune_factor;
double m_cfreq;
/* instrument flavour */
bool m_flute;
bool m_reed;
bool m_brass;
/* harmonics */
gdouble m_harm0;
gdouble m_harm1;
gdouble m_harm2;
gdouble m_harm3;
gdouble m_harm4;
gdouble m_harm5;
/* phase accumulators */
guint32 m_harm0_paccu;
guint32 m_harm1_paccu;
guint32 m_harm2_paccu;
guint32 m_harm3_paccu;
guint32 m_harm4_paccu;
guint32 m_harm5_paccu;
/* mix_freq() specific tables */
const Tables *m_tables;
void
config (Properties *properties)
{
m_tables = properties->tables;
m_cfreq = properties->base_freq;
m_transpose_factor = bse_transpose_factor (properties->transpose);
m_fine_tune_factor = bse_cent_factor (properties->fine_tune);
// percent -> factor conversions
m_harm0 = properties->harm0 / 100.0;
m_harm1 = properties->harm1 / 100.0;
m_harm2 = properties->harm2 / 100.0;
m_harm3 = properties->harm3 / 100.0;
m_harm4 = properties->harm4 / 100.0;
m_harm5 = properties->harm5 / 100.0;
m_flute = properties->flute;
m_reed = properties->reed;
m_brass = properties->brass;
}
void
reset()
{
guint32 rfactor = bse_main_args->allow_randomization ? 1 : 0;
guint32 mix_freq_256 = mix_freq() * 256;
/* to make all notes sound a bit different, randomize the initial phase of
* each harmonic (except if the user requested deterministic behaviour)
*/
m_harm0_paccu = rfactor * g_random_int_range (0, mix_freq_256);
m_harm1_paccu = rfactor * g_random_int_range (0, mix_freq_256);
m_harm2_paccu = rfactor * g_random_int_range (0, mix_freq_256);
m_harm3_paccu = rfactor * g_random_int_range (0, mix_freq_256);
m_harm4_paccu = rfactor * g_random_int_range (0, mix_freq_256);
m_harm5_paccu = rfactor * g_random_int_range (0, mix_freq_256);
}
static inline gfloat
table_pos (const gfloat *table,
guint freq_256,
guint mix_freq_256,
guint32 *paccu)
{
*paccu += freq_256;
while (*paccu >= mix_freq_256)
*paccu -= mix_freq_256;
return table[*paccu >> 8];
}
void
process (unsigned int n_values)
{
const gfloat *sine_table = &m_tables->sine_table[0];
const gfloat *flute_table = m_flute ? &m_tables->triangle_table[0] : sine_table;
const gfloat *reed_table = m_reed ? &m_tables->pulse_table[0] : sine_table;
const gfloat *ifreq = istream (ICHANNEL_FREQ_IN).values;
gfloat *ovalues = ostream (OCHANNEL_AUDIO_OUT).values;
extraneous newline, please remove.
guint freq_256, mix_freq_256;
guint freq_256_harm0, freq_256_harm1;
guint i;
if (istream (ICHANNEL_FREQ_IN).connected)
freq_256 = BSE_FREQ_FROM_VALUE (ifreq[0]) * m_transpose_factor * m_fine_tune_factor * 256 + 0.5;
else
freq_256 = m_cfreq * m_transpose_factor * m_fine_tune_factor * 256 + 0.5;
mix_freq_256 = mix_freq() * 256;
freq_256_harm0 = freq_256 / 2;
freq_256_harm1 = freq_256;
if (m_brass)
{
guint freq_256_harm2 = freq_256 * 2;
guint freq_256_harm3 = freq_256_harm2 * 2;
guint freq_256_harm4 = freq_256_harm3 * 2;
guint freq_256_harm5 = freq_256_harm4 * 2;
for (i = 0; i < n_values; i++)
{
gfloat vaccu;
vaccu = table_pos (sine_table, freq_256_harm0, mix_freq_256, &m_harm0_paccu) * m_harm0;
vaccu += table_pos (sine_table, freq_256_harm1, mix_freq_256, &m_harm1_paccu) * m_harm1;
vaccu += table_pos (reed_table, freq_256_harm2, mix_freq_256, &m_harm2_paccu) * m_harm2;
vaccu += table_pos (sine_table, freq_256_harm3, mix_freq_256, &m_harm3_paccu) * m_harm3;
vaccu += table_pos (flute_table, freq_256_harm4, mix_freq_256, &m_harm4_paccu) * m_harm4;
vaccu += table_pos (flute_table, freq_256_harm5, mix_freq_256, &m_harm5_paccu) * m_harm5;
ovalues[i] = vaccu;
}
}
else
{
guint freq_256_harm2 = freq_256 * 3 / 2;
guint freq_256_harm3 = freq_256 * 2;
guint freq_256_harm4 = freq_256 * 3;
guint freq_256_harm5 = freq_256_harm3 * 2;
for (i = 0; i < n_values; i++)
{
gfloat vaccu;
vaccu = table_pos (sine_table, freq_256_harm0, mix_freq_256, &m_harm0_paccu) * m_harm0;
vaccu += table_pos (sine_table, freq_256_harm1, mix_freq_256, &m_harm1_paccu) * m_harm1;
vaccu += table_pos (sine_table, freq_256_harm2, mix_freq_256, &m_harm2_paccu) * m_harm2;
vaccu += table_pos (reed_table, freq_256_harm3, mix_freq_256, &m_harm3_paccu) * m_harm3;
vaccu += table_pos (sine_table, freq_256_harm4, mix_freq_256, &m_harm4_paccu) * m_harm4;
vaccu += table_pos (flute_table, freq_256_harm5, mix_freq_256, &m_harm5_paccu) * m_harm5;
ovalues[i] = vaccu;
}
}
}
};
public:
void
prepare1()
{
guint irate = (guint) bse_engine_sample_freq();
this is an uneccessary cast. but also, the statement shouldn't be here
in the first place. C++ modules may not call bse_engine_sample_freq().
the best way i can currently think of to ref/unref sampling rate
specific tables is in the constructor and destructor of class Module,
using it's mix_freq() method. this constructor and destructor are
currently being executed in the BSE thread, but still, access of
the global table_mapis then better protected by a mutex.
if (table_map[irate])
table_map[irate]->ref_count++;
else
table_map[irate] = new Tables (irate);
tables = table_map[irate];
}
void
reset1()
{
guint irate = (guint) bse_engine_sample_freq();
if (--table_map[irate]->ref_count == 0)
{
delete table_map[irate];
table_map[irate] = 0;
}
}
for ref counting, this isn't the best coding style, as mentioned already,
there should be dedicated and clearly named _ref()/_unref() methods that
do this kind of stuff.
bool
property_changed (OrganPropertyID prop_id)
{
switch (prop_id)
{
/* implement special handling of GUI properties */
case PROP_BASE_FREQ:
base_note = bse_note_from_freq (base_freq);
notify ("base_note");
break;
case PROP_BASE_NOTE:
base_freq = bse_note_to_freq (base_note);
notify ("base_freq");
break;
default: ;
}
return false;
}
/* implement creation and config methods for synthesis Module */
BSE_EFFECT_INTEGRATE_MODULE (Organ, Module, Properties);
};
map<guint, Organ::Tables*> Organ::table_map;
this can actually be declared outside the class and then use
static linkage to reduce the exported symbols. that'll make particular
sense if refactored out of the class as a functional unit of:
- a table_map protecting mutex,
- the table_map with static linkage
- a table_map ref() function that returns a const Tables*
- a table_map unref() function
all accesses will simply go thorugh ref()/unref() then.
BSE_CXX_DEFINE_EXPORTS();
BSE_CXX_REGISTER_EFFECT (Organ);
} // Dav
} // Bse
except for the table_map which is definitely a tricky issue, this
looks like a pretty ok port. thanks for tackling it.
the diff (without davorgan.cc / davorgan.idl):
================================================================================
Index: sfi/ChangeLog
===================================================================
--- sfi/ChangeLog (revision 4015)
+++ sfi/ChangeLog (working copy)
@@ -1,3 +1,16 @@
+Mon Oct 23 15:22:37 2006 Stefan Westerfeld <stefan space twc de>
+
+ * sfidl-parser.cc: Don't use g_strdup_printf, but g_ascii_formatd for
+ formatting doubles (locale independancy). Some simplification could be
+ achieved by switching from char* to std::string for some code.
+ Switched double format from "%.17g" to "%.17e". This keeps doubles in
+ param specs like (50.0/100.0) in tact, because the C++ compiler will
+ still recognize that we have doubles here.
+ The old code would print (50/100), because "%g" omits decimal point
+ and trailing digits for those doubles that can be represented without,
+ so that the result of the division (when evaluated by the C++ compiler)
+ would be 0, instead of the expected 0.5.
+
Sat Oct 21 17:29:05 2006 Tim Janik <timj gtk org>
* sfitests.h, sfiwrapper.cc: adapt to init settings changes.
Index: sfi/sfidl-parser.cc
===================================================================
--- sfi/sfidl-parser.cc (revision 4015)
+++ sfi/sfidl-parser.cc (working copy)
@@ -37,6 +37,14 @@ Sfidl::string_from_int (long long int ll
return str;
}
+// we don't need that (yet) in the Sfidl namespace
+static std::string
+string_from_double (double value)
+{
+ char buffer[G_ASCII_DTOSTR_BUF_SIZE + 1] = "";
+ g_ascii_formatd (buffer, G_ASCII_DTOSTR_BUF_SIZE, "%.17e", value);
+ return buffer;
+}
there is a Birnet funciton named like this already, re-using that name
just makes the below code highly confusing (because it's hard to tell
at which place which funciton gets called).
either the above fix should go into the birnet variant, or the above
function should be renamed.
namespace {
using namespace Sfidl;
@@ -997,16 +1005,13 @@ GTokenType Parser::parseStringOrConst (s
if (ci->name == s &&
ci->type != Constant::tIdent) /* identifier constants can't be expanded to strings */
{
- char *x = 0;
switch (ci->type)
{
case Constant::tInt:
- s = x = g_strdup_printf ("%lldLL", ci->i);
- g_free (x);
+ s = string_from_int (ci->i) + "LL";
break;
case Constant::tFloat:
- s = x = g_strdup_printf ("%.17g", ci->f);
- g_free (x);
+ s = string_from_double (ci->f);
break;
case Constant::tString:
s = ci->str;
@@ -1522,13 +1527,13 @@ GTokenType Parser::parseParamHints (Para
while (!g_scanner_eof (scanner) && bracelevel > 0)
{
GTokenType t = scanner_get_next_token_with_colon_identifiers (scanner);
- gchar *token_as_string = 0, *x = 0;
+ string token_as_string;
bool current_arg_complete = false;
+ char *tmp = 0;
telling from the use below, declaring tmp without initialization
could help the compiler catch programming errors.
also, it should be moved into the innermost scope (that is a general rule
we apply), i.e. inside the switch {} or case {} braces.
if(int(t) > 0 && int(t) <= 255)
{
- token_as_string = g_new0 (char, 2); /* FIXME: leak */
- token_as_string[0] = char(t);
+ token_as_string = char(t);
we put spaces before parenthesis in function calls.
}
switch (t)
{
@@ -1540,13 +1545,13 @@ GTokenType Parser::parseParamHints (Para
break;
case ',': current_arg_complete = true;
break;
- case G_TOKEN_STRING: x = g_strescape (scanner->value.v_string, 0);
- token_as_string = g_strdup_printf ("\"%s\"", x);
- g_free (x);
+ case G_TOKEN_STRING: tmp = g_strescape (scanner->value.v_string, 0);
+ token_as_string = string ("\"") + tmp + "\"";
+ g_free (tmp);
break;
- case G_TOKEN_INT: token_as_string = g_strdup_printf ("%llu", scanner->value.v_int64);
+ case G_TOKEN_INT: token_as_string = string_from_int (scanner->value.v_int64);
break;
- case G_TOKEN_FLOAT: token_as_string = g_strdup_printf ("%.17g", scanner->value.v_float);
+ case G_TOKEN_FLOAT: token_as_string = string_from_double (scanner->value.v_float);
break;
case G_TOKEN_IDENTIFIER:
{
@@ -1562,23 +1567,23 @@ GTokenType Parser::parseParamHints (Para
}
if (ci == constants.end())
- token_as_string = g_strdup_printf ("%s", scanner->value.v_identifier);
+ token_as_string = scanner->value.v_identifier;
else switch (ci->type)
{
case Constant::tInt:
- token_as_string = g_strdup_printf ("%lldLL", ci->i);
+ token_as_string = string_from_int (ci->i) + "LL";
break;
case Constant::tFloat:
- token_as_string = g_strdup_printf ("%.17g", ci->f);
+ token_as_string = string_from_double (ci->f);
break;
case Constant::tIdent:
- token_as_string = g_strdup (ci->str.c_str());
+ token_as_string = ci->str;
break;
case Constant::tString:
- x = g_strescape (ci->str.c_str(), 0);
- token_as_string = g_strdup_printf ("\"%s\"", x);
- g_free (x);
- break;
+ tmp = g_strescape (ci->str.c_str(), 0);
+ token_as_string = string("\"") + tmp + "\"";
+ g_free (tmp);
+ break;
default:
g_assert_not_reached ();
break;
@@ -1586,7 +1591,7 @@ GTokenType Parser::parseParamHints (Para
}
break;
default:
- if (!token_as_string)
+ if (token_as_string.empty())
return GTokenType (')');
}
if (current_arg_complete)
@@ -1601,16 +1606,15 @@ GTokenType Parser::parseParamHints (Para
}
current_arg = "";
}
- else if (token_as_string)
+ else if (!token_as_string.empty())
{
current_arg += token_as_string;
}
- if (token_as_string && bracelevel)
+ if (!token_as_string.empty() && bracelevel)
{
if (args != "")
args += ' ';
args += token_as_string;
- g_free (token_as_string);
}
}
def.args = args;
Index: tests/audio/organsong.bse
===================================================================
--- tests/audio/organsong.bse (revision 4015)
+++ tests/audio/organsong.bse (working copy)
@@ -1,6 +1,6 @@
; BseProject
-(bse-version "0.7.1")
+(bse-version "0.7.0")
(container-child "BseWaveRepo::Wave-Repository"
(modification-time "2006-10-21 19:32:55")
this will break our report: checks. bse files in the tarball/svn are supposed to
always be uptodate. so you really can run the compat check only once before
comitting.
Index: bse/bsecompat.c
===================================================================
--- bse/bsecompat.c (revision 4015)
+++ bse/bsecompat.c (working copy)
@@ -38,6 +38,7 @@ bse_compat_rewrite_type_name (BseStorage
{ 0, 6, 2, "ArtsStereoCompressor", "BseArtsCompressor" },
{ 0, 6, 2, "DavBassFilter", "BseDavBassFilter" },
{ 0, 6, 2, "DavChorus", "BseDavChorus" },
+ { 0, 7, 0, "DavOrgan", "BseDavOrgan" },
};
guint i;
for (i = 0; i < G_N_ELEMENTS (type_changes); i++)
Index: bse/ChangeLog
===================================================================
--- bse/ChangeLog (revision 4015)
+++ bse/ChangeLog (working copy)
@@ -1,3 +1,9 @@
+Mon Oct 23 15:21:03 2006 Stefan Westerfeld <stefan space twc de>
+
+ * bsecompat.c: Added DavOrgan -> BseDavOrgan compatibility rewrite
+ typename rule for files <= 0.7.0, since the DavOrgan module is now
+ implemented in C++, and thus properly namespaced.
+
Sun Oct 22 00:22:27 2006 Tim Janik <timj gtk org>
* bsemain.c: let allow_randomization default to TRUE, added
Index: plugins/ChangeLog
===================================================================
--- plugins/ChangeLog (revision 4017)
+++ plugins/ChangeLog (working copy)
@@ -1,3 +1,13 @@
+Mon Oct 23 16:12:17 2006 Stefan Westerfeld <stefan space twc de>
+
+ * Makefile.am:
+ * Makefile.plugins: Switch from the C implementation of DavOrgan to
+ the C++ implementation of DavOrgan.
+
+ * davorgan.cc: Ported C code from DavOrgan to C++.
+
+ * davorgan.idl: Wrote a proper IDL file for the DavOrgan module.
+
Mon Oct 23 16:10:57 2006 Stefan Westerfeld <stefan space twc de>
* davorgan.idl:
Index: plugins/Makefile.plugins
===================================================================
--- plugins/Makefile.plugins (revision 4015)
+++ plugins/Makefile.plugins (working copy)
[...]
useless diff, this file is generated by an extra makefile rule.
Index: plugins/Makefile.am
===================================================================
--- plugins/Makefile.am (revision 4015)
+++ plugins/Makefile.am (working copy)
@@ -21,6 +21,7 @@ plugin_idl_files = $(strip \
bsesummation.idl \
davbassfilter.idl \
davchorus.idl \
+ davorgan.idl \
standardsaturator.idl \
standardguspatchenvelope.idl \
)
@@ -44,7 +45,6 @@ PLUGIN_CFILES = $(strip \
bsemult.[hc] \
bsesimpleadsr.[hc] \
bsesequencer.[hc] \
- davorgan.[hc] \
davxtalstrings.[hc] \
davsyndrum.[hc] \
davcanyondelay.[hc] \
Index: ChangeLog
===================================================================
--- ChangeLog (revision 4015)
+++ ChangeLog (working copy)
@@ -1,3 +1,10 @@
+Mon Oct 23 15:57:20 2006 Stefan Westerfeld <stefan space twc de>
+
+ * tests/audio/organsong.bse: Downgraded test file version from 0.7.1
+ to 0.7.0 to activate type rewriting compatibility for the file,
+ because 0.7.1 will has a C++ version of DavOrgan (which is called
+ BseDavOrgan).
+
we don't support that unfortunately.
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]