2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file loader library * |
* libgig - C++ cross-platform Gigasampler format file loader library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003 by Christian Schoenebeck * |
* Copyright (C) 2003, 2004 by Christian Schoenebeck * |
6 |
* <cuse@users.sourceforge.net> * |
* <cuse@users.sourceforge.net> * |
7 |
* * |
* * |
8 |
* This library is free software; you can redistribute it and/or modify * |
* This library 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 * |
63 |
#define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03) |
#define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03) |
64 |
#define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03) |
#define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03) |
65 |
#define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03) |
#define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03) |
66 |
//TODO: the transformation functions are not very accurate compared to the original ones |
#define GIG_VELOCITY_TRANSFORM_NONLINEAR(x,dynamic,scale) (-0.1666235937e0+0.5143775427e-4*x*x+0.5318278732e-1*dynamic*dynamic-0.3560390502e-4*scale*scale+0.4683631221e-2*x-0.9484386143e-1*dynamic+0.8030068910e-2*scale) |
67 |
#define GIG_VELOCITY_TRANSFORM_NONLINEAR(x,dynamic,scale) ((1.0-1.0/pow(x,1.0/(129.0-x))) * (1.0+scale/20.0) + (5.0-dynamic)*pow(x/300.0* (1.0+2.0*scale/128.0),2)) |
#define GIG_VELOCITY_TRANSFORM_LINEAR(x,dynamic,scale) (((1.0+scale*3.0/128.0)/110.0)*x+dynamic/5.0+dynamic*scale) |
68 |
#define GIG_VELOCITY_TRANSFORM_LINEAR(x,dynamic,scale) ((1.0+scale*3.0/128.0)/110.0*x+(5.0-dynamic)/5.0+(5.0-dynamic)*scale) |
#define GIG_VELOCITY_TRANSFORM_SPECIAL(x,dynamic,scale) (-0.1630504921e0+0.5794551347e-4*x*x+0.8361491099e-2*dynamic*dynamic-0.4303475615e-5*scale*scale+0.2085522765e-2*x+0.1313747345e-1*dynamic+0.3220916836e-2*scale) |
|
#define GIG_VELOCITY_TRANSFORM_SPECIAL(x,dynamic,scale) ((1.0+9.0*scale/129.0)*(1.0-1.0/pow(x,1.0/(129.0-x))+pow(3.0*x/pow(129,2),2)+pow((5.0-dynamic)*x/500.0,2))) |
|
69 |
|
|
70 |
/** Gigasampler specific classes and definitions */ |
/** Gigasampler specific classes and definitions */ |
71 |
namespace gig { |
namespace gig { |
167 |
vcf_res_ctrl_genpurpose6 = 3 ///< General Purpose Controller 6 (Button, MIDI Controller 81) |
vcf_res_ctrl_genpurpose6 = 3 ///< General Purpose Controller 6 (Button, MIDI Controller 81) |
168 |
} vcf_res_ctrl_t; |
} vcf_res_ctrl_t; |
169 |
|
|
170 |
/** Defines how attenuation (=gain / VCA) is controlled by. */ |
/** |
171 |
typedef enum { |
* Defines a controller that has a certain contrained influence on a |
172 |
attenuation_ctrl_none = 0x00, |
* particular synthesis parameter (used to define attenuation controller, |
173 |
attenuation_ctrl_modwheel = 0x03, ///< Modulation Wheel (MIDI Controller 1) |
* EG1 controller and EG2 controller). |
174 |
attenuation_ctrl_breath = 0x05, ///< Breath Controller (Coarse, MIDI Controller 2) |
* |
175 |
attenuation_ctrl_foot = 0x07, ///< Foot Pedal (Coarse, MIDI Controller 4) |
* You should use the respective <i>typedef</i> (means either |
176 |
attenuation_ctrl_effect1 = 0x0d, ///< Effect Controller 1 (Coarse, MIDI Controller 12) |
* attenuation_ctrl_t, eg1_ctrl_t or eg2_ctrl_t) in your code! |
177 |
attenuation_ctrl_effect2 = 0x0f, ///< Effect Controller 2 (Coarse, MIDI Controller 13) |
*/ |
178 |
attenuation_ctrl_genpurpose1 = 0x11, ///< General Purpose Controller 1 (Slider, MIDI Controller 16) |
struct leverage_ctrl_t { |
179 |
attenuation_ctrl_genpurpose2 = 0x13, ///< General Purpose Controller 2 (Slider, MIDI Controller 17) |
typedef enum { |
180 |
attenuation_ctrl_genpurpose3 = 0x15, ///< General Purpose Controller 3 (Slider, MIDI Controller 18) |
type_none = 0x00, ///< No controller defined |
181 |
attenuation_ctrl_genpurpose4 = 0x17, ///< General Purpose Controller 4 (Slider, MIDI Controller 19) |
type_channelaftertouch = 0x2f, ///< Channel Key Pressure |
182 |
attenuation_ctrl_portamentotime = 0x0b, ///< Portamento Time (Coarse, MIDI Controller 5) |
type_velocity = 0xff, ///< Key Velocity |
183 |
attenuation_ctrl_sustainpedal = 0x01, ///< Sustain Pedal (MIDI Controller 64) |
type_controlchange = 0xfe ///< Ordinary MIDI control change controller, see field 'controller_number' |
184 |
attenuation_ctrl_portamento = 0x19, ///< Portamento (MIDI Controller 65) |
} type_t; |
185 |
attenuation_ctrl_sostenutopedal = 0x1b, ///< Sostenuto Pedal (MIDI Controller 66) |
|
186 |
attenuation_ctrl_softpedal = 0x09, ///< Soft Pedal (MIDI Controller 67) |
type_t type; ///< Controller type |
187 |
attenuation_ctrl_genpurpose5 = 0x1d, ///< General Purpose Controller 5 (Button, MIDI Controller 80) |
uint controller_number; ///< MIDI controller number if this controller is a control change controller, 0 otherwise |
188 |
attenuation_ctrl_genpurpose6 = 0x1f, ///< General Purpose Controller 6 (Button, MIDI Controller 81) |
}; |
189 |
attenuation_ctrl_genpurpose7 = 0x21, ///< General Purpose Controller 7 (Button, MIDI Controller 82) |
|
190 |
attenuation_ctrl_genpurpose8 = 0x23, ///< General Purpose Controller 8 (Button, MIDI Controller 83) |
/** |
191 |
attenuation_ctrl_effect1depth = 0x25, ///< Effect 1 Depth (MIDI Controller 91) |
* Defines controller influencing attenuation. |
192 |
attenuation_ctrl_effect2depth = 0x27, ///< Effect 2 Depth (MIDI Controller 92) |
* |
193 |
attenuation_ctrl_effect3depth = 0x29, ///< Effect 3 Depth (MIDI Controller 93) |
* @see leverage_ctrl_t |
194 |
attenuation_ctrl_effect4depth = 0x2b, ///< Effect 4 Depth (MIDI Controller 94) |
*/ |
195 |
attenuation_ctrl_effect5depth = 0x2d, ///< Effect 5 Depth (MIDI Controller 95) |
typedef leverage_ctrl_t attenuation_ctrl_t; |
196 |
attenuation_ctrl_channelaftertouch = 0x2f, ///< Channel Key Pressure |
|
197 |
attenuation_ctrl_velocity = 0xff ///< Key Velocity |
/** |
198 |
} attenuation_ctrl_t, eg1_ctrl_t, eg2_ctrl_t; |
* Defines controller influencing envelope generator 1. |
199 |
|
* |
200 |
|
* @see leverage_ctrl_t |
201 |
|
*/ |
202 |
|
typedef leverage_ctrl_t eg1_ctrl_t; |
203 |
|
|
204 |
|
/** |
205 |
|
* Defines controller influencing envelope generator 2. |
206 |
|
* |
207 |
|
* @see leverage_ctrl_t |
208 |
|
*/ |
209 |
|
typedef leverage_ctrl_t eg2_ctrl_t; |
210 |
|
|
211 |
/** |
/** |
212 |
* Defines the type of dimension, that is how the dimension zones (and |
* Defines the type of dimension, that is how the dimension zones (and |
292 |
#endif // WORDS_BIGENDIAN |
#endif // WORDS_BIGENDIAN |
293 |
}; |
}; |
294 |
|
|
295 |
|
/** Reflects the current playback state for a sample. */ |
296 |
|
struct playback_state_t { |
297 |
|
unsigned long position; ///< Current position within the sample. |
298 |
|
bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined). |
299 |
|
unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. |
300 |
|
}; |
301 |
|
|
302 |
// just symbol prototyping |
// just symbol prototyping |
303 |
class File; |
class File; |
304 |
class Instrument; |
class Instrument; |
331 |
bool EG1Hold; ///< If <i>true</i>, Decay1 stage should be postponed until the sample reached the sample loop start. |
bool EG1Hold; ///< If <i>true</i>, Decay1 stage should be postponed until the sample reached the sample loop start. |
332 |
eg1_ctrl_t EG1Controller; ///< MIDI Controller which has influence on sample amplitude EG parameters (attack, decay, release). |
eg1_ctrl_t EG1Controller; ///< MIDI Controller which has influence on sample amplitude EG parameters (attack, decay, release). |
333 |
bool EG1ControllerInvert; ///< Invert values coming from defined EG1 controller. |
bool EG1ControllerInvert; ///< Invert values coming from defined EG1 controller. |
334 |
uint8_t EG1ControllerAttackInfluence; ///< Amount EG1 Controller has influence on the EG1 Attack time. |
uint8_t EG1ControllerAttackInfluence; ///< Amount EG1 Controller has influence on the EG1 Attack time (0 - 3, where 0 means off). |
335 |
uint8_t EG1ControllerDecayInfluence; ///< Amount EG1 Controller has influence on the EG1 Decay time. |
uint8_t EG1ControllerDecayInfluence; ///< Amount EG1 Controller has influence on the EG1 Decay time (0 - 3, where 0 means off). |
336 |
uint8_t EG1ControllerReleaseInfluence; ///< Amount EG1 Controller has influence on the EG1 Release time. |
uint8_t EG1ControllerReleaseInfluence; ///< Amount EG1 Controller has influence on the EG1 Release time (0 - 3, where 0 means off). |
337 |
double LFO1Frequency; ///< Frequency of the sample amplitude LFO (0.10 - 10.00 Hz). |
double LFO1Frequency; ///< Frequency of the sample amplitude LFO (0.10 - 10.00 Hz). |
338 |
uint16_t LFO1InternalDepth; ///< Firm pitch of the sample amplitude LFO (0 - 1200 cents). |
uint16_t LFO1InternalDepth; ///< Firm pitch of the sample amplitude LFO (0 - 1200 cents). |
339 |
uint16_t LFO1ControlDepth; ///< Controller depth influencing sample amplitude LFO pitch (0 - 1200 cents). |
uint16_t LFO1ControlDepth; ///< Controller depth influencing sample amplitude LFO pitch (0 - 1200 cents). |
350 |
double EG2Release; ///< Release time of the filter cutoff EG (0.000 - 60.000s). |
double EG2Release; ///< Release time of the filter cutoff EG (0.000 - 60.000s). |
351 |
eg2_ctrl_t EG2Controller; ///< MIDI Controller which has influence on filter cutoff EG parameters (attack, decay, release). |
eg2_ctrl_t EG2Controller; ///< MIDI Controller which has influence on filter cutoff EG parameters (attack, decay, release). |
352 |
bool EG2ControllerInvert; ///< Invert values coming from defined EG2 controller. |
bool EG2ControllerInvert; ///< Invert values coming from defined EG2 controller. |
353 |
uint8_t EG2ControllerAttackInfluence; ///< Amount EG2 Controller has influence on the EG2 Attack time. |
uint8_t EG2ControllerAttackInfluence; ///< Amount EG2 Controller has influence on the EG2 Attack time (0 - 3, where 0 means off). |
354 |
uint8_t EG2ControllerDecayInfluence; ///< Amount EG2 Controller has influence on the EG2 Decay time. |
uint8_t EG2ControllerDecayInfluence; ///< Amount EG2 Controller has influence on the EG2 Decay time (0 - 3, where 0 means off). |
355 |
uint8_t EG2ControllerReleaseInfluence; ///< Amount EG2 Controller has influence on the EG2 Release time. |
uint8_t EG2ControllerReleaseInfluence; ///< Amount EG2 Controller has influence on the EG2 Release time (0 - 3, where 0 means off). |
356 |
double LFO2Frequency; ///< Frequency of the filter cutoff LFO (0.10 - 10.00 Hz). |
double LFO2Frequency; ///< Frequency of the filter cutoff LFO (0.10 - 10.00 Hz). |
357 |
uint16_t LFO2InternalDepth; ///< Firm pitch of the filter cutoff LFO (0 - 1200 cents). |
uint16_t LFO2InternalDepth; ///< Firm pitch of the filter cutoff LFO (0 - 1200 cents). |
358 |
uint16_t LFO2ControlDepth; ///< Controller depth influencing filter cutoff LFO pitch (0 - 1200). |
uint16_t LFO2ControlDepth; ///< Controller depth influencing filter cutoff LFO pitch (0 - 1200). |
381 |
bool VCFKeyboardTracking; ///< If <i>true</i>: VCF cutoff frequence will be dependend to the note key position relative to the defined breakpoint value. |
bool VCFKeyboardTracking; ///< If <i>true</i>: VCF cutoff frequence will be dependend to the note key position relative to the defined breakpoint value. |
382 |
uint8_t VCFKeyboardTrackingBreakpoint; ///< See VCFKeyboardTracking (0 - 127). |
uint8_t VCFKeyboardTrackingBreakpoint; ///< See VCFKeyboardTracking (0 - 127). |
383 |
// Key Velocity Transformations |
// Key Velocity Transformations |
384 |
curve_type_t VelocityResponseCurve; ///< Defines a transformation curve to the incoming velocity values affecting amplitude. |
curve_type_t VelocityResponseCurve; ///< Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). |
385 |
uint8_t VelocityResponseDepth; ///< Dynamic range of velocity affecting amplitude (0 - 4). |
uint8_t VelocityResponseDepth; ///< Dynamic range of velocity affecting amplitude (0 - 4) (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead). |
386 |
uint8_t VelocityResponseCurveScaling; ///< 0 - 127 |
uint8_t VelocityResponseCurveScaling; ///< 0 - 127 (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead) |
387 |
curve_type_t ReleaseVelocityResponseCurve; ///< Defines a transformation curve to the incoming release veloctiy values affecting envelope times. |
curve_type_t ReleaseVelocityResponseCurve; ///< Defines a transformation curve to the incoming release veloctiy values affecting envelope times. |
388 |
uint8_t ReleaseVelocityResponseDepth; ///< Dynamic range of release velocity affecting envelope time (0 - 4). |
uint8_t ReleaseVelocityResponseDepth; ///< Dynamic range of release velocity affecting envelope time (0 - 4). |
389 |
uint8_t ReleaseTriggerDecay; ///< 0 - 8 |
uint8_t ReleaseTriggerDecay; ///< 0 - 8 |
393 |
dim_bypass_ctrl_t DimensionBypass; ///< If defined, the MIDI controller can switch on/off the dimension in realtime. |
dim_bypass_ctrl_t DimensionBypass; ///< If defined, the MIDI controller can switch on/off the dimension in realtime. |
394 |
int8_t Pan; ///< Panorama / Balance (-64..0..63 <-> left..middle..right) |
int8_t Pan; ///< Panorama / Balance (-64..0..63 <-> left..middle..right) |
395 |
bool SelfMask; ///< If <i>true</i>: high velocity notes will stop low velocity notes at the same note, with that you can save voices that wouldn't be audible anyway. |
bool SelfMask; ///< If <i>true</i>: high velocity notes will stop low velocity notes at the same note, with that you can save voices that wouldn't be audible anyway. |
396 |
attenuation_ctrl_t AttenuationControl; ///< MIDI Controller which has influence on the volume level of the sample (or entire sample group). |
attenuation_ctrl_t AttenuationController; ///< MIDI Controller which has influence on the volume level of the sample (or entire sample group). |
397 |
bool InvertAttenuationControl; ///< Inverts the values coming from the defined Attenuation Controller. |
bool InvertAttenuationController; ///< Inverts the values coming from the defined Attenuation Controller. |
398 |
uint8_t AttenuationControlTreshold; ///< 0-127 |
uint8_t AttenuationControllerThreshold;///< 0-127 |
399 |
uint8_t ChannelOffset; ///< Audio output where the audio signal of the dimension region should be routed to (0 - 9). |
uint8_t ChannelOffset; ///< Audio output where the audio signal of the dimension region should be routed to (0 - 9). |
400 |
bool SustainDefeat; ///< If <i>true</i>: Sustain pedal will not hold a note. |
bool SustainDefeat; ///< If <i>true</i>: Sustain pedal will not hold a note. |
401 |
bool MSDecode; ///< Gigastudio flag: defines if Mid Side Recordings should be decoded. |
bool MSDecode; ///< Gigastudio flag: defines if Mid Side Recordings should be decoded. |
414 |
~DimensionRegion(); |
~DimensionRegion(); |
415 |
friend class Region; |
friend class Region; |
416 |
private: |
private: |
417 |
|
typedef enum { ///< Used to decode attenuation, EG1 and EG2 controller |
418 |
|
_lev_ctrl_none = 0x00, |
419 |
|
_lev_ctrl_modwheel = 0x03, ///< Modulation Wheel (MIDI Controller 1) |
420 |
|
_lev_ctrl_breath = 0x05, ///< Breath Controller (Coarse, MIDI Controller 2) |
421 |
|
_lev_ctrl_foot = 0x07, ///< Foot Pedal (Coarse, MIDI Controller 4) |
422 |
|
_lev_ctrl_effect1 = 0x0d, ///< Effect Controller 1 (Coarse, MIDI Controller 12) |
423 |
|
_lev_ctrl_effect2 = 0x0f, ///< Effect Controller 2 (Coarse, MIDI Controller 13) |
424 |
|
_lev_ctrl_genpurpose1 = 0x11, ///< General Purpose Controller 1 (Slider, MIDI Controller 16) |
425 |
|
_lev_ctrl_genpurpose2 = 0x13, ///< General Purpose Controller 2 (Slider, MIDI Controller 17) |
426 |
|
_lev_ctrl_genpurpose3 = 0x15, ///< General Purpose Controller 3 (Slider, MIDI Controller 18) |
427 |
|
_lev_ctrl_genpurpose4 = 0x17, ///< General Purpose Controller 4 (Slider, MIDI Controller 19) |
428 |
|
_lev_ctrl_portamentotime = 0x0b, ///< Portamento Time (Coarse, MIDI Controller 5) |
429 |
|
_lev_ctrl_sustainpedal = 0x01, ///< Sustain Pedal (MIDI Controller 64) |
430 |
|
_lev_ctrl_portamento = 0x19, ///< Portamento (MIDI Controller 65) |
431 |
|
_lev_ctrl_sostenutopedal = 0x1b, ///< Sostenuto Pedal (MIDI Controller 66) |
432 |
|
_lev_ctrl_softpedal = 0x09, ///< Soft Pedal (MIDI Controller 67) |
433 |
|
_lev_ctrl_genpurpose5 = 0x1d, ///< General Purpose Controller 5 (Button, MIDI Controller 80) |
434 |
|
_lev_ctrl_genpurpose6 = 0x1f, ///< General Purpose Controller 6 (Button, MIDI Controller 81) |
435 |
|
_lev_ctrl_genpurpose7 = 0x21, ///< General Purpose Controller 7 (Button, MIDI Controller 82) |
436 |
|
_lev_ctrl_genpurpose8 = 0x23, ///< General Purpose Controller 8 (Button, MIDI Controller 83) |
437 |
|
_lev_ctrl_effect1depth = 0x25, ///< Effect 1 Depth (MIDI Controller 91) |
438 |
|
_lev_ctrl_effect2depth = 0x27, ///< Effect 2 Depth (MIDI Controller 92) |
439 |
|
_lev_ctrl_effect3depth = 0x29, ///< Effect 3 Depth (MIDI Controller 93) |
440 |
|
_lev_ctrl_effect4depth = 0x2b, ///< Effect 4 Depth (MIDI Controller 94) |
441 |
|
_lev_ctrl_effect5depth = 0x2d, ///< Effect 5 Depth (MIDI Controller 95) |
442 |
|
_lev_ctrl_channelaftertouch = 0x2f, ///< Channel Key Pressure |
443 |
|
_lev_ctrl_velocity = 0xff ///< Key Velocity |
444 |
|
} _lev_ctrl_t; |
445 |
typedef std::map<uint32_t, double*> VelocityTableMap; |
typedef std::map<uint32_t, double*> VelocityTableMap; |
446 |
|
|
447 |
static uint Instances; ///< Number of DimensionRegion instances. |
static uint Instances; ///< Number of DimensionRegion instances. |
448 |
static VelocityTableMap* pVelocityTables; ///< Contains the tables corresponding to the various velocity parameters (VelocityResponseCurve and VelocityResponseDepth). |
static VelocityTableMap* pVelocityTables; ///< Contains the tables corresponding to the various velocity parameters (VelocityResponseCurve and VelocityResponseDepth). |
449 |
double* pVelocityAttenuationTable; ///< Points to the velocity table corresponding to the velocity parameters of this DimensionRegion. |
double* pVelocityAttenuationTable; ///< Points to the velocity table corresponding to the velocity parameters of this DimensionRegion. |
450 |
|
|
451 |
|
leverage_ctrl_t DecodeLeverageController(_lev_ctrl_t EncodedController); |
452 |
}; |
}; |
453 |
|
|
454 |
/** Encapsulates sample waves used for playback. */ |
/** Encapsulates sample waves used for playback. */ |
483 |
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
484 |
unsigned long GetPos(); |
unsigned long GetPos(); |
485 |
unsigned long Read(void* pBuffer, unsigned long SampleCount); |
unsigned long Read(void* pBuffer, unsigned long SampleCount); |
486 |
|
unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState); |
487 |
protected: |
protected: |
488 |
static unsigned int Instances; ///< Number of instances of class Sample. |
static unsigned int Instances; ///< Number of instances of class Sample. |
489 |
static unsigned long DecompressionBufferSize; ///< Current size of the decompression buffer. |
static unsigned long DecompressionBufferSize; ///< Current size of the decompression buffer. |
495 |
|
|
496 |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset); |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset); |
497 |
~Sample(); |
~Sample(); |
498 |
|
/** |
499 |
|
* Swaps the order of the data words in the given memory area |
500 |
|
* with a granularity given by \a WordSize. |
501 |
|
* |
502 |
|
* @param pData - pointer to the memory area to be swapped |
503 |
|
* @param AreaSize - size of the memory area to be swapped (in bytes) |
504 |
|
* @param WordSize - size of the data words (in bytes) |
505 |
|
*/ |
506 |
|
inline void SwapMemoryArea(void* pData, unsigned long AreaSize, uint WordSize) { |
507 |
|
switch (WordSize) { // TODO: unefficient |
508 |
|
case 1: { |
509 |
|
uint8_t* pDst = (uint8_t*) pData; |
510 |
|
uint8_t cache; |
511 |
|
unsigned long lo = 0, hi = AreaSize - 1; |
512 |
|
for (; lo < hi; hi--, lo++) { |
513 |
|
cache = pDst[lo]; |
514 |
|
pDst[lo] = pDst[hi]; |
515 |
|
pDst[hi] = cache; |
516 |
|
} |
517 |
|
break; |
518 |
|
} |
519 |
|
case 2: { |
520 |
|
uint16_t* pDst = (uint16_t*) pData; |
521 |
|
uint16_t cache; |
522 |
|
unsigned long lo = 0, hi = (AreaSize >> 1) - 1; |
523 |
|
for (; lo < hi; hi--, lo++) { |
524 |
|
cache = pDst[lo]; |
525 |
|
pDst[lo] = pDst[hi]; |
526 |
|
pDst[hi] = cache; |
527 |
|
} |
528 |
|
break; |
529 |
|
} |
530 |
|
case 4: { |
531 |
|
uint32_t* pDst = (uint32_t*) pData; |
532 |
|
uint32_t cache; |
533 |
|
unsigned long lo = 0, hi = (AreaSize >> 2) - 1; |
534 |
|
for (; lo < hi; hi--, lo++) { |
535 |
|
cache = pDst[lo]; |
536 |
|
pDst[lo] = pDst[hi]; |
537 |
|
pDst[hi] = cache; |
538 |
|
} |
539 |
|
break; |
540 |
|
} |
541 |
|
default: { |
542 |
|
uint8_t* pCache = new uint8_t[WordSize]; // TODO: unefficient |
543 |
|
unsigned long lo = 0, hi = AreaSize - WordSize; |
544 |
|
for (; lo < hi; hi -= WordSize, lo += WordSize) { |
545 |
|
memcpy(pCache, (uint8_t*) pData + lo, WordSize); |
546 |
|
memcpy((uint8_t*) pData + lo, (uint8_t*) pData + hi, WordSize); |
547 |
|
memcpy((uint8_t*) pData + hi, pCache, WordSize); |
548 |
|
} |
549 |
|
delete[] pCache; |
550 |
|
break; |
551 |
|
} |
552 |
|
} |
553 |
|
} |
554 |
|
inline long Min(long A, long B) { |
555 |
|
return (A > B) ? B : A; |
556 |
|
} |
557 |
|
inline long Abs(long val) { return (val > 0) ? val : -val; } |
558 |
private: |
private: |
559 |
void ScanCompressedSample(); |
void ScanCompressedSample(); |
560 |
friend class File; |
friend class File; |