/[svn]/linuxsampler/trunk/src/voice.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/voice.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 25 by schoenebeck, Sun Dec 7 05:03:43 2003 UTC revision 26 by schoenebeck, Fri Dec 26 16:39:58 2003 UTC
# Line 23  Line 23 
23  #ifndef __VOICE_H__  #ifndef __VOICE_H__
24  #define __VOICE_H__  #define __VOICE_H__
25    
   
26  #include "global.h"  #include "global.h"
27  #include "diskthread.h"  #include "diskthread.h"
28  #include "ringbuffer.h"  #include "ringbuffer.h"
# Line 57  class Voice { Line 56  class Voice {
56          };          };
57    
58          // Attributes          // Attributes
59          float                Volume;          float                Volume;            ///< Volume level of the voice
60          float*               pOutput;           ///< Audio output buffer          float*               pOutput;           ///< Audio output buffer
61          uint                 OutputBufferSize;  ///< Fragment size of the audio output buffer          uint                 OutputBufferSize;  ///< Fragment size of the audio output buffer
62          double               Pos;          double               Pos;               ///< Current playback position in sample
63          double               CurrentPitch;          double               CurrentPitch;      ///< Current pitch depth (number of sample points to move on with each render step)
64          gig::Sample*         pSample;          gig::Sample*         pSample;           ///< Pointer to the sample to be played back
65          gig::Region*         pRegion;          gig::Region*         pRegion;           ///< Pointer to the articulation information of the respective keyboard region of this voice
66          bool                 Active;          bool                 Active;            ///< If this voice object is currently in usage
67          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
68          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
69          Stream::reference_t  DiskStreamRef;          Stream::reference_t  DiskStreamRef;     ///< Reference / link to the disk stream
70          unsigned long        MaxRAMPos;         ///< The upper allowed limit (not actually the end) in the RAM sample cache, after that point it's not safe to chase the interpolator another time over over the current cache position, instead we switch to disk then.          unsigned long        MaxRAMPos;         ///< The upper allowed limit (not actually the end) in the RAM sample cache, after that point it's not safe to chase the interpolator another time over over the current cache position, instead we switch to disk then.
71            bool                 RAMLoop;           ///< If this voice has a loop defined which completely fits into the cached RAM part of the sample, in this case we handle the looping within the voice class, else if the loop is located in the disk stream part, we let the disk stream handle the looping
72            int                  LoopCyclesLeft;    ///< In case there is a RAMLoop and it's not an endless loop; reflects number of loop cycles left to be passed
73    
74          // Static Attributes          // Static Attributes
75          static DiskThread*   pDiskThread;          static DiskThread*   pDiskThread;       ///< Pointer to the disk thread, to be able to order a disk stream and later to delete the stream again
76    
77          // Methods          // Methods
78          void       Interpolate(sample_t* pSrc);          void        Interpolate(sample_t* pSrc);
79            void        InterpolateAndLoop(sample_t* pSrc);
80            inline void InterpolateOneStep_Stereo(sample_t* pSrc, int& i, float& effective_volume) {
81                int   pos_int   = double_to_int(this->Pos);  // integer position
82                float pos_fract = this->Pos - pos_int;       // fractional part of position
83                pos_int <<= 1;
84    
85                #if USE_LINEAR_INTERPOLATION
86                    // left channel
87                    this->pOutput[i++] += effective_volume * (pSrc[pos_int]   + pos_fract * (pSrc[pos_int+2] - pSrc[pos_int]));
88                    // right channel
89                    this->pOutput[i++] += effective_volume * (pSrc[pos_int+1] + pos_fract * (pSrc[pos_int+3] - pSrc[pos_int+1]));
90                #else // polynomial interpolation
91                    // calculate left channel
92                    float xm1 = pSrc[pos_int];
93                    float x0  = pSrc[pos_int+2];
94                    float x1  = pSrc[pos_int+4];
95                    float x2  = pSrc[pos_int+6];
96                    float a   = (3 * (x0 - x1) - xm1 + x2) / 2;
97                    float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
98                    float c   = (x1 - xm1) / 2;
99                    this->pOutput[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
100    
101                    //calculate right channel
102                    xm1 = pSrc[pos_int+1];
103                    x0  = pSrc[pos_int+3];
104                    x1  = pSrc[pos_int+5];
105                    x2  = pSrc[pos_int+7];
106                    a   = (3 * (x0 - x1) - xm1 + x2) / 2;
107                    b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
108                    c   = (x1 - xm1) / 2;
109                    this->pOutput[i++] += effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
110                #endif // USE_LINEAR_INTERPOLATION
111    
112                this->Pos += this->CurrentPitch;
113            }
114            inline void InterpolateOneStep_Mono(sample_t* pSrc, int& i, float& effective_volume) {
115                int   pos_int   = double_to_int(this->Pos);  // integer position
116                float pos_fract = this->Pos - pos_int;       // fractional part of position
117    
118                #if USE_LINEAR_INTERPOLATION
119                    float sample_point  = effective_volume * (pSrc[pos_int] + pos_fract * (pSrc[pos_int+1] - pSrc[pos_int]));
120                #else // polynomial interpolation
121                    float xm1 = pSrc[pos_int];
122                    float x0  = pSrc[pos_int+1];
123                    float x1  = pSrc[pos_int+2];
124                    float x2  = pSrc[pos_int+3];
125                    float a   = (3 * (x0 - x1) - xm1 + x2) / 2;
126                    float b   = 2 * x1 + xm1 - (5 * x0 + x2) / 2;
127                    float c   = (x1 - xm1) / 2;
128                    float sample_point = effective_volume * ((((a * pos_fract) + b) * pos_fract + c) * pos_fract + x0);
129                #endif // USE_LINEAR_INTERPOLATION
130    
131                this->pOutput[i++] += sample_point;
132                this->pOutput[i++] += sample_point;
133    
134                this->Pos += this->CurrentPitch;
135            }
136          inline int double_to_int(double f) {          inline int double_to_int(double f) {
137              #if ARCH_X86              #if ARCH_X86
138              int i;              int i;

Legend:
Removed from v.25  
changed lines
  Added in v.26

  ViewVC Help
Powered by ViewVC