Path: blob/master/libs/fluidsynth/src/synth/fluid_voice.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*/192021#ifndef _FLUID_VOICE_H22#define _FLUID_VOICE_H2324#include "fluid_phase.h"25#include "fluid_gen.h"26#include "fluid_mod.h"27#include "fluid_iir_filter.h"28#include "fluid_adsr_env.h"29#include "fluid_lfo.h"30#include "fluid_rvoice.h"31#include "fluid_rvoice_event.h"3233#define NO_CHANNEL 0xff3435typedef struct _fluid_overflow_prio_t fluid_overflow_prio_t;3637struct _fluid_overflow_prio_t38{39float percussion; /**< Is this voice on the drum channel? Then add this score */40float released; /**< Is this voice in release stage? Then add this score (usually negative) */41float sustained; /**< Is this voice sustained? Then add this score (usually negative) */42float volume; /**< Multiply current (or future) volume (a value between 0 and 1) */43float age; /**< This score will be divided by the number of seconds the voice has lasted */44float important; /**< This score will be added to all important channels */45char *important_channels; /**< "important" flags indexed by MIDI channel number */46int num_important_channels; /**< Number of elements in the important_channels array */47};4849enum fluid_voice_status50{51FLUID_VOICE_CLEAN,52FLUID_VOICE_ON,53FLUID_VOICE_SUSTAINED, /* Sustained by Sustain pedal */54FLUID_VOICE_HELD_BY_SOSTENUTO, /* Sustained by Sostenuto pedal */55FLUID_VOICE_OFF56};575859/*60* fluid_voice_t61*/62struct _fluid_voice_t63{64unsigned int id; /* the id is incremented for every new noteon.65it's used for noteoff's */66unsigned char status;67unsigned char chan; /* the channel number, quick access for channel messages */68unsigned char key; /* the key of the noteon event, quick access for noteoff */69unsigned char vel; /* the velocity of the noteon event */70fluid_channel_t *channel;71fluid_rvoice_eventhandler_t *eventhandler;72fluid_zone_range_t *zone_range; /* instrument zone range*/73fluid_sample_t *sample; /* Pointer to sample (dupe in rvoice) */74fluid_sample_t *overflow_sample; /* Pointer to sample (dupe in overflow_rvoice) */7576unsigned int start_time;77int mod_count;78fluid_mod_t mod[FLUID_NUM_MOD];79fluid_gen_t gen[GEN_LAST];8081/* basic parameters */82fluid_real_t output_rate; /* the sample rate of the synthesizer (dupe in rvoice) */8384/* basic parameters */85fluid_real_t pitch; /* the pitch in midicents (dupe in rvoice) */86fluid_real_t attenuation; /* the attenuation in centibels (dupe in rvoice) */87fluid_real_t root_pitch;8889/* master gain (dupe in rvoice) */90fluid_real_t synth_gain;9192/* pan */93fluid_real_t pan;9495/* balance */96fluid_real_t balance;9798/* reverb */99fluid_real_t reverb_send;100101/* chorus */102fluid_real_t chorus_send;103104/* rvoice control */105fluid_rvoice_t *rvoice;106fluid_rvoice_t *overflow_rvoice; /* Used temporarily and only in overflow situations */107char can_access_rvoice; /* False if rvoice is being rendered in separate thread */108char can_access_overflow_rvoice; /* False if overflow_rvoice is being rendered in separate thread */109char has_noteoff; /* Flag set when noteoff has been sent */110111#ifdef WITH_PROFILING112/* for debugging */113double ref;114#endif115};116117118fluid_voice_t *new_fluid_voice(fluid_rvoice_eventhandler_t *handler, fluid_real_t output_rate);119void delete_fluid_voice(fluid_voice_t *voice);120121void fluid_voice_start(fluid_voice_t *voice);122void fluid_voice_calculate_gen_pitch(fluid_voice_t *voice);123124int fluid_voice_init(fluid_voice_t *voice, fluid_sample_t *sample,125fluid_zone_range_t *inst_zone_range,126fluid_channel_t *channel, int key, int vel,127unsigned int id, unsigned int time, fluid_real_t gain);128129int fluid_voice_modulate(fluid_voice_t *voice, int cc, int ctrl);130int fluid_voice_modulate_all(fluid_voice_t *voice);131132/** Set the NRPN value of a generator. */133int fluid_voice_set_param(fluid_voice_t *voice, int gen, fluid_real_t value);134135136/** Set the gain. */137int fluid_voice_set_gain(fluid_voice_t *voice, fluid_real_t gain);138139void fluid_voice_set_output_rate(fluid_voice_t *voice, fluid_real_t value);140141142/** Update all the synthesis parameters, which depend on generator143'gen'. This is only necessary after changing a generator of an144already operating voice. Most applications will not need this145function.*/146void fluid_voice_update_param(fluid_voice_t *voice, int gen);147148/** legato modes */149/* force in the attack section for legato mode multi_retrigger: 1 */150void fluid_voice_update_multi_retrigger_attack(fluid_voice_t *voice, int tokey, int vel);151/* Update portamento parameter */152void fluid_voice_update_portamento(fluid_voice_t *voice, int fromkey, int tokey);153154155void fluid_voice_release(fluid_voice_t *voice);156void fluid_voice_noteoff(fluid_voice_t *voice);157void fluid_voice_off(fluid_voice_t *voice);158void fluid_voice_stop(fluid_voice_t *voice);159void fluid_voice_add_mod_local(fluid_voice_t *voice, fluid_mod_t *mod, int mode, int check_limit_count);160void fluid_voice_overflow_rvoice_finished(fluid_voice_t *voice);161162int fluid_voice_kill_excl(fluid_voice_t *voice);163float fluid_voice_get_overflow_prio(fluid_voice_t *voice,164fluid_overflow_prio_t *score,165unsigned int cur_time);166167#define OVERFLOW_PRIO_CANNOT_KILL 999999.168169/**170* Locks the rvoice for rendering, so it can't be modified directly171*/172static FLUID_INLINE void173fluid_voice_lock_rvoice(fluid_voice_t *voice)174{175voice->can_access_rvoice = 0;176}177178/**179* Unlocks the rvoice for rendering, so it can be modified directly180*/181static FLUID_INLINE void182fluid_voice_unlock_rvoice(fluid_voice_t *voice)183{184voice->can_access_rvoice = 1;185}186187#define _AVAILABLE(voice) ((voice)->can_access_rvoice && \188(((voice)->status == FLUID_VOICE_CLEAN) || ((voice)->status == FLUID_VOICE_OFF)))189//#define _RELEASED(voice) ((voice)->chan == NO_CHANNEL)190#define _SAMPLEMODE(voice) ((int)(voice)->gen[GEN_SAMPLEMODE].val)191192193fluid_real_t fluid_voice_gen_value(const fluid_voice_t *voice, int num);194void fluid_voice_set_custom_filter(fluid_voice_t *voice, enum fluid_iir_filter_type type, enum fluid_iir_filter_flags flags);195196197#endif /* _FLUID_VOICE_H */198199200