On 2011-01-29 21:01, jimmy wrote:
--- On Fri, 1/28/11, David Henningsson<di...@ubuntu.com>  wrote:

On 2011-01-28 23:07, jimmy wrote:

Here's the revised patch file for the new channel
field "is_drum_channel".

Thanks, but you're missing the patch :-)

// David


Oops, here it is.

Thanks. I've fixed a few bugs in your patch - see the attached diff.

But there was one thing keeping me from committing the fixed version:

+
+  /* if style == XG and bankmsb == 127, convert the channel to drum mode.
+   * How should "newval" above be calculated (same as MMA style) ??? */
+  if (style == FLUID_BANK_STYLE_XG && (127 == bankmsb))
+  {
+      chan->is_drum_channel = CHANNEL_TYPE_DRUM;
+  }
+

...this doesn't feel right. First, it seems you can alter your channel type via MIDI to be a drum channel, but there is no way to alter it back to melodic (?).

Second, how should we calculate the new banknum in XG mode? Given your comment, you don't seem to be certain yourself.

Could you start off with my fixed version of your patch, fix this as well, and send a new diff back? Thanks!

// David
diff --git a/fluidsynth/include/fluidsynth/synth.h b/fluidsynth/include/fluidsynth/synth.h
index 0e7dec7..94b06d2 100644
--- a/fluidsynth/include/fluidsynth/synth.h
+++ b/fluidsynth/include/fluidsynth/synth.h
@@ -100,6 +100,15 @@ FLUIDSYNTH_API int fluid_synth_program_reset(fluid_synth_t* synth);
 FLUIDSYNTH_API int fluid_synth_system_reset(fluid_synth_t* synth);
 
 
+enum fluid_midi_channel_type
+{
+  CHANNEL_TYPE_MELODIC = 0,
+  CHANNEL_TYPE_DRUM = 1
+};
+
+int fluid_synth_set_channel_type(fluid_synth_t* synth, int chan, int type);
+
+
 /* Low level access */
 FLUIDSYNTH_API fluid_preset_t* fluid_synth_get_channel_preset(fluid_synth_t* synth, int chan);
 FLUIDSYNTH_API int fluid_synth_start(fluid_synth_t* synth, unsigned int id, 
diff --git a/fluidsynth/src/synth/fluid_chan.c b/fluidsynth/src/synth/fluid_chan.c
index 50850e7..235a16a 100644
--- a/fluidsynth/src/synth/fluid_chan.c
+++ b/fluidsynth/src/synth/fluid_chan.c
@@ -67,8 +67,9 @@ fluid_channel_init(fluid_channel_t* chan)
   fluid_preset_t *newpreset;
   int prognum, banknum;
 
+  chan->channel_type = (chan->channum == 9) ? CHANNEL_TYPE_DRUM : CHANNEL_TYPE_MELODIC;
   prognum = 0;
-  banknum = (chan->channum == 9)? 128 : 0; /* ?? */
+  banknum = (chan->channel_type == CHANNEL_TYPE_DRUM) ? DRUM_INST_BANK : 0;
 
   chan->sfont_bank_prog = 0 << SFONT_SHIFTVAL | banknum << BANK_SHIFTVAL
     | prognum << PROG_SHIFTVAL;
@@ -231,9 +232,9 @@ fluid_channel_set_bank_lsb(fluid_channel_t* chan, int banklsb)
   int oldval, newval, style;
 
   style = chan->synth->bank_select;
-  if (style == FLUID_BANK_STYLE_GM ||
-      style == FLUID_BANK_STYLE_GS ||
-      chan->channum == 9) //TODO: ask for channel drum mode, instead of number
+  if (FLUID_BANK_STYLE_GM == style ||
+      FLUID_BANK_STYLE_GS == style ||
+      chan->channel_type == CHANNEL_TYPE_DRUM)
       return; /* ignored */
 
   oldval = chan->sfont_bank_prog;
@@ -251,11 +252,10 @@ fluid_channel_set_bank_msb(fluid_channel_t* chan, int bankmsb)
   int oldval, newval, style;
 
   style = chan->synth->bank_select;
-  if (style == FLUID_BANK_STYLE_GM ||
-      style == FLUID_BANK_STYLE_XG ||
-      chan->channum == 9) //TODO: ask for channel drum mode, instead of number
+  if (FLUID_BANK_STYLE_GM == style ||
+      FLUID_BANK_STYLE_XG == style ||
+      chan->channel_type == CHANNEL_TYPE_DRUM)
       return; /* ignored */
-  //TODO: if style == XG and bankmsb == 127, convert the channel to drum mode
 
   oldval = chan->sfont_bank_prog;
   if (style == FLUID_BANK_STYLE_GS)
@@ -263,6 +263,7 @@ fluid_channel_set_bank_msb(fluid_channel_t* chan, int bankmsb)
   else /* style == FLUID_BANK_STYLE_MMA */
       newval = (oldval & ~BANKMSB_MASKVAL) | (bankmsb << (BANK_SHIFTVAL + 7));
   chan->sfont_bank_prog = newval;
+
 }
 
 /* Get SoundFont ID, MIDI bank and/or program.  Use NULL to ignore a value. */
