282 |
#endif // WORDS_BIGENDIAN |
#endif // WORDS_BIGENDIAN |
283 |
}; |
}; |
284 |
|
|
285 |
|
/** Reflects the current playback state for a sample. */ |
286 |
|
struct playback_state_t { |
287 |
|
unsigned long position; ///< Current position within the sample. |
288 |
|
bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined). |
289 |
|
unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. |
290 |
|
}; |
291 |
|
|
292 |
// just symbol prototyping |
// just symbol prototyping |
293 |
class File; |
class File; |
294 |
class Instrument; |
class Instrument; |
443 |
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); |
444 |
unsigned long GetPos(); |
unsigned long GetPos(); |
445 |
unsigned long Read(void* pBuffer, unsigned long SampleCount); |
unsigned long Read(void* pBuffer, unsigned long SampleCount); |
446 |
|
unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState); |
447 |
protected: |
protected: |
448 |
static unsigned int Instances; ///< Number of instances of class Sample. |
static unsigned int Instances; ///< Number of instances of class Sample. |
449 |
static unsigned long DecompressionBufferSize; ///< Current size of the decompression buffer. |
static unsigned long DecompressionBufferSize; ///< Current size of the decompression buffer. |
455 |
|
|
456 |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset); |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset); |
457 |
~Sample(); |
~Sample(); |
458 |
|
/** |
459 |
|
* Swaps the order of the data words in the given memory area |
460 |
|
* with a granularity given by \a WordSize. |
461 |
|
* |
462 |
|
* @param pData - pointer to the memory area to be swapped |
463 |
|
* @param AreaSize - size of the memory area to be swapped (in bytes) |
464 |
|
* @param WordSize - size of the data words (in bytes) |
465 |
|
*/ |
466 |
|
inline void SwapMemoryArea(void* pData, unsigned long AreaSize, uint WordSize) { |
467 |
|
switch (WordSize) { // TODO: unefficient |
468 |
|
case 1: { |
469 |
|
uint8_t* pDst = (uint8_t*) pData; |
470 |
|
uint8_t cache; |
471 |
|
unsigned long lo = 0, hi = AreaSize - 1; |
472 |
|
for (; lo < hi; hi--, lo++) { |
473 |
|
cache = pDst[lo]; |
474 |
|
pDst[lo] = pDst[hi]; |
475 |
|
pDst[hi] = cache; |
476 |
|
} |
477 |
|
break; |
478 |
|
} |
479 |
|
case 2: { |
480 |
|
uint16_t* pDst = (uint16_t*) pData; |
481 |
|
uint16_t cache; |
482 |
|
unsigned long lo = 0, hi = (AreaSize >> 1) - 1; |
483 |
|
for (; lo < hi; hi--, lo++) { |
484 |
|
cache = pDst[lo]; |
485 |
|
pDst[lo] = pDst[hi]; |
486 |
|
pDst[hi] = cache; |
487 |
|
} |
488 |
|
break; |
489 |
|
} |
490 |
|
case 4: { |
491 |
|
uint32_t* pDst = (uint32_t*) pData; |
492 |
|
uint32_t cache; |
493 |
|
unsigned long lo = 0, hi = (AreaSize >> 2) - 1; |
494 |
|
for (; lo < hi; hi--, lo++) { |
495 |
|
cache = pDst[lo]; |
496 |
|
pDst[lo] = pDst[hi]; |
497 |
|
pDst[hi] = cache; |
498 |
|
} |
499 |
|
break; |
500 |
|
} |
501 |
|
default: { |
502 |
|
uint8_t* pCache = new uint8_t[WordSize]; // TODO: unefficient |
503 |
|
unsigned long lo = 0, hi = AreaSize - WordSize; |
504 |
|
for (; lo < hi; hi -= WordSize, lo += WordSize) { |
505 |
|
memcpy(pCache, (uint8_t*) pData + lo, WordSize); |
506 |
|
memcpy((uint8_t*) pData + lo, (uint8_t*) pData + hi, WordSize); |
507 |
|
memcpy((uint8_t*) pData + hi, pCache, WordSize); |
508 |
|
} |
509 |
|
delete[] pCache; |
510 |
|
break; |
511 |
|
} |
512 |
|
} |
513 |
|
} |
514 |
|
inline long Min(long A, long B) { |
515 |
|
return (A > B) ? B : A; |
516 |
|
} |
517 |
|
inline long Abs(long val) { return (val > 0) ? val : -val; } |
518 |
private: |
private: |
519 |
void ScanCompressedSample(); |
void ScanCompressedSample(); |
520 |
friend class File; |
friend class File; |