Re: DavOrgan C++ port - please review



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]