void Channel::setcc(int num, int value) { cc[num] = value; // printf("setcc %d %d\n", num, value); switch (num) { case SUSTAIN_SWITCH: if (value < 64) synth->damp_voices(channum); break; case BANK_SELECT_MSB: { bank_msb = value & 0x7f; setBanknum(bank_msb << 7); } break; case BANK_SELECT_LSB: /* FIXME: according to the Downloadable Sounds II specification, bit 31 should be set when we receive the message on channel 10 (drum channel) */ setBanknum((value & 0x7f) + (bank_msb << 7)); break; case ALL_NOTES_OFF: synth->allNotesOff(channum); break; case ALL_SOUND_OFF: synth->allSoundsOff(channum); break; case ALL_CTRL_OFF: initCtrl(); synth->modulate_voices_all(channum); break; case DATA_ENTRY_MSB: { int data = (value << 7) + cc[DATA_ENTRY_LSB]; /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ if ((cc[NRPN_MSB] == 120) && (cc[NRPN_LSB] < 100)) { float val = fluid_gen_scale_nrpn(nrpn_select, data); qDebug("%s: %d: Data = %d, value = %f", __FILE__, __LINE__, data, val); synth->set_gen(channum, nrpn_select, val); } break; } case NRPN_MSB: cc[NRPN_LSB] = 0; nrpn_select = 0; break; case NRPN_LSB: /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ if (cc[NRPN_MSB] == 120) { if (value == 100) nrpn_select += 100; else if (value == 101) nrpn_select += 1000; else if (value == 102) nrpn_select += 10000; else if (value < 100) { nrpn_select += value; qDebug("%s: %d: NRPN Select = %d", __FILE__, __LINE__, nrpn_select); } } break; case RPN_MSB: break; case RPN_LSB: /* erase any previously received NRPN message */ cc[NRPN_MSB] = 0; cc[NRPN_LSB] = 0; nrpn_select = 0; break; default: synth->modulate_voices(channum, true, num); } }
/* * fluid_channel_cc */ int fluid_channel_cc(fluid_channel_t* chan, int num, int value) { chan->cc[num] = value; switch (num) { case SUSTAIN_SWITCH: { if (value < 64) { /* printf("** sustain off\n"); */ fluid_synth_damp_voices(chan->synth, chan->channum); } else { /* printf("** sustain on\n"); */ } } break; case BANK_SELECT_MSB: { chan->bank_msb = (unsigned char) (value & 0x7f); /* printf("** bank select msb recieved: %d\n", value); */ /* I fixed the handling of a MIDI bank select controller 0, e.g., bank select MSB (or "coarse" bank select according to my spec). Prior to this fix a channel's bank number was only changed upon reception of MIDI bank select controller 32, e.g, bank select LSB (or "fine" bank-select according to my spec). [KLE] FIXME: is this correct? [PH] */ fluid_channel_set_banknum(chan, (unsigned int)(value & 0x7f)); /* KLE */ } break; case BANK_SELECT_LSB: { /* FIXME: according to the Downloadable Sounds II specification, bit 31 should be set when we receive the message on channel 10 (drum channel) */ fluid_channel_set_banknum(chan, (((unsigned int) value & 0x7f) + ((unsigned int) chan->bank_msb << 7))); } break; case ALL_NOTES_OFF: fluid_synth_all_notes_off(chan->synth, chan->channum); break; case ALL_SOUND_OFF: fluid_synth_all_sounds_off(chan->synth, chan->channum); break; case ALL_CTRL_OFF: fluid_channel_init_ctrl(chan); fluid_synth_modulate_voices_all(chan->synth, chan->channum); break; case DATA_ENTRY_MSB: { int data = (value << 7) + chan->cc[DATA_ENTRY_LSB]; if (chan->nrpn_active) /* NRPN is active? */ { /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ if ((chan->cc[NRPN_MSB] == 120) && (chan->cc[NRPN_LSB] < 100)) { if (chan->nrpn_select < GEN_LAST) { float val = fluid_gen_scale_nrpn(chan->nrpn_select, data); fluid_synth_set_gen(chan->synth, chan->channum, chan->nrpn_select, val); } chan->nrpn_select = 0; /* Reset to 0 */ } } else if (chan->cc[RPN_MSB] == 0) /* RPN is active: MSB = 0? */ { switch (chan->cc[RPN_LSB]) { case RPN_PITCH_BEND_RANGE: fluid_channel_pitch_wheel_sens (chan, value); /* Set bend range in semitones */ /* FIXME - Handle LSB? (Fine bend range in cents) */ break; case RPN_CHANNEL_FINE_TUNE: /* Fine tune is 14 bit over +/-1 semitone (+/- 100 cents, 8192 = center) */ fluid_synth_set_gen(chan->synth, chan->channum, GEN_FINETUNE, (data - 8192) / 8192.0 * 100.0); break; case RPN_CHANNEL_COARSE_TUNE: /* Coarse tune is 7 bit and in semitones (64 is center) */ fluid_synth_set_gen(chan->synth, chan->channum, GEN_COARSETUNE, value - 64); break; case RPN_TUNING_PROGRAM_CHANGE: break; case RPN_TUNING_BANK_SELECT: break; case RPN_MODULATION_DEPTH_RANGE: break; } } break; } case NRPN_MSB: chan->cc[NRPN_LSB] = 0; chan->nrpn_select = 0; chan->nrpn_active = 1; break; case NRPN_LSB: /* SontFont 2.01 NRPN Message (Sect. 9.6, p. 74) */ if (chan->cc[NRPN_MSB] == 120) { if (value == 100) { chan->nrpn_select += 100; } else if (value == 101) { chan->nrpn_select += 1000; } else if (value == 102) { chan->nrpn_select += 10000; } else if (value < 100) { chan->nrpn_select += value; } } chan->nrpn_active = 1; break; case RPN_MSB: case RPN_LSB: chan->nrpn_active = 0; break; default: fluid_synth_modulate_voices(chan->synth, chan->channum, 1, num); } return FLUID_OK; }