29 # define CHUNK_ID_MSP1 0x4d535031 30 # define CHUNK_ID_RLP1 0x524c5031 31 # define CHUNK_ID_SMP1 0x534d5031 32 # define CHUNK_ID_SMD1 0x534d4431 33 # define CHUNK_ID_NAME 0x4e414d45 34 #else // little endian 35 # define CHUNK_ID_MSP1 0x3150534d 36 # define CHUNK_ID_RLP1 0x31504c52 37 # define CHUNK_ID_SMP1 0x31504d53 38 # define CHUNK_ID_SMD1 0x31444d53 39 # define CHUNK_ID_NAME 0x454d414e 40 #endif // WORDS_BIGENDIAN 42 #define SMD1_CHUNK_HEADER_SZ 12 47 static const String PATH_SEP =
"\\";
49 static const String PATH_SEP =
"/";
55 template<
unsigned int SZ>
58 int n = ck->
Read(buf, SZ, 1);
60 throw Exception(
"Premature end while reading text field");
67 return readText<24>(ck);
72 return readText<16>(ck);
77 return readText<12>(ck);
82 size_t pos = filename.find_last_of(
'.');
83 if (pos == String::npos)
return filename;
84 return filename.substr(0, pos);
102 throw Exception(
"Not a Korg sample file ('SMP1' chunk not found)");
104 throw Exception(
"Not a Korg sample file ('SMP1' chunk size too small)");
115 throw Exception(
"Not a Korg sample file ('SMD1' chunk not found)");
117 throw Exception(
"Not a Korg sample file ('SMD1' chunk size too small)");
127 if (RAMCache.
pStart)
delete[] (int8_t*) RAMCache.
pStart;
128 if (riff)
delete riff;
199 if (RAMCache.
pStart)
delete[] (int8_t*) RAMCache.
pStart;
200 unsigned long allocationsize = (SampleCount + NullSamplesCount) *
FrameSize();
202 RAMCache.
pStart =
new int8_t[allocationsize];
235 if (RAMCache.
pStart)
delete[] (int8_t*) RAMCache.
pStart;
253 unsigned long samplePos =
GetPos();
256 samplePos += SampleCount;
262 samplePos -= SampleCount;
266 samplePos = SampleCount;
270 unsigned long bytes = samplePos *
FrameSize();
303 unsigned long samplestoread = SampleCount, totalreadsamples = 0, readsamples;
305 if (samplestoread)
do {
307 samplestoread -= readsamples;
308 totalreadsamples += readsamples;
309 }
while (readsamples && samplestoread);
311 return totalreadsamples;
341 : parent(parent), rlp1(rlp1)
377 throw Exception(
"Not a Korg instrument file ('MSP1' chunk not found)");
379 throw Exception(
"Not a Korg instrument file ('MSP1' chunk size too small)");
393 throw Exception(
"Not a Korg instrument file ('RLP1' chunk not found)");
394 if (rlp1->
GetSize() < 18 * nSamples)
395 throw Exception(
"Not a Korg instrument file ('RLP1' chunk size too small)");
396 for (
int i = 0; i < nSamples; ++i) {
398 regions.push_back(region);
403 if (riff)
delete riff;
404 for (
int i = 0; i < regions.size(); ++i)
409 if (index < 0 || index >= regions.size())
411 return regions[index];
415 return regions.size();
441 std::cout <<
"Korg::Exception: " <<
Message << std::endl;
unsigned long SetPos(unsigned long SampleCount, RIFF::stream_whence_t Whence=RIFF::stream_start)
Sets the position within the sample (in sample points, not in bytes).
Exception(String Message)
KMPRegion(KMPInstrument *parent, RIFF::Chunk *rlp1)
stream_whence_t
File stream position dependent to these relations.
unsigned long Read(void *pData, unsigned long WordCount, unsigned long WordSize)
Reads WordCount number of data words with given WordSize and copies it into a buffer pointed by pData...
String readText16(RIFF::Chunk *ck)
Read 16 bytes of ASCII text from given chunk and return it as String.
String readText12(RIFF::Chunk *ck)
Read 12 bytes of ASCII text from given chunk and return it as String.
String removeFileTypeExtension(const String &filename)
For example passing "FOO.KMP" will return "FOO".
String Name() const
Returns the long name (Name24) if it was stored in the file, otherwise returns the short name (Name16...
uint32_t SamplePoints
Currently the library expects all Korg samples to be Mono, thus the value here might be incorrect in ...
uint8_t Attributes
Bit field of flags, better call IsCompressed(), CompressionID() and Use2ndStart() instead of accessin...
unsigned long Size
Size of the actual data in the buffer in bytes.
String readText24(RIFF::Chunk *ck)
Read 24 bytes of ASCII text from given chunk and return it as String.
uint8_t OriginalKey
Note of sample's original pitch, a.k.a. "root key" (0..127).
unsigned long SetPos(unsigned long Where, stream_whence_t Whence=stream_start)
Sets the position within the chunk body, thus within the data portion of the chunk (in bytes).
String Name24
Longer Human readable name (24 characters) of the instrument for display purposes (not the file name)...
uint8_t Channels
Number of audio channels (seems to be always 1, thus Mono for all Korg sound files ATM).
String Name
Sample name for drums (since this name is always stored with 16 bytes, this name must never be longer...
KMPInstrument * GetInstrument() const
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads the whole sample wave into RAM.
unsigned long ReadUint32(uint32_t *pData, unsigned long WordCount=1)
Reads WordCount number of 32 Bit unsigned integer words and copies it into the buffer pointed by pDat...
unsigned long GetPos()
Position within the chunk data body.
KMPInstrument(const String &filename)
Pointer address and size of a buffer.
String readText(RIFF::Chunk *ck)
int8_t FilterCutoff
-50..0
unsigned long Read(void *pBuffer, unsigned long SampleCount)
Reads SampleCount number of sample points from the current position into the buffer pointed by pBuffe...
KORG sound format specific classes and definitions.
String FullSampleFileName() const
String libraryVersion()
Returns version of this C++ library.
void * pStart
Points to the beginning of the buffer.
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
int GetRegionCount() const
unsigned long GetPos() const
Returns the current position in the sample (in sample points).
KMPRegion * GetRegion(int index)
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
File * GetFile()
Returns pointer to the chunk's File object.
KSFSample(const String &filename)
uint8_t Attributes
Bit field of attribute flags (ATM only bit 0 is used, better call Use2ndStart() instead of accessing ...
Region of a .KMP multi sample file.
Not a "real" RIFF file: First chunk in file is an ordinary data chunk, not a List chunk,...
int8_t Tune
-99..+99 cents
int FrameSize() const
Returns the size of one sample point of this sample in bytes.
String libraryName()
Returns the name of this C++ library.
String SampleFileName
Base file name of sample file (12 bytes). Call FullSampleFileName() for getting the file name with pa...
uint32_t SampleRate
i.e. 44100
uint8_t BitDepth
i.e. 8 or 16
RIFF specific classes and definitions.
unsigned long GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
uint8_t CompressionID() const
unsigned long NullExtensionSize
The buffer might be bigger than the actual data, if that's the case that unused space at the end of t...
bool IsCompressed() const
uint8_t TopKey
The end of this region on the keyboard (0..127). The start of this region is given by TopKey+1 of the...
buffer_t LoadSampleData()
Loads the whole sample wave into RAM.
String Name16
Human readable name of the instrument for display purposes (not the file name). Since this name is al...
#define SMD1_CHUNK_HEADER_SZ
int8_t Level
-99..+99 cents
Korg format specific exception.
buffer_t GetCache() const
Returns current cached sample points.
unsigned long ReadInt8(int8_t *pData, unsigned long WordCount=1)
Reads WordCount number of 8 Bit signed integer words and copies it into the buffer pointed by pData.
unsigned long ReadUint8(uint8_t *pData, unsigned long WordCount=1)
Reads WordCount number of 8 Bit unsigned integer words and copies it into the buffer pointed by pData...