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-2008 Christian Schoenebeck * |
* Copyright (C) 2005-2008 Christian Schoenebeck * |
7 |
* Copyright (C) 2009-2011 Christian Schoenebeck and Grigor Iliev * |
* Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev * |
8 |
* * |
* * |
9 |
* This program is free software; you can redistribute it and/or modify * |
* This program is free software; you can redistribute it and/or modify * |
10 |
* 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 * |
37 |
#include "../gig/SmoothVolume.h" |
#include "../gig/SmoothVolume.h" |
38 |
#include "../gig/Synthesizer.h" |
#include "../gig/Synthesizer.h" |
39 |
#include "../gig/Profiler.h" |
#include "../gig/Profiler.h" |
40 |
|
#include "SignalUnitRack.h" |
41 |
|
|
42 |
// include the appropriate (unsigned) triangle LFO implementation |
// include the appropriate (unsigned) triangle LFO implementation |
43 |
#if CONFIG_UNSIGNED_TRIANG_ALGO == INT_MATH_SOLUTION |
#if CONFIG_UNSIGNED_TRIANG_ALGO == INT_MATH_SOLUTION |
83 |
public: |
public: |
84 |
type_t Type; ///< Voice Type (bit field, a voice may have several types) |
type_t Type; ///< Voice Type (bit field, a voice may have several types) |
85 |
int MIDIKey; ///< MIDI key number of the key that triggered the voice |
int MIDIKey; ///< MIDI key number of the key that triggered the voice |
86 |
|
uint8_t MIDIVelocity; ///< MIDI velocity of the key that triggered the voice |
87 |
|
int MIDIPan; ///< the current MIDI pan value plus the value from RegionInfo |
88 |
|
|
89 |
|
SignalUnitRack* const pSignalUnitRack; |
90 |
|
|
91 |
AbstractVoice(); |
AbstractVoice(SignalUnitRack* pRack); |
92 |
virtual ~AbstractVoice(); |
virtual ~AbstractVoice(); |
93 |
|
|
94 |
inline bool IsActive() { return PlaybackState; } |
inline bool IsActive() { return PlaybackState; } |
104 |
int iKeyGroup |
int iKeyGroup |
105 |
); |
); |
106 |
|
|
107 |
|
/** Invoked when the voice is freed - gone from active to inactive. */ |
108 |
|
virtual void VoiceFreed() { } |
109 |
|
|
110 |
virtual void Synthesize(uint Samples, sample_t* pSrc, uint Skip); |
virtual void Synthesize(uint Samples, sample_t* pSrc, uint Skip); |
111 |
|
|
112 |
|
uint GetSampleRate() { return GetEngine()->SampleRate; } |
113 |
|
|
114 |
|
uint8_t GetControllerValue(uint8_t Controller) { |
115 |
|
return (Controller > 128) ? 0 : pEngineChannel->ControllerTable[Controller]; |
116 |
|
} |
117 |
|
|
118 |
void processCCEvents(RTList<Event>::Iterator& itEvent, uint End); |
void processCCEvents(RTList<Event>::Iterator& itEvent, uint End); |
119 |
void processPitchEvent(RTList<Event>::Iterator& itEvent); |
void processPitchEvent(RTList<Event>::Iterator& itEvent); |
122 |
void processGroupEvents(RTList<Event>::Iterator& itEvent, uint End); |
void processGroupEvents(RTList<Event>::Iterator& itEvent, uint End); |
123 |
void UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent); |
void UpdatePortamentoPos(Pool<Event>::Iterator& itNoteOffEvent); |
124 |
void Kill(Pool<Event>::Iterator& itKillEvent); |
void Kill(Pool<Event>::Iterator& itKillEvent); |
125 |
|
void CreateEq(); |
126 |
|
|
127 |
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. |
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. |
128 |
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 |
168 |
gig::SynthesisParam finalSynthesisParameters; |
gig::SynthesisParam finalSynthesisParameters; |
169 |
gig::Loop loop; |
gig::Loop loop; |
170 |
RTList<Event>* pGroupEvents; ///< Events directed to an exclusive group |
RTList<Event>* pGroupEvents; ///< Events directed to an exclusive group |
171 |
|
|
172 |
|
EqSupport* pEq; ///< Used for per voice equalization |
173 |
|
bool bEqSupport; |
174 |
|
|
175 |
|
void PrintEqInfo() { |
176 |
|
if (!bEqSupport || pEq == NULL) { |
177 |
|
dmsg(1,("EQ support: no\n")); |
178 |
|
} else { |
179 |
|
pEq->PrintInfo(); |
180 |
|
} |
181 |
|
} |
182 |
|
|
183 |
virtual AbstractEngine* GetEngine() = 0; |
virtual AbstractEngine* GetEngine() = 0; |
184 |
virtual SampleInfo GetSampleInfo() = 0; |
virtual SampleInfo GetSampleInfo() = 0; |
186 |
virtual InstrumentInfo GetInstrumentInfo() = 0; |
virtual InstrumentInfo GetInstrumentInfo() = 0; |
187 |
|
|
188 |
/** |
/** |
189 |
|
* Most of the important members of the voice are set when the voice |
190 |
|
* is triggered (like pEngineChannel, pRegion, pSample, etc). |
191 |
|
* This method is called after these members are set and before |
192 |
|
* the voice is actually triggered. |
193 |
|
* Override this method if you need to do some additional |
194 |
|
* initialization which depends on these members before the voice |
195 |
|
* is triggered. |
196 |
|
*/ |
197 |
|
virtual void AboutToTrigger() { } |
198 |
|
|
199 |
|
virtual bool EG1Finished(); |
200 |
|
|
201 |
|
/** |
202 |
* Gets the sample cache size in bytes. |
* Gets the sample cache size in bytes. |
203 |
*/ |
*/ |
204 |
virtual unsigned long GetSampleCacheSize() = 0; |
virtual unsigned long GetSampleCacheSize() = 0; |
205 |
|
|
206 |
|
/** |
207 |
|
* Because in most cases we cache part of the sample in RAM, if the |
208 |
|
* offset is too big (will extend beyond the RAM cache if the cache contains |
209 |
|
* the beginning of the sample) we should cache in the RAM buffer not the |
210 |
|
* beginning of the sample but a part that starts from the sample offset point. |
211 |
|
* In that case the current sample position should start from zero (Pos). |
212 |
|
* When the offset fits into RAM buffer or the whole sample is cached |
213 |
|
* in RAM, Pos should contain the actual offset. |
214 |
|
* We don't trim the sample because it might have a defined |
215 |
|
* loop start point before the start point of the playback. |
216 |
|
*/ |
217 |
|
virtual void SetSampleStartOffset(); |
218 |
|
|
219 |
/** |
/** |
220 |
* Returns the correct amplitude factor for the given \a MIDIKeyVelocity. |
* Returns the correct amplitude factor for the given \a MIDIKeyVelocity. |
300 |
|
|
301 |
virtual void ProcessGroupEvent(RTList<Event>::Iterator& itEvent) = 0; |
virtual void ProcessGroupEvent(RTList<Event>::Iterator& itEvent) = 0; |
302 |
void EnterReleaseStage(); |
void EnterReleaseStage(); |
303 |
|
|
304 |
|
virtual int CalculatePan(uint8_t pan) = 0; |
305 |
}; |
}; |
306 |
} // namespace LinuxSampler |
} // namespace LinuxSampler |
307 |
|
|