31 |
|
|
32 |
#include "../../common/RTMath.h" |
#include "../../common/RTMath.h" |
33 |
#include "../../common/RingBuffer.h" |
#include "../../common/RingBuffer.h" |
34 |
#include "../../common/RTELMemoryPool.h" |
#include "../../common/Pool.h" |
35 |
#include "../../drivers/audio/AudioOutputDevice.h" |
#include "../../drivers/audio/AudioOutputDevice.h" |
36 |
#include "../../lib/fileloader/libgig/gig.h" |
#include "../../lib/fileloader/libgig/gig.h" |
37 |
#include "../common/BiquadFilter.h" |
#include "../common/BiquadFilter.h" |
92 |
int MIDIKey; ///< MIDI key number of the key that triggered the voice |
int MIDIKey; ///< MIDI key number of the key that triggered the voice |
93 |
uint KeyGroup; |
uint KeyGroup; |
94 |
DiskThread* pDiskThread; ///< Pointer to the disk thread, to be able to order a disk stream and later to delete the stream again |
DiskThread* pDiskThread; ///< Pointer to the disk thread, to be able to order a disk stream and later to delete the stream again |
95 |
|
RTList<Voice>::Iterator itChildVoice; ///< Points to the next layer voice (if any). This field is currently only used by the voice stealing algorithm. |
96 |
|
|
97 |
// Methods |
// Methods |
98 |
Voice(); |
Voice(); |
99 |
~Voice(); |
~Voice(); |
100 |
void Kill(Event* pKillEvent); |
void Kill(Pool<Event>::Iterator& itKillEvent); |
|
void KillImmediately(); |
|
101 |
void Render(uint Samples); |
void Render(uint Samples); |
102 |
void Reset(); |
void Reset(); |
103 |
void SetOutput(AudioOutputDevice* pAudioOutputDevice); |
void SetOutput(AudioOutputDevice* pAudioOutputDevice); |
104 |
void SetEngine(Engine* pEngine); |
void SetEngine(Engine* pEngine); |
105 |
int Trigger(Event* pNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer = 0, bool ReleaseTriggerVoice = false); |
int Trigger(Pool<Event>::Iterator& itNoteOnEvent, int PitchBend, ::gig::Instrument* pInstrument, int iLayer = 0, bool ReleaseTriggerVoice = false); |
106 |
inline bool IsActive() { return Active; } |
inline bool IsActive() { return PlaybackState; } |
107 |
private: |
private: |
108 |
// Types |
// Types |
109 |
enum playback_state_t { |
enum playback_state_t { |
110 |
playback_state_ram, |
playback_state_end = 0, |
111 |
playback_state_disk, |
playback_state_ram = 1, |
112 |
playback_state_end |
playback_state_disk = 2 |
113 |
}; |
}; |
114 |
|
|
115 |
// Attributes |
// Attributes |
124 |
::gig::Sample* pSample; ///< Pointer to the sample to be played back |
::gig::Sample* pSample; ///< Pointer to the sample to be played back |
125 |
::gig::Region* pRegion; ///< Pointer to the articulation information of the respective keyboard region of this voice |
::gig::Region* pRegion; ///< Pointer to the articulation information of the respective keyboard region of this voice |
126 |
::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 |
|
bool Active; ///< If this voice object is currently in usage |
|
127 |
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 |
128 |
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 |
129 |
Stream::reference_t DiskStreamRef; ///< Reference / link to the disk stream |
Stream::reference_t DiskStreamRef; ///< Reference / link to the disk stream |
147 |
LFO<gig::VCAManipulator>* pLFO1; ///< Low Frequency Oscillator 1 (Amplification) |
LFO<gig::VCAManipulator>* pLFO1; ///< Low Frequency Oscillator 1 (Amplification) |
148 |
LFO<gig::VCFCManipulator>* pLFO2; ///< Low Frequency Oscillator 2 (Filter cutoff frequency) |
LFO<gig::VCFCManipulator>* pLFO2; ///< Low Frequency Oscillator 2 (Filter cutoff frequency) |
149 |
LFO<gig::VCOManipulator>* pLFO3; ///< Low Frequency Oscillator 3 (Pitch) |
LFO<gig::VCOManipulator>* pLFO3; ///< Low Frequency Oscillator 3 (Pitch) |
150 |
Event* pTriggerEvent; ///< First event on the key's list the voice should process (only needed for the first audio fragment in which voice was triggered, after that it will be set to NULL). |
Pool<Event>::Iterator itTriggerEvent; ///< First event on the key's list the voice should process (only needed for the first audio fragment in which voice was triggered, after that it will be set to NULL). |
151 |
Event* pKillEvent; ///< Event which caused this voice to be killed |
Pool<Event>::Iterator itKillEvent; ///< Event which caused this voice to be killed |
152 |
|
|
153 |
// Static Methods |
// Static Methods |
154 |
static float CalculateFilterCutoffCoeff(); |
static float CalculateFilterCutoffCoeff(); |
155 |
static int CalculateFilterUpdateMask(); |
static int CalculateFilterUpdateMask(); |
156 |
|
|
157 |
// Methods |
// Methods |
158 |
|
void KillImmediately(); |
159 |
void ProcessEvents(uint Samples); |
void ProcessEvents(uint Samples); |
160 |
#if ENABLE_FILTER |
#if ENABLE_FILTER |
161 |
void CalculateBiquadParameters(uint Samples); |
void CalculateBiquadParameters(uint Samples); |