Skip to content

Commit 6e9d84f

Browse files
jjceresaderselbst
authored andcommitted
Forbid DATA_ENTRY_LSB to modulate (#465)
and document illegal CC modulation
1 parent f52e4fd commit 6e9d84f

File tree

1 file changed

+61
-18
lines changed

1 file changed

+61
-18
lines changed

src/synth/fluid_synth.c

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ fluid_synth_damp_voices_by_sostenuto_LOCAL(fluid_synth_t *synth, int chan)
13181318
* @param mod Modulator info (values copied, passed in object can be freed immediately afterwards)
13191319
* @param mode Determines how to handle an existing identical modulator (#fluid_synth_add_mod)
13201320
* @return #FLUID_OK on success, #FLUID_FAILED otherwise
1321-
*
1321+
*
13221322
* @note Not realtime safe (due to internal memory allocation) and therefore should not be called
13231323
* from synthesis context at the risk of stalling audio output.
13241324
*/
@@ -1388,7 +1388,7 @@ fluid_synth_add_default_mod(fluid_synth_t *synth, const fluid_mod_t *mod, int mo
13881388
* @param synth synth instance
13891389
* @param mod The modulator to remove
13901390
* @return #FLUID_OK if a matching modulator was found and successfully removed, #FLUID_FAILED otherwise
1391-
*
1391+
*
13921392
* @note Not realtime safe (due to internal memory allocation) and therefore should not be called
13931393
* from synthesis context at the risk of stalling audio output.
13941394
*/
@@ -1513,7 +1513,37 @@ fluid_synth_cc(fluid_synth_t *synth, int chan, int num, int val)
15131513
FLUID_API_RETURN(result);
15141514
}
15151515

1516-
/* Local synthesis thread variant of MIDI CC set function. */
1516+
/* Local synthesis thread variant of MIDI CC set function.
1517+
Most of CC are allowed to modulate but not all. A comment describes if CC num
1518+
isn't allowed to modulate.
1519+
Following explanations should help to understand both MIDI specifications and
1520+
Soundfont specifications in regard to MIDI specs.
1521+
1522+
MIDI specs:
1523+
CC LSB (32 to 63) are LSB contributions to CC MSB (0 to 31).
1524+
It's up to the synthesizer to decide to take LSB values into account or not.
1525+
Actually Fluidsynth doesn't use CC LSB value inside fluid_voice_update_param()
1526+
(once fluid_voice_modulate() has been triggered). This is because actually
1527+
fluidsynth needs only 7 bits resolution (and not 14 bits) from these CCs.
1528+
So fluidsynth is using only 7 bit MSB (except for portamento time).
1529+
In regard to MIDI specs Fluidsynth behaves correctly.
1530+
1531+
Soundfont specs 2.01 - 8.2.1:
1532+
To deal correctly with MIDI CC (regardless if any synth will use CC MSB alone (7 bit)
1533+
or both CCs MSB,LSB (14 bits) during synthesis), SF specs recommend not making use of
1534+
CC LSB (i.e only CC MSB) in modulator sources to trigger modulation (i.e modulators
1535+
with CC LSB connected to sources inputs should be ignored).
1536+
These specifics are particularly suited for synths that use 14 bits CCs. In this case,
1537+
the MIDI transmitter sends CC LSB first followed by CC MSB. The MIDI synth receives
1538+
both CC LSB and CC MSB but only CC MSB will trigger the modulation.
1539+
This will produce correct synthesis parameters update from a correct 14 bits CC.
1540+
If in SF specs, modulator sources with CC LSB had been accepted, both CC LSB and
1541+
CC MSB will triggers 2 modulations. This leads to incorrect synthesis parameters
1542+
update followed by correct synthesis parameters update.
1543+
1544+
However, as long as fluidsynth will use only CC 7 bits resolution, it is safe to ignore
1545+
these SF recommendations on CC receive.
1546+
*/
15171547
static int
15181548
fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
15191549
{
@@ -1525,8 +1555,11 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
15251555

15261556
switch(num)
15271557
{
1558+
case LOCAL_CONTROL: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
1559+
break;
15281560

15291561
/* CC omnioff, omnion, mono, poly */
1562+
/* not allowed to modulate (spec SF 2.01 - 8.2.1) */
15301563
case POLY_OFF:
15311564
case POLY_ON:
15321565
case OMNI_OFF:
@@ -1581,18 +1614,18 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
15811614

15821615
return FLUID_FAILED;
15831616

1584-
case LEGATO_SWITCH:
1617+
case LEGATO_SWITCH: /* not allowed to modulate */
15851618
/* handles Poly/mono commutation on Legato pedal On/Off.*/
15861619
fluid_channel_cc_legato(chan, value);
15871620
break;
15881621

1589-
case PORTAMENTO_SWITCH:
1622+
case PORTAMENTO_SWITCH: /* not allowed to modulate */
15901623
/* Special handling of the monophonic list */
15911624
/* Invalids the most recent note played in a staccato manner */
15921625
fluid_channel_invalid_prev_note_staccato(chan);
15931626
break;
15941627

1595-
case SUSTAIN_SWITCH:
1628+
case SUSTAIN_SWITCH: /* not allowed to modulate */
15961629

15971630
/* Release voices if Sustain switch is released */
15981631
if(value < 64) /* Sustain is released */
@@ -1602,7 +1635,7 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
16021635

16031636
break;
16041637

1605-
case SOSTENUTO_SWITCH:
1638+
case SOSTENUTO_SWITCH: /* not allowed to modulate */
16061639

16071640
/* Release voices if Sostetuno switch is released */
16081641
if(value < 64) /* Sostenuto is released */
@@ -1617,28 +1650,31 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
16171650

16181651
break;
16191652

1620-
case BANK_SELECT_MSB:
1653+
case BANK_SELECT_MSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
16211654
fluid_channel_set_bank_msb(chan, value & 0x7F);
16221655
break;
16231656

1624-
case BANK_SELECT_LSB:
1657+
case BANK_SELECT_LSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
16251658
fluid_channel_set_bank_lsb(chan, value & 0x7F);
16261659
break;
16271660

1628-
case ALL_NOTES_OFF:
1661+
case ALL_NOTES_OFF: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
16291662
fluid_synth_all_notes_off_LOCAL(synth, channum);
16301663
break;
16311664

1632-
case ALL_SOUND_OFF:
1665+
case ALL_SOUND_OFF: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
16331666
fluid_synth_all_sounds_off_LOCAL(synth, channum);
16341667
break;
16351668

1636-
case ALL_CTRL_OFF:
1669+
case ALL_CTRL_OFF: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
16371670
fluid_channel_init_ctrl(chan, 1);
16381671
fluid_synth_modulate_voices_all_LOCAL(synth, channum);
16391672
break;
16401673

1641-
case DATA_ENTRY_MSB:
1674+
case DATA_ENTRY_LSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
1675+
break;
1676+
1677+
case DATA_ENTRY_MSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
16421678
{
16431679
int data = (value << 7) + fluid_channel_get_cc(chan, DATA_ENTRY_LSB);
16441680

@@ -1698,13 +1734,13 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
16981734
break;
16991735
}
17001736

1701-
case NRPN_MSB:
1737+
case NRPN_MSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
17021738
fluid_channel_set_cc(chan, NRPN_LSB, 0);
17031739
chan->nrpn_select = 0;
17041740
chan->nrpn_active = 1;
17051741
break;
17061742

1707-
case NRPN_LSB:
1743+
case NRPN_LSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
17081744

17091745
/* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */
17101746
if(fluid_channel_get_cc(chan, NRPN_MSB) == 120)
@@ -1730,8 +1766,8 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
17301766
chan->nrpn_active = 1;
17311767
break;
17321768

1733-
case RPN_MSB:
1734-
case RPN_LSB:
1769+
case RPN_MSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
1770+
case RPN_LSB: /* not allowed to modulate (spec SF 2.01 - 8.2.1) */
17351771
chan->nrpn_active = 0;
17361772
break;
17371773

@@ -1741,7 +1777,14 @@ fluid_synth_cc_LOCAL(fluid_synth_t *synth, int channum, int num)
17411777

17421778
/* fall-through */
17431779
default:
1744-
return fluid_synth_modulate_voices_LOCAL(synth, channum, 1, num);
1780+
/* CC lsb shouldn't allowed to modulate (spec SF 2.01 - 8.2.1) */
1781+
/* However, as long fluidsynth will use only CC 7 bits resolution, it
1782+
is safe to ignore these SF recommendations on CC receive. See
1783+
explanations above */
1784+
/* if (! (32 <= num && num <= 63)) */
1785+
{
1786+
return fluid_synth_modulate_voices_LOCAL(synth, channum, 1, num);
1787+
}
17451788
}
17461789

17471790
return FLUID_OK;

0 commit comments

Comments
 (0)