27 #include "Serialization.h" 36 #define GIG_FILE_EXT_VERSION 2 43 #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB 46 #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x)) 47 #define GIG_EXP_ENCODE(x) (log(x) / log(1.000000008813822)) 48 #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01)) 49 #define GIG_PITCH_TRACK_ENCODE(x) ((x) ? 0x00 : 0x01) 50 #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03) 51 #define GIG_VCF_RESONANCE_CTRL_ENCODE(x) ((x & 0x03) << 4) 52 #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03) 53 #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03) 54 #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03) 55 #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x) ((x & 0x03) << 1) 56 #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x) ((x & 0x03) << 3) 57 #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x) ((x & 0x03) << 5) 59 #define SRLZ(member) \ 60 archive->serializeMember(*this, member, #member); 69 inline int get12lo(
const unsigned char* pSrc)
71 const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
72 return x & 0x800 ? x - 0x1000 : x;
75 inline int get12hi(
const unsigned char* pSrc)
77 const int x = pSrc[1] >> 4 | pSrc[2] << 4;
78 return x & 0x800 ? x - 0x1000 : x;
81 inline int16_t get16(
const unsigned char* pSrc)
83 return int16_t(pSrc[0] | pSrc[1] << 8);
86 inline int get24(
const unsigned char* pSrc)
88 const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
89 return x & 0x800000 ? x - 0x1000000 : x;
92 inline void store24(
unsigned char* pDst,
int x)
99 void Decompress16(
int compressionmode,
const unsigned char* params,
100 int srcStep,
int dstStep,
101 const unsigned char* pSrc, int16_t* pDst,
102 file_offset_t currentframeoffset,
103 file_offset_t copysamples)
105 switch (compressionmode) {
107 pSrc += currentframeoffset * srcStep;
108 while (copysamples) {
117 int y = get16(params);
118 int dy = get16(params + 2);
119 while (currentframeoffset) {
123 currentframeoffset--;
125 while (copysamples) {
137 void Decompress24(
int compressionmode,
const unsigned char* params,
138 int dstStep,
const unsigned char* pSrc, uint8_t* pDst,
139 file_offset_t currentframeoffset,
140 file_offset_t copysamples,
int truncatedBits)
142 int y, dy, ddy, dddy;
144 #define GET_PARAMS(params) \ 146 dy = y - get24((params) + 3); \ 147 ddy = get24((params) + 6); \ 148 dddy = get24((params) + 9) 150 #define SKIP_ONE(x) \ 156 #define COPY_ONE(x) \ 158 store24(pDst, y << truncatedBits); \ 161 switch (compressionmode) {
163 pSrc += currentframeoffset * 3;
164 while (copysamples) {
165 store24(pDst, get24(pSrc) << truncatedBits);
174 while (currentframeoffset) {
175 SKIP_ONE(get16(pSrc));
177 currentframeoffset--;
179 while (copysamples) {
180 COPY_ONE(get16(pSrc));
188 while (currentframeoffset > 1) {
189 SKIP_ONE(get12lo(pSrc));
190 SKIP_ONE(get12hi(pSrc));
192 currentframeoffset -= 2;
194 if (currentframeoffset) {
195 SKIP_ONE(get12lo(pSrc));
196 currentframeoffset--;
198 COPY_ONE(get12hi(pSrc));
203 while (copysamples > 1) {
204 COPY_ONE(get12lo(pSrc));
205 COPY_ONE(get12hi(pSrc));
210 COPY_ONE(get12lo(pSrc));
216 while (currentframeoffset) {
217 SKIP_ONE(int8_t(*pSrc++));
218 currentframeoffset--;
220 while (copysamples) {
221 COPY_ONE(int8_t(*pSrc++));
228 const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
229 const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
230 const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
231 const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
239 static uint32_t* __initCRCTable() {
240 static uint32_t res[256];
242 for (
int i = 0 ; i < 256 ; i++) {
244 for (
int j = 0 ; j < 8 ; j++) {
245 c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
252 static const uint32_t* __CRCTable = __initCRCTable();
259 inline static void __resetCRC(uint32_t& crc) {
282 static void __calculateCRC(
unsigned char* buf,
size_t bufSize, uint32_t& crc) {
283 for (
size_t i = 0 ; i < bufSize ; i++) {
284 crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
293 inline static void __finalizeCRC(uint32_t& crc) {
302 static split_type_t __resolveSplitType(dimension_t dimension) {
304 dimension == dimension_layer ||
305 dimension == dimension_samplechannel ||
306 dimension == dimension_releasetrigger ||
307 dimension == dimension_keyboard ||
308 dimension == dimension_roundrobin ||
309 dimension == dimension_random ||
310 dimension == dimension_smartmidi ||
311 dimension == dimension_roundrobinkeyboard
312 ) ? split_type_bit : split_type_normal;
315 static int __resolveZoneSize(dimension_def_t& dimension_definition) {
316 return (dimension_definition.split_type == split_type_normal)
317 ? int(128.0 / dimension_definition.zones) : 0;
347 eg_opt_t::eg_opt_t() {
349 AttackHoldCancel =
true;
352 ReleaseCancel =
true;
357 SRLZ(AttackHoldCancel);
393 static const DLS::Info::string_length_t fixedStringLengths[] = {
394 { CHUNK_ID_INAM, 64 },
408 uint32_t crc = pFile->GetSampleChecksumByIndex(index);
415 uint16_t iSampleGroup = pCk3gix->
ReadInt16();
471 if (version == 3 &&
BitDepth == 24) {
476 ScanCompressedSample();
541 const int iReadAtOnce = 32*1024;
542 char* buf =
new char[iReadAtOnce * orig->
FrameSize];
544 file_offset_t restorePos = pOrig->
GetPos();
547 for (file_offset_t n = pOrig->
Read(buf, iReadAtOnce); n;
548 n = pOrig->
Read(buf, iReadAtOnce))
552 pOrig->
SetPos(restorePos);
575 pCkSmpl = pWaveList->
AddSubChunk(CHUNK_ID_SMPL, 60);
588 store32(&pData[28],
Loops);
592 store32(&pData[36],
LoopID);
601 if (!pCk3gix) pCk3gix = pWaveList->
AddSubChunk(CHUNK_ID_3GIX, 4);
603 uint16_t iSampleGroup = 0;
604 File* pFile =
static_cast<File*
>(pParent);
605 if (pFile->pGroups) {
606 std::list<Group*>::iterator iter = pFile->pGroups->begin();
607 std::list<Group*>::iterator end = pFile->pGroups->end();
608 for (
int i = 0; iter != end; i++, iter++) {
617 store16(&pData[0], iSampleGroup);
629 void Sample::ScanCompressedSample() {
632 std::list<file_offset_t> frameOffsets;
640 for (
int i = 0 ; ; i++) {
643 if (
BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->
GetPos());
647 if (mode_l > 5 || mode_r > 5)
throw gig::Exception(
"Unknown compression mode");
648 const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
652 ((pCkData->
RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
653 (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
658 pCkData->
SetPos(frameSize, RIFF::stream_curpos);
662 for (
int i = 0 ; ; i++) {
663 if (
BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->
GetPos());
667 const file_offset_t frameSize = bytesPerFrame[mode];
671 ((pCkData->
RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
676 pCkData->
SetPos(frameSize, RIFF::stream_curpos);
683 FrameTable =
new file_offset_t[frameOffsets.size()];
684 std::list<file_offset_t>::iterator end = frameOffsets.end();
685 std::list<file_offset_t>::iterator iter = frameOffsets.begin();
686 for (
int i = 0; iter != end; i++, iter++) {
788 file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->
FrameSize;
889 case RIFF::stream_curpos:
892 case RIFF::stream_end:
895 case RIFF::stream_backward:
898 case RIFF::stream_start:
default:
904 file_offset_t frame = this->
SamplePos / 2048;
910 file_offset_t orderedBytes = SampleCount * this->
FrameSize;
911 file_offset_t result = pCkData->
SetPos(orderedBytes, Whence);
912 return (result == orderedBytes) ? SampleCount
961 file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
962 uint8_t* pDst = (uint8_t*) pBuffer;
971 if (
GetPos() <= loopEnd) {
974 case loop_type_bidirectional: {
979 if (!pPlaybackState->
reverse) {
981 samplestoloopend = loopEnd -
GetPos();
982 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
983 samplestoread -= readsamples;
984 totalreadsamples += readsamples;
985 if (readsamples == samplestoloopend) {
986 pPlaybackState->
reverse =
true;
989 }
while (samplestoread && readsamples);
999 file_offset_t swapareastart = totalreadsamples;
1001 file_offset_t samplestoreadinloop = Min(samplestoread, loopoffset);
1002 file_offset_t reverseplaybackend =
GetPos() - samplestoreadinloop;
1004 SetPos(reverseplaybackend);
1008 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
1009 samplestoreadinloop -= readsamples;
1010 samplestoread -= readsamples;
1011 totalreadsamples += readsamples;
1012 }
while (samplestoreadinloop && readsamples);
1014 SetPos(reverseplaybackend);
1016 if (reverseplaybackend == loop.
LoopStart) {
1018 pPlaybackState->
reverse =
false;
1022 if (totalreadsamples > swapareastart)
1023 SwapMemoryArea(&pDst[swapareastart * this->
FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1025 }
while (samplestoread && readsamples);
1029 case loop_type_backward: {
1031 if (!pPlaybackState->
reverse)
do {
1032 samplestoloopend = loopEnd -
GetPos();
1033 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1034 samplestoread -= readsamples;
1035 totalreadsamples += readsamples;
1036 if (readsamples == samplestoloopend) {
1037 pPlaybackState->
reverse =
true;
1040 }
while (samplestoread && readsamples);
1042 if (!samplestoread)
break;
1050 file_offset_t swapareastart = totalreadsamples;
1054 file_offset_t reverseplaybackend = loop.
LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.
LoopLength);
1056 SetPos(reverseplaybackend);
1062 samplestoloopend = loopEnd -
GetPos();
1063 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
1064 samplestoreadinloop -= readsamples;
1065 samplestoread -= readsamples;
1066 totalreadsamples += readsamples;
1067 if (readsamples == samplestoloopend) {
1071 }
while (samplestoreadinloop && readsamples);
1073 SetPos(reverseplaybackend);
1076 SwapMemoryArea(&pDst[swapareastart * this->
FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1084 samplestoloopend = loopEnd -
GetPos();
1085 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1086 samplestoread -= readsamples;
1087 totalreadsamples += readsamples;
1088 if (readsamples == samplestoloopend) {
1092 }
while (samplestoread && readsamples);
1100 if (samplestoread)
do {
1101 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], samplestoread, pExternalDecompressionBuffer);
1102 samplestoread -= readsamples;
1103 totalreadsamples += readsamples;
1104 }
while (readsamples && samplestoread);
1109 return totalreadsamples;
1135 if (SampleCount == 0)
return 0;
1142 return Channels == 2 ? pCkData->
Read(pBuffer, SampleCount << 1, 2) >> 1
1143 : pCkData->
Read(pBuffer, SampleCount, 2);
1149 file_offset_t assumedsize = GuessSize(SampleCount),
1151 remainingsamples = SampleCount,
1152 copysamples, skipsamples,
1159 if (pDecompressionBuffer->
Size < assumedsize) {
1160 std::cerr <<
"gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1161 SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1162 remainingsamples = SampleCount;
1163 assumedsize = GuessSize(SampleCount);
1166 unsigned char* pSrc = (
unsigned char*) pDecompressionBuffer->
pStart;
1167 int16_t* pDst = static_cast<int16_t*>(pBuffer);
1168 uint8_t* pDst24 =
static_cast<uint8_t*
>(pBuffer);
1169 remainingbytes = pCkData->
Read(pSrc, assumedsize, 1);
1171 while (remainingsamples && remainingbytes) {
1173 file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset;
1175 int mode_l = *pSrc++, mode_r = 0;
1179 framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1180 rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1181 nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1182 if (remainingbytes < framebytes) {
1184 if (mode_l == 4 && (framesamples & 1)) {
1185 rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1188 rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1193 framebytes = bytesPerFrame[mode_l] + 1;
1194 nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1195 if (remainingbytes < framebytes) {
1201 if (currentframeoffset + remainingsamples >= framesamples) {
1202 if (currentframeoffset <= framesamples) {
1203 copysamples = framesamples - currentframeoffset;
1204 skipsamples = currentframeoffset;
1208 skipsamples = framesamples;
1215 copysamples = remainingsamples;
1216 skipsamples = currentframeoffset;
1217 pCkData->
SetPos(remainingbytes, RIFF::stream_backward);
1218 this->
FrameOffset = currentframeoffset + copysamples;
1220 remainingsamples -= copysamples;
1222 if (remainingbytes > framebytes) {
1223 remainingbytes -= framebytes;
1224 if (remainingsamples == 0 &&
1225 currentframeoffset + copysamples == framesamples) {
1230 pCkData->
SetPos(remainingbytes, RIFF::stream_backward);
1233 else remainingbytes = 0;
1235 currentframeoffset -= skipsamples;
1237 if (copysamples == 0) {
1242 const unsigned char*
const param_l = pSrc;
1244 if (mode_l != 2) pSrc += 12;
1247 const unsigned char*
const param_r = pSrc;
1248 if (mode_r != 2) pSrc += 12;
1250 Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1252 Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1254 pDst24 += copysamples * 6;
1257 Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1259 pDst24 += copysamples * 3;
1263 if (mode_l) pSrc += 4;
1267 const unsigned char*
const param_r = pSrc;
1268 if (mode_r) pSrc += 4;
1270 step = (2 - mode_l) + (2 - mode_r);
1271 Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1272 Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1273 skipsamples, copysamples);
1274 pDst += copysamples << 1;
1278 Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1279 pDst += copysamples;
1282 pSrc += nextFrameOffset;
1286 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1287 assumedsize = GuessSize(remainingsamples);
1288 pCkData->
SetPos(remainingbytes, RIFF::stream_backward);
1290 remainingbytes = pCkData->
Read(pDecompressionBuffer->
pStart, assumedsize, 1);
1291 pSrc = (
unsigned char*) pDecompressionBuffer->
pStart;
1295 this->
SamplePos += (SampleCount - remainingsamples);
1297 return (SampleCount - remainingsamples);
1328 if (pCkData->
GetPos() == 0) {
1331 if (
GetSize() < SampleCount)
throw Exception(
"Could not write sample data, current sample size to small");
1336 res =
Channels == 2 ? pCkData->
Write(pBuffer, SampleCount << 1, 2) >> 1
1337 : pCkData->
Write(pBuffer, SampleCount, 2);
1339 __calculateCRC((
unsigned char *)pBuffer, SampleCount *
FrameSize, crc);
1345 File* pFile =
static_cast<File*
>(GetParent());
1369 const double worstCaseHeaderOverhead =
1370 (256.0 + 12.0 + 2.0 ) / 256.0;
1371 result.
Size = (file_offset_t) (
double(MaxReadSize) * 3.0 * 2.0 * worstCaseHeaderOverhead);
1385 if (DecompressionBuffer.
Size && DecompressionBuffer.
pStart) {
1386 delete[] (int8_t*) DecompressionBuffer.
pStart;
1387 DecompressionBuffer.
pStart = NULL;
1388 DecompressionBuffer.
Size = 0;
1448 uint32_t crc = CalculateWaveDataChecksum();
1449 if (pActually) *pActually =
crc;
1450 return crc == this->
crc;
1453 uint32_t Sample::CalculateWaveDataChecksum() {
1454 const size_t sz = 20*1024;
1455 std::vector<uint8_t> buffer(sz);
1463 file_offset_t nRead =
Read(&buffer[0], n);
1464 if (nRead <= 0)
break;
1465 __calculateCRC(&buffer[0], nRead *
FrameSize, crc);
1487 size_t DimensionRegion::Instances = 0;
1488 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1490 DimensionRegion::DimensionRegion(
Region* pParent,
RIFF::List* _3ewl) :
DLS::Sampler(_3ewl) {
1496 if (_3ewl->
GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1497 else memset(&Crossfade, 0, 4);
1499 if (!pVelocityTables) pVelocityTables =
new VelocityTableMap;
1504 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1505 EG3Attack = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1514 EG1Attack = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1515 EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1518 EG1Release = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1519 EG1Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->
ReadUint8()));
1520 uint8_t eg1ctrloptions = _3ewa->
ReadUint8();
1521 EG1ControllerInvert = eg1ctrloptions & 0x01;
1522 EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1523 EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1524 EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1525 EG2Controller = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->
ReadUint8()));
1526 uint8_t eg2ctrloptions = _3ewa->
ReadUint8();
1527 EG2ControllerInvert = eg2ctrloptions & 0x01;
1528 EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1529 EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1530 EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1531 LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1532 EG2Attack = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1533 EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1536 EG2Release = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1539 LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1543 EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1544 EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1548 EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1549 EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1552 uint8_t velocityresponse = _3ewa->
ReadUint8();
1553 if (velocityresponse < 5) {
1555 VelocityResponseDepth = velocityresponse;
1556 }
else if (velocityresponse < 10) {
1557 VelocityResponseCurve = curve_type_linear;
1558 VelocityResponseDepth = velocityresponse - 5;
1559 }
else if (velocityresponse < 15) {
1560 VelocityResponseCurve = curve_type_special;
1561 VelocityResponseDepth = velocityresponse - 10;
1563 VelocityResponseCurve = curve_type_unknown;
1564 VelocityResponseDepth = 0;
1566 uint8_t releasevelocityresponse = _3ewa->
ReadUint8();
1567 if (releasevelocityresponse < 5) {
1569 ReleaseVelocityResponseDepth = releasevelocityresponse;
1570 }
else if (releasevelocityresponse < 10) {
1571 ReleaseVelocityResponseCurve = curve_type_linear;
1572 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1573 }
else if (releasevelocityresponse < 15) {
1574 ReleaseVelocityResponseCurve = curve_type_special;
1575 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1577 ReleaseVelocityResponseCurve = curve_type_unknown;
1578 ReleaseVelocityResponseDepth = 0;
1580 VelocityResponseCurveScaling = _3ewa->
ReadUint8();
1581 AttenuationControllerThreshold = _3ewa->
ReadInt8();
1583 SampleStartOffset = (uint16_t) _3ewa->
ReadInt16();
1585 uint8_t pitchTrackDimensionBypass = _3ewa->
ReadInt8();
1586 PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1587 if (pitchTrackDimensionBypass & 0x10) DimensionBypass = dim_bypass_ctrl_94;
1588 else if (pitchTrackDimensionBypass & 0x20) DimensionBypass = dim_bypass_ctrl_95;
1589 else DimensionBypass = dim_bypass_ctrl_none;
1591 Pan = (pan < 64) ? pan : -((
int)pan - 63);
1592 SelfMask = _3ewa->
ReadInt8() & 0x01;
1595 LFO3Controller =
static_cast<lfo3_ctrl_t
>(lfo3ctrl & 0x07);
1596 LFO3Sync = lfo3ctrl & 0x20;
1597 InvertAttenuationController = lfo3ctrl & 0x80;
1598 AttenuationController = DecodeLeverageController(static_cast<_lev_ctrl_t>(_3ewa->
ReadUint8()));
1600 LFO2Controller =
static_cast<lfo2_ctrl_t
>(lfo2ctrl & 0x07);
1601 LFO2FlipPhase = lfo2ctrl & 0x80;
1602 LFO2Sync = lfo2ctrl & 0x20;
1603 bool extResonanceCtrl = lfo2ctrl & 0x40;
1605 LFO1Controller =
static_cast<lfo1_ctrl_t
>(lfo1ctrl & 0x07);
1606 LFO1FlipPhase = lfo1ctrl & 0x80;
1607 LFO1Sync = lfo1ctrl & 0x40;
1608 VCFResonanceController = (extResonanceCtrl) ? static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1611 EG3Depth = (eg3depth <= 1200) ? eg3depth
1612 : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1);
1615 uint8_t regoptions = _3ewa->
ReadUint8();
1616 MSDecode = regoptions & 0x01;
1617 SustainDefeat = regoptions & 0x02;
1619 VelocityUpperLimit = _3ewa->
ReadInt8();
1622 ReleaseTriggerDecay = _3ewa->
ReadUint8();
1627 VCFEnabled = vcfcutoff & 0x80;
1628 VCFCutoff = vcfcutoff & 0x7f;
1629 VCFCutoffController =
static_cast<vcf_cutoff_ctrl_t
>(_3ewa->
ReadUint8());
1630 uint8_t vcfvelscale = _3ewa->
ReadUint8();
1631 VCFCutoffControllerInvert = vcfvelscale & 0x80;
1632 VCFVelocityScale = vcfvelscale & 0x7f;
1634 uint8_t vcfresonance = _3ewa->
ReadUint8();
1635 VCFResonance = vcfresonance & 0x7f;
1636 VCFResonanceDynamic = !(vcfresonance & 0x80);
1637 uint8_t vcfbreakpoint = _3ewa->
ReadUint8();
1638 VCFKeyboardTracking = vcfbreakpoint & 0x80;
1639 VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f;
1640 uint8_t vcfvelocity = _3ewa->
ReadUint8();
1641 VCFVelocityDynamicRange = vcfvelocity % 5;
1642 VCFVelocityCurve =
static_cast<curve_type_t
>(vcfvelocity / 5);
1643 VCFType =
static_cast<vcf_type_t
>(_3ewa->
ReadUint8());
1645 if (lfo3ctrl & 0x40)
1646 VCFType = vcf_type_lowpassturbo;
1649 _3ewa->
Read(DimensionUpperLimits, 1, 8);
1651 memset(DimensionUpperLimits, 0, 8);
1655 LFO3Frequency = 1.0;
1657 LFO1InternalDepth = 0;
1658 LFO3InternalDepth = 0;
1659 LFO1ControlDepth = 0;
1660 LFO3ControlDepth = 0;
1666 EG1Controller.controller_number = 0;
1667 EG1ControllerInvert =
false;
1668 EG1ControllerAttackInfluence = 0;
1669 EG1ControllerDecayInfluence = 0;
1670 EG1ControllerReleaseInfluence = 0;
1672 EG2Controller.controller_number = 0;
1673 EG2ControllerInvert =
false;
1674 EG2ControllerAttackInfluence = 0;
1675 EG2ControllerDecayInfluence = 0;
1676 EG2ControllerReleaseInfluence = 0;
1677 LFO1Frequency = 1.0;
1682 LFO2ControlDepth = 0;
1683 LFO2Frequency = 1.0;
1684 LFO2InternalDepth = 0;
1686 EG1InfiniteSustain =
true;
1689 EG2InfiniteSustain =
true;
1692 VelocityResponseDepth = 3;
1694 ReleaseVelocityResponseDepth = 3;
1695 VelocityResponseCurveScaling = 32;
1696 AttenuationControllerThreshold = 0;
1697 SampleStartOffset = 0;
1699 DimensionBypass = dim_bypass_ctrl_none;
1702 LFO3Controller = lfo3_ctrl_modwheel;
1704 InvertAttenuationController =
false;
1706 AttenuationController.controller_number = 0;
1708 LFO2FlipPhase =
false;
1711 LFO1FlipPhase =
false;
1717 SustainDefeat =
false;
1718 VelocityUpperLimit = 0;
1719 ReleaseTriggerDecay = 0;
1724 VCFCutoffControllerInvert =
false;
1725 VCFVelocityScale = 0;
1727 VCFResonanceDynamic =
false;
1728 VCFKeyboardTracking =
false;
1729 VCFKeyboardTrackingBreakpoint = 0;
1730 VCFVelocityDynamicRange = 0x04;
1731 VCFVelocityCurve = curve_type_linear;
1733 memset(DimensionUpperLimits, 127, 8);
1739 eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
1740 for (
int i = 0; i < 2; ++i) {
1750 pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1751 VelocityResponseDepth,
1752 VelocityResponseCurveScaling);
1754 pVelocityReleaseTable = GetReleaseVelocityTable(
1755 ReleaseVelocityResponseCurve,
1756 ReleaseVelocityResponseDepth
1759 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1760 VCFVelocityDynamicRange,
1762 VCFCutoffController);
1764 SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1776 pParentList = _3ewl;
1780 VelocityTable =
new uint8_t[128];
1781 for (
int k = 0 ; k < 128 ; k++)
1814 if (VelocityTable)
delete [] VelocityTable;
1815 if (pSampleLoops)
delete [] pSampleLoops;
1829 pRegion = pOriginalRegion;
1833 if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1834 pSample = pOriginalSample;
1837 if (mSamples && mSamples->count(orig->
pSample)) {
1838 pSample = mSamples->find(orig->
pSample)->second;
1843 VelocityTable =
new uint8_t[128];
1844 for (
int k = 0 ; k < 128 ; k++)
1860 SRLZ(VelocityUpperLimit);
1865 SRLZ(EG1InfiniteSustain);
1869 SRLZ(EG1Controller);
1870 SRLZ(EG1ControllerInvert);
1871 SRLZ(EG1ControllerAttackInfluence);
1872 SRLZ(EG1ControllerDecayInfluence);
1873 SRLZ(EG1ControllerReleaseInfluence);
1874 SRLZ(LFO1Frequency);
1875 SRLZ(LFO1InternalDepth);
1876 SRLZ(LFO1ControlDepth);
1877 SRLZ(LFO1Controller);
1878 SRLZ(LFO1FlipPhase);
1884 SRLZ(EG2InfiniteSustain);
1887 SRLZ(EG2Controller);
1888 SRLZ(EG2ControllerInvert);
1889 SRLZ(EG2ControllerAttackInfluence);
1890 SRLZ(EG2ControllerDecayInfluence);
1891 SRLZ(EG2ControllerReleaseInfluence);
1892 SRLZ(LFO2Frequency);
1893 SRLZ(LFO2InternalDepth);
1894 SRLZ(LFO2ControlDepth);
1895 SRLZ(LFO2Controller);
1896 SRLZ(LFO2FlipPhase);
1900 SRLZ(LFO3Frequency);
1901 SRLZ(LFO3InternalDepth);
1902 SRLZ(LFO3ControlDepth);
1903 SRLZ(LFO3Controller);
1907 SRLZ(VCFCutoffController);
1908 SRLZ(VCFCutoffControllerInvert);
1910 SRLZ(VCFVelocityCurve);
1911 SRLZ(VCFVelocityScale);
1912 SRLZ(VCFVelocityDynamicRange);
1914 SRLZ(VCFResonanceDynamic);
1915 SRLZ(VCFResonanceController);
1916 SRLZ(VCFKeyboardTracking);
1917 SRLZ(VCFKeyboardTrackingBreakpoint);
1918 SRLZ(VelocityResponseCurve);
1919 SRLZ(VelocityResponseDepth);
1920 SRLZ(VelocityResponseCurveScaling);
1921 SRLZ(ReleaseVelocityResponseCurve);
1922 SRLZ(ReleaseVelocityResponseDepth);
1923 SRLZ(ReleaseTriggerDecay);
1926 SRLZ(DimensionBypass);
1929 SRLZ(AttenuationController);
1930 SRLZ(InvertAttenuationController);
1931 SRLZ(AttenuationControllerThreshold);
1932 SRLZ(ChannelOffset);
1933 SRLZ(SustainDefeat);
1936 SRLZ(SampleAttenuation);
1950 DLS::Sampler::SetGain(gain);
1951 SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1967 RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1969 pData[12] = Crossfade.in_start;
1970 pData[13] = Crossfade.in_end;
1971 pData[14] = Crossfade.out_start;
1972 pData[15] = Crossfade.out_end;
1975 RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
1977 File* pFile = (
File*) GetParent()->GetParent()->GetParent();
1979 _3ewa = pParentList->AddSubChunk(CHUNK_ID_3EWA, version3 ? 148 : 140);
1985 const uint32_t chunksize = (uint32_t) _3ewa->
GetNewSize();
1986 store32(&pData[0], chunksize);
1988 const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
1989 store32(&pData[4], lfo3freq);
1991 const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
1992 store32(&pData[8], eg3attack);
1996 store16(&pData[14], LFO1InternalDepth);
2000 store16(&pData[18], LFO3InternalDepth);
2004 store16(&pData[22], LFO1ControlDepth);
2008 store16(&pData[26], LFO3ControlDepth);
2010 const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
2011 store32(&pData[28], eg1attack);
2013 const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
2014 store32(&pData[32], eg1decay1);
2018 store16(&pData[38], EG1Sustain);
2020 const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
2021 store32(&pData[40], eg1release);
2023 const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
2026 const uint8_t eg1ctrloptions =
2027 (EG1ControllerInvert ? 0x01 : 0x00) |
2028 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
2029 GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
2030 GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
2031 pData[45] = eg1ctrloptions;
2033 const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
2036 const uint8_t eg2ctrloptions =
2037 (EG2ControllerInvert ? 0x01 : 0x00) |
2038 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
2039 GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
2040 GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
2041 pData[47] = eg2ctrloptions;
2043 const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
2044 store32(&pData[48], lfo1freq);
2046 const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
2047 store32(&pData[52], eg2attack);
2049 const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
2050 store32(&pData[56], eg2decay1);
2054 store16(&pData[62], EG2Sustain);
2056 const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
2057 store32(&pData[64], eg2release);
2061 store16(&pData[70], LFO2ControlDepth);
2063 const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
2064 store32(&pData[72], lfo2freq);
2068 store16(&pData[78], LFO2InternalDepth);
2070 const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
2071 store32(&pData[80], eg1decay2);
2075 store16(&pData[86], EG1PreAttack);
2077 const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
2078 store32(&pData[88], eg2decay2);
2082 store16(&pData[94], EG2PreAttack);
2085 if (VelocityResponseDepth > 4)
throw Exception(
"VelocityResponseDepth must be between 0 and 4");
2086 uint8_t velocityresponse = VelocityResponseDepth;
2087 switch (VelocityResponseCurve) {
2090 case curve_type_linear:
2091 velocityresponse += 5;
2093 case curve_type_special:
2094 velocityresponse += 10;
2096 case curve_type_unknown:
2098 throw Exception(
"Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2100 pData[96] = velocityresponse;
2104 if (ReleaseVelocityResponseDepth > 4)
throw Exception(
"ReleaseVelocityResponseDepth must be between 0 and 4");
2105 uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
2106 switch (ReleaseVelocityResponseCurve) {
2109 case curve_type_linear:
2110 releasevelocityresponse += 5;
2112 case curve_type_special:
2113 releasevelocityresponse += 10;
2115 case curve_type_unknown:
2117 throw Exception(
"Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2119 pData[97] = releasevelocityresponse;
2122 pData[98] = VelocityResponseCurveScaling;
2124 pData[99] = AttenuationControllerThreshold;
2128 store16(&pData[104], SampleStartOffset);
2133 uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
2134 switch (DimensionBypass) {
2135 case dim_bypass_ctrl_94:
2136 pitchTrackDimensionBypass |= 0x10;
2138 case dim_bypass_ctrl_95:
2139 pitchTrackDimensionBypass |= 0x20;
2141 case dim_bypass_ctrl_none:
2145 throw Exception(
"Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
2147 pData[108] = pitchTrackDimensionBypass;
2150 const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63);
2153 const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
2154 pData[110] = selfmask;
2159 uint8_t lfo3ctrl = LFO3Controller & 0x07;
2160 if (LFO3Sync) lfo3ctrl |= 0x20;
2161 if (InvertAttenuationController) lfo3ctrl |= 0x80;
2162 if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40;
2163 pData[112] = lfo3ctrl;
2166 const uint8_t attenctl = EncodeLeverageController(AttenuationController);
2167 pData[113] = attenctl;
2170 uint8_t lfo2ctrl = LFO2Controller & 0x07;
2171 if (LFO2FlipPhase) lfo2ctrl |= 0x80;
2172 if (LFO2Sync) lfo2ctrl |= 0x20;
2174 pData[114] = lfo2ctrl;
2178 uint8_t lfo1ctrl = LFO1Controller & 0x07;
2179 if (LFO1FlipPhase) lfo1ctrl |= 0x80;
2180 if (LFO1Sync) lfo1ctrl |= 0x40;
2182 lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
2183 pData[115] = lfo1ctrl;
2186 const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
2187 : uint16_t(((-EG3Depth) - 1) ^ 0xfff);
2188 store16(&pData[116], eg3depth);
2192 const uint8_t channeloffset = ChannelOffset * 4;
2193 pData[120] = channeloffset;
2196 uint8_t regoptions = 0;
2197 if (MSDecode) regoptions |= 0x01;
2198 if (SustainDefeat) regoptions |= 0x02;
2199 pData[121] = regoptions;
2204 pData[124] = VelocityUpperLimit;
2208 pData[128] = ReleaseTriggerDecay;
2212 const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00;
2213 pData[131] = eg1hold;
2215 const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) |
2217 pData[132] = vcfcutoff;
2219 pData[133] = VCFCutoffController;
2221 const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) |
2222 (VCFVelocityScale & 0x7f);
2223 pData[134] = vcfvelscale;
2227 const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) |
2228 (VCFResonance & 0x7f);
2229 pData[136] = vcfresonance;
2231 const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) |
2232 (VCFKeyboardTrackingBreakpoint & 0x7f);
2233 pData[137] = vcfbreakpoint;
2235 const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2236 VCFVelocityCurve * 5;
2237 pData[138] = vcfvelocity;
2239 const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ?
vcf_type_lowpass : VCFType;
2240 pData[139] = vcftype;
2242 if (chunksize >= 148) {
2243 memcpy(&pData[140], DimensionUpperLimits, 8);
2248 RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2253 if (memcmp(&EG1Options, &defaultOpt,
sizeof(
eg_opt_t)) ||
2254 memcmp(&EG2Options, &defaultOpt,
sizeof(
eg_opt_t)))
2256 lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, 2);
2258 pParentList->MoveSubChunk(lsde, (
RIFF::Chunk*)NULL);
2262 unsigned char* pData = (
unsigned char*) lsde->
LoadChunkData();
2263 eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
2264 for (
int i = 0; i < 2; ++i) {
2267 (pEGOpts[i]->AttackHoldCancel ? (1<<1) : 0) |
2268 (pEGOpts[i]->Decay1Cancel ? (1<<2) : 0) |
2269 (pEGOpts[i]->Decay2Cancel ? (1<<3) : 0) |
2270 (pEGOpts[i]->ReleaseCancel ? (1<<4) : 0);
2275 double* DimensionRegion::GetReleaseVelocityTable(curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2276 curve_type_t curveType = releaseVelocityResponseCurve;
2277 uint8_t depth = releaseVelocityResponseDepth;
2282 (curveType == curve_type_special && depth == 4)) {
2286 return GetVelocityTable(curveType, depth, 0);
2289 double* DimensionRegion::GetCutoffVelocityTable(curve_type_t vcfVelocityCurve,
2290 uint8_t vcfVelocityDynamicRange,
2291 uint8_t vcfVelocityScale,
2292 vcf_cutoff_ctrl_t vcfCutoffController)
2294 curve_type_t curveType = vcfVelocityCurve;
2295 uint8_t depth = vcfVelocityDynamicRange;
2300 (curveType == curve_type_special && depth == 4)) {
2301 curveType = curve_type_special;
2304 return GetVelocityTable(curveType, depth,
2305 (vcfCutoffController <= vcf_cutoff_ctrl_none2)
2306 ? vcfVelocityScale : 0);
2310 double* DimensionRegion::GetVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling)
2314 switch (curveType) {
2316 case curve_type_linear:
2318 printf(
"Warning: Invalid depth (0x%x) for velocity curve type (0x%x).\n", depth, curveType);
2323 case curve_type_special:
2325 printf(
"Warning: Invalid depth (0x%x) for velocity curve type 'special'.\n", depth);
2330 case curve_type_unknown:
2332 printf(
"Warning: Unknown velocity curve type (0x%x).\n", curveType);
2333 curveType = curve_type_linear;
2340 uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2341 if (pVelocityTables->count(tableKey)) {
2342 table = (*pVelocityTables)[tableKey];
2345 table = CreateVelocityTable(curveType, depth, scaling);
2346 (*pVelocityTables)[tableKey] = table;
2351 Region* DimensionRegion::GetParent()
const {
2361 leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2363 switch (EncodedController) {
2365 case _lev_ctrl_none:
2369 case _lev_ctrl_velocity:
2370 decodedcontroller.
type = leverage_ctrl_t::type_velocity;
2373 case _lev_ctrl_channelaftertouch:
2374 decodedcontroller.
type = leverage_ctrl_t::type_channelaftertouch;
2379 case _lev_ctrl_modwheel:
2380 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2383 case _lev_ctrl_breath:
2384 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2387 case _lev_ctrl_foot:
2388 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2391 case _lev_ctrl_effect1:
2392 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2395 case _lev_ctrl_effect2:
2396 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2399 case _lev_ctrl_genpurpose1:
2400 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2403 case _lev_ctrl_genpurpose2:
2404 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2407 case _lev_ctrl_genpurpose3:
2408 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2411 case _lev_ctrl_genpurpose4:
2412 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2415 case _lev_ctrl_portamentotime:
2416 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2419 case _lev_ctrl_sustainpedal:
2420 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2423 case _lev_ctrl_portamento:
2424 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2427 case _lev_ctrl_sostenutopedal:
2428 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2431 case _lev_ctrl_softpedal:
2432 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2435 case _lev_ctrl_genpurpose5:
2436 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2439 case _lev_ctrl_genpurpose6:
2440 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2443 case _lev_ctrl_genpurpose7:
2444 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2447 case _lev_ctrl_genpurpose8:
2448 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2451 case _lev_ctrl_effect1depth:
2452 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2455 case _lev_ctrl_effect2depth:
2456 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2459 case _lev_ctrl_effect3depth:
2460 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2463 case _lev_ctrl_effect4depth:
2464 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2467 case _lev_ctrl_effect5depth:
2468 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2475 case _lev_ctrl_CC3_EXT:
2476 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2479 case _lev_ctrl_CC6_EXT:
2480 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2483 case _lev_ctrl_CC7_EXT:
2484 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2487 case _lev_ctrl_CC8_EXT:
2488 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2491 case _lev_ctrl_CC9_EXT:
2492 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2495 case _lev_ctrl_CC10_EXT:
2496 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2499 case _lev_ctrl_CC11_EXT:
2500 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2503 case _lev_ctrl_CC14_EXT:
2504 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2507 case _lev_ctrl_CC15_EXT:
2508 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2511 case _lev_ctrl_CC20_EXT:
2512 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2515 case _lev_ctrl_CC21_EXT:
2516 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2519 case _lev_ctrl_CC22_EXT:
2520 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2523 case _lev_ctrl_CC23_EXT:
2524 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2527 case _lev_ctrl_CC24_EXT:
2528 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2531 case _lev_ctrl_CC25_EXT:
2532 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2535 case _lev_ctrl_CC26_EXT:
2536 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2539 case _lev_ctrl_CC27_EXT:
2540 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2543 case _lev_ctrl_CC28_EXT:
2544 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2547 case _lev_ctrl_CC29_EXT:
2548 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2551 case _lev_ctrl_CC30_EXT:
2552 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2555 case _lev_ctrl_CC31_EXT:
2556 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2559 case _lev_ctrl_CC68_EXT:
2560 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2563 case _lev_ctrl_CC69_EXT:
2564 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2567 case _lev_ctrl_CC70_EXT:
2568 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2571 case _lev_ctrl_CC71_EXT:
2572 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2575 case _lev_ctrl_CC72_EXT:
2576 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2579 case _lev_ctrl_CC73_EXT:
2580 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2583 case _lev_ctrl_CC74_EXT:
2584 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2587 case _lev_ctrl_CC75_EXT:
2588 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2591 case _lev_ctrl_CC76_EXT:
2592 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2595 case _lev_ctrl_CC77_EXT:
2596 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2599 case _lev_ctrl_CC78_EXT:
2600 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2603 case _lev_ctrl_CC79_EXT:
2604 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2607 case _lev_ctrl_CC84_EXT:
2608 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2611 case _lev_ctrl_CC85_EXT:
2612 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2615 case _lev_ctrl_CC86_EXT:
2616 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2619 case _lev_ctrl_CC87_EXT:
2620 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2623 case _lev_ctrl_CC89_EXT:
2624 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2627 case _lev_ctrl_CC90_EXT:
2628 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2631 case _lev_ctrl_CC96_EXT:
2632 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2635 case _lev_ctrl_CC97_EXT:
2636 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2639 case _lev_ctrl_CC102_EXT:
2640 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2643 case _lev_ctrl_CC103_EXT:
2644 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2647 case _lev_ctrl_CC104_EXT:
2648 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2651 case _lev_ctrl_CC105_EXT:
2652 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2655 case _lev_ctrl_CC106_EXT:
2656 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2659 case _lev_ctrl_CC107_EXT:
2660 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2663 case _lev_ctrl_CC108_EXT:
2664 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2667 case _lev_ctrl_CC109_EXT:
2668 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2671 case _lev_ctrl_CC110_EXT:
2672 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2675 case _lev_ctrl_CC111_EXT:
2676 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2679 case _lev_ctrl_CC112_EXT:
2680 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2683 case _lev_ctrl_CC113_EXT:
2684 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2687 case _lev_ctrl_CC114_EXT:
2688 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2691 case _lev_ctrl_CC115_EXT:
2692 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2695 case _lev_ctrl_CC116_EXT:
2696 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2699 case _lev_ctrl_CC117_EXT:
2700 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2703 case _lev_ctrl_CC118_EXT:
2704 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2707 case _lev_ctrl_CC119_EXT:
2708 decodedcontroller.
type = leverage_ctrl_t::type_controlchange;
2716 printf(
"Warning: Unknown leverage controller type (0x%x).\n", EncodedController);
2719 return decodedcontroller;
2725 DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(
leverage_ctrl_t DecodedController) {
2726 _lev_ctrl_t encodedcontroller;
2727 switch (DecodedController.
type) {
2730 encodedcontroller = _lev_ctrl_none;
2732 case leverage_ctrl_t::type_velocity:
2733 encodedcontroller = _lev_ctrl_velocity;
2735 case leverage_ctrl_t::type_channelaftertouch:
2736 encodedcontroller = _lev_ctrl_channelaftertouch;
2740 case leverage_ctrl_t::type_controlchange:
2743 encodedcontroller = _lev_ctrl_modwheel;
2746 encodedcontroller = _lev_ctrl_breath;
2749 encodedcontroller = _lev_ctrl_foot;
2752 encodedcontroller = _lev_ctrl_effect1;
2755 encodedcontroller = _lev_ctrl_effect2;
2758 encodedcontroller = _lev_ctrl_genpurpose1;
2761 encodedcontroller = _lev_ctrl_genpurpose2;
2764 encodedcontroller = _lev_ctrl_genpurpose3;
2767 encodedcontroller = _lev_ctrl_genpurpose4;
2770 encodedcontroller = _lev_ctrl_portamentotime;
2773 encodedcontroller = _lev_ctrl_sustainpedal;
2776 encodedcontroller = _lev_ctrl_portamento;
2779 encodedcontroller = _lev_ctrl_sostenutopedal;
2782 encodedcontroller = _lev_ctrl_softpedal;
2785 encodedcontroller = _lev_ctrl_genpurpose5;
2788 encodedcontroller = _lev_ctrl_genpurpose6;
2791 encodedcontroller = _lev_ctrl_genpurpose7;
2794 encodedcontroller = _lev_ctrl_genpurpose8;
2797 encodedcontroller = _lev_ctrl_effect1depth;
2800 encodedcontroller = _lev_ctrl_effect2depth;
2803 encodedcontroller = _lev_ctrl_effect3depth;
2806 encodedcontroller = _lev_ctrl_effect4depth;
2809 encodedcontroller = _lev_ctrl_effect5depth;
2816 encodedcontroller = _lev_ctrl_CC3_EXT;
2819 encodedcontroller = _lev_ctrl_CC6_EXT;
2822 encodedcontroller = _lev_ctrl_CC7_EXT;
2825 encodedcontroller = _lev_ctrl_CC8_EXT;
2828 encodedcontroller = _lev_ctrl_CC9_EXT;
2831 encodedcontroller = _lev_ctrl_CC10_EXT;
2834 encodedcontroller = _lev_ctrl_CC11_EXT;
2837 encodedcontroller = _lev_ctrl_CC14_EXT;
2840 encodedcontroller = _lev_ctrl_CC15_EXT;
2843 encodedcontroller = _lev_ctrl_CC20_EXT;
2846 encodedcontroller = _lev_ctrl_CC21_EXT;
2849 encodedcontroller = _lev_ctrl_CC22_EXT;
2852 encodedcontroller = _lev_ctrl_CC23_EXT;
2855 encodedcontroller = _lev_ctrl_CC24_EXT;
2858 encodedcontroller = _lev_ctrl_CC25_EXT;
2861 encodedcontroller = _lev_ctrl_CC26_EXT;
2864 encodedcontroller = _lev_ctrl_CC27_EXT;
2867 encodedcontroller = _lev_ctrl_CC28_EXT;
2870 encodedcontroller = _lev_ctrl_CC29_EXT;
2873 encodedcontroller = _lev_ctrl_CC30_EXT;
2876 encodedcontroller = _lev_ctrl_CC31_EXT;
2879 encodedcontroller = _lev_ctrl_CC68_EXT;
2882 encodedcontroller = _lev_ctrl_CC69_EXT;
2885 encodedcontroller = _lev_ctrl_CC70_EXT;
2888 encodedcontroller = _lev_ctrl_CC71_EXT;
2891 encodedcontroller = _lev_ctrl_CC72_EXT;
2894 encodedcontroller = _lev_ctrl_CC73_EXT;
2897 encodedcontroller = _lev_ctrl_CC74_EXT;
2900 encodedcontroller = _lev_ctrl_CC75_EXT;
2903 encodedcontroller = _lev_ctrl_CC76_EXT;
2906 encodedcontroller = _lev_ctrl_CC77_EXT;
2909 encodedcontroller = _lev_ctrl_CC78_EXT;
2912 encodedcontroller = _lev_ctrl_CC79_EXT;
2915 encodedcontroller = _lev_ctrl_CC84_EXT;
2918 encodedcontroller = _lev_ctrl_CC85_EXT;
2921 encodedcontroller = _lev_ctrl_CC86_EXT;
2924 encodedcontroller = _lev_ctrl_CC87_EXT;
2927 encodedcontroller = _lev_ctrl_CC89_EXT;
2930 encodedcontroller = _lev_ctrl_CC90_EXT;
2933 encodedcontroller = _lev_ctrl_CC96_EXT;
2936 encodedcontroller = _lev_ctrl_CC97_EXT;
2939 encodedcontroller = _lev_ctrl_CC102_EXT;
2942 encodedcontroller = _lev_ctrl_CC103_EXT;
2945 encodedcontroller = _lev_ctrl_CC104_EXT;
2948 encodedcontroller = _lev_ctrl_CC105_EXT;
2951 encodedcontroller = _lev_ctrl_CC106_EXT;
2954 encodedcontroller = _lev_ctrl_CC107_EXT;
2957 encodedcontroller = _lev_ctrl_CC108_EXT;
2960 encodedcontroller = _lev_ctrl_CC109_EXT;
2963 encodedcontroller = _lev_ctrl_CC110_EXT;
2966 encodedcontroller = _lev_ctrl_CC111_EXT;
2969 encodedcontroller = _lev_ctrl_CC112_EXT;
2972 encodedcontroller = _lev_ctrl_CC113_EXT;
2975 encodedcontroller = _lev_ctrl_CC114_EXT;
2978 encodedcontroller = _lev_ctrl_CC115_EXT;
2981 encodedcontroller = _lev_ctrl_CC116_EXT;
2984 encodedcontroller = _lev_ctrl_CC117_EXT;
2987 encodedcontroller = _lev_ctrl_CC118_EXT;
2990 encodedcontroller = _lev_ctrl_CC119_EXT;
2994 throw gig::Exception(
"leverage controller number is not supported by the gig format");
3000 return encodedcontroller;
3003 DimensionRegion::~DimensionRegion() {
3007 VelocityTableMap::iterator iter;
3008 for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
3009 double* pTable = iter->second;
3010 if (pTable)
delete[] pTable;
3012 pVelocityTables->clear();
3013 delete pVelocityTables;
3014 pVelocityTables = NULL;
3016 if (VelocityTable)
delete[] VelocityTable;
3031 return pVelocityAttenuationTable[MIDIKeyVelocity];
3034 double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
3035 return pVelocityReleaseTable[MIDIKeyVelocity];
3038 double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
3039 return pVelocityCutoffTable[MIDIKeyVelocity];
3047 pVelocityAttenuationTable =
3049 curve, VelocityResponseDepth, VelocityResponseCurveScaling
3051 VelocityResponseCurve = curve;
3059 pVelocityAttenuationTable =
3061 VelocityResponseCurve, depth, VelocityResponseCurveScaling
3063 VelocityResponseDepth = depth;
3071 pVelocityAttenuationTable =
3073 VelocityResponseCurve, VelocityResponseDepth, scaling
3075 VelocityResponseCurveScaling = scaling;
3083 pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
3084 ReleaseVelocityResponseCurve = curve;
3092 pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
3093 ReleaseVelocityResponseDepth = depth;
3101 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
3102 VCFCutoffController = controller;
3110 pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
3111 VCFVelocityCurve = curve;
3119 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
3120 VCFVelocityDynamicRange = range;
3128 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
3129 VCFVelocityScale = scaling;
3132 double* DimensionRegion::CreateVelocityTable(curve_type_t curveType, uint8_t depth, uint8_t scaling) {
3137 const int lin0[] = { 1, 1, 127, 127 };
3138 const int lin1[] = { 1, 21, 127, 127 };
3139 const int lin2[] = { 1, 45, 127, 127 };
3140 const int lin3[] = { 1, 74, 127, 127 };
3141 const int lin4[] = { 1, 127, 127, 127 };
3144 const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
3145 const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
3147 const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
3149 const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
3151 const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
3154 const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
3155 113, 127, 127, 127 };
3156 const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
3157 118, 127, 127, 127 };
3158 const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
3159 85, 90, 91, 127, 127, 127 };
3160 const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
3161 117, 127, 127, 127 };
3162 const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
3166 const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
3167 91, 127, 127, 127 };
3169 const int*
const curves[] = { non0, non1, non2, non3, non4,
3170 lin0, lin1, lin2, lin3, lin4,
3171 spe0, spe1, spe2, spe3, spe4, spe5 };
3173 double*
const table =
new double[128];
3175 const int* curve = curves[curveType * 5 + depth];
3176 const int s = scaling == 0 ? 20 : scaling;
3179 for (
int x = 1 ; x < 128 ; x++) {
3181 if (x > curve[2]) curve += 2;
3182 double y = curve[1] + (x - curve[0]) *
3183 (
double(curve[3] - curve[1]) / (curve[2] - curve[0]));
3188 if (s < 20 && y >= 0.5)
3189 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
3206 for (
int i = 0; i < 256; i++) {
3207 pDimensionRegions[i] = NULL;
3210 File* file = (
File*) GetParent()->GetParent();
3211 int dimensionBits = (file->
pVersion && file->
pVersion->major == 3) ? 8 : 5;
3217 LoadDimensionRegions(rgnList);
3222 for (
int i = 0; i < dimensionBits; i++) {
3223 dimension_t dimension =
static_cast<dimension_t
>(_3lnk->
ReadUint8());
3230 pDimensionDefinitions[i].bits = 0;
3231 pDimensionDefinitions[i].zones = 0;
3232 pDimensionDefinitions[i].split_type = split_type_bit;
3233 pDimensionDefinitions[i].zone_size = 0;
3236 pDimensionDefinitions[i].dimension = dimension;
3237 pDimensionDefinitions[i].bits = bits;
3238 pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits;
3239 pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
3240 pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
3244 if (dimension == dimension_layer) Layers = pDimensionDefinitions[i].zones;
3246 _3lnk->
SetPos(3, RIFF::stream_curpos);
3248 for (
int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
3252 UpdateVelocityTable();
3262 for (uint i = 0; i < DimensionRegions; i++) {
3263 uint32_t wavepoolindex = _3lnk->
ReadUint32();
3264 if (file->pWavePoolTable && pDimensionRegions[i])
3265 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
3270 DimensionRegions = 0;
3271 for (
int i = 0 ; i < 8 ; i++) {
3273 pDimensionDefinitions[i].bits = 0;
3274 pDimensionDefinitions[i].zones = 0;
3279 if (!DimensionRegions) {
3281 if (!_3prg) _3prg = rgnList->
AddSubList(LIST_TYPE_3PRG);
3284 DimensionRegions = 1;
3303 pSample = pDimensionRegions[0]->pSample;
3309 for (
int i = 0; i < DimensionRegions; i++) {
3310 pDimensionRegions[i]->UpdateChunks(pProgress);
3313 File* pFile = (
File*) GetParent()->GetParent();
3315 const int iMaxDimensions = version3 ? 8 : 5;
3316 const int iMaxDimensionRegions = version3 ? 256 : 32;
3319 RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3321 const int _3lnkChunkSize = version3 ? 1092 : 172;
3322 _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3326 pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), (
RIFF::Chunk*)NULL);
3331 store32(&pData[0], DimensionRegions);
3333 for (
int i = 0; i < iMaxDimensions; i++) {
3334 pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3335 pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3336 pData[6 + i * 8] = pDimensionDefinitions[i].dimension ==
dimension_none ? 0 : shift;
3337 pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3338 pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3341 shift += pDimensionDefinitions[i].bits;
3345 const int iWavePoolOffset = version3 ? 68 : 44;
3346 for (uint i = 0; i < iMaxDimensionRegions; i++) {
3347 int iWaveIndex = -1;
3348 if (i < DimensionRegions) {
3349 if (!pFile->pSamples || !pFile->pSamples->size())
throw gig::Exception(
"Could not update gig::Region, there are no samples");
3350 File::SampleList::iterator iter = pFile->pSamples->begin();
3351 File::SampleList::iterator end = pFile->pSamples->end();
3352 for (
int index = 0; iter != end; ++iter, ++index) {
3353 if (*iter == pDimensionRegions[i]->pSample) {
3359 store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3363 void Region::LoadDimensionRegions(
RIFF::List* rgn) {
3366 int dimensionRegionNr = 0;
3370 pDimensionRegions[dimensionRegionNr] =
new DimensionRegion(
this, _3ewl);
3371 dimensionRegionNr++;
3375 if (dimensionRegionNr == 0)
throw gig::Exception(
"No dimension region found.");
3386 void Region::UpdateVelocityTable() {
3389 for (
int i = 0 ; i < Dimensions ; i++) {
3390 if (pDimensionDefinitions[i].dimension == gig::dimension_velocity) {
3395 if (veldim == -1)
return;
3398 for (
int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3399 int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3403 for (
int i = 0 ; i < DimensionRegions ; i++) {
3404 const int end = i + step * pDimensionDefinitions[veldim].zones;
3407 if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3408 pDimensionRegions[i]->VelocityUpperLimit) {
3410 uint8_t* table = pDimensionRegions[i]->VelocityTable;
3412 table =
new uint8_t[128];
3413 pDimensionRegions[i]->VelocityTable = table;
3416 int velocityZone = 0;
3417 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) {
3418 for (
int k = i ; k < end ; k += step) {
3420 for (; tableidx <= d->
DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3424 for (
int k = i ; k < end ; k += step) {
3426 for (; tableidx <= d->
VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3431 if (pDimensionRegions[i]->VelocityTable) {
3433 pDimensionRegions[i]->VelocityTable = 0;
3440 for (j = 0 ; j < Dimensions ; j++) {
3441 if (j == veldim) i += skipveldim;
3444 if (dim[j] < pDimensionDefinitions[j].zones)
break;
3448 i += ((1 << pDimensionDefinitions[j].bits) -
3449 pDimensionDefinitions[j].zones) << shift;
3452 shift += pDimensionDefinitions[j].bits;
3454 if (j == Dimensions)
break;
3475 if (pDimDef->
zones < 2)
3476 throw gig::Exception(
"Could not add new dimension, amount of requested zones must always be at least two");
3477 if (pDimDef->
bits < 1)
3478 throw gig::Exception(
"Could not add new dimension, amount of requested requested zone bits must always be at least one");
3479 if (pDimDef->
dimension == dimension_samplechannel) {
3480 if (pDimDef->
zones != 2)
3481 throw gig::Exception(
"Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3482 if (pDimDef->
bits != 1)
3483 throw gig::Exception(
"Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3487 File* file = (
File*) GetParent()->GetParent();
3488 const int iMaxDimensions = (file->
pVersion && file->
pVersion->major == 3) ? 8 : 5;
3489 if (Dimensions >= iMaxDimensions)
3490 throw gig::Exception(
"Could not add new dimension, max. amount of " + ToString(iMaxDimensions) +
" dimensions already reached");
3492 int iCurrentBits = 0;
3493 for (
int i = 0; i < Dimensions; i++)
3494 iCurrentBits += pDimensionDefinitions[i].bits;
3495 if (iCurrentBits >= iMaxDimensions)
3496 throw gig::Exception(
"Could not add new dimension, max. amount of " + ToString(iMaxDimensions) +
" dimension bits already reached");
3497 const int iNewBits = iCurrentBits + pDimDef->
bits;
3498 if (iNewBits > iMaxDimensions)
3499 throw gig::Exception(
"Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) +
" dimension bits");
3501 for (
int i = 0; i < Dimensions; i++)
3502 if (pDimensionDefinitions[i].dimension == pDimDef->
dimension)
3503 throw gig::Exception(
"Could not add new dimension, there is already a dimension of the same type");
3508 int pos = pDimDef->
dimension == dimension_samplechannel ? 0 : Dimensions;
3510 for (
int i = 0 ; i < pos ; i++)
3511 bitpos += pDimensionDefinitions[i].bits;
3514 for (
int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3515 for (
int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3516 for (
int j = Dimensions ; j > pos ; j--) {
3517 pDimensionRegions[i]->DimensionUpperLimits[j] =
3518 pDimensionRegions[i]->DimensionUpperLimits[j - 1];
3523 pDimensionDefinitions[pos] = *pDimDef;
3527 __resolveSplitType(pDimensionDefinitions[pos].dimension);
3528 pDimensionDefinitions[pos].zone_size =
3529 __resolveZoneSize(pDimensionDefinitions[pos]);
3536 for (
int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3537 for (
int k = 0 ; k < (1 << bitpos) ; k++) {
3538 pDimensionRegions[(i << pDimDef->
bits) + k] = pDimensionRegions[i + k];
3540 for (
int j = 1 ; j < (1 << pDimDef->
bits) ; j++) {
3541 for (
int k = 0 ; k < (1 << bitpos) ; k++) {
3543 if (moveTo) _3prg->
MoveSubChunk(pNewDimRgnListChunk, moveTo);
3546 pDimensionRegions[(i << pDimDef->
bits) + (j << bitpos) + k] =
3552 moveTo = pDimensionRegions[i]->pParentList;
3556 int mask = (1 << bitpos) - 1;
3557 for (
int z = 0 ; z < pDimDef->
zones ; z++) {
3558 uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->
zones - 1);
3559 for (
int i = 0 ; i < 1 << iCurrentBits ; i++) {
3560 pDimensionRegions[((i & ~mask) << pDimDef->
bits) |
3562 (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3569 if (pDimDef->
dimension == dimension_layer) Layers = pDimDef->
zones;
3571 UpdateVelocityTable();
3587 int iDimensionNr = -1;
3588 for (
int i = 0; i < Dimensions; i++) {
3589 if (&pDimensionDefinitions[i] == pDimDef) {
3594 if (iDimensionNr < 0)
throw gig::Exception(
"Invalid dimension_def_t pointer");
3598 for (
int i = 0; i < iDimensionNr; i++)
3599 iLowerBits += pDimensionDefinitions[i].bits;
3603 for (
int i = iDimensionNr + 1; i < Dimensions; i++)
3604 iUpperBits += pDimensionDefinitions[i].bits;
3610 for (
int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3611 for (
int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3612 for (
int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3613 int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3614 iObsoleteBit << iLowerBits |
3617 _3prg->
DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3618 delete pDimensionRegions[iToDelete];
3619 pDimensionRegions[iToDelete] = NULL;
3627 for (
int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3628 if (!pDimensionRegions[iTo]) {
3629 if (iFrom <= iTo) iFrom = iTo + 1;
3630 while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3631 if (iFrom < 256 && pDimensionRegions[iFrom]) {
3632 pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3633 pDimensionRegions[iFrom] = NULL;
3639 for (
int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3641 for (
int i = iDimensionNr + 1; i < Dimensions; i++) {
3648 for (
int i = iDimensionNr + 1; i < Dimensions; i++) {
3649 pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
3651 pDimensionDefinitions[Dimensions - 1].dimension =
dimension_none;
3652 pDimensionDefinitions[Dimensions - 1].bits = 0;
3653 pDimensionDefinitions[Dimensions - 1].zones = 0;
3658 if (pDimDef->
dimension == dimension_layer) Layers = 1;
3678 throw gig::Exception(
"Could not delete dimension zone, no such dimension of given type");
3679 if (oldDef->
zones <= 2)
3680 throw gig::Exception(
"Could not delete dimension zone, because it would end up with only one zone.");
3681 if (zone < 0 || zone >= oldDef->
zones)
3682 throw gig::Exception(
"Could not delete dimension zone, requested zone index out of bounds.");
3684 const int newZoneSize = oldDef->
zones - 1;
3693 RIFF::List* pCkInstrument = instr->pCkInstrument;
3695 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
3697 tempRgn =
new Region(instr, rgn);
3705 for (
int i = 0; i < Dimensions; ++i) {
3709 def.
zones = newZoneSize;
3718 int tempReducedDimensionIndex = -1;
3719 for (
int d = 0; d < tempRgn->
Dimensions; ++d) {
3721 tempReducedDimensionIndex = d;
3727 for (
int iDst = 0; iDst < 256; ++iDst) {
3729 if (!dstDimRgn)
continue;
3730 std::map<dimension_t,int> dimCase;
3731 bool isValidZone =
true;
3732 for (
int d = 0, baseBits = 0; d < tempRgn->
Dimensions; ++d) {
3735 (iDst >> baseBits) & ((1 << dstBits) - 1);
3736 baseBits += dstBits;
3739 isValidZone =
false;
3743 if (!isValidZone)
continue;
3746 const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3747 if (dimCase[type] >= zone) dimCase[type]++;
3752 if (newDef.
split_type == split_type_normal && isLastZone)
3760 DeleteDimension(oldDef);
3761 AddDimension(&newDef);
3762 for (
int iSrc = 0; iSrc < 256; ++iSrc) {
3764 if (!srcDimRgn)
continue;
3765 std::map<dimension_t,int> dimCase;
3766 for (
int d = 0, baseBits = 0; d < tempRgn->
Dimensions; ++d) {
3769 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3770 baseBits += srcBits;
3775 if (!dstDimRgn)
continue;
3782 UpdateVelocityTable();
3802 throw gig::Exception(
"Could not split dimension zone, no such dimension of given type");
3803 if (zone < 0 || zone >= oldDef->
zones)
3804 throw gig::Exception(
"Could not split dimension zone, requested zone index out of bounds.");
3806 const int newZoneSize = oldDef->
zones + 1;
3815 RIFF::List* pCkInstrument = instr->pCkInstrument;
3817 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
3819 tempRgn =
new Region(instr, rgn);
3827 for (
int i = 0; i < Dimensions; ++i) {
3831 def.
zones = newZoneSize;
3832 if ((1 << oldDef->
bits) < newZoneSize) def.
bits++;
3840 int tempIncreasedDimensionIndex = -1;
3841 for (
int d = 0; d < tempRgn->
Dimensions; ++d) {
3843 tempIncreasedDimensionIndex = d;
3849 for (
int iSrc = 0; iSrc < 256; ++iSrc) {
3851 if (!srcDimRgn)
continue;
3852 std::map<dimension_t,int> dimCase;
3853 bool isValidZone =
true;
3854 for (
int d = 0, baseBits = 0; d < Dimensions; ++d) {
3855 const int srcBits = pDimensionDefinitions[d].bits;
3856 dimCase[pDimensionDefinitions[d].dimension] =
3857 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3859 if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
3860 isValidZone =
false;
3863 baseBits += srcBits;
3865 if (!isValidZone)
continue;
3868 if (dimCase[type] > zone) dimCase[type]++;
3874 if (dimCase[type] == zone) {
3876 if (newDef.
split_type == split_type_normal) {
3881 std::map<dimension_t,int> lowerCase = dimCase;
3899 DeleteDimension(oldDef);
3900 AddDimension(&newDef);
3901 for (
int iSrc = 0; iSrc < 256; ++iSrc) {
3903 if (!srcDimRgn)
continue;
3904 std::map<dimension_t,int> dimCase;
3905 for (
int d = 0, baseBits = 0; d < tempRgn->
Dimensions; ++d) {
3908 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3909 baseBits += srcBits;
3914 if (!dstDimRgn)
continue;
3921 UpdateVelocityTable();
3939 if (oldType == newType)
return;
3942 throw gig::Exception(
"No dimension with provided old dimension type exists on this region");
3943 if (newType == dimension_samplechannel && def->
zones != 2)
3944 throw gig::Exception(
"Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
3945 if (GetDimensionDefinition(newType))
3946 throw gig::Exception(
"There is already a dimension with requested new dimension type on this region");
3948 def->
split_type = __resolveSplitType(newType);
3952 uint8_t bits[8] = {};
3953 for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
3954 it != DimCase.end(); ++it)
3956 for (
int d = 0; d < Dimensions; ++d) {
3957 if (pDimensionDefinitions[d].dimension == it->first) {
3958 bits[d] = it->second;
3959 goto nextDimCaseSlice;
3966 return GetDimensionRegionByBit(bits);
3979 for (
int i = 0; i < Dimensions; ++i)
3980 if (pDimensionDefinitions[i].dimension == type)
3981 return &pDimensionDefinitions[i];
3986 for (
int i = 0; i < 256; i++) {
3987 if (pDimensionRegions[i])
delete pDimensionRegions[i];
4015 for (uint i = 0; i < Dimensions; i++) {
4016 if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4021 switch (pDimensionDefinitions[i].split_type) {
4022 case split_type_normal:
4023 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4025 for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4026 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i])
break;
4030 bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4033 case split_type_bit:
4034 const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4035 bits = DimValues[i] & limiter_mask;
4038 dimregidx |= bits << bitpos;
4040 bitpos += pDimensionDefinitions[i].bits;
4043 if (!dimreg)
return NULL;
4049 bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4051 const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4052 dimregidx |= (bits & limiter_mask) << velbitpos;
4053 dimreg = pDimensionRegions[dimregidx & 255];
4058 int Region::GetDimensionRegionIndexByValue(
const uint DimValues[8]) {
4064 for (uint i = 0; i < Dimensions; i++) {
4065 if (pDimensionDefinitions[i].dimension == dimension_velocity) {
4070 switch (pDimensionDefinitions[i].split_type) {
4071 case split_type_normal:
4072 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4074 for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4075 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i])
break;
4079 bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4082 case split_type_bit:
4083 const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4084 bits = DimValues[i] & limiter_mask;
4087 dimregidx |= bits << bitpos;
4089 bitpos += pDimensionDefinitions[i].bits;
4093 if (!dimreg)
return -1;
4099 bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4101 const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4102 dimregidx |= (bits & limiter_mask) << velbitpos;
4119 return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
4120 << pDimensionDefinitions[5].bits | DimBits[5])
4121 << pDimensionDefinitions[4].bits | DimBits[4])
4122 << pDimensionDefinitions[3].bits | DimBits[3])
4123 << pDimensionDefinitions[2].bits | DimBits[2])
4124 << pDimensionDefinitions[1].bits | DimBits[1])
4125 << pDimensionDefinitions[0].bits | DimBits[0]];
4138 if (pSample)
return static_cast<gig::Sample*
>(pSample);
4139 else return static_cast<gig::Sample*
>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
4142 Sample* Region::GetSampleFromWavePool(
unsigned int WavePoolTableIndex,
progress_t* pProgress) {
4143 if ((int32_t)WavePoolTableIndex == -1)
return NULL;
4144 File* file = (
File*) GetParent()->GetParent();
4145 if (!file->pWavePoolTable)
return NULL;
4146 if (WavePoolTableIndex + 1 > file->WavePoolCount)
return NULL;
4150 uint64_t soughtoffset =
4151 uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
4152 uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
4155 if (sample->ullWavePoolOffset == soughtoffset)
4161 file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
4162 file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
4165 if (sample->ullWavePoolOffset == soughtoffset &&
4197 if (mSamples && mSamples->count((
gig::Sample*)orig->pSample)) {
4198 pSample = mSamples->find((
gig::Sample*)orig->pSample)->second;
4202 for (
int i = Dimensions - 1; i >= 0; --i) {
4203 DeleteDimension(&pDimensionDefinitions[i]);
4212 for (
int i = 0; i < 256; i++) {
4214 pDimensionRegions[i]->CopyAssign(
4227 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(
RIFF::Chunk* _3ewg) {
4233 for (
int i = 0 ; i < Triggers ; i++) {
4234 pTriggers[i].TriggerPoint = _3ewg->
ReadUint8();
4235 pTriggers[i].Descending = _3ewg->
ReadUint8();
4236 pTriggers[i].VelSensitivity = _3ewg->
ReadUint8();
4238 pTriggers[i].NoteOff = _3ewg->
ReadUint8();
4239 pTriggers[i].Velocity = _3ewg->
ReadUint8();
4240 pTriggers[i].OverridePedal = _3ewg->
ReadUint8();
4245 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
4246 ControllerNumber(0),
4250 void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData)
const {
4253 pData[36] = Triggers;
4254 pData[40] = ControllerNumber;
4255 for (
int i = 0 ; i < Triggers ; i++) {
4256 pData[46 + i * 8] = pTriggers[i].TriggerPoint;
4257 pData[47 + i * 8] = pTriggers[i].Descending;
4258 pData[48 + i * 8] = pTriggers[i].VelSensitivity;
4259 pData[49 + i * 8] = pTriggers[i].Key;
4260 pData[50 + i * 8] = pTriggers[i].NoteOff;
4261 pData[51 + i * 8] = pTriggers[i].Velocity;
4262 pData[52 + i * 8] = pTriggers[i].OverridePedal;
4266 MidiRuleLegato::MidiRuleLegato(
RIFF::Chunk* _3ewg) {
4270 BypassUseController = _3ewg->
ReadUint8();
4285 MidiRuleLegato::MidiRuleLegato() :
4287 BypassUseController(
false),
4289 BypassController(1),
4292 ReleaseTriggerKey(0),
4296 KeyRange.low = KeyRange.high = 0;
4299 void MidiRuleLegato::UpdateChunks(uint8_t* pData)
const {
4302 pData[36] = LegatoSamples;
4303 pData[40] = BypassUseController;
4304 pData[41] = BypassKey;
4305 pData[42] = BypassController;
4306 store16(&pData[43], ThresholdTime);
4307 store16(&pData[47], ReleaseTime);
4308 pData[51] = KeyRange.low;
4309 pData[52] = KeyRange.high;
4310 pData[64] = ReleaseTriggerKey;
4311 pData[65] = AltSustain1Key;
4312 pData[66] = AltSustain2Key;
4315 MidiRuleAlternator::MidiRuleAlternator(
RIFF::Chunk* _3ewg) {
4319 Polyphonic = flags & 8;
4320 Chained = flags & 4;
4321 Selector = (flags & 2) ? selector_controller :
4322 (flags & 1) ? selector_key_switch : selector_none;
4328 KeySwitchRange.low = _3ewg->
ReadUint8();
4329 KeySwitchRange.high = _3ewg->
ReadUint8();
4334 int n = std::min(
int(Articulations), 32);
4335 for (
int i = 0 ; i < n ; i++) {
4339 n = std::min(
int(Patterns), 32);
4340 for (
int i = 0 ; i < n ; i++) {
4343 _3ewg->
Read(&pPatterns[i][0], 1, 32);
4347 MidiRuleAlternator::MidiRuleAlternator() :
4350 Selector(selector_none),
4355 PlayRange.low = PlayRange.high = 0;
4356 KeySwitchRange.low = KeySwitchRange.high = 0;
4359 void MidiRuleAlternator::UpdateChunks(uint8_t* pData)
const {
4362 pData[36] = Articulations;
4363 pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4364 (Selector == selector_controller ? 2 :
4365 (Selector == selector_key_switch ? 1 : 0));
4366 pData[38] = Patterns;
4368 pData[43] = KeySwitchRange.low;
4369 pData[44] = KeySwitchRange.high;
4370 pData[45] = Controller;
4371 pData[46] = PlayRange.low;
4372 pData[47] = PlayRange.high;
4374 char* str =
reinterpret_cast<char*
>(pData);
4376 int n = std::min(
int(Articulations), 32);
4377 for (
int i = 0 ; i < n ; i++, pos += 32) {
4378 strncpy(&str[pos], pArticulations[i].c_str(), 32);
4382 n = std::min(
int(Patterns), 32);
4383 for (
int i = 0 ; i < n ; i++, pos += 49) {
4384 strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4385 pData[pos + 16] = pPatterns[i].Size;
4386 memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4399 Compression = (Compression_t) ckScri->
ReadUint32();
4400 Encoding = (Encoding_t) ckScri->
ReadUint32();
4401 Language = (Language_t) ckScri->
ReadUint32();
4402 Bypass = (Language_t) ckScri->
ReadUint32() & 1;
4405 Name.resize(nameSize,
' ');
4406 for (
int i = 0; i < nameSize; ++i)
4409 ckScri->
SetPos(
sizeof(int32_t) + headerSize);
4411 uint32_t scriptSize = uint32_t(ckScri->
GetSize() - ckScri->
GetPos());
4412 data.resize(scriptSize);
4413 for (
int i = 0; i < scriptSize; ++i)
4416 Compression = COMPRESSION_NONE;
4417 Encoding = ENCODING_ASCII;
4418 Language = LANGUAGE_NKSP;
4421 Name =
"Unnamed Script";
4433 s.resize(data.size(),
' ');
4434 memcpy(&s[0], &data[0], data.size());
4445 data.resize(text.size());
4446 memcpy(&data[0], &text[0], text.size());
4461 __calculateCRC(&data[0], data.size(),
crc);
4464 const file_offset_t chunkSize = (file_offset_t) 7*
sizeof(int32_t) + Name.size() + data.size();
4465 if (!pChunk) pChunk =
pGroup->pList->AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4466 else pChunk->Resize(chunkSize);
4468 uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4470 store32(&pData[pos], uint32_t(6*
sizeof(int32_t) + Name.size()));
4471 pos +=
sizeof(int32_t);
4472 store32(&pData[pos], Compression);
4473 pos +=
sizeof(int32_t);
4474 store32(&pData[pos], Encoding);
4475 pos +=
sizeof(int32_t);
4476 store32(&pData[pos], Language);
4477 pos +=
sizeof(int32_t);
4478 store32(&pData[pos], Bypass ? 1 : 0);
4479 pos +=
sizeof(int32_t);
4480 store32(&pData[pos], crc);
4481 pos +=
sizeof(int32_t);
4482 store32(&pData[pos], (uint32_t) Name.size());
4483 pos +=
sizeof(int32_t);
4484 for (
int i = 0; i < Name.size(); ++i, ++pos)
4485 pData[pos] = Name[i];
4486 for (
int i = 0; i < data.size(); ++i, ++pos)
4487 pData[pos] = data[i];
4497 if (this->pGroup == pGroup)
return;
4499 pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4529 void Script::RemoveAllScriptReferences() {
4546 ::LoadString(ckName, Name);
4548 Name =
"Default Group";
4552 ScriptGroup::~ScriptGroup() {
4554 std::list<Script*>::iterator iter = pScripts->begin();
4555 std::list<Script*>::iterator end = pScripts->end();
4556 while (iter != end) {
4576 pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
4579 ::SaveString(CHUNK_ID_LSNM, NULL, pList, Name, String(
"Unnamed Group"),
true, 64);
4581 for (std::list<Script*>::iterator it = pScripts->begin();
4582 it != pScripts->end(); ++it)
4584 (*it)->UpdateChunks(pProgress);
4597 if (!pScripts) LoadScripts();
4598 std::list<Script*>::iterator it = pScripts->begin();
4599 for (uint i = 0; it != pScripts->end(); ++i, ++it)
4600 if (i == index)
return *it;
4616 if (!pScripts) LoadScripts();
4618 pScripts->push_back(pScript);
4633 if (!pScripts) LoadScripts();
4634 std::list<Script*>::iterator iter =
4635 find(pScripts->begin(), pScripts->end(), pScript);
4636 if (iter == pScripts->end())
4637 throw gig::Exception(
"Could not delete script, could not find given script");
4638 pScripts->erase(iter);
4639 pScript->RemoveAllScriptReferences();
4640 if (pScript->pChunk)
4645 void ScriptGroup::LoadScripts() {
4646 if (pScripts)
return;
4647 pScripts =
new std::list<Script*>;
4650 for (
RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck;
4651 ck = pList->GetNextSubChunk())
4653 if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4654 pScripts->push_back(
new Script(
this, ck));
4663 static const DLS::Info::string_length_t fixedStringLengths[] = {
4664 { CHUNK_ID_INAM, 64 },
4665 { CHUNK_ID_ISFT, 12 },
4671 for (
int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4676 PianoReleaseMode =
false;
4677 DimensionKeyRange.low = 0;
4678 DimensionKeyRange.high = 0;
4680 pMidiRules[0] = NULL;
4692 uint8_t dimkeystart = _3ewg->
ReadUint8();
4693 PianoReleaseMode = dimkeystart & 0x01;
4694 DimensionKeyRange.low = dimkeystart >> 1;
4695 DimensionKeyRange.high = _3ewg->
ReadUint8();
4707 }
else if (id1 == 0) {
4709 }
else if (id1 == 3) {
4715 else if (id1 != 0 || id2 != 0) {
4720 pMidiRules[i] = NULL;
4725 if (pFile->GetAutoLoad()) {
4726 if (!pRegions) pRegions =
new RegionList;
4732 __notify_progress(pProgress, (
float) pRegions->size() / (float) Regions);
4733 pRegions->push_back(
new Region(
this, rgn));
4738 UpdateRegionKeyTable();
4751 ckSCSL->
SetPos(headerSize);
4752 int unknownSpace = slotSize - 2*
sizeof(uint32_t);
4753 for (
int i = 0; i < slotCount; ++i) {
4754 _ScriptPooolEntry e;
4757 if (unknownSpace) ckSCSL->
SetPos(unknownSpace, RIFF::stream_curpos);
4758 scriptPoolFileOffsets.push_back(e);
4764 __notify_progress(pProgress, 1.0f);
4767 void Instrument::UpdateRegionKeyTable() {
4768 for (
int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4769 RegionList::iterator iter = pRegions->begin();
4770 RegionList::iterator end = pRegions->end();
4771 for (; iter != end; ++iter) {
4773 const int low = std::max(
int(pRegion->
KeyRange.
low), 0);
4774 const int high = std::min(
int(pRegion->
KeyRange.
high), 127);
4775 for (
int iKey = low; iKey <= high; iKey++) {
4776 RegionKeyTable[iKey] = pRegion;
4782 for (
int i = 0 ; pMidiRules[i] ; i++) {
4783 delete pMidiRules[i];
4785 delete[] pMidiRules;
4786 if (pScriptRefs)
delete pScriptRefs;
4805 RegionList::iterator iter = pRegions->begin();
4806 RegionList::iterator end = pRegions->end();
4807 for (; iter != end; ++iter)
4808 (*iter)->UpdateChunks(pProgress);
4813 if (!lart) lart = pCkInstrument->
AddSubList(LIST_TYPE_LART);
4826 store16(&pData[0], EffectSend);
4827 store32(&pData[2], Attenuation);
4829 store16(&pData[8], PitchbendRange);
4830 const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
4831 DimensionKeyRange.low << 1;
4832 pData[10] = dimkeystart;
4833 pData[11] = DimensionKeyRange.high;
4835 if (pMidiRules[0] == 0 && _3ewg->
GetSize() >= 34) {
4839 for (
int i = 0 ; pMidiRules[i] ; i++) {
4840 pMidiRules[i]->UpdateChunks(pData);
4845 if (ScriptSlotCount()) {
4851 if (!lst3LS) lst3LS = pCkInstrument->
AddSubList(LIST_TYPE_3LS);
4852 const int slotCount = (int) pScriptRefs->size();
4853 const int headerSize = 3 *
sizeof(uint32_t);
4854 const int slotSize = 2 *
sizeof(uint32_t);
4855 const int totalChunkSize = headerSize + slotCount * slotSize;
4857 if (!ckSCSL) ckSCSL = lst3LS->
AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
4858 else ckSCSL->
Resize(totalChunkSize);
4861 store32(&pData[pos], headerSize);
4862 pos +=
sizeof(uint32_t);
4863 store32(&pData[pos], slotCount);
4864 pos +=
sizeof(uint32_t);
4865 store32(&pData[pos], slotSize);
4866 pos +=
sizeof(uint32_t);
4867 for (
int i = 0; i < slotCount; ++i) {
4870 int bogusFileOffset = 0;
4871 store32(&pData[pos], bogusFileOffset);
4872 pos +=
sizeof(uint32_t);
4873 store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
4874 pos +=
sizeof(uint32_t);
4883 void Instrument::UpdateScriptFileOffsets() {
4885 if (pScriptRefs && pScriptRefs->size() > 0) {
4888 const int slotCount = (int) pScriptRefs->size();
4889 const int headerSize = 3 *
sizeof(uint32_t);
4890 ckSCSL->
SetPos(headerSize);
4891 for (
int i = 0; i < slotCount; ++i) {
4892 uint32_t fileOffset = uint32_t(
4893 (*pScriptRefs)[i].script->pChunk->GetFilePos() -
4894 (*pScriptRefs)[i].script->pChunk->GetPos() -
4899 ckSCSL->
SetPos(
sizeof(uint32_t), RIFF::stream_curpos);
4912 if (!pRegions || pRegions->empty() || Key > 127)
return NULL;
4913 return RegionKeyTable[Key];
4930 if (!pRegions)
return NULL;
4931 RegionsIterator = pRegions->begin();
4932 return static_cast<gig::Region*
>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4944 if (!pRegions)
return NULL;
4946 return static_cast<gig::Region*
>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
4949 Region* Instrument::AddRegion() {
4952 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
4955 pRegions->push_back(pNewRegion);
4956 Regions = (uint32_t) pRegions->size();
4958 UpdateRegionKeyTable();
4963 void Instrument::DeleteRegion(
Region* pRegion) {
4964 if (!pRegions)
return;
4965 DLS::Instrument::DeleteRegion((
DLS::Region*) pRegion);
4967 UpdateRegionKeyTable();
4998 if (dst && GetParent() != dst->GetParent())
5000 "gig::Instrument::MoveTo() can only be used for moving within " 5001 "the same gig file." 5008 File::InstrumentList& list = *pFile->pInstruments;
5010 File::InstrumentList::iterator itFrom =
5011 std::find(list.begin(), list.end(),
static_cast<DLS::Instrument*
>(
this));
5013 File::InstrumentList::iterator itTo =
5014 std::find(list.begin(), list.end(),
static_cast<DLS::Instrument*
>(dst));
5016 list.splice(itTo, list, itFrom);
5022 this->pCkInstrument,
5023 (
RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
5038 return pMidiRules[i];
5047 delete pMidiRules[0];
5060 delete pMidiRules[0];
5073 delete pMidiRules[0];
5086 delete pMidiRules[i];
5090 void Instrument::LoadScripts() {
5091 if (pScriptRefs)
return;
5092 pScriptRefs =
new std::vector<_ScriptPooolRef>;
5093 if (scriptPoolFileOffsets.empty())
return;
5095 for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
5096 uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
5099 for (uint s = 0; group->
GetScript(s); ++s) {
5101 if (script->pChunk) {
5102 uint32_t offset = uint32_t(
5104 script->pChunk->
GetPos() -
5107 if (offset == soughtOffset)
5109 _ScriptPooolRef ref;
5110 ref.script = script;
5111 ref.bypass = scriptPoolFileOffsets[k].bypass;
5112 pScriptRefs->push_back(ref);
5120 scriptPoolFileOffsets.clear();
5137 if (index >= pScriptRefs->size())
return NULL;
5138 return pScriptRefs->at(index).script;
5178 _ScriptPooolRef ref = { pScript, bypass };
5179 pScriptRefs->push_back(ref);
5198 if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
5200 _ScriptPooolRef tmp = (*pScriptRefs)[index1];
5201 (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
5202 (*pScriptRefs)[index2] = tmp;
5213 if (index >= pScriptRefs->size())
return;
5214 pScriptRefs->erase( pScriptRefs->begin() + index );
5231 for (ssize_t i = pScriptRefs->size() - 1; i >= 0; --i) {
5232 if ((*pScriptRefs)[i].script == pScript) {
5233 pScriptRefs->erase( pScriptRefs->begin() + i );
5253 return uint(pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size());
5273 if (index >= ScriptSlotCount())
return false;
5274 return pScriptRefs ? pScriptRefs->at(index).bypass
5275 : scriptPoolFileOffsets.at(index).bypass;
5293 if (index >= ScriptSlotCount())
return;
5295 pScriptRefs->at(index).bypass = bBypass;
5297 scriptPoolFileOffsets.at(index).bypass = bBypass;
5324 DLS::Instrument::CopyAssignCore(orig);
5328 EffectSend = orig->EffectSend;
5331 PianoReleaseMode = orig->PianoReleaseMode;
5333 scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
5334 pScriptRefs = orig->pScriptRefs;
5337 for (
int i = 0 ; pMidiRules[i] ; i++) {
5338 delete pMidiRules[i];
5341 pMidiRules[0] = NULL;
5344 while (Regions) DeleteRegion(GetFirstRegion());
5347 RegionList::const_iterator it = orig->pRegions->begin();
5348 for (
int i = 0; i < orig->
Regions; ++i, ++it) {
5349 Region* dstRgn = AddRegion();
5352 static_cast<gig::Region*>(*it),
5358 UpdateRegionKeyTable();
5373 pNameChunk = ck3gnm;
5374 ::LoadString(pNameChunk, Name);
5379 if (pNameChunk) pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
5396 _3gri = pFile->pRIFF->
AddSubList(LIST_TYPE_3GRI);
5400 if (!_3gnl) _3gnl = _3gri->
AddSubList(LIST_TYPE_3GNL);
5405 if (strcmp(static_cast<char*>(ck->LoadChunkData()),
"") == 0) {
5413 ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl, Name, String(
"Unnamed Group"),
true, 64);
5430 if (pSample->GetGroup() ==
this)
return pSample;
5448 if (pSample->GetGroup() ==
this)
return pSample;
5468 Group* pOtherGroup = NULL;
5469 for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
5470 if (pOtherGroup !=
this)
break;
5473 "Could not move samples to another group, since there is no " 5474 "other Group. This is a bug, report it!" 5477 for (
Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
5489 0, 2, 19980628 & 0xffff, 19980628 >> 16
5494 0, 3, 20030331 & 0xffff, 20030331 >> 16
5497 static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
5498 { CHUNK_ID_IARL, 256 },
5499 { CHUNK_ID_IART, 128 },
5500 { CHUNK_ID_ICMS, 128 },
5501 { CHUNK_ID_ICMT, 1024 },
5502 { CHUNK_ID_ICOP, 128 },
5503 { CHUNK_ID_ICRD, 128 },
5504 { CHUNK_ID_IENG, 128 },
5505 { CHUNK_ID_IGNR, 128 },
5506 { CHUNK_ID_IKEY, 128 },
5507 { CHUNK_ID_IMED, 128 },
5508 { CHUNK_ID_INAM, 128 },
5509 { CHUNK_ID_IPRD, 128 },
5510 { CHUNK_ID_ISBJ, 128 },
5511 { CHUNK_ID_ISFT, 128 },
5512 { CHUNK_ID_ISRC, 128 },
5513 { CHUNK_ID_ISRF, 128 },
5514 { CHUNK_ID_ITCH, 128 },
5520 *pVersion = VERSION_3;
5522 pScriptGroups = NULL;
5528 pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
5529 pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
5530 pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
5538 pScriptGroups = NULL;
5544 std::list<Group*>::iterator iter = pGroups->begin();
5545 std::list<Group*>::iterator end = pGroups->end();
5546 while (iter != end) {
5552 if (pScriptGroups) {
5553 std::list<ScriptGroup*>::iterator iter = pScriptGroups->begin();
5554 std::list<ScriptGroup*>::iterator end = pScriptGroups->end();
5555 while (iter != end) {
5559 delete pScriptGroups;
5564 if (!pSamples) LoadSamples(pProgress);
5565 if (!pSamples)
return NULL;
5566 SamplesIterator = pSamples->begin();
5567 return static_cast<gig::Sample*
>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5571 if (!pSamples)
return NULL;
5573 return static_cast<gig::Sample*
>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5582 if (!pSamples) LoadSamples();
5583 if (!pSamples)
return NULL;
5584 DLS::File::SampleList::iterator it = pSamples->begin();
5585 for (
int i = 0; i < index; ++i) {
5587 if (it == pSamples->end())
return NULL;
5589 if (it == pSamples->end())
return NULL;
5601 if (!pSamples) LoadSamples();
5602 __ensureMandatoryChunksExist();
5612 pSamples->push_back(pSample);
5626 if (!pSamples || !pSamples->size())
throw gig::Exception(
"Could not delete sample as there are no samples");
5627 SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (
DLS::Sample*) pSample);
5628 if (iter == pSamples->end())
throw gig::Exception(
"Could not delete sample, could not find given sample");
5629 if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator;
5630 pSamples->erase(iter);
5633 SampleList::iterator tmp = SamplesIterator;
5635 for (
Instrument* instrument = GetFirstInstrument() ; instrument ;
5636 instrument = GetNextInstrument()) {
5637 for (
Region* region = instrument->GetFirstRegion() ; region ;
5638 region = instrument->GetNextRegion()) {
5640 if (region->GetSample() == pSample) region->SetSample(NULL);
5642 for (
int i = 0 ; i < region->DimensionRegions ; i++) {
5648 SamplesIterator = tmp;
5651 void File::LoadSamples() {
5655 void File::LoadSamples(
progress_t* pProgress) {
5658 if (!pGroups) LoadGroups();
5660 if (!pSamples) pSamples =
new SampleList;
5665 int iSampleIndex = 0;
5666 int iTotalSamples = WavePoolCount;
5672 for (
int i = 0 ; i < WavePoolCount ; i++) {
5673 if (pWavePoolTableHi[i] > lastFileNo) lastFileNo = pWavePoolTableHi[i];
5676 String name(pRIFF->GetFileName());
5677 int nameLen = (int) name.length();
5679 if (nameLen > 4 && name.substr(nameLen - 4) ==
".gig") nameLen -= 4;
5681 for (
int fileNo = 0 ; ; ) {
5684 file_offset_t wvplFileOffset = wvpl->
GetFilePos();
5689 const float subprogress = (float) iSampleIndex / (
float) iTotalSamples;
5690 __notify_progress(pProgress, subprogress);
5692 file_offset_t waveFileOffset = wave->
GetFilePos();
5693 pSamples->push_back(
new Sample(
this, wave, waveFileOffset - wvplFileOffset, fileNo, iSampleIndex));
5700 if (fileNo == lastFileNo)
break;
5704 sprintf(suffix,
".gx%02d", fileNo);
5705 name.replace(nameLen, 5, suffix);
5707 ExtensionFiles.push_back(file);
5711 __notify_progress(pProgress, 1.0);
5715 if (!pInstruments) LoadInstruments();
5716 if (!pInstruments)
return NULL;
5717 InstrumentsIterator = pInstruments->begin();
5718 return static_cast<gig::Instrument*
>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5722 if (!pInstruments)
return NULL;
5723 InstrumentsIterator++;
5724 return static_cast<gig::Instrument*
>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5735 if (!pInstruments) {
5740 __divide_progress(pProgress, &subprogress, 3.0f, 0.0f);
5741 __notify_progress(&subprogress, 0.0f);
5743 GetFirstSample(&subprogress);
5744 __notify_progress(&subprogress, 1.0f);
5747 if (pProgress && pProgress->
callback) {
5751 __notify_progress(&subprogress, 0.0f);
5752 LoadInstruments(&subprogress);
5753 __notify_progress(&subprogress, 1.0f);
5755 if (!pInstruments)
return NULL;
5756 InstrumentsIterator = pInstruments->begin();
5757 for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
5758 if (i == index)
return static_cast<gig::Instrument*
>( *InstrumentsIterator );
5759 InstrumentsIterator++;
5772 if (!pInstruments) LoadInstruments();
5773 __ensureMandatoryChunksExist();
5789 pInstruments->push_back(pInstrument);
5826 static int iCallCount = -1;
5828 std::map<Group*,Group*> mGroups;
5829 std::map<Sample*,Sample*> mSamples;
5832 for (
int i = 0; pFile->
GetGroup(i); ++i) {
5833 Group* g = AddGroup();
5835 "COPY" + ToString(iCallCount) +
"_" + pFile->
GetGroup(i)->
Name;
5840 for (
int i = 0; pFile->
GetSample(i); ++i) {
5851 dg->
Name =
"COPY" + ToString(iCallCount) +
"_" + sg->
Name;
5852 for (
int iScript = 0; sg->
GetScript(iScript); ++iScript) {
5866 Save(GetFileName());
5884 for (
int i = 0; pFile->
GetSample(i); ++i) {
5898 if (!pInstruments)
throw gig::Exception(
"Could not delete instrument as there are no instruments");
5899 InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (
DLS::Instrument*) pInstrument);
5900 if (iter == pInstruments->end())
throw gig::Exception(
"Could not delete instrument, could not find given instrument");
5901 pInstruments->erase(iter);
5905 void File::LoadInstruments() {
5906 LoadInstruments(NULL);
5909 void File::LoadInstruments(
progress_t* pProgress) {
5910 if (!pInstruments) pInstruments =
new InstrumentList;
5912 if (lstInstruments) {
5913 int iInstrumentIndex = 0;
5918 const float localProgress = (float) iInstrumentIndex / (
float) Instruments;
5919 __notify_progress(pProgress, localProgress);
5923 __divide_progress(pProgress, &subprogress, Instruments, iInstrumentIndex);
5925 pInstruments->push_back(
new Instrument(
this, lstInstr, &subprogress));
5931 __notify_progress(pProgress, 1.0);
5943 int iWaveIndex = GetWaveTableIndexOf(pSample);
5944 if (iWaveIndex < 0)
throw gig::Exception(
"Could not update crc, could not find sample");
5947 _3crc->
SetPos(iWaveIndex * 8);
5953 uint32_t File::GetSampleChecksum(
Sample* pSample) {
5955 int iWaveIndex = GetWaveTableIndexOf(pSample);
5956 if (iWaveIndex < 0)
throw gig::Exception(
"Could not retrieve reference crc of sample, could not resolve sample's wave table index");
5958 return GetSampleChecksumByIndex(iWaveIndex);
5961 uint32_t File::GetSampleChecksumByIndex(
int index) {
5962 if (index < 0)
throw gig::Exception(
"Could not retrieve reference crc of sample, invalid wave pool index of sample");
5965 if (!_3crc)
throw gig::Exception(
"Could not retrieve reference crc of sample, no checksums stored for this file yet");
5967 if (!pData)
throw gig::Exception(
"Could not retrieve reference crc of sample, no checksums stored for this file yet");
5970 size_t pos = index * 8;
5972 throw gig::Exception(
"Could not retrieve reference crc of sample, could not seek to required position in crc chunk");
5974 uint32_t one = load32(&pData[pos]);
5976 throw gig::Exception(
"Could not retrieve reference crc of sample, because reference checksum table is damaged");
5978 return load32(&pData[pos+4]);
5981 int File::GetWaveTableIndexOf(
gig::Sample* pSample) {
5982 if (!pSamples) GetFirstSample();
5983 File::SampleList::iterator iter = pSamples->begin();
5984 File::SampleList::iterator end = pSamples->end();
5985 for (
int index = 0; iter != end; ++iter, ++index)
5986 if (*iter == pSample)
5999 if (!_3crc)
return false;
6002 if (!pSamples) GetFirstSample();
6003 if (_3crc->
GetNewSize() != pSamples->size() * 8)
return false;
6005 const file_offset_t n = _3crc->
GetNewSize() / 8;
6008 if (!pData)
return false;
6010 for (file_offset_t i = 0; i < n; ++i) {
6011 uint32_t one = pData[i*2];
6012 if (one != 1)
return false;
6036 if (!pSamples) GetFirstSample();
6038 bool bRequiresSave =
false;
6043 _3crc = pRIFF->
AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6046 if (einf && pVersion && pVersion->major == 3) pRIFF->
MoveSubChunk(_3crc, einf);
6047 bRequiresSave =
true;
6048 }
else if (_3crc->
GetNewSize() != pSamples->size() * 8) {
6049 _3crc->
Resize(pSamples->size() * 8);
6050 bRequiresSave =
true;
6053 if (bRequiresSave) {
6056 File::SampleList::iterator iter = pSamples->begin();
6057 File::SampleList::iterator end = pSamples->end();
6058 for (; iter != end; ++iter) {
6060 int index = GetWaveTableIndexOf(pSample);
6061 if (index < 0)
throw gig::Exception(
"Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6063 pData[index*2+1] = pSample->CalculateWaveDataChecksum();
6068 pRIFF->
SetMode(RIFF::stream_mode_read_write);
6070 File::SampleList::iterator iter = pSamples->begin();
6071 File::SampleList::iterator end = pSamples->end();
6072 for (; iter != end; ++iter) {
6074 int index = GetWaveTableIndexOf(pSample);
6075 if (index < 0)
throw gig::Exception(
"Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6076 pSample->
crc = pSample->CalculateWaveDataChecksum();
6077 SetSampleChecksum(pSample, pSample->
crc);
6082 return bRequiresSave;
6086 if (!pGroups) LoadGroups();
6088 GroupsIterator = pGroups->begin();
6089 return *GroupsIterator;
6093 if (!pGroups)
return NULL;
6095 return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
6105 if (!pGroups) LoadGroups();
6106 GroupsIterator = pGroups->begin();
6107 for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
6108 if (i == index)
return *GroupsIterator;
6125 if (!pGroups) LoadGroups();
6126 GroupsIterator = pGroups->begin();
6127 for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
6128 if ((*GroupsIterator)->Name == name)
return *GroupsIterator;
6132 Group* File::AddGroup() {
6133 if (!pGroups) LoadGroups();
6135 __ensureMandatoryChunksExist();
6137 pGroups->push_back(pGroup);
6151 if (!pGroups) LoadGroups();
6152 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(),
pGroup);
6153 if (iter == pGroups->end())
throw gig::Exception(
"Could not delete group, could not find given group");
6154 if (pGroups->size() == 1)
throw gig::Exception(
"Cannot delete group, there must be at least one default group!");
6157 DeleteSample(pSample);
6160 pGroups->erase(iter);
6175 if (!pGroups) LoadGroups();
6176 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(),
pGroup);
6177 if (iter == pGroups->end())
throw gig::Exception(
"Could not delete group, could not find given group");
6178 if (pGroups->size() == 1)
throw gig::Exception(
"Cannot delete group, there must be at least one default group!");
6181 pGroups->erase(iter);
6185 void File::LoadGroups() {
6186 if (!pGroups) pGroups =
new std::list<Group*>;
6195 if (pVersion && pVersion->major == 3 &&
6196 strcmp(static_cast<char*>(ck->
LoadChunkData()),
"") == 0)
break;
6198 pGroups->push_back(
new Group(
this, ck));
6205 if (!pGroups->size()) {
6207 pGroup->
Name =
"Default Group";
6208 pGroups->push_back(pGroup);
6220 if (!pScriptGroups) LoadScriptGroups();
6221 std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6222 for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6223 if (i == index)
return *it;
6236 if (!pScriptGroups) LoadScriptGroups();
6237 std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6238 for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6239 if ((*it)->Name == name)
return *it;
6252 if (!pScriptGroups) LoadScriptGroups();
6254 pScriptGroups->push_back(pScriptGroup);
6255 return pScriptGroup;
6271 if (!pScriptGroups) LoadScriptGroups();
6272 std::list<ScriptGroup*>::iterator iter =
6273 find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
6274 if (iter == pScriptGroups->end())
6275 throw gig::Exception(
"Could not delete script group, could not find given script group");
6276 pScriptGroups->erase(iter);
6277 for (
int i = 0; pScriptGroup->
GetScript(i); ++i)
6279 if (pScriptGroup->pList)
6281 delete pScriptGroup;
6284 void File::LoadScriptGroups() {
6285 if (pScriptGroups)
return;
6286 pScriptGroups =
new std::list<ScriptGroup*>;
6292 if (lst->GetListType() == LIST_TYPE_RTIS) {
6293 pScriptGroups->push_back(
new ScriptGroup(
this, lst));
6311 bool newFile = pRIFF->
GetSubList(LIST_TYPE_INFO) == NULL;
6328 if (pScriptGroups) {
6330 for (std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6331 it != pScriptGroups->end(); ++it)
6333 (*it)->UpdateChunks(pProgress);
6352 if (first != info) {
6367 if (!_3gnl) _3gnl = _3gri->
AddSubList(LIST_TYPE_3GNL);
6371 if (pVersion && pVersion->major == 3) {
6373 for (
int i = 0 ; i < 128 ; i++) {
6374 if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl,
"",
"",
true, 64);
6379 std::list<Group*>::iterator iter = pGroups->begin();
6380 std::list<Group*>::iterator end = pGroups->end();
6381 for (; iter != end; ++iter) {
6382 (*iter)->UpdateChunks(pProgress);
6402 int sublen = int(pSamples->size() / 8 + 49);
6403 int einfSize = (Instruments + 1) * sublen;
6407 if (einf->
GetSize() != einfSize) {
6411 }
else if (newFile) {
6412 einf = pRIFF->
AddSubChunk(CHUNK_ID_EINF, einfSize);
6417 std::map<gig::Sample*,int> sampleMap;
6419 for (
Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
6420 sampleMap[pSample] = sampleIdx++;
6423 int totnbusedsamples = 0;
6424 int totnbusedchannels = 0;
6425 int totnbregions = 0;
6426 int totnbdimregions = 0;
6428 int instrumentIdx = 0;
6430 memset(&pData[48], 0, sublen - 48);
6432 for (
Instrument* instrument = GetFirstInstrument() ; instrument ;
6433 instrument = GetNextInstrument()) {
6434 int nbusedsamples = 0;
6435 int nbusedchannels = 0;
6436 int nbdimregions = 0;
6439 memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
6441 for (
Region* region = instrument->GetFirstRegion() ; region ;
6442 region = instrument->GetNextRegion()) {
6443 for (
int i = 0 ; i < region->DimensionRegions ; i++) {
6446 int sampleIdx = sampleMap[d->
pSample];
6447 int byte = 48 + sampleIdx / 8;
6448 int bit = 1 << (sampleIdx & 7);
6449 if ((pData[(instrumentIdx + 1) * sublen + byte] & bit) == 0) {
6450 pData[(instrumentIdx + 1) * sublen + byte] |= bit;
6454 if ((pData[byte] & bit) == 0) {
6463 nbdimregions += region->DimensionRegions;
6467 store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
6468 store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
6469 store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
6470 store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
6471 store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
6472 store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
6474 store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
6475 store32(&pData[(instrumentIdx + 1) * sublen + 40], (uint32_t) pSamples->size());
6478 totnbregions += instrument->Regions;
6479 totnbdimregions += nbdimregions;
6480 totnbloops += nbloops;
6485 store32(&pData[4], totnbusedchannels);
6486 store32(&pData[8], totnbusedsamples);
6487 store32(&pData[12], Instruments);
6488 store32(&pData[16], totnbregions);
6489 store32(&pData[20], totnbdimregions);
6490 store32(&pData[24], totnbloops);
6493 store32(&pData[40], (uint32_t) pSamples->size());
6513 _3crc->
Resize(pSamples->size() * 8);
6515 _3crc = pRIFF->
AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6517 if (einf && pVersion && pVersion->major == 3) pRIFF->
MoveSubChunk(_3crc, einf);
6520 uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
6522 File::SampleList::iterator iter = pSamples->begin();
6523 File::SampleList::iterator end = pSamples->end();
6524 for (
int index = 0; iter != end; ++iter, ++index) {
6527 pData[index*2+1] = pSample->
crc;
6536 for (
Instrument* instrument = GetFirstInstrument(); instrument;
6537 instrument = GetNextInstrument())
6539 instrument->UpdateScriptFileOffsets();
6580 va_start(arg, format);
6581 Message = assemble(format, arg);
6585 Exception::Exception(String format, va_list arg) :
DLS::Exception() {
6586 Message = assemble(format, arg);
6589 void Exception::PrintMessage() {
6590 std::cout <<
"gig::Exception: " << Message << std::endl;
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...
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
void AddContentOf(File *pFile)
Add content of another existing file.
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
bool IsNew() const
Returns true if this file has been created new from scratch and has not been stored to disk yet...
file_offset_t position
Current position within the sample.
Encapsulates articulation informations of a dimension region.
dimension_none
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
sample_loop_t * pSampleLoops
Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
void SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined)...
Destination container for serialization, and source container for deserialization.
file_offset_t FrameOffset
Current offset (sample points) in current sample frame (for decompression only).
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
String GetScriptAsText()
Returns the current script (i.e.
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
split_type_normal split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
vcf_res_ctrl_none
Defines how the filter resonance is controlled by.
Sample * AddSample()
Add a new 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).
Parses DLS Level 1 and 2 compliant files and provides abstract access to the data.
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
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...
stream_whence_t
File stream position dependent to these relations.
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
Chunk * GetFirstSubChunk()
Returns the first subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
Group of Gigasampler samples.
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
String Name
Stores the name of this Group.
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index)...
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
Defines behavior options for envelope generators (gig format extension).
Script * AddScript()
Add new instrument script.
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...
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Instrument * AddInstrument()
Add a new instrument definition.
file_offset_t GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
Script * GetScript(uint index)
Get instrument script.
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
Will be thrown whenever a DLS specific error occurs while trying to access a DLS File.
MIDI rule for triggering notes by control change events.
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...
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
curve_type_nonlinear
Defines the shape of a function graph.
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
file_offset_t Size
Size of the actual data in the buffer in bytes.
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
static size_t Instances
Number of instances of class Sample.
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
void ReadString(String &s, int size)
Reads a null-padded string of size characters and copies it into the string s.
file_offset_t GetSize() const
Returns sample size.
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
lfo2_ctrl_internal
Defines how LFO2 is controlled by.
uint32_t crc
Reflects CRC-32 checksum of the raw sample data at the last time when the sample's raw wave form data...
Defines a controller that has a certain contrained influence on a particular synthesis parameter (use...
uint16_t Channels
Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mon...
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Defines Region information of a Gigasampler/GigaStudio instrument.
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise)...
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
lfo1_ctrl_internal
Defines how LFO1 is controlled by.
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it's original sample rate...
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
Defines Sample Loop Points.
Language_t Language
Programming language and dialect the script is written in.
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
unsigned int Dimensions
Number of defined dimensions, do not alter!
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...
bool VerifySampleChecksumTable()
Checks whether the file's "3CRC" chunk was damaged.
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
List * GetFirstSubList()
Returns the first sublist within the list (that is a subchunk with chunk ID "LIST").
DimensionRegion * GetDimensionRegionByValue(const uint DimValues[8])
Use this method in your audio engine to get the appropriate dimension region with it's articulation d...
Compression_t Compression
Whether the script was/should be compressed, and if so, which compression algorithm shall be used...
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction...
Region * GetFirstRegion()
Returns the first Region of the instrument.
String libraryVersion()
Returns version of this C++ library.
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set...
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File...
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
void GenerateDLSID()
Generates a new DLSID for the resource.
void SetVCFCutoffController(vcf_cutoff_ctrl_t controller)
Updates the respective member variable and the lookup table / cache that depends on this value...
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Sample * pSample
Points to the Sample which is assigned to the dimension region.
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used...
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
List * GetParent() const
Returns pointer to the chunk's parent list chunk.
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
virtual void CopyAssign(const Sample *orig)
Make a deep copy of the Sample object given by orig and assign it to this object. ...
void SetAutoLoad(bool b)
Enable / disable automatic loading.
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
uint16_t low
Low value of range.
bool ReleaseCancel
Whether the "release" stage is cancelled when receiving a note-on (default: true).
void SetFixedStringLengths(const string_length_t *lengths)
Forces specific Info fields to be of a fixed length when being saved to a file.
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
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...
static buffer_t InternalDecompressionBuffer
Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples.
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
Pointer address and size of a buffer.
bool Decay1Cancel
Whether the "decay 1" stage is cancelled when receiving a note-off (default: true).
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
bool Bypass
Global bypass: if enabled, this script shall not be executed by the sampler for any instrument...
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
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)...
Group * GetGroup(uint index)
Returns the group with the given index.
String Name
Arbitrary name of the script, which may be displayed i.e. in an instrument editor.
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
uint ScriptSlotCount() const
Instrument's amount of script slots.
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors...
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
uint32_t SampleLoops
Reflects the number of sample loops.
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
void Resize(file_offset_t NewSize)
Resize sample.
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
void Resize(file_offset_t NewSize)
Resize sample.
uint16_t high
High value of range.
float __range_min
Only for internal usage, do not modify!
unsigned int Layers
Amount of defined layers (1 - 32). A value of 1 actually means no layering, a value > 1 means there i...
void * pStart
Points to the beginning of the buffer.
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...
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
Chunk * GetNextSubChunk()
Returns the next subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
void RemoveScriptSlot(uint index)
Remove script slot.
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
void DeleteGroupOnly(Group *pGroup)
Delete a group.
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
vcf_cutoff_ctrl_none
Defines how the filter cutoff frequency is controlled by.
uint32_t LoopID
Specifies the unique ID that corresponds to one of the defined cue points in the cue point list (only...
type_none
Defines possible controllers.
void DeleteSample(Sample *pSample)
Delete a sample.
bool IsScriptSlotBypassed(uint index)
Whether script execution shall be skipped.
loop_type_normal
Standard types of sample loops.
int GetFileOffsetSize() const
Returns the current size (in bytes) of file offsets stored in the headers of all chunks of this file...
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
uint32_t LoopLength
Length of the looping area (in sample points).
ScriptGroup * AddScriptGroup()
Add new instrument script group.
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field...
uint32_t GetChunkID() const
Chunk ID in unsigned integer representation.
ScriptGroup * GetScriptGroup(uint index)
Get instrument script group (by index).
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
bool RebuildSampleChecksumTable()
Recalculates CRC32 checksums for all samples and rebuilds this gig file's checksum table with those n...
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
Sample * GetNextSample()
Returns the next Sample of the Group.
Used for indicating the progress of a certain task.
file_offset_t ReadAndLoop(void *pBuffer, file_offset_t SampleCount, playback_state_t *pPlaybackState, DimensionRegion *pDimRgn, buffer_t *pExternalDecompressionBuffer=NULL)
Reads SampleCount number of sample points from the position stored in pPlaybackState into the buffer ...
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...
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
uint32_t GetListType() const
Returns unsigned integer representation of the list's ID.
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
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...
uint32_t GetWaveDataCRC32Checksum()
Returns the CRC-32 checksum of the sample's raw wave form data at the time when this sample's wave fo...
unsigned long FileNo
File number (> 0 when sample is stored in an extension file, 0 when it's in the gig) ...
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
Sample * GetFirstSample(progress_t *pProgress=NULL)
Returns a pointer to the first Sample object of the file, NULL otherwise.
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset, unsigned long fileNo=0, int index=-1)
Constructor.
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL...
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
uint32_t LoopStart
The start value specifies the offset (in sample points) in the waveform data of the first sample poin...
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
bool AttackHoldCancel
Whether the "attack hold" stage is cancelled when receiving a note-off (default: true).
String Name
Name of this script group. For example to be displayed in an instrument editor.
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame...
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
bool GetAutoLoad()
Returns whether automatic loading is enabled.
void * LoadChunkData()
Load chunk body into RAM.
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...
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
void SwapScriptSlots(uint index1, uint index2)
Flip two script slots with each other (gig format extension).
Abstract base class for all MIDI rules.
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
virtual void UpdateChunks(progress_t *pProgress)
Apply all the gig file's current instruments, samples, groups and settings to the respective RIFF chu...
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
bool AttackCancel
Whether the "attack" stage is cancelled when receiving a note-off (default: true).
dimension_def_t pDimensionDefinitions[8]
Defines the five (gig2) or eight (gig3) possible dimensions (the dimension's controller and number of...
uint8_t zones
Number of zones the dimension has.
vcf_type_lowpass
Defines which frequencies are filtered by the VCF.
buffer_t GetCache()
Returns current cached sample points.
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value...
void Resize(file_offset_t NewSize)
Resize chunk.
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value...
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
file_offset_t Read(void *pBuffer, file_offset_t SampleCount, buffer_t *pExternalDecompressionBuffer=NULL)
Reads SampleCount number of sample points from the current position into the buffer pointed by pBuffe...
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
String ArchivalLocation
<IARL-ck>. Indicates where the subject of the file is stored.
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
file_offset_t GetNewSize() const
New chunk size if it was modified with Resize(), otherwise value returned will be equal to GetSize()...
Encapsulates sample waves used for playback.
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
type_t type
Controller type.
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
File * GetFile() const
Returns pointer to the chunk's File object.
A MIDI rule not yet implemented by libgig.
Sample * GetSample(uint index)
Returns Sample object of index.
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
Real-time instrument script (gig format extension).
bool SetMode(stream_mode_t NewMode)
Change file access mode.
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
smpte_format_no_offset
Society of Motion Pictures and Television E time format.
Gigasampler/GigaStudio specific classes and definitions.
float __range_max
Only for internal usage, do not modify!
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
virtual void CopyAssign(const DimensionRegion *orig)
Make a (semi) deep copy of the DimensionRegion object given by orig and assign it to this object...
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks. ...
uint32_t LoopFraction
The fractional value specifies a fraction of a sample at which to loop. This allows a loop to be fine...
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0, 4 or 6)
Instrument * GetInstrument(uint index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
void CopyAssignCore(const Sample *orig)
Make a deep copy of the Sample object given by orig (without the actual sample waveform data however)...
Group of instrument scripts (gig format extension).
file_offset_t GetFilePos() const
Current, actual offset of chunk data body start in file.
Provides convenient access to Gigasampler/GigaStudio .gig files.
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
MIDI rule for instruments with legato samples.
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Sample * GetFirstSample()
Returns the first Sample of this Group.
dimension_def_t * GetDimensionDefinition(dimension_t type)
Searches in the current Region for a dimension of the given dimension type and returns the precise co...
bool VerifyWaveData(uint32_t *pActually=NULL)
Checks the integrity of this sample's raw audio wave data.
file_offset_t GetCurrentFileSize() const
Returns the current size of this file (in bytes) as it is currently yet stored on disk...
Provides all neccessary information for the synthesis of a DLS Instrument.
Provides access to a Gigasampler/GigaStudio instrument.
void SetScriptSlotBypassed(uint index, bool bBypass)
Defines whether execution shall be skipped.
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Encoding_t Encoding
Format the script's source code text is encoded with.
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
virtual void CopyAssign(const Instrument *orig)
Make a (semi) deep copy of the Instrument object given by orig and assign it to this object...
String libraryName()
Returns the name of this C++ library.
Quadtuple version number ("major.minor.release.build").
bool Decay2Cancel
Whether the "decay 2" stage is cancelled when receiving a note-off (default: true).
void MoveTo(Instrument *dst)
Move this instrument at the position before.
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
Script * GetScriptOfSlot(uint index)
Get instrument script (gig format extension).
void CopyAssign(const Script *orig)
Make a (semi) deep copy of the Script object given by orig and assign it to this object.
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...).
file_offset_t GetPos() const
Position within the chunk data body (starting with 0).
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...
DLS specific classes and definitions.
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
uint32_t Manufacturer
Specifies the MIDI Manufacturer's Association (MMA) Manufacturer code for the sampler intended to rec...
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...
MIDI rule to automatically cycle through specified sequences of different articulations.
Reflects the current playback state for a sample.
General dimension definition.
void CopyAssignMeta(const Sample *orig)
Make a (semi) deep copy of the Sample object given by orig (without the actual waveform data) and ass...
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
void DeleteScript(Script *pScript)
Delete an instrument script.
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
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...
List * GetNextSubList()
Returns the next sublist (that is a subchunk with chunk ID "LIST") within the list.
Defines Region information of an Instrument.
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
Region * GetNextRegion()
Returns the next Region of the instrument.
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file's current instruments, samples and settings to the respective RIFF chunks...
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.