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 
   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 
   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 = (int) 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);
 
   90     KSFSample::KSFSample(
const String& filename) {
 
  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)");
 
  126     KSFSample::~KSFSample() {
 
  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();
 
  255             case RIFF::stream_curpos:
 
  256                 samplePos += SampleCount;
 
  258             case RIFF::stream_end:
 
  261             case RIFF::stream_backward:
 
  262                 samplePos -= SampleCount;
 
  264             case RIFF::stream_start:
 
  266                 samplePos = SampleCount;
 
  270         unsigned long bytes = samplePos * 
FrameSize();
 
  272         unsigned long result = smd1->
SetPos(SMD1_CHUNK_HEADER_SZ + bytes);
 
  273         return (result - SMD1_CHUNK_HEADER_SZ) / 
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;
 
  321     uint8_t KSFSample::CompressionID()
 const {
 
  325     bool KSFSample::IsCompressed()
 const {
 
  329     bool KSFSample::Use2ndStart()
 const {
 
  333     String KSFSample::FileName()
 const {
 
  334         return riff->GetFileName();
 
  340     KMPRegion::KMPRegion(KMPInstrument* parent, 
RIFF::Chunk* rlp1)
 
  341         : parent(parent), rlp1(rlp1)
 
  344         Transpose   = (OriginalKey >> 7) & 1;
 
  354     KMPRegion::~KMPRegion() {
 
  357     String KMPRegion::FullSampleFileName()
 const {
 
  362     KMPInstrument* KMPRegion::GetInstrument()
 const {
 
  369     KMPInstrument::KMPInstrument(
const String& filename) {
 
  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) {
 
  397             KMPRegion* region = 
new KMPRegion(
this, rlp1);
 
  398             regions.push_back(region);
 
  402     KMPInstrument::~KMPInstrument() {
 
  403         if (riff) 
delete riff;
 
  404         for (
int i = 0; i < regions.size(); ++i)
 
  408     KMPRegion* KMPInstrument::GetRegion(
int index) {
 
  409         if (index < 0 || index >= regions.size())
 
  411         return regions[index];
 
  414     int KMPInstrument::GetRegionCount()
 const {
 
  415         return (
int) regions.size();
 
  418     bool KMPInstrument::Use2ndStart()
 const {
 
  430     String KMPInstrument::FileName()
 const {
 
  431         return riff->GetFileName();
 
  437     Exception::Exception(String Message) : 
RIFF::Exception(Message) {
 
  440     void Exception::PrintMessage()
 const {
 
  441         std::cout << 
"Korg::Exception: " << Message << std::endl;
 
String Name16
Human readable name of the instrument for display purposes (not the file name). Since this name is al...
uint8_t Attributes
Bit field of attribute flags (ATM only bit 0 is used, better call Use2ndStart() instead of accessing ...
String Name24
Longer Human readable name (24 characters) of the instrument for display purposes (not the file name)...
String Name() const
Returns the long name (Name24) if it was stored in the file, otherwise returns the short name (Name16...
String SampleFileName
Base file name of sample file (12 bytes). Call FullSampleFileName() for getting the file name with pa...
uint8_t BitDepth
i.e. 8 or 16
uint8_t Channels
Number of audio channels (seems to be always 1, thus Mono for all Korg sound files ATM).
buffer_t GetCache() const
Returns current cached sample points.
unsigned long Read(void *pBuffer, unsigned long SampleCount)
Reads SampleCount number of sample points from the current position into the buffer pointed by pBuffe...
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).
uint32_t SamplePoints
Currently the library expects all Korg samples to be Mono, thus the value here might be incorrect in ...
String Name
Sample name for drums (since this name is always stored with 16 bytes, this name must never be longer...
buffer_t LoadSampleData()
Loads the whole sample wave into RAM.
int FrameSize() const
Returns the size of one sample point of this sample in bytes.
uint32_t SampleRate
i.e. 44100
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads the whole sample wave into RAM.
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
uint8_t Attributes
Bit field of flags, better call IsCompressed(), CompressionID() and Use2ndStart() instead of accessin...
unsigned long GetPos() const
Returns the current position in the sample (in sample points).
file_offset_t ReadInt8(int8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit signed integer words and copies it into the buffer pointed by pData.
file_offset_t SetPos(file_offset_t Where, stream_whence_t Whence=stream_start)
Sets the position within the chunk body, thus within the data portion of the chunk (in bytes).
file_offset_t ReadUint32(uint32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit unsigned integer words and copies it into the buffer pointed by pDat...
file_offset_t GetPos() const
Current read/write position within the chunk data body (starting with 0).
file_offset_t Read(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Reads WordCount number of data words with given WordSize and copies it into a buffer pointed by pData...
file_offset_t ReadUint8(uint8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit unsigned integer words and copies it into the buffer pointed by pData...
file_offset_t GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
File * GetFile() const
Returns pointer to the chunk's File object.
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
KORG sound format specific classes and definitions.
String libraryVersion()
Returns version of this C++ library.
String libraryName()
Returns the name of this C++ library.
String readText16(RIFF::Chunk *ck)
Read 16 bytes of ASCII text from given chunk and return it as String.
String readText24(RIFF::Chunk *ck)
Read 24 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".
RIFF specific classes and definitions.
stream_whence_t
File stream position dependent to these relations.
@ layout_flat
Not a "real" RIFF file: First chunk in file is an ordinary data chunk, not a List chunk,...
Pointer address and size of a buffer.
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 t...
void * pStart
Points to the beginning of the buffer.
file_offset_t Size
Size of the actual data in the buffer in bytes.