Path: blob/master/libs/fluidsynth/src/synth/fluid_chan.h
4396 views
/* FluidSynth - A Software Synthesizer1*2* Copyright (C) 2003 Peter Hanappe and others.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public License6* as published by the Free Software Foundation; either version 2.1 of7* the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful, but10* WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public15* License along with this library; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA17* 02110-1301, USA18*/1920#ifndef _FLUID_CHAN_H21#define _FLUID_CHAN_H2223#include "fluidsynth_priv.h"24#include "fluid_midi.h"25#include "fluid_tuning.h"26#include "fluid_gen.h"2728/* The mononophonic list is part of the legato detector for monophonic mode */29/* see fluid_synth_monopoly.c about a description of the legato detector device */30/* Size of the monophonic list31- 1 is the minimum. it allows playing legato passage of any number32of notes on noteon only.33- Size above 1 allows playing legato on noteon but also on noteOff.34This allows the musician to play fast trills.35This feature is particularly usful when the MIDI input device is a keyboard.36Choosing a size of 10 is sufficient (because most musicians have only 1037fingers when playing a monophonic instrument).38*/39#define FLUID_CHANNEL_SIZE_MONOLIST 104041/*4243The monophonic list44+------------------------------------------------+45| +----+ +----+ +----+ +----+ |46| |note| |note| |note| |note| |47+--->|vel |-->|vel |-->....-->|vel |-->|vel |----+48+----+ +----+ +----+ +----+49/|\ /|\50| |51i_first i_last5253The monophonic list is a circular buffer of FLUID_CHANNEL_SIZE_MONOLIST elements.54Each element is linked forward at initialisation time.55- when a note is added at noteOn (see fluid_channel_add_monolist()) each56element is use in the forward direction and indexed by i_last variable.57- when a note is removed at noteOff (see fluid_channel_remove_monolist()),58the element concerned is fast unlinked and relinked after the i_last element.5960The most recent note added is indexed by i_last.61The most ancient note added is the first note indexed by i_first. i_first is62moving in the forward direction in a circular manner.6364*/65struct mononote66{67unsigned char next; /* next note */68unsigned char note; /* note */69unsigned char vel; /* velocity */70};7172/*73* fluid_channel_t74*75* Mutual exclusion notes (as of 1.1.2):76* None - everything should have been synchronized by the synth.77*/78struct _fluid_channel_t79{80fluid_synth_t *synth; /**< Parent synthesizer instance */81int channum; /**< MIDI channel number */8283/* Poly Mono variables see macro access description */84int mode; /**< Poly Mono mode */85int mode_val; /**< number of channel in basic channel group */8687/* monophonic list - legato detector */88unsigned char i_first; /**< First note index */89unsigned char i_last; /**< most recent note index since the most recent add */90unsigned char prev_note; /**< previous note of the most recent add/remove */91unsigned char n_notes; /**< actual number of notes in the list */92struct mononote monolist[FLUID_CHANNEL_SIZE_MONOLIST]; /**< monophonic list */9394unsigned char key_mono_sustained; /**< previous sustained monophonic note */95unsigned char previous_cc_breath; /**< Previous Breath */96enum fluid_channel_legato_mode legatomode; /**< legato mode */97enum fluid_channel_portamento_mode portamentomode; /**< portamento mode */98/*- End of Poly/mono variables description */99100unsigned char cc[128]; /**< MIDI controller values from [0;127] */101unsigned char key_pressure[128]; /**< MIDI polyphonic key pressure from [0;127] */102103/* Drum channel flag, CHANNEL_TYPE_MELODIC, or CHANNEL_TYPE_DRUM. */104enum fluid_midi_channel_type channel_type;105enum fluid_interp interp_method; /**< Interpolation method (enum fluid_interp) */106107unsigned char channel_pressure; /**< MIDI channel pressure from [0;127] */108float pitch_wheel_sensitivity; /**< Current pitch wheel sensitivity */109short pitch_bend; /**< Current pitch bend value */110/* Sostenuto order id gives the order of SostenutoOn event.111* This value is useful to known when the sostenuto pedal is depressed112* (before or after a key note). We need to compare SostenutoOrderId with voice id.113*/114unsigned int sostenuto_orderid;115116int tuning_bank; /**< Current tuning bank number */117int tuning_prog; /**< Current tuning program number */118fluid_tuning_t *tuning; /**< Micro tuning */119120fluid_preset_t *preset; /**< Selected preset */121int sfont_bank_prog; /**< SoundFont ID (bit 21-31), bank (bit 7-20), program (bit 0-6) */122123/* NRPN system */124enum fluid_gen_type nrpn_select; /* Generator ID of SoundFont NRPN message */125char nrpn_active; /* 1 if data entry CCs are for NRPN, 0 if RPN */126127char awe32_filter_coeff;128129/* The values of the generators, set by NRPN messages, or by130* fluid_synth_set_gen(), are cached in the channel so they can be131* applied to future notes. They are copied to a voice's generators132* in fluid_voice_init(), which calls fluid_gen_init(). */133fluid_real_t gen[GEN_LAST];134135/* Same for AWE32 NRPNs, however they override the gen's default values */136struct137{138enum fluid_gen_flags flags;139fluid_real_t val;140} override_gen_default[GEN_LAST];141};142143fluid_channel_t *new_fluid_channel(fluid_synth_t *synth, int num);144void fluid_channel_init_ctrl(fluid_channel_t *chan, int is_all_ctrl_off);145void delete_fluid_channel(fluid_channel_t *chan);146void fluid_channel_reset(fluid_channel_t *chan);147int fluid_channel_set_preset(fluid_channel_t *chan, fluid_preset_t *preset);148void fluid_channel_set_sfont_bank_prog(fluid_channel_t *chan, int sfont,149int bank, int prog);150void fluid_channel_set_bank_lsb(fluid_channel_t *chan, int banklsb);151void fluid_channel_set_bank_msb(fluid_channel_t *chan, int bankmsb);152void fluid_channel_get_sfont_bank_prog(fluid_channel_t *chan, int *sfont,153int *bank, int *prog);154fluid_real_t fluid_channel_get_key_pitch(fluid_channel_t *chan, int key);155156#define fluid_channel_get_preset(chan) ((chan)->preset)157#define fluid_channel_set_cc(chan, num, val) \158((chan)->cc[num] = (val))159#define fluid_channel_get_cc(chan, num) \160((chan)->cc[num])161#define fluid_channel_get_key_pressure(chan, key) \162((chan)->key_pressure[key])163#define fluid_channel_set_key_pressure(chan, key, val) \164((chan)->key_pressure[key] = (val))165#define fluid_channel_get_channel_pressure(chan) \166((chan)->channel_pressure)167#define fluid_channel_set_channel_pressure(chan, val) \168((chan)->channel_pressure = (val))169#define fluid_channel_get_pitch_bend(chan) \170((chan)->pitch_bend)171#define fluid_channel_set_pitch_bend(chan, val) \172((chan)->pitch_bend = (val))173#define fluid_channel_get_pitch_wheel_sensitivity(chan) \174((chan)->pitch_wheel_sensitivity)175#define fluid_channel_set_pitch_wheel_sensitivity(chan, val) \176((chan)->pitch_wheel_sensitivity = (val))177#define fluid_channel_get_num(chan) ((chan)->channum)178#define fluid_channel_set_interp_method(chan, new_method) \179((chan)->interp_method = (new_method))180#define fluid_channel_get_interp_method(chan) \181((chan)->interp_method);182#define fluid_channel_set_tuning(_c, _t) { (_c)->tuning = _t; }183#define fluid_channel_has_tuning(_c) ((_c)->tuning != NULL)184#define fluid_channel_get_tuning(_c) ((_c)->tuning)185#define fluid_channel_get_tuning_bank(chan) \186((chan)->tuning_bank)187#define fluid_channel_set_tuning_bank(chan, bank) \188((chan)->tuning_bank = (bank))189#define fluid_channel_get_tuning_prog(chan) \190((chan)->tuning_prog)191#define fluid_channel_set_tuning_prog(chan, prog) \192((chan)->tuning_prog = (prog))193#define fluid_channel_portamentotime(_c) \194((_c)->cc[PORTAMENTO_TIME_MSB] * 128 + (_c)->cc[PORTAMENTO_TIME_LSB])195#define fluid_channel_portamento(_c) ((_c)->cc[PORTAMENTO_SWITCH] >= 64)196#define fluid_channel_breath_msb(_c) ((_c)->cc[BREATH_MSB] > 0)197#define fluid_channel_clear_portamento(_c) ((_c)->cc[PORTAMENTO_CTRL] = INVALID_NOTE)198#define fluid_channel_legato(_c) ((_c)->cc[LEGATO_SWITCH] >= 64)199#define fluid_channel_sustained(_c) ((_c)->cc[SUSTAIN_SWITCH] >= 64)200#define fluid_channel_sostenuto(_c) ((_c)->cc[SOSTENUTO_SWITCH] >= 64)201#define fluid_channel_set_gen(_c, _n, _v) { (_c)->gen[_n] = _v; }202#define fluid_channel_get_gen(_c, _n) ((_c)->gen[_n])203#define fluid_channel_get_min_note_length_ticks(chan) \204((chan)->synth->min_note_length_ticks)205206/* Macros interface to poly/mono mode variables */207#define MASK_BASICCHANINFOS (FLUID_CHANNEL_MODE_MASK|FLUID_CHANNEL_BASIC|FLUID_CHANNEL_ENABLED)208/* Set the basic channel infos for a MIDI basic channel */209#define fluid_channel_set_basic_channel_info(chan,Infos) \210(chan->mode = (chan->mode & ~MASK_BASICCHANINFOS) | (Infos & MASK_BASICCHANINFOS))211/* Reset the basic channel infos for a MIDI basic channel */212#define fluid_channel_reset_basic_channel_info(chan) (chan->mode &= ~MASK_BASICCHANINFOS)213214/* Macros interface to breath variables */215#define FLUID_CHANNEL_BREATH_MASK (FLUID_CHANNEL_BREATH_POLY|FLUID_CHANNEL_BREATH_MONO|FLUID_CHANNEL_BREATH_SYNC)216/* Set the breath infos for a MIDI channel */217#define fluid_channel_set_breath_info(chan,BreathInfos) \218(chan->mode = (chan->mode & ~FLUID_CHANNEL_BREATH_MASK) | (BreathInfos & FLUID_CHANNEL_BREATH_MASK))219/* Get the breath infos for a MIDI channel */220#define fluid_channel_get_breath_info(chan) (chan->mode & FLUID_CHANNEL_BREATH_MASK)221222/* Returns true when channel is mono or legato is on */223#define fluid_channel_is_playing_mono(chan) ((chan->mode & FLUID_CHANNEL_POLY_OFF) ||\224fluid_channel_legato(chan))225226/* Macros interface to monophonic list variables */227#define INVALID_NOTE (255)228/* Returns true when a note is a valid note */229#define fluid_channel_is_valid_note(n) (n != INVALID_NOTE)230/* Marks prev_note as invalid. */231#define fluid_channel_clear_prev_note(chan) (chan->prev_note = INVALID_NOTE)232233/* Returns the most recent note from i_last entry of the monophonic list */234#define fluid_channel_last_note(chan) (chan->monolist[chan->i_last].note)235236/* Returns the most recent velocity from i_last entry of the monophonic list */237#define fluid_channel_last_vel(chan) (chan->monolist[chan->i_last].vel)238239/*240prev_note is used to determine fromkey_portamento as well as241fromkey_legato (see fluid_synth_get_fromkey_portamento_legato()).242243prev_note is updated on noteOn/noteOff mono by the legato detector as this:244- On noteOn mono, before adding a new note into the monolist,the most245recent note in the list (i.e at i_last position) is kept in prev_note.246- Similarly, on noteOff mono , before removing a note out of the monolist,247the most recent note (i.e those at i_last position) is kept in prev_note.248*/249#define fluid_channel_prev_note(chan) (chan->prev_note)250251/* Interface to poly/mono mode variables */252enum fluid_channel_mode_flags_internal253{254FLUID_CHANNEL_BASIC = 0x04, /**< if flag set the corresponding midi channel is a basic channel */255FLUID_CHANNEL_ENABLED = 0x08, /**< if flag set the corresponding midi channel is enabled, else disabled, i.e. channel ignores any MIDI messages */256257/*258FLUID_CHANNEL_LEGATO_PLAYING bit of channel mode keeps trace of the legato /staccato259state playing.260FLUID_CHANNEL_LEGATO_PLAYING bit is updated on noteOn/noteOff mono by the legato detector:261- On noteOn, before inserting a new note into the monolist.262- On noteOff, after removing a note out of the monolist.263264- On noteOn, this state is used by fluid_synth_noteon_mono_LOCAL()265to play the current note legato or staccato.266- On noteOff, this state is used by fluid_synth_noteoff_mono_LOCAL()267to play the current noteOff legato with the most recent note.268*/269/* bit7, 1: means legato playing , 0: means staccato playing */270FLUID_CHANNEL_LEGATO_PLAYING = 0x80271};272273/* End of interface to monophonic list variables */274275void fluid_channel_add_monolist(fluid_channel_t *chan, unsigned char key, unsigned char vel, unsigned char onenote);276int fluid_channel_search_monolist(fluid_channel_t *chan, unsigned char key, int *i_prev);277void fluid_channel_remove_monolist(fluid_channel_t *chan, int i, int *i_prev);278void fluid_channel_clear_monolist(fluid_channel_t *chan);279void fluid_channel_set_onenote_monolist(fluid_channel_t *chan, unsigned char key, unsigned char vel);280void fluid_channel_invalid_prev_note_staccato(fluid_channel_t *chan);281void fluid_channel_cc_legato(fluid_channel_t *chan, int value);282void fluid_channel_cc_breath_note_on_off(fluid_channel_t *chan, int value);283284int fluid_channel_get_override_gen_default(fluid_channel_t *chan, int gen, fluid_real_t *val);285void fluid_channel_set_override_gen_default(fluid_channel_t *chan, int gen, fluid_real_t val);286287#endif /* _FLUID_CHAN_H */288289290