diff --git a/fluidsynth/src/synth/fluid_chan.h b/fluidsynth/src/synth/fluid_chan.h
index 879dc6f..38caf8f 100644
--- a/fluidsynth/src/synth/fluid_chan.h
+++ b/fluidsynth/src/synth/fluid_chan.h
@@ -74,6 +74,10 @@ struct _fluid_channel_t
    * flag indicating whether the NRPN value is absolute or not.
    */
   char gen_abs[GEN_LAST];
+
+  /* Drum channel flag, CHANNEL_TYPE_MELODIC, or CHANNEL_TYPE_DRUM. */
+  int channel_type;
+
 };
 
 fluid_channel_t* new_fluid_channel(fluid_synth_t* synth, int num);
diff --git a/fluidsynth/src/synth/fluid_synth.c b/fluidsynth/src/synth/fluid_synth.c
index d583154..b134704 100644
--- a/fluidsynth/src/synth/fluid_synth.c
+++ b/fluidsynth/src/synth/fluid_synth.c
@@ -1876,13 +1876,13 @@ fluid_synth_program_change(fluid_synth_t* synth, int chan, int prognum)
   /* Special handling of channel 10 (or 9 counting from 0). channel
    * 10 is the percussion channel.
    *
-   * FIXME - Shouldn't hard code bank selection for channel 10.  I think this
+   * FIXME - I think this
    * is a hack for MIDI files that do bank changes in GM mode.  Proper way to
    * handle this would probably be to ignore bank changes when in GM mode. - JG
    */
   if (prognum != FLUID_UNSET_PROGRAM)
   {
-    if (channel->channum == 9)
+    if (channel->channel_type == CHANNEL_TYPE_DRUM)
       preset = fluid_synth_find_preset(synth, DRUM_INST_BANK, prognum);
     else preset = fluid_synth_find_preset(synth, banknum, prognum);
 
@@ -1893,7 +1893,7 @@ fluid_synth_program_change(fluid_synth_t* synth, int chan, int prognum)
       subst_prog = prognum;
 
       /* Melodic instrument? */
-      if (channel->channum != 9 && banknum != DRUM_INST_BANK)
+      if ((channel->channel_type != CHANNEL_TYPE_DRUM) && (DRUM_INST_BANK != banknum))
       {
         subst_bank = 0;
 
@@ -4990,3 +4990,23 @@ void fluid_synth_api_exit(fluid_synth_t* synth)
   }
   
 }
+
+
+/**
+ * Set midi channel type 
+ * @param synth FluidSynth instance
+ * @param chan MIDI channel number (0 to MIDI channel count - 1)
+ * @param type CHANNEL_TYPE_MELODIC, or CHANNEL_TYPE_DRUM
+ * @return FLUID_OK on success, FLUID_FAILED otherwise
+ * @since 1.1.3
+ */
+int fluid_synth_set_channel_type(fluid_synth_t* synth, int chan, int type)
+{
+  fluid_return_val_if_fail ((type >= CHANNEL_TYPE_MELODIC) && (type <= CHANNEL_TYPE_DRUM), FLUID_FAILED);
+  FLUID_API_ENTRY_CHAN(FLUID_FAILED);
+  
+  synth->channel[chan]->channel_type = type;
+
+  FLUID_API_RETURN(FLUID_OK);
+}
+
diff --git a/fluidsynth/src/synth/fluid_voice.c b/fluidsynth/src/synth/fluid_voice.c
index f6e773c..7d7e49c 100644
--- a/fluidsynth/src/synth/fluid_voice.c
+++ b/fluidsynth/src/synth/fluid_voice.c
@@ -1493,7 +1493,7 @@ fluid_voice_get_overflow_prio(fluid_voice_t* voice,
    * Then it is very important.
    * Also skip the released and sustained scores.
    */
-  if (voice->chan == 9){
+  if (voice->channel->channel_type == CHANNEL_TYPE_DRUM){
     this_voice_prio += score->percussion;
   } 
   else if (voice->has_noteoff) {
_______________________________________________
fluid-dev mailing list
fluid-dev@nongnu.org
http://lists.nongnu.org/mailman/listinfo/fluid-dev

Reply via email to