31 #include <CoreFoundation/CFUUID.h>
32 #elif defined(HAVE_UUID_UUID_H)
33 #include <uuid/uuid.h>
39 #define CONN_TRANSFORM_SRC(x) ((x >> 10) & 0x000F)
40 #define CONN_TRANSFORM_CTL(x) ((x >> 4) & 0x000F)
41 #define CONN_TRANSFORM_DST(x) (x & 0x000F)
42 #define CONN_TRANSFORM_BIPOLAR_SRC(x) (x & 0x4000)
43 #define CONN_TRANSFORM_BIPOLAR_CTL(x) (x & 0x0100)
44 #define CONN_TRANSFORM_INVERT_SRC(x) (x & 0x8000)
45 #define CONN_TRANSFORM_INVERT_CTL(x) (x & 0x0200)
48 #define CONN_TRANSFORM_SRC_ENCODE(x) ((x & 0x000F) << 10)
49 #define CONN_TRANSFORM_CTL_ENCODE(x) ((x & 0x000F) << 4)
50 #define CONN_TRANSFORM_DST_ENCODE(x) (x & 0x000F)
51 #define CONN_TRANSFORM_BIPOLAR_SRC_ENCODE(x) ((x) ? 0x4000 : 0)
52 #define CONN_TRANSFORM_BIPOLAR_CTL_ENCODE(x) ((x) ? 0x0100 : 0)
53 #define CONN_TRANSFORM_INVERT_SRC_ENCODE(x) ((x) ? 0x8000 : 0)
54 #define CONN_TRANSFORM_INVERT_CTL_ENCODE(x) ((x) ? 0x0200 : 0)
56 #define DRUM_TYPE_MASK 0x80000000
58 #define F_RGN_OPTION_SELFNONEXCLUSIVE 0x0001
60 #define F_WAVELINK_PHASE_MASTER 0x0001
61 #define F_WAVELINK_MULTICHANNEL 0x0002
63 #define F_WSMP_NO_TRUNCATION 0x0001
64 #define F_WSMP_NO_COMPRESSION 0x0002
66 #define MIDI_BANK_COARSE(x) ((x & 0x00007F00) >> 8)
67 #define MIDI_BANK_FINE(x) (x & 0x0000007F)
68 #define MIDI_BANK_MERGE(coarse, fine) ((((uint16_t) coarse) << 7) | fine)
69 #define MIDI_BANK_ENCODE(coarse, fine) (((coarse & 0x0000007F) << 8) | (fine & 0x0000007F))
76 void Connection::Init(conn_block_t* Header) {
79 Destination = (
conn_dst_t) Header->destination;
80 Scale = Header->scale;
81 SourceTransform = (
conn_trn_t) CONN_TRANSFORM_SRC(Header->transform);
82 ControlTransform = (
conn_trn_t) CONN_TRANSFORM_CTL(Header->transform);
83 DestinationTransform = (
conn_trn_t) CONN_TRANSFORM_DST(Header->transform);
84 SourceInvert = CONN_TRANSFORM_INVERT_SRC(Header->transform);
85 SourceBipolar = CONN_TRANSFORM_BIPOLAR_SRC(Header->transform);
86 ControlInvert = CONN_TRANSFORM_INVERT_CTL(Header->transform);
87 ControlBipolar = CONN_TRANSFORM_BIPOLAR_CTL(Header->transform);
90 Connection::conn_block_t Connection::ToConnBlock() {
94 c.destination = Destination;
96 c.transform = CONN_TRANSFORM_SRC_ENCODE(SourceTransform) |
97 CONN_TRANSFORM_CTL_ENCODE(ControlTransform) |
98 CONN_TRANSFORM_DST_ENCODE(DestinationTransform) |
99 CONN_TRANSFORM_INVERT_SRC_ENCODE(SourceInvert) |
100 CONN_TRANSFORM_BIPOLAR_SRC_ENCODE(SourceBipolar) |
101 CONN_TRANSFORM_INVERT_CTL_ENCODE(ControlInvert) |
102 CONN_TRANSFORM_BIPOLAR_CTL_ENCODE(ControlBipolar);
120 pArticulationCk = artl;
133 Connection::conn_block_t connblock;
135 artl->
Read(&connblock.source, 1, 2);
136 artl->
Read(&connblock.control, 1, 2);
137 artl->
Read(&connblock.destination, 1, 2);
138 artl->
Read(&connblock.transform, 1, 2);
139 artl->
Read(&connblock.scale, 1, 4);
144 Articulation::~Articulation() {
155 const int iEntrySize = 12;
157 uint8_t* pData = (uint8_t*) pArticulationCk->
LoadChunkData();
158 store16(&pData[0], HeaderSize);
161 Connection::conn_block_t c =
pConnections[i].ToConnBlock();
162 store16(&pData[HeaderSize + i * iEntrySize], c.source);
163 store16(&pData[HeaderSize + i * iEntrySize + 2], c.control);
164 store16(&pData[HeaderSize + i * iEntrySize + 4], c.destination);
165 store16(&pData[HeaderSize + i * iEntrySize + 6], c.transform);
166 store32(&pData[HeaderSize + i * iEntrySize + 8], c.scale);
187 Articulator::Articulator(
RIFF::List* ParentList) {
188 pParentList = ParentList;
189 pArticulations = NULL;
201 if (!pArticulations) LoadArticulations();
202 if (!pArticulations)
return NULL;
203 if (pos >= pArticulations->size())
return NULL;
204 return (*pArticulations)[pos];
217 if (!pArticulations) LoadArticulations();
218 if (!pArticulations)
return NULL;
219 ArticulationsIterator = pArticulations->begin();
220 return (ArticulationsIterator != pArticulations->end()) ? *ArticulationsIterator : NULL;
235 if (!pArticulations)
return NULL;
236 ArticulationsIterator++;
237 return (ArticulationsIterator != pArticulations->end()) ? *ArticulationsIterator : NULL;
240 void Articulator::LoadArticulations() {
243 if (!lart) lart = pParentList->
GetSubList(LIST_TYPE_LART);
245 uint32_t artCkType = (lart->
GetListType() == LIST_TYPE_LAR2) ? CHUNK_ID_ART2
251 if (art->GetChunkID() == artCkType) {
252 if (!pArticulations) pArticulations =
new ArticulationList;
259 Articulator::~Articulator() {
260 if (pArticulations) {
261 ArticulationList::iterator iter = pArticulations->begin();
262 ArticulationList::iterator end = pArticulations->end();
263 while (iter != end) {
267 delete pArticulations;
278 if (pArticulations) {
279 ArticulationList::iterator iter = pArticulations->begin();
280 ArticulationList::iterator end = pArticulations->end();
281 for (; iter != end; ++iter) {
282 (*iter)->UpdateChunks(pProgress);
292 if (pArticulations) {
293 ArticulationList::iterator iter = pArticulations->begin();
294 ArticulationList::iterator end = pArticulations->end();
295 for (; iter != end; ++iter) {
296 (*iter)->DeleteChunks();
322 pFixedStringLengths = NULL;
323 pResourceListChunk = list;
327 LoadString(CHUNK_ID_INAM, lstINFO,
Name);
330 LoadString(CHUNK_ID_ICMT, lstINFO,
Comments);
331 LoadString(CHUNK_ID_IPRD, lstINFO,
Product);
332 LoadString(CHUNK_ID_ICOP, lstINFO,
Copyright);
333 LoadString(CHUNK_ID_IART, lstINFO,
Artists);
334 LoadString(CHUNK_ID_IGNR, lstINFO,
Genre);
335 LoadString(CHUNK_ID_IKEY, lstINFO,
Keywords);
336 LoadString(CHUNK_ID_IENG, lstINFO,
Engineer);
337 LoadString(CHUNK_ID_ITCH, lstINFO,
Technician);
338 LoadString(CHUNK_ID_ISFT, lstINFO,
Software);
339 LoadString(CHUNK_ID_IMED, lstINFO,
Medium);
340 LoadString(CHUNK_ID_ISRC, lstINFO,
Source);
341 LoadString(CHUNK_ID_ISRF, lstINFO,
SourceForm);
343 LoadString(CHUNK_ID_ISBJ, lstINFO,
Subject);
363 pFixedStringLengths = lengths;
371 void Info::LoadString(uint32_t ChunkID,
RIFF::List* lstINFO, String& s) {
391 void Info::SaveString(uint32_t ChunkID,
RIFF::List* lstINFO,
const String& s,
const String& sDefault) {
393 if (pFixedStringLengths) {
394 for (
int i = 0 ; pFixedStringLengths[i].length ; i++) {
395 if (pFixedStringLengths[i].chunkId == ChunkID) {
396 size = pFixedStringLengths[i].length;
402 ::SaveString(ChunkID, ck, lstINFO, s, sDefault, size != 0, size);
413 if (!pResourceListChunk)
return;
418 String defaultName =
"";
419 String defaultCreationDate =
"";
420 String defaultSoftware =
"";
421 String defaultComments =
"";
423 uint32_t resourceType = pResourceListChunk->
GetListType();
426 lstINFO = pResourceListChunk->
AddSubList(LIST_TYPE_INFO);
429 defaultName =
"NONAME";
431 if (resourceType == RIFF_TYPE_DLS) {
433 time_t now = time(NULL);
434 tm* pNowBroken = localtime(&now);
436 strftime(buf, 11,
"%F", pNowBroken);
437 defaultCreationDate = buf;
441 if (resourceType == RIFF_TYPE_DLS || resourceType == LIST_TYPE_INS)
450 SaveString(CHUNK_ID_IART, lstINFO,
Artists, String(
""));
451 SaveString(CHUNK_ID_ICMS, lstINFO,
Commissioned, String(
""));
452 SaveString(CHUNK_ID_ICMT, lstINFO,
Comments, defaultComments);
453 SaveString(CHUNK_ID_ICOP, lstINFO,
Copyright, String(
""));
454 SaveString(CHUNK_ID_ICRD, lstINFO,
CreationDate, defaultCreationDate);
455 SaveString(CHUNK_ID_IENG, lstINFO,
Engineer, String(
""));
456 SaveString(CHUNK_ID_IGNR, lstINFO,
Genre, String(
""));
457 SaveString(CHUNK_ID_IKEY, lstINFO,
Keywords, String(
""));
458 SaveString(CHUNK_ID_IMED, lstINFO,
Medium, String(
""));
459 SaveString(CHUNK_ID_INAM, lstINFO,
Name, defaultName);
460 SaveString(CHUNK_ID_IPRD, lstINFO,
Product, String(
""));
461 SaveString(CHUNK_ID_ISBJ, lstINFO,
Subject, String(
""));
462 SaveString(CHUNK_ID_ISFT, lstINFO,
Software, defaultSoftware);
463 SaveString(CHUNK_ID_ISRC, lstINFO,
Source, String(
""));
464 SaveString(CHUNK_ID_ISRF, lstINFO,
SourceForm, String(
""));
465 SaveString(CHUNK_ID_ITCH, lstINFO,
Technician, String(
""));
505 pFixedStringLengths = orig->pFixedStringLengths;
524 pResourceList = lstResource;
541 Resource::~Resource() {
574 if (!ckDLSID) ckDLSID = pResourceList->
AddSubChunk(CHUNK_ID_DLID, 16);
577 store32(&pData[0],
pDLSID->ulData1);
578 store16(&pData[4],
pDLSID->usData2);
579 store16(&pData[6],
pDLSID->usData3);
580 memcpy(&pData[8],
pDLSID->abData, 8);
588 #if defined(WIN32) || defined(__APPLE__) || defined(HAVE_UUID_GENERATE)
598 pDLSID->ulData1 = uuid.Data1;
599 pDLSID->usData2 = uuid.Data2;
600 pDLSID->usData3 = uuid.Data3;
601 memcpy(
pDLSID->abData, uuid.Data4, 8);
603 #elif defined(__APPLE__)
605 CFUUIDRef uuidRef = CFUUIDCreate(NULL);
606 CFUUIDBytes uuid = CFUUIDGetUUIDBytes(uuidRef);
608 pDLSID->ulData1 = uuid.byte0 | uuid.byte1 << 8 | uuid.byte2 << 16 | uuid.byte3 << 24;
609 pDLSID->usData2 = uuid.byte4 | uuid.byte5 << 8;
610 pDLSID->usData3 = uuid.byte6 | uuid.byte7 << 8;
611 pDLSID->abData[0] = uuid.byte8;
612 pDLSID->abData[1] = uuid.byte9;
613 pDLSID->abData[2] = uuid.byte10;
614 pDLSID->abData[3] = uuid.byte11;
615 pDLSID->abData[4] = uuid.byte12;
616 pDLSID->abData[5] = uuid.byte13;
617 pDLSID->abData[6] = uuid.byte14;
618 pDLSID->abData[7] = uuid.byte15;
619 #elif defined(HAVE_UUID_GENERATE)
622 pDLSID->ulData1 = uuid[0] | uuid[1] << 8 | uuid[2] << 16 | uuid[3] << 24;
623 pDLSID->usData2 = uuid[4] | uuid[5] << 8;
624 pDLSID->usData3 = uuid[6] | uuid[7] << 8;
625 memcpy(
pDLSID->abData, &uuid[8], 8);
627 # error "Missing support for uuid generation"
646 pParentList = ParentList;
662 SamplerOptions = F_WSMP_NO_COMPRESSION;
665 NoSampleDepthTruncation = SamplerOptions & F_WSMP_NO_TRUNCATION;
666 NoSampleCompression = SamplerOptions & F_WSMP_NO_COMPRESSION;
669 wsmp->
SetPos(uiHeaderSize);
679 Sampler::~Sampler() {
683 void Sampler::SetGain(int32_t gain) {
698 wsmp = pParentList->
AddSubChunk(CHUNK_ID_WSMP, wsmpSize);
699 }
else if (wsmp->
GetSize() != wsmpSize) {
704 store32(&pData[0], uiHeaderSize);
706 SamplerOptions = (NoSampleDepthTruncation) ? SamplerOptions | F_WSMP_NO_TRUNCATION
707 : SamplerOptions & (~F_WSMP_NO_TRUNCATION);
708 SamplerOptions = (NoSampleCompression) ? SamplerOptions | F_WSMP_NO_COMPRESSION
709 : SamplerOptions & (~F_WSMP_NO_COMPRESSION);
710 store16(&pData[4], UnityNote);
711 store16(&pData[6], FineTune);
712 store32(&pData[8],
Gain);
713 store32(&pData[12], SamplerOptions);
718 store32(&pData[uiHeaderSize + i * 16],
pSampleLoops[i].Size);
719 store32(&pData[uiHeaderSize + i * 16 + 4],
pSampleLoops[i].LoopType);
720 store32(&pData[uiHeaderSize + i * 16 + 8],
pSampleLoops[i].LoopStart);
721 store32(&pData[uiHeaderSize + i * 16 + 12],
pSampleLoops[i].LoopLength);
771 throw Exception(
"Could not delete Sample Loop, because it does not exist");
790 UnityNote = orig->UnityNote;
791 FineTune = orig->FineTune;
793 NoSampleDepthTruncation = orig->NoSampleDepthTruncation;
794 NoSampleCompression = orig->NoSampleCompression;
795 SamplerOptions = orig->SamplerOptions;
824 pWaveList = waveList;
924 const file_offset_t restorePos = pOrig->pCkData->
GetPos();
926 for (file_offset_t todo = pOrig->
GetSize(), i = 0; todo; ) {
927 const int iReadAtOnce = 64*1024;
928 file_offset_t n = (iReadAtOnce < todo) ? iReadAtOnce : todo;
929 n = pOrig->
Read(&buf[i], n);
934 pOrig->pCkData->
SetPos(restorePos);
987 if (
FormatTag != DLS_WAVE_FORMAT_PCM)
return 0;
1020 if (
FormatTag != DLS_WAVE_FORMAT_PCM)
throw Exception(
"Sample's format is not DLS_WAVE_FORMAT_PCM");
1021 if (NewSize < 1)
throw Exception(
"Sample size must be at least one sample point");
1022 if ((NewSize >> 48) != 0)
1023 throw Exception(
"Unrealistic high DLS sample size detected");
1024 const file_offset_t sizeInBytes = NewSize *
FrameSize;
1026 if (pCkData) pCkData->
Resize(sizeInBytes);
1027 else pCkData = pWaveList->
AddSubChunk(CHUNK_ID_DATA, sizeInBytes);
1047 if (
FormatTag != DLS_WAVE_FORMAT_PCM)
return 0;
1048 if (!pCkData)
throw Exception(
"No data chunk created for sample yet, call Sample::Resize() to create one");
1049 file_offset_t orderedBytes = SampleCount *
FrameSize;
1050 file_offset_t result = pCkData->
SetPos(orderedBytes, Whence);
1051 return (result == orderedBytes) ? SampleCount
1065 if (
FormatTag != DLS_WAVE_FORMAT_PCM)
return 0;
1085 if (
FormatTag != DLS_WAVE_FORMAT_PCM)
return 0;
1086 if (
GetSize() < SampleCount)
throw Exception(
"Could not write sample data, current sample size to small");
1100 throw Exception(
"Could not save sample, only PCM format is supported");
1103 throw Exception(
"Could not save sample, there is no sample data to save");
1108 if (!pCkFormat) pCkFormat = pWaveList->
AddSubChunk(CHUNK_ID_FMT, 16);
1125 pCkRegion = rgnList;
1132 rgnh->
Read(&KeyRange, 2, 2);
1133 rgnh->
Read(&VelocityRange, 2, 2);
1138 rgnh->
Read(&Layer, 1,
sizeof(uint16_t));
1142 KeyRange.high = 127;
1143 VelocityRange.low = 0;
1144 VelocityRange.high = 127;
1145 FormatOptionFlags = F_RGN_OPTION_SELFNONEXCLUSIVE;
1149 SelfNonExclusive = FormatOptionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE;
1161 WaveLinkOptionFlags = 0;
1164 WavePoolTableIndex = 0;
1166 PhaseMaster = WaveLinkOptionFlags & F_WAVELINK_PHASE_MASTER;
1167 MultiChannel = WaveLinkOptionFlags & F_WAVELINK_MULTICHANNEL;
1198 Sample* Region::GetSample() {
1199 if (pSample)
return pSample;
1200 File* file = (
File*) GetParent()->GetParent();
1201 uint64_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
1206 if (sample->ullWavePoolOffset == soughtoffset)
return (pSample = sample);
1217 this->pSample = pSample;
1218 WavePoolTableIndex = 0;
1234 if (!pInstrument->pRegions) pInstrument->LoadRegions();
1235 if (!pInstrument->pRegions)
return;
1240 Region* prev_region = NULL;
1242 Instrument::RegionList::iterator iter = pInstrument->pRegions->begin();
1243 iter != pInstrument->pRegions->end(); iter++
1245 if ((*iter)->KeyRange.low > this->KeyRange.low) {
1249 prev_region = *iter;
1253 if (prev_region !=
this) pInstrument->MoveRegion(
this, r);
1266 if (!rgnh) rgnh = pCkRegion->
AddSubChunk(CHUNK_ID_RGNH, Layer ? 14 : 12);
1268 FormatOptionFlags = (SelfNonExclusive)
1269 ? FormatOptionFlags | F_RGN_OPTION_SELFNONEXCLUSIVE
1270 : FormatOptionFlags & (~F_RGN_OPTION_SELFNONEXCLUSIVE);
1274 store16(&pData[4], VelocityRange.
low);
1275 store16(&pData[6], VelocityRange.
high);
1276 store16(&pData[8], FormatOptionFlags);
1277 store16(&pData[10], KeyGroup);
1278 if (rgnh->
GetSize() >= 14) store16(&pData[12], Layer);
1287 if (!wlnk) wlnk = pCkRegion->
AddSubChunk(CHUNK_ID_WLNK, 12);
1289 WaveLinkOptionFlags = (PhaseMaster)
1290 ? WaveLinkOptionFlags | F_WAVELINK_PHASE_MASTER
1291 : WaveLinkOptionFlags & (~F_WAVELINK_PHASE_MASTER);
1292 WaveLinkOptionFlags = (MultiChannel)
1293 ? WaveLinkOptionFlags | F_WAVELINK_MULTICHANNEL
1294 : WaveLinkOptionFlags & (~F_WAVELINK_MULTICHANNEL);
1297 File* pFile = (
File*) GetParent()->GetParent();
1298 if (pFile->pSamples) {
1299 File::SampleList::iterator iter = pFile->pSamples->begin();
1300 File::SampleList::iterator end = pFile->pSamples->end();
1301 for (
int i = 0; iter != end; ++iter, i++) {
1302 if (*iter == pSample) {
1308 WavePoolTableIndex = index;
1310 store16(&pData[0], WaveLinkOptionFlags);
1311 store16(&pData[2], PhaseGroup);
1312 store32(&pData[4], Channel);
1313 store32(&pData[8], WavePoolTableIndex);
1332 VelocityRange = orig->VelocityRange;
1333 KeyGroup = orig->KeyGroup;
1334 Layer = orig->Layer;
1335 SelfNonExclusive = orig->SelfNonExclusive;
1336 PhaseMaster = orig->PhaseMaster;
1337 PhaseGroup = orig->PhaseGroup;
1338 MultiChannel = orig->MultiChannel;
1339 Channel = orig->Channel;
1342 if (GetParent()->GetParent() == orig->GetParent()->GetParent()) {
1343 WavePoolTableIndex = orig->WavePoolTableIndex;
1344 pSample = orig->pSample;
1346 WavePoolTableIndex = -1;
1349 FormatOptionFlags = orig->FormatOptionFlags;
1350 WaveLinkOptionFlags = orig->WaveLinkOptionFlags;
1373 pCkInstrument = insList;
1375 midi_locale_t locale;
1381 insh->
Read(&locale, 2, 4);
1385 locale.instrument = 0;
1389 IsDrum = locale.bank & DRUM_TYPE_MASK;
1403 if (!pRegions) LoadRegions();
1404 if (!pRegions)
return 0;
1405 return pRegions->size();
1419 if (!pRegions) LoadRegions();
1420 if (!pRegions)
return NULL;
1421 if (pos >= pRegions->size())
return NULL;
1422 return (*pRegions)[pos];
1435 if (!pRegions) LoadRegions();
1436 if (!pRegions)
return NULL;
1437 RegionsIterator = pRegions->begin();
1438 return (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL;
1452 if (!pRegions)
return NULL;
1454 return (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL;
1457 void Instrument::LoadRegions() {
1458 if (!pRegions) pRegions =
new RegionList;
1461 uint32_t regionCkType = (lrgn->
GetSubList(LIST_TYPE_RGN2)) ? LIST_TYPE_RGN2 : LIST_TYPE_RGN;
1466 if (rgn->GetListType() == regionCkType) {
1467 pRegions->push_back(
new Region(
this, rgn));
1473 Region* Instrument::AddRegion() {
1474 if (!pRegions) LoadRegions();
1476 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
1478 Region* pNewRegion =
new Region(
this, rgn);
1479 const size_t idxIt = RegionsIterator - pRegions->begin();
1480 pRegions->push_back(pNewRegion);
1481 RegionsIterator = pRegions->begin() + std::min(idxIt, pRegions->size());
1482 Regions = (uint32_t) pRegions->size();
1486 void Instrument::MoveRegion(Region* pSrc, Region* pDst) {
1489 for (
size_t i = 0; i < pRegions->size(); ++i) {
1490 if ((*pRegions)[i] == pSrc) {
1491 const size_t idxIt = RegionsIterator - pRegions->begin();
1492 pRegions->erase(pRegions->begin() + i);
1493 RegionList::iterator iter = find(pRegions->begin(), pRegions->end(), pDst);
1494 pRegions->insert(iter, pSrc);
1495 RegionsIterator = pRegions->begin() + std::min(idxIt, pRegions->size());
1500 void Instrument::DeleteRegion(Region* pRegion) {
1501 if (!pRegions)
return;
1502 RegionList::iterator iter = find(pRegions->begin(), pRegions->end(), pRegion);
1503 if (iter == pRegions->end())
return;
1504 const size_t idxIt = RegionsIterator - pRegions->begin();
1505 pRegions->erase(iter);
1506 RegionsIterator = pRegions->begin() + std::min(idxIt, pRegions->size());
1507 Regions = (uint32_t) pRegions->size();
1508 pRegion->DeleteChunks();
1525 if (!insh) insh = pCkInstrument->
AddSubChunk(CHUNK_ID_INSH, 12);
1528 Regions = (pRegions) ? uint32_t(pRegions->size()) : 0;
1529 midi_locale_t locale;
1532 locale.bank = (
IsDrum) ? locale.bank | DRUM_TYPE_MASK : locale.bank & (~DRUM_TYPE_MASK);
1535 store32(&pData[4], locale.bank);
1536 store32(&pData[8], locale.instrument);
1538 if (!pRegions)
return;
1539 RegionList::iterator iter = pRegions->begin();
1540 RegionList::iterator end = pRegions->end();
1541 for (
int i = 0; iter != end; ++iter, ++i) {
1545 __divide_progress(pProgress, &subprogress, pRegions->size(), i);
1547 (*iter)->UpdateChunks(&subprogress);
1549 (*iter)->UpdateChunks(NULL);
1552 __notify_progress(pProgress, 1.0);
1561 RegionList::iterator iter = pRegions->begin();
1562 RegionList::iterator end = pRegions->end();
1563 while (iter != end) {
1582 RegionList::iterator it = pRegions->begin();
1583 RegionList::iterator end = pRegions->end();
1584 for (; it != end; ++it)
1585 (*it)->DeleteChunks();
1589 if (pCkInstrument) {
1592 pCkInstrument = NULL;
1596 void Instrument::CopyAssignCore(
const Instrument* orig) {
1619 CopyAssignCore(orig);
1624 RegionList::const_iterator it = orig->pRegions->begin();
1625 for (
int i = 0; i < orig->
Regions; ++i, ++it) {
1626 Region* dstRgn = AddRegion();
1654 pWavePoolTable = NULL;
1655 pWavePoolTableHi = NULL;
1656 WavePoolHeaderSize = 8;
1659 pInstruments = NULL;
1661 b64BitWavePoolOffsets =
false;
1674 if (!pRIFF)
throw DLS::Exception(
"NULL pointer reference to RIFF::File object.");
1675 this->pRIFF = pRIFF;
1687 if (!colh)
throw DLS::Exception(
"Mandatory chunks in RIFF list chunk not found.");
1694 pWavePoolTable = NULL;
1695 pWavePoolTableHi = NULL;
1696 WavePoolHeaderSize = 8;
1697 b64BitWavePoolOffsets =
false;
1703 pWavePoolTable =
new uint32_t[WavePoolCount];
1704 pWavePoolTableHi =
new uint32_t[WavePoolCount];
1705 ptbl->
SetPos(WavePoolHeaderSize);
1708 b64BitWavePoolOffsets = (ptbl->
GetSize() - WavePoolHeaderSize == WavePoolCount * 8);
1709 if (b64BitWavePoolOffsets) {
1710 for (
int i = 0 ; i < WavePoolCount ; i++) {
1718 ptbl->
Read(pWavePoolTable, WavePoolCount,
sizeof(uint32_t));
1719 for (
int i = 0 ; i < WavePoolCount ; i++) pWavePoolTableHi[i] = 0;
1724 pInstruments = NULL;
1729 InstrumentList::iterator iter = pInstruments->begin();
1730 InstrumentList::iterator end = pInstruments->end();
1731 while (iter != end) {
1735 delete pInstruments;
1739 SampleList::iterator iter = pSamples->begin();
1740 SampleList::iterator end = pSamples->end();
1741 while (iter != end) {
1748 if (pWavePoolTable)
delete[] pWavePoolTable;
1749 if (pWavePoolTableHi)
delete[] pWavePoolTableHi;
1751 for (std::list<RIFF::File*>::iterator i = ExtensionFiles.begin() ; i != ExtensionFiles.end() ; i++)
1764 if (!pSamples) LoadSamples();
1765 if (!pSamples)
return NULL;
1766 if (index >= pSamples->size())
return NULL;
1767 return (*pSamples)[index];
1778 if (!pSamples) LoadSamples();
1779 if (!pSamples)
return NULL;
1780 SamplesIterator = pSamples->begin();
1781 return (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL;
1792 if (!pSamples)
return NULL;
1794 return (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL;
1797 void File::LoadSamples() {
1798 if (!pSamples) pSamples =
new SampleList;
1801 file_offset_t wvplFileOffset = wvpl->
GetFilePos() -
1807 if (wave->GetListType() == LIST_TYPE_WAVE) {
1808 file_offset_t waveFileOffset = wave->GetFilePos() -
1810 pSamples->push_back(
new Sample(
this, wave, waveFileOffset - wvplFileOffset));
1823 if (wave->GetListType() == LIST_TYPE_WAVE) {
1826 pSamples->push_back(
new Sample(
this, wave, waveFileOffset - dwplFileOffset));
1842 if (!pSamples) LoadSamples();
1843 if (!pSamples)
return 0;
1844 return pSamples->size();
1855 if (!pSamples) LoadSamples();
1861 const size_t idxIt = SamplesIterator - pSamples->begin();
1862 pSamples->push_back(pSample);
1863 SamplesIterator = pSamples->begin() + std::min(idxIt, pSamples->size());
1875 if (!pSamples)
return;
1876 SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), pSample);
1877 if (iter == pSamples->end())
return;
1878 const size_t idxIt = SamplesIterator - pSamples->begin();
1879 pSamples->erase(iter);
1880 SamplesIterator = pSamples->begin() + std::min(idxIt, pSamples->size());
1893 if (!pInstruments) LoadInstruments();
1894 if (!pInstruments)
return NULL;
1895 if (index >= pInstruments->size())
return NULL;
1896 return (*pInstruments)[index];
1907 if (!pInstruments) LoadInstruments();
1908 if (!pInstruments)
return NULL;
1909 InstrumentsIterator = pInstruments->begin();
1910 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1921 if (!pInstruments)
return NULL;
1922 InstrumentsIterator++;
1923 return (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL;
1926 void File::LoadInstruments() {
1927 if (!pInstruments) pInstruments =
new InstrumentList;
1929 if (lstInstruments) {
1932 lstInstr; lstInstr = lstInstruments->
GetSubListAt(++i))
1934 if (lstInstr->GetListType() == LIST_TYPE_INS) {
1935 pInstruments->push_back(
new Instrument(
this, lstInstr));
1949 if (!pInstruments) LoadInstruments();
1954 const size_t idxIt = InstrumentsIterator - pInstruments->begin();
1955 pInstruments->push_back(pInstrument);
1956 InstrumentsIterator = pInstruments->begin() + std::min(idxIt, pInstruments->size());
1968 if (!pInstruments)
return;
1969 InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), pInstrument);
1970 if (iter == pInstruments->end())
return;
1971 const size_t idxIt = InstrumentsIterator - pInstruments->begin();
1972 pInstruments->erase(iter);
1973 InstrumentsIterator = pInstruments->begin() + std::min(idxIt, pInstruments->size());
1999 if (index < 0 || index >= ExtensionFiles.size())
return NULL;
2000 std::list<RIFF::File*>::iterator iter = ExtensionFiles.begin();
2001 for (
int i = 0; iter != ExtensionFiles.end(); ++iter, ++i)
2002 if (i == index)
return *iter;
2016 return pRIFF->GetFileName();
2024 pRIFF->SetFileName(name);
2042 if (!ckVersion) ckVersion = pRIFF->
AddSubChunk(CHUNK_ID_VERS, 8);
2044 store16(&pData[0],
pVersion->minor);
2045 store16(&pData[2],
pVersion->major);
2046 store16(&pData[4],
pVersion->build);
2047 store16(&pData[6],
pVersion->release);
2051 Instruments = (pInstruments) ? uint32_t(pInstruments->size()) : 0;
2053 if (!colh) colh = pRIFF->
AddSubChunk(CHUNK_ID_COLH, 4);
2062 __divide_progress(pProgress, &subprogress, 20.f, 0.f);
2065 InstrumentList::iterator iter = pInstruments->begin();
2066 InstrumentList::iterator end = pInstruments->end();
2067 for (
int i = 0; iter != end; ++iter, ++i) {
2070 __divide_progress(&subprogress, &subsubprogress, pInstruments->size(), i);
2072 (*iter)->UpdateChunks(&subsubprogress);
2075 __notify_progress(&subprogress, 1.0);
2077 InstrumentList::iterator iter = pInstruments->begin();
2078 InstrumentList::iterator end = pInstruments->end();
2079 for (
int i = 0; iter != end; ++iter, ++i) {
2080 (*iter)->UpdateChunks(NULL);
2086 const int iSamples = (pSamples) ?
int(pSamples->size()) : 0;
2087 int iPtblOffsetSize = (b64BitWavePoolOffsets) ? 8 : 4;
2089 if (!ptbl) ptbl = pRIFF->
AddSubChunk(CHUNK_ID_PTBL, 1 );
2090 int iPtblSize = WavePoolHeaderSize + iPtblOffsetSize * iSamples;
2093 WavePoolCount = iSamples;
2094 store32(&pData[4], WavePoolCount);
2096 memset(&pData[WavePoolHeaderSize], 0, iPtblSize - WavePoolHeaderSize);
2103 __divide_progress(pProgress, &subprogress, 20.f, 1.f);
2106 SampleList::iterator iter = pSamples->begin();
2107 SampleList::iterator end = pSamples->end();
2108 for (
int i = 0; iter != end; ++iter, ++i) {
2111 __divide_progress(&subprogress, &subsubprogress, pSamples->size(), i);
2113 (*iter)->UpdateChunks(&subsubprogress);
2116 __notify_progress(&subprogress, 1.0);
2118 SampleList::iterator iter = pSamples->begin();
2119 SampleList::iterator end = pSamples->end();
2120 for (
int i = 0; iter != end; ++iter, ++i) {
2121 (*iter)->UpdateChunks(NULL);
2130 std::list<RIFF::File*> poolFiles;
2132 if (!ExtensionFiles.empty()) {
2133 std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();
2134 for (; it != ExtensionFiles.end(); ++it) {
2140 const std::string oldName = (*it)->GetFileName();
2141 const bool isGigaPulseFile = (extensionOfPath(oldName) ==
"gx99");
2142 if (isGigaPulseFile)
2143 pGigaPulseFile = *it;
2145 poolFiles.push_back(*it);
2151 if (!poolFiles.empty()) {
2152 const int n = poolFiles.size();
2153 const int iHeaderSize = 4;
2154 const int iEntrySize = 144;
2159 ckXfil->
Resize(iHeaderSize + n * iEntrySize);
2161 ckXfil = pRIFF->
AddSubChunk(CHUNK_ID_XFIL, iHeaderSize + n * iEntrySize);
2167 std::list<RIFF::File*>::iterator itExtFile = poolFiles.begin();
2168 for (
int i = 0, iOffset = 4; i < n;
2169 ++itExtFile, ++i, iOffset += iEntrySize)
2172 std::string file = lastPathComponent(
2173 (*itExtFile)->GetFileName()
2175 if (file.length() + 6 > 128)
2176 throw Exception(
"Fatal error, extension filename length exceeds 122 byte maximum");
2177 uint8_t* pStrings = &pData[iOffset];
2178 memset(pStrings, 0, 128);
2179 memcpy(pStrings, file.c_str(), file.length());
2180 pStrings += file.length() + 1;
2181 std::string ext = file.substr(file.length()-5);
2182 memcpy(pStrings, ext.c_str(), 5);
2184 uint8_t* pId = &pData[iOffset + 128];
2186 RIFF::Chunk* ckDLSID = (*itExtFile)->GetSubChunk(CHUNK_ID_DLID);
2188 ckDLSID->
Read(&
id.ulData1, 1, 4);
2189 ckDLSID->
Read(&
id.usData2, 1, 2);
2190 ckDLSID->
Read(&
id.usData3, 1, 2);
2191 ckDLSID->
Read(
id.abData, 8, 1);
2193 ckDLSID = (*itExtFile)->AddSubChunk(CHUNK_ID_DLID, 16);
2196 store32(&pData[0],
id.ulData1);
2197 store16(&pData[4],
id.usData2);
2198 store16(&pData[6],
id.usData3);
2199 memcpy(&pData[8],
id.abData, 8);
2201 store32(&pId[0],
id.ulData1);
2202 store16(&pId[4],
id.usData2);
2203 store16(&pId[6],
id.usData3);
2204 memcpy(&pId[8],
id.abData, 8);
2214 if (pGigaPulseFile) {
2216 if (!ckDoxf) ckDoxf = pRIFF->
AddSubChunk(CHUNK_ID_DOXF, 148);
2221 uint8_t* pId = &pData[132];
2224 throw Exception(
"Fatal error, GigaPulse file does not contain a DLS ID chunk");
2229 id.ulData1 = load32(&pData[0]);
2230 id.usData2 = load16(&pData[4]);
2231 id.usData3 = load16(&pData[6]);
2232 memcpy(
id.abData, &pData[8], 8);
2234 store32(&pId[0],
id.ulData1);
2235 store16(&pId[4],
id.usData2);
2236 store16(&pId[6],
id.usData3);
2237 memcpy(&pId[8],
id.abData, 8);
2250 const bool bRequires64Bit = (finalFileSize >> 32) != 0 ||
2251 poolFiles.size() > 0;
2252 if (b64BitWavePoolOffsets != bRequires64Bit) {
2253 b64BitWavePoolOffsets = bRequires64Bit;
2254 iPtblOffsetSize = (b64BitWavePoolOffsets) ? 8 : 4;
2255 iPtblSize = WavePoolHeaderSize + iPtblOffsetSize * iSamples;
2260 __notify_progress(pProgress, 1.0);
2279 const size_t nExtFiles = ExtensionFiles.size();
2280 const float tasks = nExtFiles + 1.f;
2283 if (!ExtensionFiles.empty()) {
2285 const std::string baseName = pathWithoutExtension(Path);
2287 std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();
2288 for (
int i = 0; it != ExtensionFiles.end(); ++i, ++it) {
2294 const std::string oldName = (*it)->GetFileName();
2295 const bool isGigaPulseFile = (extensionOfPath(oldName) ==
"gx99");
2296 std::string ext = (isGigaPulseFile) ?
".gx99" : strPrint(
".gx%02d", i+1);
2297 std::string newPath = baseName + ext;
2302 __divide_progress(pProgress, &subprogress, tasks,
float(i));
2304 (*it)->Save(newPath, &subprogress);
2306 (*it)->Save(newPath);
2312 __divide_progress(pProgress, &subprogress, tasks, nExtFiles);
2317 __divide_progress(&subprogress, &subsubprogress, 1.f, 0.f, 0.05f);
2326 __divide_progress(&subprogress, &subsubprogress, 1.f, 0.05f, 1.f);
2328 pRIFF->
Save(Path, &subsubprogress);
2335 __notify_progress(pProgress, 1.0);
2350 const size_t nExtFiles = ExtensionFiles.size();
2351 const float tasks = nExtFiles + 1.f;
2354 if (!ExtensionFiles.empty()) {
2355 std::list<RIFF::File*>::iterator it = ExtensionFiles.begin();
2356 for (
int i = 0; it != ExtensionFiles.end(); ++i, ++it) {
2361 __divide_progress(pProgress, &subprogress, tasks,
float(i));
2363 (*it)->Save(&subprogress);
2371 __divide_progress(pProgress, &subprogress, tasks, nExtFiles);
2376 __divide_progress(&subprogress, &subsubprogress, 1.f, 0.f, 0.05f);
2385 __divide_progress(&subprogress, &subsubprogress, 1.f, 0.05f, 1.f);
2387 pRIFF->
Save(&subsubprogress);
2394 __notify_progress(pProgress, 1.0);
2408 __UpdateWavePoolTableChunk();
2419 if (!lstInstruments) pRIFF->
AddSubList(LIST_TYPE_LINS);
2423 const int iOffsetSize = (b64BitWavePoolOffsets) ? 8 : 4;
2424 ptbl = pRIFF->
AddSubChunk(CHUNK_ID_PTBL, WavePoolHeaderSize + iOffsetSize);
2428 if (!wvpl) pRIFF->
AddSubList(LIST_TYPE_WVPL);
2440 void File::__UpdateWavePoolTableChunk() {
2441 __UpdateWavePoolTable();
2443 const int iOffsetSize = (b64BitWavePoolOffsets) ? 8 : 4;
2445 WavePoolCount = (pSamples) ? uint32_t(pSamples->size()) : 0;
2446 const file_offset_t ulRequiredSize = WavePoolHeaderSize + iOffsetSize * WavePoolCount;
2447 if (ptbl->
GetSize() < ulRequiredSize)
throw Exception(
"Fatal error, 'ptbl' chunk too small");
2449 file_offset_t ullOriginalPos = ptbl->
GetPos();
2452 uint32_t tmp = WavePoolHeaderSize;
2454 tmp = WavePoolCount;
2457 ptbl->
SetPos(WavePoolHeaderSize);
2458 if (b64BitWavePoolOffsets) {
2459 for (
int i = 0 ; i < WavePoolCount ; i++) {
2460 tmp = pWavePoolTableHi[i];
2462 tmp = pWavePoolTable[i];
2466 for (
int i = 0 ; i < WavePoolCount ; i++) {
2467 tmp = pWavePoolTable[i];
2472 ptbl->
SetPos(ullOriginalPos);
2480 void File::__UpdateWavePoolTable() {
2481 WavePoolCount = (pSamples) ? uint32_t(pSamples->size()) : 0;
2483 if (pWavePoolTable)
delete[] pWavePoolTable;
2484 if (pWavePoolTableHi)
delete[] pWavePoolTableHi;
2485 pWavePoolTable =
new uint32_t[WavePoolCount];
2486 pWavePoolTableHi =
new uint32_t[WavePoolCount];
2487 if (!pSamples)
return;
2490 uint64_t wvplFileOffset = wvpl->
GetFilePos() -
2492 if (!b64BitWavePoolOffsets) {
2493 SampleList::iterator iter = pSamples->begin();
2494 SampleList::iterator end = pSamples->end();
2495 for (
int i = 0 ; iter != end ; ++iter, i++) {
2496 uint64_t _64BitOffset =
2497 (*iter)->pWaveList->GetFilePos() -
2498 (*iter)->pWaveList->GetPos() -
2501 (*iter)->ullWavePoolOffset = _64BitOffset;
2502 pWavePoolTable[i] = (uint32_t) _64BitOffset;
2505 if (ExtensionFiles.empty()) {
2506 SampleList::iterator iter = pSamples->begin();
2507 SampleList::iterator end = pSamples->end();
2508 for (
int i = 0 ; iter != end ; ++iter, i++) {
2509 uint64_t _64BitOffset =
2510 (*iter)->pWaveList->GetFilePos() -
2511 (*iter)->pWaveList->GetPos() -
2514 (*iter)->ullWavePoolOffset = _64BitOffset;
2515 pWavePoolTableHi[i] = (uint32_t) (_64BitOffset >> 32);
2516 pWavePoolTable[i] = (uint32_t) _64BitOffset;
2520 std::vector<RIFF::File*> poolFiles;
2521 poolFiles.push_back(pRIFF);
2522 poolFiles.insert(poolFiles.end(), ExtensionFiles.begin(), ExtensionFiles.end());
2527 SampleList::iterator iter = pSamples->begin();
2528 SampleList::iterator end = pSamples->end();
2529 for (
int i = 0 ; iter != end ; ++iter, i++) {
2533 if (pPoolFile != pCurPoolFile) {
2534 pCurPoolFile = pPoolFile;
2536 std::vector<RIFF::File*>::iterator sIter;
2537 sIter = std::find(poolFiles.begin(), poolFiles.end(), pPoolFile);
2538 if (sIter != poolFiles.end())
2539 fileNo = std::distance(poolFiles.begin(), sIter);
2545 throw DLS::Exception(
"Fatal error, pool file has no 'wvpl' list chunk");
2551 uint64_t _64BitOffset =
2552 (*iter)->pWaveList->GetFilePos() -
2553 (*iter)->pWaveList->GetPos() -
2556 pWavePoolTableHi[i] = (uint32_t) fileNo;
2557 pWavePoolTable[i] = (uint32_t) _64BitOffset;
2558 (*iter)->ullWavePoolOffset = _64BitOffset;
2568 Exception::Exception() :
RIFF::Exception() {
2571 Exception::Exception(String format, ...) :
RIFF::Exception() {
2573 va_start(arg, format);
2574 Message = assemble(format, arg);
2578 Exception::Exception(String format, va_list arg) :
RIFF::Exception() {
2579 Message = assemble(format, arg);
2582 void Exception::PrintMessage() {
2583 std::cout <<
"DLS::Exception: " << Message << std::endl;
Provides access to the defined connections used for the synthesis model.
Connection * pConnections
Points to the beginning of a Connection array.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Articulation object.
virtual void UpdateChunks(progress_t *pProgress)
Apply articulation connections to the respective RIFF chunks.
uint32_t Connections
Reflects the number of Connections.
Articulation(RIFF::Chunk *artl)
Constructor.
Abstract base class for classes that provide articulation information (thus for Instrument and Region...
virtual void UpdateChunks(progress_t *pProgress)
Apply all articulations to the respective RIFF chunks.
Articulation * GetNextArticulation()
Returns the next Articulation from the list of articulations.
Articulation * GetFirstArticulation()
Returns the first Articulation in the list of articulations.
Articulation * GetArticulation(size_t pos)
Returns Articulation at supplied pos position within the articulation list.
virtual void CopyAssign(const Articulator *orig)
Not yet implemented in this version, since the .gig format does not need to copy DLS articulators and...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Articulator object.
Defines a connection within the synthesis model.
Will be thrown whenever a DLS specific error occurs while trying to access a DLS File.
Parses DLS Level 1 and 2 compliant files and provides abstract access to the data.
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL.
Instrument * AddInstrument()
Add a new instrument definition.
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file's current instruments, samples and settings to the respective RIFF chunks.
void __ensureMandatoryChunksExist()
Checks if all (for DLS) mandatory chunks exist, if not they will be created.
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
Sample * GetSample(size_t index)
Returns Sample object of index.
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
void SetFileName(const String &name)
You may call this method store a future file name, so you don't have to to pass it to the Save() call...
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
uint32_t Instruments
Reflects the number of available Instrument objects.
virtual void Save(const String &Path, progress_t *pProgress=NULL)
Save changes to another file.
Instrument * GetInstrument(size_t index)
Returns the instrument with the given index from the list of instruments of this file.
bool bOwningRiff
If true then pRIFF was implicitly allocated by this class and hence pRIFF will automatically be freed...
size_t CountSamples()
Returns the total amount of samples of this DLS file.
void DeleteSample(Sample *pSample)
Delete a sample.
RIFF::File * GetRiffFile()
Returns the underlying RIFF::File used for persistency of this DLS::File object.
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
Sample * AddSample()
Add a new sample.
RIFF::File * GetExtensionFile(int index)
Returns extension file of given index.
String GetFileName()
File name of this DLS file.
Optional information for DLS files, instruments, samples, etc.
String Subject
<ISBJ-ck>. Describes the contents of the file.
String Genre
<IGNR-ck>. Descirbes the original work, such as, Jazz, Classic, Rock, Techno, Rave,...
String Keywords
<IKEY-ck>. Provides a list of keywords that refer to the file or subject of the file....
String SourceForm
<ISRF-ck>. Identifies the original form of the material that was digitized, such as record,...
String Comments
<ICMT-ck>. Provides general comments about the file or the subject of the file. Sentences might end w...
String Medium
<IMED-ck>. Describes the original subject of the file, such as, record, CD, and so forth.
void SetFixedStringLengths(const string_length_t *lengths)
Forces specific Info fields to be of a fixed length when being saved to a file.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Info object.
Info(RIFF::List *list)
Constructor.
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
String Artists
<IART-ck>. Lists the artist of the original subject of the file.
String Product
<IPRD-ck>. Specifies the name of the title the file was originally intended for, such as World Ruler ...
virtual void CopyAssign(const Info *orig)
Make a deep copy of the Info object given by orig and assign it to this object.
String Name
<INAM-ck>. Stores the title of the subject of the file, such as, Seattle From Above.
String CreationDate
<ICRD-ck>. Specifies the date the subject of the file was created. List dates in yyyy-mm-dd format.
String ArchivalLocation
<IARL-ck>. Indicates where the subject of the file is stored.
String Engineer
<IENG-ck>. Stores the name of the engineer who worked on the file. Multiple engineer names are separa...
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current info values.
String Commissioned
<ICMS-ck>. Lists the name of the person or organization that commissioned the subject of the file,...
String Copyright
<ICOP-ck>. Records the copyright information for the file.
String Source
<ISRC-ck>. Identifies the name of the person or organization who supplied the original subject of the...
String Technician
<ITCH-ck>. Identifies the technician who sampled the subject file.
Provides all neccessary information for the synthesis of a DLS Instrument.
virtual ~Instrument()
Destructor.
virtual void CopyAssign(const Instrument *orig)
Make a (semi) deep copy of the Instrument object given by orig and assign it to this object.
uint8_t MIDIBankFine
Reflects the MIDI Bank number for MIDI Control Change 32 (bank 1 - 128).
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Instrument object.
Region * GetFirstRegion()
Returns the first Region of the instrument.
Region * GetNextRegion()
Returns the next Region of the instrument.
uint8_t MIDIBankCoarse
Reflects the MIDI Bank number for MIDI Control Change 0 (bank 1 - 128).
bool IsDrum
Indicates if the Instrument is a drum type, as they differ in the synthesis model of DLS from melodic...
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
uint16_t MIDIBank
Reflects combination of MIDIBankCoarse and MIDIBankFine (bank 1 - bank 16384). Do not change this val...
Instrument(File *pFile, RIFF::List *insList)
Constructor.
uint32_t MIDIProgram
Specifies the MIDI Program Change Number this Instrument should be assigned to.
Region * GetRegionAt(size_t pos)
Returns Region at supplied pos position within the region list of this instrument.
size_t CountRegions()
Returns the amount of regions of this instrument.
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Defines Region information of an Instrument.
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
virtual ~Region()
Destructor.
void SetSample(Sample *pSample)
Assign another sample to this Region.
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Region object.
Abstract base class which encapsulates data structures which all DLS resources are able to provide.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Resource object.
Resource(Resource *Parent, RIFF::List *lstResource)
Constructor.
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
dlsid_t * pDLSID
Points to a dlsid_t structure if the file provided a DLS ID else is NULL.
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current Resource data.
void GenerateDLSID()
Generates a new DLSID for the resource.
virtual void CopyAssign(const Resource *orig)
Make a deep copy of the Resource object given by orig and assign it to this object.
Encapsulates sample waves used for playback.
file_offset_t Read(void *pBuffer, file_offset_t SampleCount)
Reads SampleCount number of sample points from the current position into the buffer pointed by pBuffe...
void ReleaseSampleData()
Free sample data from RAM.
void CopyAssignCore(const Sample *orig)
Make a deep copy of the Sample object given by orig (without the actual sample waveform data however)...
uint16_t BlockAlign
The block alignment (in bytes) of the waveform data. Playback software needs to process a multiple of...
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
void Resize(file_offset_t NewSize)
Resize sample.
file_offset_t SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence=RIFF::stream_start)
Sets the position within the sample (in sample points, not in bytes).
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
virtual void CopyAssign(const Sample *orig)
Make a deep copy of the Sample object given by orig and assign it to this object.
void * LoadSampleData()
Load sample data into RAM.
uint16_t Channels
Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mon...
file_offset_t GetSize() const
Returns sample size.
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise),...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Sample object.
uint16_t FormatTag
Format ID of the waveform data (should be DLS_WAVE_FORMAT_PCM for DLS1 compliant files,...
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used,...
uint32_t AverageBytesPerSecond
The average number of bytes per second at which the waveform data should be transferred (Playback sof...
virtual ~Sample()
Destructor.
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset)
Constructor.
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
Abstract base class which provides mandatory informations about sample players in general.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Sampler object.
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
virtual void CopyAssign(const Sampler *orig)
Make a deep copy of the Sampler object given by orig and assign it to this object.
void AddSampleLoop(sample_loop_t *pLoopDef)
Adds a new sample loop with the provided loop definition.
uint32_t SampleLoops
Reflects the number of sample loops.
sample_loop_t * pSampleLoops
Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
void DeleteSampleLoop(sample_loop_t *pLoopDef)
Deletes an existing sample loop.
void Resize(file_offset_t NewSize)
Resize chunk.
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 GetFilePos() const
Current, actual offset in file of current chunk data body read/write position.
void ReleaseChunkData()
Free loaded chunk body from RAM.
file_offset_t Write(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Writes WordCount number of data words with given WordSize from the buffer pointed by pData.
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
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 ReadUint16(uint16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit unsigned integer words and copies it into the buffer pointed by pDat...
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 ReadInt16(int16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit signed integer words and copies it into the buffer pointed by pData.
uint32_t GetChunkID() const
Chunk ID in unsigned integer representation.
void * LoadChunkData()
Load chunk body into RAM.
file_offset_t ReadInt32(int32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit signed integer words and copies it into the buffer pointed by pData.
List * GetParent() const
Returns pointer to the chunk's parent list chunk.
file_offset_t WriteUint32(uint32_t *pData, file_offset_t WordCount=1)
Writes WordCount number of 32 Bit unsigned integer words from the buffer pointed by pData to the chun...
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.
int GetFileOffsetSize() const
Returns the current size (in bytes) of file offsets stored in the headers of all chunks of this file.
void SetByteOrder(endian_t Endian)
Set the byte order to be used when saving.
file_offset_t GetRequiredFileSize()
Returns the required size (in bytes) for this RIFF File to be saved to disk.
virtual void Save(progress_t *pProgress=NULL)
Save changes to same file.
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
List * GetSubListAt(size_t pos)
Returns sublist chunk with list type ListType at supplied pos position among all subchunks of type Li...
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
uint32_t GetListType() const
Returns unsigned integer representation of the list's ID.
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
Chunk * GetSubChunkAt(size_t pos)
Returns subchunk at supplied pos position within this chunk list.
DLS specific classes and definitions.
String libraryName()
Returns the name of this C++ library.
String libraryVersion()
Returns version of this C++ library.
conn_src_t
Connection Sources.
conn_dst_t
Connection Destinations.
conn_trn_t
Connection Transforms.
RIFF specific classes and definitions.
stream_whence_t
File stream position dependent to these relations.
uint64_t file_offset_t
Type used by libgig for handling file positioning during file I/O tasks.
Every subject of an DLS file and the file itself can have an unique, computer generated ID.
uint16_t low
Low value of range.
uint16_t high
High value of range.
Defines Sample Loop Points.
uint32_t Size
For internal usage only: usually reflects exactly sizeof(sample_loop_t), otherwise if the value is la...
Quadtuple version number ("major.minor.release.build").
Used for indicating the progress of a certain task.