2 |
* * |
* * |
3 |
* libgig - C++ cross-platform Gigasampler format file access library * |
* libgig - C++ cross-platform Gigasampler format file access library * |
4 |
* * |
* * |
5 |
* Copyright (C) 2003-2015 by Christian Schoenebeck * |
* Copyright (C) 2003-2016 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 * |
45 |
# define CHUNK_ID_SCRI 0x53637269 // own gig format extension |
# define CHUNK_ID_SCRI 0x53637269 // own gig format extension |
46 |
# define CHUNK_ID_LSNM 0x4c534e4d // own gig format extension |
# define CHUNK_ID_LSNM 0x4c534e4d // own gig format extension |
47 |
# define CHUNK_ID_SCSL 0x5343534c // own gig format extension |
# define CHUNK_ID_SCSL 0x5343534c // own gig format extension |
48 |
|
# define CHUNK_ID_FFMT 0x46466D74 // own gig format extension |
49 |
#else // little endian |
#else // little endian |
50 |
# define LIST_TYPE_3PRG 0x67727033 |
# define LIST_TYPE_3PRG 0x67727033 |
51 |
# define LIST_TYPE_3EWL 0x6C776533 |
# define LIST_TYPE_3EWL 0x6C776533 |
64 |
# define CHUNK_ID_SCRI 0x69726353 // own gig format extension |
# define CHUNK_ID_SCRI 0x69726353 // own gig format extension |
65 |
# define CHUNK_ID_LSNM 0x4d4e534c // own gig format extension |
# define CHUNK_ID_LSNM 0x4d4e534c // own gig format extension |
66 |
# define CHUNK_ID_SCSL 0x4c534353 // own gig format extension |
# define CHUNK_ID_SCSL 0x4c534353 // own gig format extension |
67 |
|
# define CHUNK_ID_FFMT 0x746D4646 // own gig format extension |
68 |
#endif // WORDS_BIGENDIAN |
#endif // WORDS_BIGENDIAN |
69 |
|
|
70 |
/** Gigasampler/GigaStudio specific classes and definitions */ |
/** Gigasampler/GigaStudio specific classes and definitions */ |
72 |
|
|
73 |
typedef std::string String; |
typedef std::string String; |
74 |
typedef RIFF::progress_t progress_t; |
typedef RIFF::progress_t progress_t; |
75 |
|
typedef RIFF::file_offset_t file_offset_t; |
76 |
|
|
77 |
/** Lower and upper limit of a range. */ |
/** Lower and upper limit of a range. */ |
78 |
struct range_t { |
struct range_t { |
83 |
/** Pointer address and size of a buffer. */ |
/** Pointer address and size of a buffer. */ |
84 |
struct buffer_t { |
struct buffer_t { |
85 |
void* pStart; ///< Points to the beginning of the buffer. |
void* pStart; ///< Points to the beginning of the buffer. |
86 |
unsigned long Size; ///< Size of the actual data in the buffer in bytes. |
file_offset_t Size; ///< Size of the actual data in the buffer in bytes. |
87 |
unsigned long NullExtensionSize; ///< The buffer might be bigger than the actual data, if that's the case that unused space at the end of the buffer is filled with NULLs and NullExtensionSize reflects that unused buffer space in bytes. Those NULL extensions are mandatory for differential algorithms that have to take the following data words into account, thus have to access past the buffer's boundary. If you don't know what I'm talking about, just forget this variable. :) |
file_offset_t NullExtensionSize; ///< The buffer might be bigger than the actual data, if that's the case that unused space at the end of the buffer is filled with NULLs and NullExtensionSize reflects that unused buffer space in bytes. Those NULL extensions are mandatory for differential algorithms that have to take the following data words into account, thus have to access past the buffer's boundary. If you don't know what I'm talking about, just forget this variable. :) |
88 |
buffer_t() { |
buffer_t() { |
89 |
pStart = NULL; |
pStart = NULL; |
90 |
Size = 0; |
Size = 0; |
310 |
|
|
311 |
/** Reflects the current playback state for a sample. */ |
/** Reflects the current playback state for a sample. */ |
312 |
struct playback_state_t { |
struct playback_state_t { |
313 |
unsigned long position; ///< Current position within the sample. |
file_offset_t position; ///< Current position within the sample. |
314 |
bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined). |
bool reverse; ///< If playback direction is currently backwards (in case there is a pingpong or reverse loop defined). |
315 |
unsigned long loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. |
file_offset_t loop_cycles_left; ///< How many times the loop has still to be passed, this value will be decremented with each loop cycle. |
316 |
}; |
}; |
317 |
|
|
318 |
// just symbol prototyping |
// just symbol prototyping |
654 |
|
|
655 |
// own methods |
// own methods |
656 |
buffer_t LoadSampleData(); |
buffer_t LoadSampleData(); |
657 |
buffer_t LoadSampleData(unsigned long SampleCount); |
buffer_t LoadSampleData(file_offset_t SampleCount); |
658 |
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount); |
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount); |
659 |
buffer_t LoadSampleDataWithNullSamplesExtension(unsigned long SampleCount, uint NullSamplesCount); |
buffer_t LoadSampleDataWithNullSamplesExtension(file_offset_t SampleCount, uint NullSamplesCount); |
660 |
buffer_t GetCache(); |
buffer_t GetCache(); |
661 |
// own static methods |
// own static methods |
662 |
static buffer_t CreateDecompressionBuffer(unsigned long MaxReadSize); |
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize); |
663 |
static void DestroyDecompressionBuffer(buffer_t& DecompressionBuffer); |
static void DestroyDecompressionBuffer(buffer_t& DecompressionBuffer); |
664 |
// overridden methods |
// overridden methods |
665 |
void ReleaseSampleData(); |
void ReleaseSampleData(); |
666 |
void Resize(int iNewSize); |
void Resize(int iNewSize); |
667 |
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
file_offset_t SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence = RIFF::stream_start); |
668 |
unsigned long GetPos() const; |
file_offset_t GetPos() const; |
669 |
unsigned long Read(void* pBuffer, unsigned long SampleCount, buffer_t* pExternalDecompressionBuffer = NULL); |
file_offset_t Read(void* pBuffer, file_offset_t SampleCount, buffer_t* pExternalDecompressionBuffer = NULL); |
670 |
unsigned long ReadAndLoop(void* pBuffer, unsigned long SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL); |
file_offset_t ReadAndLoop(void* pBuffer, file_offset_t SampleCount, playback_state_t* pPlaybackState, DimensionRegion* pDimRgn, buffer_t* pExternalDecompressionBuffer = NULL); |
671 |
unsigned long Write(void* pBuffer, unsigned long SampleCount); |
file_offset_t Write(void* pBuffer, file_offset_t SampleCount); |
672 |
Group* GetGroup() const; |
Group* GetGroup() const; |
673 |
virtual void UpdateChunks(progress_t* pProgress); |
virtual void UpdateChunks(progress_t* pProgress); |
674 |
void CopyAssignMeta(const Sample* orig); |
void CopyAssignMeta(const Sample* orig); |
677 |
static unsigned int Instances; ///< Number of instances of class Sample. |
static unsigned int Instances; ///< Number of instances of class Sample. |
678 |
static buffer_t InternalDecompressionBuffer; ///< Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples. |
static buffer_t InternalDecompressionBuffer; ///< Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples. |
679 |
Group* pGroup; ///< pointer to the Group this sample belongs to (always not-NULL) |
Group* pGroup; ///< pointer to the Group this sample belongs to (always not-NULL) |
680 |
unsigned long FrameOffset; ///< Current offset (sample points) in current sample frame (for decompression only). |
file_offset_t FrameOffset; ///< Current offset (sample points) in current sample frame (for decompression only). |
681 |
unsigned long* FrameTable; ///< For positioning within compressed samples only: stores the offset values for each frame. |
file_offset_t* FrameTable; ///< For positioning within compressed samples only: stores the offset values for each frame. |
682 |
unsigned long SamplePos; ///< For compressed samples only: stores the current position (in sample points). |
file_offset_t SamplePos; ///< For compressed samples only: stores the current position (in sample points). |
683 |
unsigned long SamplesInLastFrame; ///< For compressed samples only: length of the last sample frame. |
file_offset_t SamplesInLastFrame; ///< For compressed samples only: length of the last sample frame. |
684 |
unsigned long WorstCaseFrameSize; ///< For compressed samples only: size (in bytes) of the largest possible sample frame. |
file_offset_t WorstCaseFrameSize; ///< For compressed samples only: size (in bytes) of the largest possible sample frame. |
685 |
unsigned long SamplesPerFrame; ///< For compressed samples only: number of samples in a full sample frame. |
file_offset_t SamplesPerFrame; ///< For compressed samples only: number of samples in a full sample frame. |
686 |
buffer_t RAMCache; ///< Buffers samples (already uncompressed) in RAM. |
buffer_t RAMCache; ///< Buffers samples (already uncompressed) in RAM. |
687 |
unsigned long FileNo; ///< File number (> 0 when sample is stored in an extension file, 0 when it's in the gig) |
unsigned long FileNo; ///< File number (> 0 when sample is stored in an extension file, 0 when it's in the gig) |
688 |
RIFF::Chunk* pCk3gix; |
RIFF::Chunk* pCk3gix; |
689 |
RIFF::Chunk* pCkSmpl; |
RIFF::Chunk* pCkSmpl; |
690 |
uint32_t crc; ///< CRC-32 checksum of the raw sample data |
uint32_t crc; ///< CRC-32 checksum of the raw sample data |
691 |
|
|
692 |
Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo = 0); |
Sample(File* pFile, RIFF::List* waveList, file_offset_t WavePoolOffset, unsigned long fileNo = 0); |
693 |
~Sample(); |
~Sample(); |
694 |
|
|
695 |
// Guess size (in bytes) of a compressed sample |
// Guess size (in bytes) of a compressed sample |
696 |
inline unsigned long GuessSize(unsigned long samples) { |
inline file_offset_t GuessSize(file_offset_t samples) { |
697 |
// 16 bit: assume all frames are compressed - 1 byte |
// 16 bit: assume all frames are compressed - 1 byte |
698 |
// per sample and 5 bytes header per 2048 samples |
// per sample and 5 bytes header per 2048 samples |
699 |
|
|
700 |
// 24 bit: assume next best compression rate - 1.5 |
// 24 bit: assume next best compression rate - 1.5 |
701 |
// bytes per sample and 13 bytes header per 256 |
// bytes per sample and 13 bytes header per 256 |
702 |
// samples |
// samples |
703 |
const unsigned long size = |
const file_offset_t size = |
704 |
BitDepth == 24 ? samples + (samples >> 1) + (samples >> 8) * 13 |
BitDepth == 24 ? samples + (samples >> 1) + (samples >> 8) * 13 |
705 |
: samples + (samples >> 10) * 5; |
: samples + (samples >> 10) * 5; |
706 |
// Double for stereo and add one worst case sample |
// Double for stereo and add one worst case sample |
710 |
|
|
711 |
// Worst case amount of sample points that can be read with the |
// Worst case amount of sample points that can be read with the |
712 |
// given decompression buffer. |
// given decompression buffer. |
713 |
inline unsigned long WorstCaseMaxSamples(buffer_t* pDecompressionBuffer) { |
inline file_offset_t WorstCaseMaxSamples(buffer_t* pDecompressionBuffer) { |
714 |
return (unsigned long) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame); |
return (file_offset_t) ((float)pDecompressionBuffer->Size / (float)WorstCaseFrameSize * (float)SamplesPerFrame); |
715 |
} |
} |
716 |
private: |
private: |
717 |
void ScanCompressedSample(); |
void ScanCompressedSample(); |
1269 |
virtual void LoadInstruments(progress_t* pProgress); |
virtual void LoadInstruments(progress_t* pProgress); |
1270 |
virtual void LoadScriptGroups(); |
virtual void LoadScriptGroups(); |
1271 |
void SetSampleChecksum(Sample* pSample, uint32_t crc); |
void SetSampleChecksum(Sample* pSample, uint32_t crc); |
1272 |
|
uint GetFormatExtensionVersion() const; |
1273 |
|
bool HasMonolithicLargeFilePolicy() const; |
1274 |
friend class Region; |
friend class Region; |
1275 |
friend class Sample; |
friend class Sample; |
1276 |
friend class Instrument; |
friend class Instrument; |