3 |
* LinuxSampler - modular, streaming capable sampler * |
* LinuxSampler - modular, streaming capable sampler * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * |
6 |
* Copyright (C) 2005 Christian Schoenebeck * |
* Copyright (C) 2005 - 2007 Christian Schoenebeck * |
7 |
* * |
* * |
8 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
9 |
* it under the terms of the GNU General Public License as published by * |
* it under the terms of the GNU General Public License as published by * |
29 |
#include <gig.h> |
#include <gig.h> |
30 |
|
|
31 |
#include "../../common/RTMath.h" |
#include "../../common/RTMath.h" |
|
#include "../../common/RingBuffer.h" |
|
32 |
#include "../../common/Pool.h" |
#include "../../common/Pool.h" |
33 |
#include "../../drivers/audio/AudioOutputDevice.h" |
#include "../../drivers/audio/AudioOutputDevice.h" |
|
#include "../common/BiquadFilter.h" |
|
34 |
#include "Engine.h" |
#include "Engine.h" |
35 |
#include "EngineChannel.h" |
#include "EngineChannel.h" |
36 |
#include "Stream.h" |
#include "Stream.h" |
40 |
#include "Filter.h" |
#include "Filter.h" |
41 |
#include "../common/LFOBase.h" |
#include "../common/LFOBase.h" |
42 |
#include "SynthesisParam.h" |
#include "SynthesisParam.h" |
43 |
|
#include "SmoothVolume.h" |
44 |
|
|
45 |
// include the appropriate (unsigned) triangle LFO implementation |
// include the appropriate (unsigned) triangle LFO implementation |
46 |
#if CONFIG_UNSIGNED_TRIANG_ALGO == INT_MATH_SOLUTION |
#if CONFIG_UNSIGNED_TRIANG_ALGO == INT_MATH_SOLUTION |
103 |
type_release_trigger_required, ///< If the key of this voice will be released, it causes a release triggered voice to be spawned |
type_release_trigger_required, ///< If the key of this voice will be released, it causes a release triggered voice to be spawned |
104 |
type_release_trigger ///< Release triggered voice which cannot be killed by releasing its key |
type_release_trigger ///< Release triggered voice which cannot be killed by releasing its key |
105 |
}; |
}; |
106 |
|
|
107 |
// Attributes |
// Attributes |
108 |
type_t Type; ///< Voice Type |
type_t Type; ///< Voice Type |
109 |
int MIDIKey; ///< MIDI key number of the key that triggered the voice |
int MIDIKey; ///< MIDI key number of the key that triggered the voice |
121 |
int Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup); |
int Trigger(EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::DimensionRegion* pDimRgn, type_t VoiceType, int iKeyGroup); |
122 |
inline bool IsActive() { return PlaybackState; } |
inline bool IsActive() { return PlaybackState; } |
123 |
inline bool IsStealable() { return !itKillEvent && PlaybackState >= playback_state_ram; } |
inline bool IsStealable() { return !itKillEvent && PlaybackState >= playback_state_ram; } |
124 |
|
void UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent); |
125 |
|
|
126 |
//private: |
//private: |
127 |
// Types |
// Types |
128 |
enum playback_state_t { |
enum playback_state_t { |
135 |
// Attributes |
// Attributes |
136 |
EngineChannel* pEngineChannel; |
EngineChannel* pEngineChannel; |
137 |
Engine* pEngine; ///< Pointer to the sampler engine, to be able to access the event lists. |
Engine* pEngine; ///< Pointer to the sampler engine, to be able to access the event lists. |
138 |
float Volume; ///< Volume level of the voice |
float VolumeLeft; ///< Left channel volume. This factor is calculated when the voice is triggered and doesn't change after that. |
139 |
float PanLeft; |
float VolumeRight; ///< Right channel volume. This factor is calculated when the voice is triggered and doesn't change after that. |
140 |
float PanRight; |
SmoothVolume CrossfadeSmoother; ///< Crossfade volume, updated by crossfade CC events |
141 |
float CrossfadeVolume; ///< Current attenuation level caused by a crossfade (only if a crossfade is defined of course) |
SmoothVolume VolumeSmoother; ///< Volume, updated by CC 7 (volume) events |
142 |
|
SmoothVolume PanLeftSmoother; ///< Left channel volume, updated by CC 10 (pan) events |
143 |
|
SmoothVolume PanRightSmoother; ///< Right channel volume, updated by CC 10 (pan) events |
144 |
double Pos; ///< Current playback position in sample |
double Pos; ///< Current playback position in sample |
145 |
float PitchBase; ///< Basic pitch depth, stays the same for the whole life time of the voice |
float PitchBase; ///< Basic pitch depth, stays the same for the whole life time of the voice |
146 |
float PitchBend; ///< Current pitch value of the pitchbend wheel |
float PitchBend; ///< Current pitch value of the pitchbend wheel |
147 |
float CutoffBase; ///< Cutoff frequency before control change, EG and LFO are applied |
float CutoffBase; ///< Cutoff frequency before control change, EG and LFO are applied |
148 |
::gig::Sample* pSample; ///< Pointer to the sample to be played back |
::gig::Sample* pSample; ///< Pointer to the sample to be played back |
149 |
::gig::DimensionRegion* pDimRgn; ///< Pointer to the articulation information of current dimension region of this voice |
::gig::DimensionRegion* pDimRgn; ///< Pointer to the articulation information of current dimension region of this voice |
150 |
|
bool Orphan; ///< true if this voice is playing a sample from an instrument that is unloaded. When the voice dies, the sample (and dimension region) will be handed back to the instrument resource manager. |
151 |
playback_state_t PlaybackState; ///< When a sample will be triggered, it will be first played from RAM cache and after a couple of sample points it will switch to disk streaming and at the end of a disk stream we have to add null samples, so the interpolator can do it's work correctly |
playback_state_t PlaybackState; ///< When a sample will be triggered, it will be first played from RAM cache and after a couple of sample points it will switch to disk streaming and at the end of a disk stream we have to add null samples, so the interpolator can do it's work correctly |
152 |
bool DiskVoice; ///< If the sample is very short it completely fits into the RAM cache and doesn't need to be streamed from disk, in that case this flag is set to false |
bool DiskVoice; ///< If the sample is very short it completely fits into the RAM cache and doesn't need to be streamed from disk, in that case this flag is set to false |
153 |
Stream::reference_t DiskStreamRef; ///< Reference / link to the disk stream |
Stream::reference_t DiskStreamRef; ///< Reference / link to the disk stream |
161 |
EGDecay EG3; ///< Envelope Generator 3 (Pitch) |
EGDecay EG3; ///< Envelope Generator 3 (Pitch) |
162 |
midi_ctrl VCFCutoffCtrl; |
midi_ctrl VCFCutoffCtrl; |
163 |
midi_ctrl VCFResonanceCtrl; |
midi_ctrl VCFResonanceCtrl; |
|
static const float FILTER_CUTOFF_COEFF; |
|
164 |
LFOUnsigned* pLFO1; ///< Low Frequency Oscillator 1 (Amplification) |
LFOUnsigned* pLFO1; ///< Low Frequency Oscillator 1 (Amplification) |
165 |
LFOUnsigned* pLFO2; ///< Low Frequency Oscillator 2 (Filter cutoff frequency) |
LFOUnsigned* pLFO2; ///< Low Frequency Oscillator 2 (Filter cutoff frequency) |
166 |
LFOSigned* pLFO3; ///< Low Frequency Oscillator 3 (Pitch) |
LFOSigned* pLFO3; ///< Low Frequency Oscillator 3 (Pitch) |
172 |
Pool<Event>::Iterator itKillEvent; ///< Event which caused this voice to be killed |
Pool<Event>::Iterator itKillEvent; ///< Event which caused this voice to be killed |
173 |
//private: |
//private: |
174 |
int SynthesisMode; |
int SynthesisMode; |
|
float fFinalVolume; |
|
175 |
float fFinalCutoff; |
float fFinalCutoff; |
176 |
float fFinalResonance; |
float fFinalResonance; |
177 |
SynthesisParam finalSynthesisParameters; |
SynthesisParam finalSynthesisParameters; |
181 |
static float CalculateFilterCutoffCoeff(); |
static float CalculateFilterCutoffCoeff(); |
182 |
|
|
183 |
// Methods |
// Methods |
184 |
void KillImmediately(); |
Stream::Handle KillImmediately(bool bRequestNotification = false); |
185 |
void ProcessEvents(uint Samples); |
void ProcessEvents(uint Samples); |
186 |
void Synthesize(uint Samples, sample_t* pSrc, uint Skip); |
void Synthesize(uint Samples, sample_t* pSrc, uint Skip); |
187 |
void processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End); |
void processTransitionEvents(RTList<Event>::Iterator& itEvent, uint End); |
191 |
void processCutoffEvent(RTList<Event>::Iterator& itEvent); |
void processCutoffEvent(RTList<Event>::Iterator& itEvent); |
192 |
void processResonanceEvent(RTList<Event>::Iterator& itEvent); |
void processResonanceEvent(RTList<Event>::Iterator& itEvent); |
193 |
|
|
194 |
inline float CrossfadeAttenuation(uint8_t& CrossfadeControllerValue) { |
inline uint8_t CrossfadeAttenuation(uint8_t& CrossfadeControllerValue) { |
195 |
float att = (!pDimRgn->Crossfade.out_end) ? CrossfadeControllerValue / 127.0f /* 0,0,0,0 means no crossfade defined */ |
uint8_t c = std::max(CrossfadeControllerValue, pDimRgn->AttenuationControllerThreshold); |
196 |
: (CrossfadeControllerValue < pDimRgn->Crossfade.in_end) ? |
c = (!pDimRgn->Crossfade.out_end) ? c /* 0,0,0,0 means no crossfade defined */ |
197 |
((CrossfadeControllerValue <= pDimRgn->Crossfade.in_start) ? 0.0f |
: (c < pDimRgn->Crossfade.in_end) ? |
198 |
: float(CrossfadeControllerValue - pDimRgn->Crossfade.in_start) / float(pDimRgn->Crossfade.in_end - pDimRgn->Crossfade.in_start)) |
((c <= pDimRgn->Crossfade.in_start) ? 0 |
199 |
: (CrossfadeControllerValue <= pDimRgn->Crossfade.out_start) ? 1.0f |
: 127 * (c - pDimRgn->Crossfade.in_start) / (pDimRgn->Crossfade.in_end - pDimRgn->Crossfade.in_start)) |
200 |
: (CrossfadeControllerValue < pDimRgn->Crossfade.out_end) ? float(pDimRgn->Crossfade.out_end - CrossfadeControllerValue) / float(pDimRgn->Crossfade.out_end - pDimRgn->Crossfade.out_start) |
: (c <= pDimRgn->Crossfade.out_start) ? 127 |
201 |
: 0.0f; |
: (c < pDimRgn->Crossfade.out_end) ? 127 * (pDimRgn->Crossfade.out_end - c) / (pDimRgn->Crossfade.out_end - pDimRgn->Crossfade.out_start) |
202 |
return pDimRgn->InvertAttenuationController ? 1 - att : att; |
: 0; |
203 |
|
return pDimRgn->InvertAttenuationController ? 127 - c : c; |
204 |
} |
} |
205 |
|
|
206 |
inline float Constrain(float ValueToCheck, float Min, float Max) { |
inline float Constrain(float ValueToCheck, float Min, float Max) { |