27 #include "Serialization.h"
36 #define GIG_FILE_EXT_VERSION 2
43 #define INITIAL_SAMPLE_BUFFER_SIZE 512000
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) {
315 static int __resolveZoneSize(dimension_def_t& dimension_definition) {
317 ? int(128.0 / dimension_definition.zones) : 0;
347 eg_opt_t::eg_opt_t() {
393 static const DLS::Info::string_length_t fixedStringLengths[] = {
394 { CHUNK_ID_INAM, 64 },
408 uint32_t
crc = pFile->GetSampleChecksumByIndex(index);
417 uint16_t iSampleGroup = pCk3gix->
ReadInt16();
477 if (version > 2 &&
BitDepth == 24) {
482 ScanCompressedSample();
547 const int iReadAtOnce = 32*1024;
548 char* buf =
new char[iReadAtOnce * orig->
FrameSize];
550 file_offset_t restorePos = pOrig->
GetPos();
553 for (file_offset_t n = pOrig->
Read(buf, iReadAtOnce); n;
554 n = pOrig->
Read(buf, iReadAtOnce))
558 pOrig->
SetPos(restorePos);
581 pCkSmpl = pWaveList->
AddSubChunk(CHUNK_ID_SMPL, 60);
594 store32(&pData[28],
Loops);
598 store32(&pData[36],
LoopID);
607 if (!pCk3gix) pCk3gix = pWaveList->
AddSubChunk(CHUNK_ID_3GIX, 4);
609 uint16_t iSampleGroup = 0;
610 File* pFile =
static_cast<File*
>(pParent);
611 if (pFile->pGroups) {
612 std::list<Group*>::iterator iter = pFile->pGroups->begin();
613 std::list<Group*>::iterator end = pFile->pGroups->end();
614 for (
int i = 0; iter != end; i++, iter++) {
623 store16(&pData[0], iSampleGroup);
635 void Sample::ScanCompressedSample() {
638 std::list<file_offset_t> frameOffsets;
646 for (
int i = 0 ; ; i++) {
649 if (
BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->
GetPos());
653 if (mode_l > 5 || mode_r > 5)
throw gig::Exception(
"Unknown compression mode");
654 const file_offset_t frameSize = bytesPerFrame[mode_l] + bytesPerFrame[mode_r];
658 ((pCkData->
RemainingBytes() - headerSize[mode_l] - headerSize[mode_r]) << 3) /
659 (bitsPerSample[mode_l] + bitsPerSample[mode_r]);
664 pCkData->
SetPos(frameSize, RIFF::stream_curpos);
668 for (
int i = 0 ; ; i++) {
669 if (
BitDepth != 24 || (i & 7) == 0) frameOffsets.push_back(pCkData->
GetPos());
677 ((pCkData->
RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
682 pCkData->
SetPos(frameSize, RIFF::stream_curpos);
690 std::list<file_offset_t>::iterator end = frameOffsets.end();
691 std::list<file_offset_t>::iterator iter = frameOffsets.begin();
692 for (
int i = 0; iter != end; i++, iter++) {
794 file_offset_t allocationsize = (SampleCount + NullSamplesCount) * this->
FrameSize;
895 case RIFF::stream_curpos:
898 case RIFF::stream_end:
901 case RIFF::stream_backward:
904 case RIFF::stream_start:
default:
910 file_offset_t frame = this->
SamplePos / 2048;
916 file_offset_t orderedBytes = SampleCount * this->
FrameSize;
917 file_offset_t result = pCkData->
SetPos(orderedBytes, Whence);
918 return (result == orderedBytes) ? SampleCount
967 file_offset_t samplestoread = SampleCount, totalreadsamples = 0, readsamples, samplestoloopend;
968 uint8_t* pDst = (uint8_t*) pBuffer;
977 if (
GetPos() <= loopEnd) {
985 if (!pPlaybackState->
reverse) {
987 samplestoloopend = loopEnd -
GetPos();
988 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
989 samplestoread -= readsamples;
990 totalreadsamples += readsamples;
991 if (readsamples == samplestoloopend) {
992 pPlaybackState->
reverse =
true;
995 }
while (samplestoread && readsamples);
1005 file_offset_t swapareastart = totalreadsamples;
1007 file_offset_t samplestoreadinloop = Min(samplestoread, loopoffset);
1008 file_offset_t reverseplaybackend =
GetPos() - samplestoreadinloop;
1010 SetPos(reverseplaybackend);
1014 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], samplestoreadinloop, pExternalDecompressionBuffer);
1015 samplestoreadinloop -= readsamples;
1016 samplestoread -= readsamples;
1017 totalreadsamples += readsamples;
1018 }
while (samplestoreadinloop && readsamples);
1020 SetPos(reverseplaybackend);
1022 if (reverseplaybackend == loop.
LoopStart) {
1024 pPlaybackState->
reverse =
false;
1028 if (totalreadsamples > swapareastart)
1029 SwapMemoryArea(&pDst[swapareastart * this->
FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1031 }
while (samplestoread && readsamples);
1037 if (!pPlaybackState->
reverse)
do {
1038 samplestoloopend = loopEnd -
GetPos();
1039 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1040 samplestoread -= readsamples;
1041 totalreadsamples += readsamples;
1042 if (readsamples == samplestoloopend) {
1043 pPlaybackState->
reverse =
true;
1046 }
while (samplestoread && readsamples);
1048 if (!samplestoread)
break;
1056 file_offset_t swapareastart = totalreadsamples;
1060 file_offset_t reverseplaybackend = loop.
LoopStart + Abs((loopoffset - samplestoreadinloop) % loop.
LoopLength);
1062 SetPos(reverseplaybackend);
1068 samplestoloopend = loopEnd -
GetPos();
1069 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoreadinloop, samplestoloopend), pExternalDecompressionBuffer);
1070 samplestoreadinloop -= readsamples;
1071 samplestoread -= readsamples;
1072 totalreadsamples += readsamples;
1073 if (readsamples == samplestoloopend) {
1077 }
while (samplestoreadinloop && readsamples);
1079 SetPos(reverseplaybackend);
1082 SwapMemoryArea(&pDst[swapareastart * this->
FrameSize], (totalreadsamples - swapareastart) * this->FrameSize, this->FrameSize);
1090 samplestoloopend = loopEnd -
GetPos();
1091 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], Min(samplestoread, samplestoloopend), pExternalDecompressionBuffer);
1092 samplestoread -= readsamples;
1093 totalreadsamples += readsamples;
1094 if (readsamples == samplestoloopend) {
1098 }
while (samplestoread && readsamples);
1106 if (samplestoread)
do {
1107 readsamples =
Read(&pDst[totalreadsamples * this->
FrameSize], samplestoread, pExternalDecompressionBuffer);
1108 samplestoread -= readsamples;
1109 totalreadsamples += readsamples;
1110 }
while (readsamples && samplestoread);
1115 return totalreadsamples;
1141 if (SampleCount == 0)
return 0;
1148 return Channels == 2 ? pCkData->
Read(pBuffer, SampleCount << 1, 2) >> 1
1149 : pCkData->
Read(pBuffer, SampleCount, 2);
1155 file_offset_t assumedsize = GuessSize(SampleCount),
1157 remainingsamples = SampleCount,
1158 copysamples, skipsamples,
1165 if (pDecompressionBuffer->
Size < assumedsize) {
1166 std::cerr <<
"gig::Read(): WARNING - decompression buffer size too small!" << std::endl;
1167 SampleCount = WorstCaseMaxSamples(pDecompressionBuffer);
1168 remainingsamples = SampleCount;
1169 assumedsize = GuessSize(SampleCount);
1172 unsigned char* pSrc = (
unsigned char*) pDecompressionBuffer->
pStart;
1173 int16_t* pDst =
static_cast<int16_t*
>(pBuffer);
1174 uint8_t* pDst24 =
static_cast<uint8_t*
>(pBuffer);
1175 remainingbytes = pCkData->
Read(pSrc, assumedsize, 1);
1177 while (remainingsamples && remainingbytes) {
1179 file_offset_t framebytes, rightChannelOffset = 0, nextFrameOffset;
1181 int mode_l = *pSrc++, mode_r = 0;
1185 framebytes = bytesPerFrame[mode_l] + bytesPerFrame[mode_r] + 2;
1186 rightChannelOffset = bytesPerFrameNoHdr[mode_l];
1187 nextFrameOffset = rightChannelOffset + bytesPerFrameNoHdr[mode_r];
1188 if (remainingbytes < framebytes) {
1190 if (mode_l == 4 && (framesamples & 1)) {
1191 rightChannelOffset = ((framesamples + 1) * bitsPerSample[mode_l]) >> 3;
1194 rightChannelOffset = (framesamples * bitsPerSample[mode_l]) >> 3;
1199 framebytes = bytesPerFrame[mode_l] + 1;
1200 nextFrameOffset = bytesPerFrameNoHdr[mode_l];
1201 if (remainingbytes < framebytes) {
1207 if (currentframeoffset + remainingsamples >= framesamples) {
1208 if (currentframeoffset <= framesamples) {
1209 copysamples = framesamples - currentframeoffset;
1210 skipsamples = currentframeoffset;
1214 skipsamples = framesamples;
1221 copysamples = remainingsamples;
1222 skipsamples = currentframeoffset;
1223 pCkData->
SetPos(remainingbytes, RIFF::stream_backward);
1224 this->
FrameOffset = currentframeoffset + copysamples;
1226 remainingsamples -= copysamples;
1228 if (remainingbytes > framebytes) {
1229 remainingbytes -= framebytes;
1230 if (remainingsamples == 0 &&
1231 currentframeoffset + copysamples == framesamples) {
1236 pCkData->
SetPos(remainingbytes, RIFF::stream_backward);
1239 else remainingbytes = 0;
1241 currentframeoffset -= skipsamples;
1243 if (copysamples == 0) {
1248 const unsigned char*
const param_l = pSrc;
1250 if (mode_l != 2) pSrc += 12;
1253 const unsigned char*
const param_r = pSrc;
1254 if (mode_r != 2) pSrc += 12;
1256 Decompress24(mode_l, param_l, 6, pSrc, pDst24,
1258 Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
1260 pDst24 += copysamples * 6;
1263 Decompress24(mode_l, param_l, 3, pSrc, pDst24,
1265 pDst24 += copysamples * 3;
1269 if (mode_l) pSrc += 4;
1273 const unsigned char*
const param_r = pSrc;
1274 if (mode_r) pSrc += 4;
1276 step = (2 - mode_l) + (2 - mode_r);
1277 Decompress16(mode_l, param_l, step, 2, pSrc, pDst, skipsamples, copysamples);
1278 Decompress16(mode_r, param_r, step, 2, pSrc + (2 - mode_l), pDst + 1,
1279 skipsamples, copysamples);
1280 pDst += copysamples << 1;
1284 Decompress16(mode_l, param_l, step, 1, pSrc, pDst, skipsamples, copysamples);
1285 pDst += copysamples;
1288 pSrc += nextFrameOffset;
1292 if (remainingsamples && remainingbytes < WorstCaseFrameSize && pCkData->GetState() == RIFF::stream_ready) {
1293 assumedsize = GuessSize(remainingsamples);
1294 pCkData->
SetPos(remainingbytes, RIFF::stream_backward);
1296 remainingbytes = pCkData->
Read(pDecompressionBuffer->
pStart, assumedsize, 1);
1297 pSrc = (
unsigned char*) pDecompressionBuffer->
pStart;
1301 this->
SamplePos += (SampleCount - remainingsamples);
1303 return (SampleCount - remainingsamples);
1334 if (pCkData->
GetPos() == 0) {
1337 if (
GetSize() < SampleCount)
throw Exception(
"Could not write sample data, current sample size to small");
1342 res =
Channels == 2 ? pCkData->
Write(pBuffer, SampleCount << 1, 2) >> 1
1343 : pCkData->
Write(pBuffer, SampleCount, 2);
1345 __calculateCRC((
unsigned char *)pBuffer, SampleCount *
FrameSize,
crc);
1351 File* pFile =
static_cast<File*
>(GetParent());
1375 const double worstCaseHeaderOverhead =
1376 (256.0 + 12.0 + 2.0 ) / 256.0;
1377 result.
Size = (file_offset_t) (
double(MaxReadSize) * 3.0 * 2.0 * worstCaseHeaderOverhead);
1391 if (DecompressionBuffer.
Size && DecompressionBuffer.
pStart) {
1392 delete[] (int8_t*) DecompressionBuffer.
pStart;
1393 DecompressionBuffer.
pStart = NULL;
1394 DecompressionBuffer.
Size = 0;
1454 uint32_t
crc = CalculateWaveDataChecksum();
1455 if (pActually) *pActually =
crc;
1459 uint32_t Sample::CalculateWaveDataChecksum() {
1460 const size_t sz = 20*1024;
1461 std::vector<uint8_t> buffer(sz);
1469 file_offset_t nRead =
Read(&buffer[0], n);
1470 if (nRead <= 0)
break;
1493 size_t DimensionRegion::Instances = 0;
1494 DimensionRegion::VelocityTableMap* DimensionRegion::pVelocityTables = NULL;
1496 DimensionRegion::DimensionRegion(
Region* pParent,
RIFF::List* _3ewl) :
DLS::Sampler(_3ewl) {
1502 if (_3ewl->
GetSubChunk(CHUNK_ID_WSMP)) memcpy(&Crossfade, &SamplerOptions, 4);
1503 else memset(&Crossfade, 0, 4);
1505 if (!pVelocityTables) pVelocityTables =
new VelocityTableMap;
1512 LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1513 EG3Attack = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1522 EG1Attack = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1523 EG1Decay1 = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1526 EG1Release = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1527 EG1Controller = DecodeLeverageController(
static_cast<_lev_ctrl_t
>(_3ewa->
ReadUint8()));
1528 uint8_t eg1ctrloptions = _3ewa->
ReadUint8();
1529 EG1ControllerInvert = eg1ctrloptions & 0x01;
1530 EG1ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg1ctrloptions);
1531 EG1ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg1ctrloptions);
1532 EG1ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg1ctrloptions);
1533 EG2Controller = DecodeLeverageController(
static_cast<_lev_ctrl_t
>(_3ewa->
ReadUint8()));
1534 uint8_t eg2ctrloptions = _3ewa->
ReadUint8();
1535 EG2ControllerInvert = eg2ctrloptions & 0x01;
1536 EG2ControllerAttackInfluence = GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(eg2ctrloptions);
1537 EG2ControllerDecayInfluence = GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(eg2ctrloptions);
1538 EG2ControllerReleaseInfluence = GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(eg2ctrloptions);
1539 LFO1Frequency = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1540 EG2Attack = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1541 EG2Decay1 = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1544 EG2Release = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1547 LFO2Frequency = (double) GIG_EXP_DECODE(_3ewa->
ReadInt32());
1551 EG1Decay2 = (double) GIG_EXP_DECODE(eg1decay2);
1552 EG1InfiniteSustain = (eg1decay2 == 0x7fffffff);
1556 EG2Decay2 = (double) GIG_EXP_DECODE(eg2decay2);
1557 EG2InfiniteSustain = (eg2decay2 == 0x7fffffff);
1560 uint8_t velocityresponse = _3ewa->
ReadUint8();
1561 if (velocityresponse < 5) {
1563 VelocityResponseDepth = velocityresponse;
1564 }
else if (velocityresponse < 10) {
1566 VelocityResponseDepth = velocityresponse - 5;
1567 }
else if (velocityresponse < 15) {
1569 VelocityResponseDepth = velocityresponse - 10;
1572 VelocityResponseDepth = 0;
1574 uint8_t releasevelocityresponse = _3ewa->
ReadUint8();
1575 if (releasevelocityresponse < 5) {
1577 ReleaseVelocityResponseDepth = releasevelocityresponse;
1578 }
else if (releasevelocityresponse < 10) {
1580 ReleaseVelocityResponseDepth = releasevelocityresponse - 5;
1581 }
else if (releasevelocityresponse < 15) {
1583 ReleaseVelocityResponseDepth = releasevelocityresponse - 10;
1586 ReleaseVelocityResponseDepth = 0;
1588 VelocityResponseCurveScaling = _3ewa->
ReadUint8();
1589 AttenuationControllerThreshold = _3ewa->
ReadInt8();
1591 SampleStartOffset = (uint16_t) _3ewa->
ReadInt16();
1593 uint8_t pitchTrackDimensionBypass = _3ewa->
ReadInt8();
1594 PitchTrack = GIG_PITCH_TRACK_EXTRACT(pitchTrackDimensionBypass);
1599 Pan = (pan < 64) ? pan : -((
int)pan - 63);
1600 SelfMask = _3ewa->
ReadInt8() & 0x01;
1603 LFO3Controller =
static_cast<lfo3_ctrl_t>(lfo3ctrl & 0x07);
1604 LFO3Sync = lfo3ctrl & 0x20;
1605 InvertAttenuationController = lfo3ctrl & 0x80;
1606 AttenuationController = DecodeLeverageController(
static_cast<_lev_ctrl_t
>(_3ewa->
ReadUint8()));
1608 LFO2Controller =
static_cast<lfo2_ctrl_t>(lfo2ctrl & 0x07);
1609 LFO2FlipPhase = lfo2ctrl & 0x80;
1610 LFO2Sync = lfo2ctrl & 0x20;
1611 bool extResonanceCtrl = lfo2ctrl & 0x40;
1613 LFO1Controller =
static_cast<lfo1_ctrl_t>(lfo1ctrl & 0x07);
1614 LFO1FlipPhase = lfo1ctrl & 0x80;
1615 LFO1Sync = lfo1ctrl & 0x40;
1616 VCFResonanceController = (extResonanceCtrl) ?
static_cast<vcf_res_ctrl_t>(GIG_VCF_RESONANCE_CTRL_EXTRACT(lfo1ctrl))
1619 EG3Depth = (eg3depth <= 1200) ? eg3depth
1620 : (-1) * (int16_t) ((eg3depth ^ 0xfff) + 1);
1623 uint8_t regoptions = _3ewa->
ReadUint8();
1624 MSDecode = regoptions & 0x01;
1625 SustainDefeat = regoptions & 0x02;
1627 VelocityUpperLimit = _3ewa->
ReadInt8();
1630 ReleaseTriggerDecay = _3ewa->
ReadUint8();
1635 VCFEnabled = vcfcutoff & 0x80;
1636 VCFCutoff = vcfcutoff & 0x7f;
1638 uint8_t vcfvelscale = _3ewa->
ReadUint8();
1639 VCFCutoffControllerInvert = vcfvelscale & 0x80;
1640 VCFVelocityScale = vcfvelscale & 0x7f;
1642 uint8_t vcfresonance = _3ewa->
ReadUint8();
1643 VCFResonance = vcfresonance & 0x7f;
1644 VCFResonanceDynamic = !(vcfresonance & 0x80);
1645 uint8_t vcfbreakpoint = _3ewa->
ReadUint8();
1646 VCFKeyboardTracking = vcfbreakpoint & 0x80;
1647 VCFKeyboardTrackingBreakpoint = vcfbreakpoint & 0x7f;
1648 uint8_t vcfvelocity = _3ewa->
ReadUint8();
1649 VCFVelocityDynamicRange = vcfvelocity % 5;
1650 VCFVelocityCurve =
static_cast<curve_type_t>(vcfvelocity / 5);
1653 if (lfo3ctrl & 0x40)
1657 _3ewa->
Read(DimensionUpperLimits, 1, 8);
1659 memset(DimensionUpperLimits, 0, 8);
1663 LFO3Frequency = 1.0;
1665 LFO1InternalDepth = 0;
1666 LFO3InternalDepth = 0;
1667 LFO1ControlDepth = 0;
1668 LFO3ControlDepth = 0;
1674 EG1Controller.controller_number = 0;
1675 EG1ControllerInvert =
false;
1676 EG1ControllerAttackInfluence = 0;
1677 EG1ControllerDecayInfluence = 0;
1678 EG1ControllerReleaseInfluence = 0;
1680 EG2Controller.controller_number = 0;
1681 EG2ControllerInvert =
false;
1682 EG2ControllerAttackInfluence = 0;
1683 EG2ControllerDecayInfluence = 0;
1684 EG2ControllerReleaseInfluence = 0;
1685 LFO1Frequency = 1.0;
1690 LFO2ControlDepth = 0;
1691 LFO2Frequency = 1.0;
1692 LFO2InternalDepth = 0;
1694 EG1InfiniteSustain =
true;
1697 EG2InfiniteSustain =
true;
1700 VelocityResponseDepth = 3;
1702 ReleaseVelocityResponseDepth = 3;
1703 VelocityResponseCurveScaling = 32;
1704 AttenuationControllerThreshold = 0;
1705 SampleStartOffset = 0;
1712 InvertAttenuationController =
false;
1714 AttenuationController.controller_number = 0;
1716 LFO2FlipPhase =
false;
1719 LFO1FlipPhase =
false;
1725 SustainDefeat =
false;
1726 VelocityUpperLimit = 0;
1727 ReleaseTriggerDecay = 0;
1732 VCFCutoffControllerInvert =
false;
1733 VCFVelocityScale = 0;
1735 VCFResonanceDynamic =
false;
1736 VCFKeyboardTracking =
false;
1737 VCFKeyboardTrackingBreakpoint = 0;
1738 VCFVelocityDynamicRange = 0x04;
1741 memset(DimensionUpperLimits, 127, 8);
1748 eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
1749 for (
int i = 0; i < 2; ++i) {
1751 pEGOpts[i]->AttackCancel =
byte & 1;
1752 pEGOpts[i]->AttackHoldCancel =
byte & (1 << 1);
1753 pEGOpts[i]->Decay1Cancel =
byte & (1 << 2);
1754 pEGOpts[i]->Decay2Cancel =
byte & (1 << 3);
1755 pEGOpts[i]->ReleaseCancel =
byte & (1 << 4);
1759 if (lsde && lsde->
GetSize() > 3) {
1762 SustainReleaseTrigger =
static_cast<sust_rel_trg_t>(
byte & 0x03);
1763 NoNoteOffReleaseTrigger =
byte >> 7;
1766 NoNoteOffReleaseTrigger =
false;
1769 pVelocityAttenuationTable = GetVelocityTable(VelocityResponseCurve,
1770 VelocityResponseDepth,
1771 VelocityResponseCurveScaling);
1773 pVelocityReleaseTable = GetReleaseVelocityTable(
1774 ReleaseVelocityResponseCurve,
1775 ReleaseVelocityResponseDepth
1778 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve,
1779 VCFVelocityDynamicRange,
1781 VCFCutoffController);
1783 SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1791 DimensionRegion::DimensionRegion(
RIFF::List* _3ewl,
const DimensionRegion& src) :
DLS::Sampler(_3ewl) {
1795 pParentList = _3ewl;
1798 if (src.VelocityTable) {
1799 VelocityTable =
new uint8_t[128];
1800 for (
int k = 0 ; k < 128 ; k++)
1801 VelocityTable[k] = src.VelocityTable[k];
1803 if (src.pSampleLoops) {
1805 for (
int k = 0 ; k < src.SampleLoops ; k++)
1806 pSampleLoops[k] = src.pSampleLoops[k];
1848 pRegion = pOriginalRegion;
1852 if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1856 if (mSamples && mSamples->count(orig->
pSample)) {
1863 for (
int k = 0 ; k < 128 ; k++)
1971 DLS::Sampler::SetGain(gain);
1991 pData[13] = Crossfade.
in_end;
1993 pData[15] = Crossfade.
out_end;
1998 File* pFile = (
File*) GetParent()->GetParent()->GetParent();
2000 _3ewa = pParentList->
AddSubChunk(CHUNK_ID_3EWA, versiongt2 ? 148 : 140);
2006 const uint32_t chunksize = (uint32_t) _3ewa->
GetNewSize();
2007 store32(&pData[0], chunksize);
2009 const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(
LFO3Frequency);
2010 store32(&pData[4], lfo3freq);
2012 const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(
EG3Attack);
2013 store32(&pData[8], eg3attack);
2031 const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(
EG1Attack);
2032 store32(&pData[28], eg1attack);
2034 const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(
EG1Decay1);
2035 store32(&pData[32], eg1decay1);
2041 const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(
EG1Release);
2042 store32(&pData[40], eg1release);
2044 const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(
EG1Controller);
2047 const uint8_t eg1ctrloptions =
2052 pData[45] = eg1ctrloptions;
2054 const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(
EG2Controller);
2057 const uint8_t eg2ctrloptions =
2062 pData[47] = eg2ctrloptions;
2064 const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(
LFO1Frequency);
2065 store32(&pData[48], lfo1freq);
2067 const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(
EG2Attack);
2068 store32(&pData[52], eg2attack);
2070 const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(
EG2Decay1);
2071 store32(&pData[56], eg2decay1);
2077 const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(
EG2Release);
2078 store32(&pData[64], eg2release);
2084 const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(
LFO2Frequency);
2085 store32(&pData[72], lfo2freq);
2092 store32(&pData[80], eg1decay2);
2099 store32(&pData[88], eg2decay2);
2112 velocityresponse += 5;
2115 velocityresponse += 10;
2119 throw Exception(
"Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2121 pData[96] = velocityresponse;
2131 releasevelocityresponse += 5;
2134 releasevelocityresponse += 10;
2138 throw Exception(
"Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2140 pData[97] = releasevelocityresponse;
2154 uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(
PitchTrack);
2157 pitchTrackDimensionBypass |= 0x10;
2160 pitchTrackDimensionBypass |= 0x20;
2166 throw Exception(
"Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
2168 pData[108] = pitchTrackDimensionBypass;
2171 const uint8_t pan = (
Pan >= 0) ?
Pan : ((-
Pan) + 63);
2174 const uint8_t selfmask = (
SelfMask) ? 0x01 : 0x00;
2175 pData[110] = selfmask;
2184 pData[112] = lfo3ctrl;
2188 pData[113] = attenctl;
2195 pData[114] = lfo2ctrl;
2204 pData[115] = lfo1ctrl;
2208 : uint16_t(((-
EG3Depth) - 1) ^ 0xfff);
2209 store16(&pData[116], eg3depth);
2214 pData[120] = channeloffset;
2217 uint8_t regoptions = 0;
2220 pData[121] = regoptions;
2233 const uint8_t eg1hold = (
EG1Hold) ? 0x80 : 0x00;
2234 pData[131] = eg1hold;
2236 const uint8_t vcfcutoff = (
VCFEnabled ? 0x80 : 0x00) |
2238 pData[132] = vcfcutoff;
2244 pData[134] = vcfvelscale;
2250 pData[136] = vcfresonance;
2254 pData[137] = vcfbreakpoint;
2258 pData[138] = vcfvelocity;
2261 pData[139] = vcftype;
2263 if (chunksize >= 148) {
2270 const int lsdeSize = 4;
2279 lsde = pParentList->
AddSubChunk(CHUNK_ID_LSDE, lsdeSize);
2288 unsigned char* pData = (
unsigned char*) lsde->
LoadChunkData();
2290 for (
int i = 0; i < 2; ++i) {
2293 (pEGOpts[i]->AttackHoldCancel ? (1<<1) : 0) |
2294 (pEGOpts[i]->Decay1Cancel ? (1<<2) : 0) |
2295 (pEGOpts[i]->Decay2Cancel ? (1<<3) : 0) |
2296 (pEGOpts[i]->ReleaseCancel ? (1<<4) : 0);
2303 double* DimensionRegion::GetReleaseVelocityTable(
curve_type_t releaseVelocityResponseCurve, uint8_t releaseVelocityResponseDepth) {
2305 uint8_t depth = releaseVelocityResponseDepth;
2314 return GetVelocityTable(curveType, depth, 0);
2317 double* DimensionRegion::GetCutoffVelocityTable(
curve_type_t vcfVelocityCurve,
2318 uint8_t vcfVelocityDynamicRange,
2319 uint8_t vcfVelocityScale,
2323 uint8_t depth = vcfVelocityDynamicRange;
2332 return GetVelocityTable(curveType, depth,
2334 ? vcfVelocityScale : 0);
2338 double* DimensionRegion::GetVelocityTable(
curve_type_t curveType, uint8_t depth, uint8_t scaling)
2342 switch (curveType) {
2346 printf(
"Warning: Invalid depth (0x%x) for velocity curve type (0x%x).\n", depth, curveType);
2353 printf(
"Warning: Invalid depth (0x%x) for velocity curve type 'special'.\n", depth);
2360 printf(
"Warning: Unknown velocity curve type (0x%x).\n", curveType);
2368 uint32_t tableKey = (curveType<<16) | (depth<<8) | scaling;
2369 if (pVelocityTables->count(tableKey)) {
2370 table = (*pVelocityTables)[tableKey];
2373 table = CreateVelocityTable(curveType, depth, scaling);
2374 (*pVelocityTables)[tableKey] = table;
2379 Region* DimensionRegion::GetParent()
const {
2389 leverage_ctrl_t DimensionRegion::DecodeLeverageController(_lev_ctrl_t EncodedController) {
2390 leverage_ctrl_t decodedcontroller;
2391 switch (EncodedController) {
2393 case _lev_ctrl_none:
2395 decodedcontroller.controller_number = 0;
2397 case _lev_ctrl_velocity:
2399 decodedcontroller.controller_number = 0;
2401 case _lev_ctrl_channelaftertouch:
2403 decodedcontroller.controller_number = 0;
2407 case _lev_ctrl_modwheel:
2409 decodedcontroller.controller_number = 1;
2411 case _lev_ctrl_breath:
2413 decodedcontroller.controller_number = 2;
2415 case _lev_ctrl_foot:
2417 decodedcontroller.controller_number = 4;
2419 case _lev_ctrl_effect1:
2421 decodedcontroller.controller_number = 12;
2423 case _lev_ctrl_effect2:
2425 decodedcontroller.controller_number = 13;
2427 case _lev_ctrl_genpurpose1:
2429 decodedcontroller.controller_number = 16;
2431 case _lev_ctrl_genpurpose2:
2433 decodedcontroller.controller_number = 17;
2435 case _lev_ctrl_genpurpose3:
2437 decodedcontroller.controller_number = 18;
2439 case _lev_ctrl_genpurpose4:
2441 decodedcontroller.controller_number = 19;
2443 case _lev_ctrl_portamentotime:
2445 decodedcontroller.controller_number = 5;
2447 case _lev_ctrl_sustainpedal:
2449 decodedcontroller.controller_number = 64;
2451 case _lev_ctrl_portamento:
2453 decodedcontroller.controller_number = 65;
2455 case _lev_ctrl_sostenutopedal:
2457 decodedcontroller.controller_number = 66;
2459 case _lev_ctrl_softpedal:
2461 decodedcontroller.controller_number = 67;
2463 case _lev_ctrl_genpurpose5:
2465 decodedcontroller.controller_number = 80;
2467 case _lev_ctrl_genpurpose6:
2469 decodedcontroller.controller_number = 81;
2471 case _lev_ctrl_genpurpose7:
2473 decodedcontroller.controller_number = 82;
2475 case _lev_ctrl_genpurpose8:
2477 decodedcontroller.controller_number = 83;
2479 case _lev_ctrl_effect1depth:
2481 decodedcontroller.controller_number = 91;
2483 case _lev_ctrl_effect2depth:
2485 decodedcontroller.controller_number = 92;
2487 case _lev_ctrl_effect3depth:
2489 decodedcontroller.controller_number = 93;
2491 case _lev_ctrl_effect4depth:
2493 decodedcontroller.controller_number = 94;
2495 case _lev_ctrl_effect5depth:
2497 decodedcontroller.controller_number = 95;
2503 case _lev_ctrl_CC3_EXT:
2505 decodedcontroller.controller_number = 3;
2507 case _lev_ctrl_CC6_EXT:
2509 decodedcontroller.controller_number = 6;
2511 case _lev_ctrl_CC7_EXT:
2513 decodedcontroller.controller_number = 7;
2515 case _lev_ctrl_CC8_EXT:
2517 decodedcontroller.controller_number = 8;
2519 case _lev_ctrl_CC9_EXT:
2521 decodedcontroller.controller_number = 9;
2523 case _lev_ctrl_CC10_EXT:
2525 decodedcontroller.controller_number = 10;
2527 case _lev_ctrl_CC11_EXT:
2529 decodedcontroller.controller_number = 11;
2531 case _lev_ctrl_CC14_EXT:
2533 decodedcontroller.controller_number = 14;
2535 case _lev_ctrl_CC15_EXT:
2537 decodedcontroller.controller_number = 15;
2539 case _lev_ctrl_CC20_EXT:
2541 decodedcontroller.controller_number = 20;
2543 case _lev_ctrl_CC21_EXT:
2545 decodedcontroller.controller_number = 21;
2547 case _lev_ctrl_CC22_EXT:
2549 decodedcontroller.controller_number = 22;
2551 case _lev_ctrl_CC23_EXT:
2553 decodedcontroller.controller_number = 23;
2555 case _lev_ctrl_CC24_EXT:
2557 decodedcontroller.controller_number = 24;
2559 case _lev_ctrl_CC25_EXT:
2561 decodedcontroller.controller_number = 25;
2563 case _lev_ctrl_CC26_EXT:
2565 decodedcontroller.controller_number = 26;
2567 case _lev_ctrl_CC27_EXT:
2569 decodedcontroller.controller_number = 27;
2571 case _lev_ctrl_CC28_EXT:
2573 decodedcontroller.controller_number = 28;
2575 case _lev_ctrl_CC29_EXT:
2577 decodedcontroller.controller_number = 29;
2579 case _lev_ctrl_CC30_EXT:
2581 decodedcontroller.controller_number = 30;
2583 case _lev_ctrl_CC31_EXT:
2585 decodedcontroller.controller_number = 31;
2587 case _lev_ctrl_CC68_EXT:
2589 decodedcontroller.controller_number = 68;
2591 case _lev_ctrl_CC69_EXT:
2593 decodedcontroller.controller_number = 69;
2595 case _lev_ctrl_CC70_EXT:
2597 decodedcontroller.controller_number = 70;
2599 case _lev_ctrl_CC71_EXT:
2601 decodedcontroller.controller_number = 71;
2603 case _lev_ctrl_CC72_EXT:
2605 decodedcontroller.controller_number = 72;
2607 case _lev_ctrl_CC73_EXT:
2609 decodedcontroller.controller_number = 73;
2611 case _lev_ctrl_CC74_EXT:
2613 decodedcontroller.controller_number = 74;
2615 case _lev_ctrl_CC75_EXT:
2617 decodedcontroller.controller_number = 75;
2619 case _lev_ctrl_CC76_EXT:
2621 decodedcontroller.controller_number = 76;
2623 case _lev_ctrl_CC77_EXT:
2625 decodedcontroller.controller_number = 77;
2627 case _lev_ctrl_CC78_EXT:
2629 decodedcontroller.controller_number = 78;
2631 case _lev_ctrl_CC79_EXT:
2633 decodedcontroller.controller_number = 79;
2635 case _lev_ctrl_CC84_EXT:
2637 decodedcontroller.controller_number = 84;
2639 case _lev_ctrl_CC85_EXT:
2641 decodedcontroller.controller_number = 85;
2643 case _lev_ctrl_CC86_EXT:
2645 decodedcontroller.controller_number = 86;
2647 case _lev_ctrl_CC87_EXT:
2649 decodedcontroller.controller_number = 87;
2651 case _lev_ctrl_CC89_EXT:
2653 decodedcontroller.controller_number = 89;
2655 case _lev_ctrl_CC90_EXT:
2657 decodedcontroller.controller_number = 90;
2659 case _lev_ctrl_CC96_EXT:
2661 decodedcontroller.controller_number = 96;
2663 case _lev_ctrl_CC97_EXT:
2665 decodedcontroller.controller_number = 97;
2667 case _lev_ctrl_CC102_EXT:
2669 decodedcontroller.controller_number = 102;
2671 case _lev_ctrl_CC103_EXT:
2673 decodedcontroller.controller_number = 103;
2675 case _lev_ctrl_CC104_EXT:
2677 decodedcontroller.controller_number = 104;
2679 case _lev_ctrl_CC105_EXT:
2681 decodedcontroller.controller_number = 105;
2683 case _lev_ctrl_CC106_EXT:
2685 decodedcontroller.controller_number = 106;
2687 case _lev_ctrl_CC107_EXT:
2689 decodedcontroller.controller_number = 107;
2691 case _lev_ctrl_CC108_EXT:
2693 decodedcontroller.controller_number = 108;
2695 case _lev_ctrl_CC109_EXT:
2697 decodedcontroller.controller_number = 109;
2699 case _lev_ctrl_CC110_EXT:
2701 decodedcontroller.controller_number = 110;
2703 case _lev_ctrl_CC111_EXT:
2705 decodedcontroller.controller_number = 111;
2707 case _lev_ctrl_CC112_EXT:
2709 decodedcontroller.controller_number = 112;
2711 case _lev_ctrl_CC113_EXT:
2713 decodedcontroller.controller_number = 113;
2715 case _lev_ctrl_CC114_EXT:
2717 decodedcontroller.controller_number = 114;
2719 case _lev_ctrl_CC115_EXT:
2721 decodedcontroller.controller_number = 115;
2723 case _lev_ctrl_CC116_EXT:
2725 decodedcontroller.controller_number = 116;
2727 case _lev_ctrl_CC117_EXT:
2729 decodedcontroller.controller_number = 117;
2731 case _lev_ctrl_CC118_EXT:
2733 decodedcontroller.controller_number = 118;
2735 case _lev_ctrl_CC119_EXT:
2737 decodedcontroller.controller_number = 119;
2743 decodedcontroller.controller_number = 0;
2744 printf(
"Warning: Unknown leverage controller type (0x%x).\n", EncodedController);
2747 return decodedcontroller;
2753 DimensionRegion::_lev_ctrl_t DimensionRegion::EncodeLeverageController(leverage_ctrl_t DecodedController) {
2754 _lev_ctrl_t encodedcontroller;
2755 switch (DecodedController.type) {
2758 encodedcontroller = _lev_ctrl_none;
2761 encodedcontroller = _lev_ctrl_velocity;
2764 encodedcontroller = _lev_ctrl_channelaftertouch;
2769 switch (DecodedController.controller_number) {
2771 encodedcontroller = _lev_ctrl_modwheel;
2774 encodedcontroller = _lev_ctrl_breath;
2777 encodedcontroller = _lev_ctrl_foot;
2780 encodedcontroller = _lev_ctrl_effect1;
2783 encodedcontroller = _lev_ctrl_effect2;
2786 encodedcontroller = _lev_ctrl_genpurpose1;
2789 encodedcontroller = _lev_ctrl_genpurpose2;
2792 encodedcontroller = _lev_ctrl_genpurpose3;
2795 encodedcontroller = _lev_ctrl_genpurpose4;
2798 encodedcontroller = _lev_ctrl_portamentotime;
2801 encodedcontroller = _lev_ctrl_sustainpedal;
2804 encodedcontroller = _lev_ctrl_portamento;
2807 encodedcontroller = _lev_ctrl_sostenutopedal;
2810 encodedcontroller = _lev_ctrl_softpedal;
2813 encodedcontroller = _lev_ctrl_genpurpose5;
2816 encodedcontroller = _lev_ctrl_genpurpose6;
2819 encodedcontroller = _lev_ctrl_genpurpose7;
2822 encodedcontroller = _lev_ctrl_genpurpose8;
2825 encodedcontroller = _lev_ctrl_effect1depth;
2828 encodedcontroller = _lev_ctrl_effect2depth;
2831 encodedcontroller = _lev_ctrl_effect3depth;
2834 encodedcontroller = _lev_ctrl_effect4depth;
2837 encodedcontroller = _lev_ctrl_effect5depth;
2844 encodedcontroller = _lev_ctrl_CC3_EXT;
2847 encodedcontroller = _lev_ctrl_CC6_EXT;
2850 encodedcontroller = _lev_ctrl_CC7_EXT;
2853 encodedcontroller = _lev_ctrl_CC8_EXT;
2856 encodedcontroller = _lev_ctrl_CC9_EXT;
2859 encodedcontroller = _lev_ctrl_CC10_EXT;
2862 encodedcontroller = _lev_ctrl_CC11_EXT;
2865 encodedcontroller = _lev_ctrl_CC14_EXT;
2868 encodedcontroller = _lev_ctrl_CC15_EXT;
2871 encodedcontroller = _lev_ctrl_CC20_EXT;
2874 encodedcontroller = _lev_ctrl_CC21_EXT;
2877 encodedcontroller = _lev_ctrl_CC22_EXT;
2880 encodedcontroller = _lev_ctrl_CC23_EXT;
2883 encodedcontroller = _lev_ctrl_CC24_EXT;
2886 encodedcontroller = _lev_ctrl_CC25_EXT;
2889 encodedcontroller = _lev_ctrl_CC26_EXT;
2892 encodedcontroller = _lev_ctrl_CC27_EXT;
2895 encodedcontroller = _lev_ctrl_CC28_EXT;
2898 encodedcontroller = _lev_ctrl_CC29_EXT;
2901 encodedcontroller = _lev_ctrl_CC30_EXT;
2904 encodedcontroller = _lev_ctrl_CC31_EXT;
2907 encodedcontroller = _lev_ctrl_CC68_EXT;
2910 encodedcontroller = _lev_ctrl_CC69_EXT;
2913 encodedcontroller = _lev_ctrl_CC70_EXT;
2916 encodedcontroller = _lev_ctrl_CC71_EXT;
2919 encodedcontroller = _lev_ctrl_CC72_EXT;
2922 encodedcontroller = _lev_ctrl_CC73_EXT;
2925 encodedcontroller = _lev_ctrl_CC74_EXT;
2928 encodedcontroller = _lev_ctrl_CC75_EXT;
2931 encodedcontroller = _lev_ctrl_CC76_EXT;
2934 encodedcontroller = _lev_ctrl_CC77_EXT;
2937 encodedcontroller = _lev_ctrl_CC78_EXT;
2940 encodedcontroller = _lev_ctrl_CC79_EXT;
2943 encodedcontroller = _lev_ctrl_CC84_EXT;
2946 encodedcontroller = _lev_ctrl_CC85_EXT;
2949 encodedcontroller = _lev_ctrl_CC86_EXT;
2952 encodedcontroller = _lev_ctrl_CC87_EXT;
2955 encodedcontroller = _lev_ctrl_CC89_EXT;
2958 encodedcontroller = _lev_ctrl_CC90_EXT;
2961 encodedcontroller = _lev_ctrl_CC96_EXT;
2964 encodedcontroller = _lev_ctrl_CC97_EXT;
2967 encodedcontroller = _lev_ctrl_CC102_EXT;
2970 encodedcontroller = _lev_ctrl_CC103_EXT;
2973 encodedcontroller = _lev_ctrl_CC104_EXT;
2976 encodedcontroller = _lev_ctrl_CC105_EXT;
2979 encodedcontroller = _lev_ctrl_CC106_EXT;
2982 encodedcontroller = _lev_ctrl_CC107_EXT;
2985 encodedcontroller = _lev_ctrl_CC108_EXT;
2988 encodedcontroller = _lev_ctrl_CC109_EXT;
2991 encodedcontroller = _lev_ctrl_CC110_EXT;
2994 encodedcontroller = _lev_ctrl_CC111_EXT;
2997 encodedcontroller = _lev_ctrl_CC112_EXT;
3000 encodedcontroller = _lev_ctrl_CC113_EXT;
3003 encodedcontroller = _lev_ctrl_CC114_EXT;
3006 encodedcontroller = _lev_ctrl_CC115_EXT;
3009 encodedcontroller = _lev_ctrl_CC116_EXT;
3012 encodedcontroller = _lev_ctrl_CC117_EXT;
3015 encodedcontroller = _lev_ctrl_CC118_EXT;
3018 encodedcontroller = _lev_ctrl_CC119_EXT;
3022 throw gig::Exception(
"leverage controller number is not supported by the gig format");
3028 return encodedcontroller;
3031 DimensionRegion::~DimensionRegion() {
3035 VelocityTableMap::iterator iter;
3036 for (iter = pVelocityTables->begin(); iter != pVelocityTables->end(); iter++) {
3037 double* pTable = iter->second;
3038 if (pTable)
delete[] pTable;
3040 pVelocityTables->clear();
3041 delete pVelocityTables;
3042 pVelocityTables = NULL;
3059 return pVelocityAttenuationTable[MIDIKeyVelocity];
3062 double DimensionRegion::GetVelocityRelease(uint8_t MIDIKeyVelocity) {
3063 return pVelocityReleaseTable[MIDIKeyVelocity];
3066 double DimensionRegion::GetVelocityCutoff(uint8_t MIDIKeyVelocity) {
3067 return pVelocityCutoffTable[MIDIKeyVelocity];
3075 pVelocityAttenuationTable =
3087 pVelocityAttenuationTable =
3099 pVelocityAttenuationTable =
3160 double* DimensionRegion::CreateVelocityTable(
curve_type_t curveType, uint8_t depth, uint8_t scaling) {
3165 const int lin0[] = { 1, 1, 127, 127 };
3166 const int lin1[] = { 1, 21, 127, 127 };
3167 const int lin2[] = { 1, 45, 127, 127 };
3168 const int lin3[] = { 1, 74, 127, 127 };
3169 const int lin4[] = { 1, 127, 127, 127 };
3172 const int non0[] = { 1, 4, 24, 5, 57, 17, 92, 57, 122, 127, 127, 127 };
3173 const int non1[] = { 1, 4, 46, 9, 93, 56, 118, 106, 123, 127,
3175 const int non2[] = { 1, 4, 46, 9, 57, 20, 102, 107, 107, 127,
3177 const int non3[] = { 1, 15, 10, 19, 67, 73, 80, 80, 90, 98, 98, 127,
3179 const int non4[] = { 1, 25, 33, 57, 82, 81, 92, 127, 127, 127 };
3182 const int spe0[] = { 1, 2, 76, 10, 90, 15, 95, 20, 99, 28, 103, 44,
3183 113, 127, 127, 127 };
3184 const int spe1[] = { 1, 2, 27, 5, 67, 18, 89, 29, 95, 35, 107, 67,
3185 118, 127, 127, 127 };
3186 const int spe2[] = { 1, 1, 33, 1, 53, 5, 61, 13, 69, 32, 79, 74,
3187 85, 90, 91, 127, 127, 127 };
3188 const int spe3[] = { 1, 32, 28, 35, 66, 48, 89, 59, 95, 65, 99, 73,
3189 117, 127, 127, 127 };
3190 const int spe4[] = { 1, 4, 23, 5, 49, 13, 57, 17, 92, 57, 122, 127,
3194 const int spe5[] = { 1, 2, 30, 5, 60, 19, 77, 70, 83, 85, 88, 106,
3195 91, 127, 127, 127 };
3197 const int*
const curves[] = { non0, non1, non2, non3, non4,
3198 lin0, lin1, lin2, lin3, lin4,
3199 spe0, spe1, spe2, spe3, spe4, spe5 };
3201 double*
const table =
new double[128];
3203 const int* curve = curves[curveType * 5 + depth];
3204 const int s = scaling == 0 ? 20 : scaling;
3207 for (
int x = 1 ; x < 128 ; x++) {
3209 if (x > curve[2]) curve += 2;
3210 double y = curve[1] + (x - curve[0]) *
3211 (
double(curve[3] - curve[1]) / (curve[2] - curve[0]));
3216 if (s < 20 && y >= 0.5)
3217 y = y / ((2 - 40.0 / s) * y + 40.0 / s - 1);
3231 Region::Region(Instrument* pInstrument,
RIFF::List* rgnList) :
DLS::Region((
DLS::Instrument*) pInstrument, rgnList) {
3234 for (
int i = 0; i < 256; i++) {
3235 pDimensionRegions[i] = NULL;
3238 File* file = (File*) GetParent()->GetParent();
3239 int dimensionBits = (file->pVersion && file->pVersion->major > 2) ? 8 : 5;
3243 if (!file->GetAutoLoad())
return;
3245 LoadDimensionRegions(rgnList);
3252 for (
int i = 0; i < dimensionBits; i++) {
3260 pDimensionDefinitions[i].bits = 0;
3261 pDimensionDefinitions[i].zones = 0;
3263 pDimensionDefinitions[i].zone_size = 0;
3266 pDimensionDefinitions[i].dimension = dimension;
3267 pDimensionDefinitions[i].bits = bits;
3268 pDimensionDefinitions[i].zones = zones ? zones : 0x01 << bits;
3269 pDimensionDefinitions[i].split_type = __resolveSplitType(dimension);
3270 pDimensionDefinitions[i].zone_size = __resolveZoneSize(pDimensionDefinitions[i]);
3274 if (dimension ==
dimension_layer) Layers = pDimensionDefinitions[i].zones;
3276 _3lnk->
SetPos(3, RIFF::stream_curpos);
3278 for (
int i = dimensionBits ; i < 8 ; i++) pDimensionDefinitions[i].bits = 0;
3282 UpdateVelocityTable();
3285 if (file->pVersion && file->pVersion->major > 2)
3291 if (file->GetAutoLoad()) {
3292 for (uint i = 0; i < DimensionRegions; i++) {
3293 uint32_t wavepoolindex = _3lnk->
ReadUint32();
3294 if (file->pWavePoolTable && pDimensionRegions[i])
3295 pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
3300 DimensionRegions = 0;
3301 for (
int i = 0 ; i < 8 ; i++) {
3303 pDimensionDefinitions[i].bits = 0;
3304 pDimensionDefinitions[i].zones = 0;
3309 if (!DimensionRegions) {
3311 if (!_3prg) _3prg = rgnList->
AddSubList(LIST_TYPE_3PRG);
3313 pDimensionRegions[0] =
new DimensionRegion(
this, _3ewl);
3314 DimensionRegions = 1;
3343 File* pFile = (
File*) GetParent()->GetParent();
3345 const int iMaxDimensions = versiongt2 ? 8 : 5;
3346 const int iMaxDimensionRegions = versiongt2 ? 256 : 32;
3351 const int _3lnkChunkSize = versiongt2 ? 1092 : 172;
3352 _3lnk = pCkRegion->
AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3363 for (
int i = 0; i < iMaxDimensions; i++) {
3375 const int iWavePoolOffset = versiongt2 ? 68 : 44;
3376 for (uint i = 0; i < iMaxDimensionRegions; i++) {
3377 int iWaveIndex = -1;
3379 if (!pFile->pSamples || !pFile->pSamples->size())
throw gig::Exception(
"Could not update gig::Region, there are no samples");
3380 File::SampleList::iterator iter = pFile->pSamples->begin();
3381 File::SampleList::iterator end = pFile->pSamples->end();
3382 for (
int index = 0; iter != end; ++iter, ++index) {
3389 store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3393 void Region::LoadDimensionRegions(
RIFF::List* rgn) {
3396 int dimensionRegionNr = 0;
3401 dimensionRegionNr++;
3405 if (dimensionRegionNr == 0)
throw gig::Exception(
"No dimension region found.");
3416 void Region::UpdateVelocityTable() {
3425 if (veldim == -1)
return;
3442 table =
new uint8_t[128];
3446 int velocityZone = 0;
3448 for (
int k = i ; k < end ; k += step) {
3450 for (; tableidx <= d->DimensionUpperLimits[veldim] ; tableidx++) table[tableidx] = velocityZone;
3454 for (
int k = i ; k < end ; k += step) {
3456 for (; tableidx <= d->VelocityUpperLimit ; tableidx++) table[tableidx] = velocityZone;
3471 if (j == veldim) i += skipveldim;
3505 if (pDimDef->
zones < 2)
3506 throw gig::Exception(
"Could not add new dimension, amount of requested zones must always be at least two");
3507 if (pDimDef->
bits < 1)
3508 throw gig::Exception(
"Could not add new dimension, amount of requested requested zone bits must always be at least one");
3510 if (pDimDef->
zones != 2)
3511 throw gig::Exception(
"Could not add new 'sample channel' dimensions, the requested amount of zones must always be 2 for this dimension type");
3512 if (pDimDef->
bits != 1)
3513 throw gig::Exception(
"Could not add new 'sample channel' dimensions, the requested amount of zone bits must always be 1 for this dimension type");
3517 File* file = (
File*) GetParent()->GetParent();
3518 const int iMaxDimensions = (file->
pVersion && file->
pVersion->major > 2) ? 8 : 5;
3520 throw gig::Exception(
"Could not add new dimension, max. amount of " + ToString(iMaxDimensions) +
" dimensions already reached");
3522 int iCurrentBits = 0;
3525 if (iCurrentBits >= iMaxDimensions)
3526 throw gig::Exception(
"Could not add new dimension, max. amount of " + ToString(iMaxDimensions) +
" dimension bits already reached");
3527 const int iNewBits = iCurrentBits + pDimDef->
bits;
3528 if (iNewBits > iMaxDimensions)
3529 throw gig::Exception(
"Could not add new dimension, new dimension would exceed max. amount of " + ToString(iMaxDimensions) +
" dimension bits");
3533 throw gig::Exception(
"Could not add new dimension, there is already a dimension of the same type");
3540 for (
int i = 0 ; i < pos ; i++)
3545 for (
int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3566 for (
int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3567 for (
int k = 0 ; k < (1 << bitpos) ; k++) {
3570 for (
int j = 1 ; j < (1 << pDimDef->
bits) ; j++) {
3571 for (
int k = 0 ; k < (1 << bitpos) ; k++) {
3573 if (moveTo) _3prg->
MoveSubChunk(pNewDimRgnListChunk, moveTo);
3586 int mask = (1 << bitpos) - 1;
3587 for (
int z = 0 ; z < pDimDef->
zones ; z++) {
3588 uint8_t upperLimit = uint8_t((z + 1) * 128.0 / pDimDef->
zones - 1);
3589 for (
int i = 0 ; i < 1 << iCurrentBits ; i++) {
3601 UpdateVelocityTable();
3617 int iDimensionNr = -1;
3624 if (iDimensionNr < 0)
throw gig::Exception(
"Invalid dimension_def_t pointer");
3628 for (
int i = 0; i < iDimensionNr; i++)
3633 for (
int i = iDimensionNr + 1; i <
Dimensions; i++)
3640 for (
int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3642 for (
int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3644 iObsoleteBit << iLowerBits |
3657 for (
int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3659 if (iFrom <= iTo) iFrom = iTo + 1;
3671 for (
int i = iDimensionNr + 1; i <
Dimensions; i++) {
3678 for (
int i = iDimensionNr + 1; i <
Dimensions; i++) {
3708 throw gig::Exception(
"Could not delete dimension zone, no such dimension of given type");
3709 if (oldDef->
zones <= 2)
3710 throw gig::Exception(
"Could not delete dimension zone, because it would end up with only one zone.");
3711 if (zone < 0 || zone >= oldDef->
zones)
3712 throw gig::Exception(
"Could not delete dimension zone, requested zone index out of bounds.");
3714 const int newZoneSize = oldDef->
zones - 1;
3723 RIFF::List* pCkInstrument = instr->pCkInstrument;
3725 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
3727 tempRgn =
new Region(instr, rgn);
3739 def.
zones = newZoneSize;
3748 int tempReducedDimensionIndex = -1;
3749 for (
int d = 0; d < tempRgn->
Dimensions; ++d) {
3751 tempReducedDimensionIndex = d;
3757 for (
int iDst = 0; iDst < 256; ++iDst) {
3759 if (!dstDimRgn)
continue;
3760 std::map<dimension_t,int> dimCase;
3761 bool isValidZone =
true;
3762 for (
int d = 0, baseBits = 0; d < tempRgn->
Dimensions; ++d) {
3765 (iDst >> baseBits) & ((1 << dstBits) - 1);
3766 baseBits += dstBits;
3769 isValidZone =
false;
3773 if (!isValidZone)
continue;
3776 const bool isLastZone = (dimCase[type] == newZoneSize - 1);
3777 if (dimCase[type] >= zone) dimCase[type]++;
3792 for (
int iSrc = 0; iSrc < 256; ++iSrc) {
3794 if (!srcDimRgn)
continue;
3795 std::map<dimension_t,int> dimCase;
3796 for (
int d = 0, baseBits = 0; d < tempRgn->
Dimensions; ++d) {
3799 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3800 baseBits += srcBits;
3805 if (!dstDimRgn)
continue;
3813 UpdateVelocityTable();
3833 throw gig::Exception(
"Could not split dimension zone, no such dimension of given type");
3834 if (zone < 0 || zone >= oldDef->
zones)
3835 throw gig::Exception(
"Could not split dimension zone, requested zone index out of bounds.");
3837 const int newZoneSize = oldDef->
zones + 1;
3846 RIFF::List* pCkInstrument = instr->pCkInstrument;
3848 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
3850 tempRgn =
new Region(instr, rgn);
3862 def.
zones = newZoneSize;
3863 if ((1 << oldDef->
bits) < newZoneSize) def.
bits++;
3871 int tempIncreasedDimensionIndex = -1;
3872 for (
int d = 0; d < tempRgn->
Dimensions; ++d) {
3874 tempIncreasedDimensionIndex = d;
3880 for (
int iSrc = 0; iSrc < 256; ++iSrc) {
3882 if (!srcDimRgn)
continue;
3883 std::map<dimension_t,int> dimCase;
3884 bool isValidZone =
true;
3885 for (
int d = 0, baseBits = 0; d <
Dimensions; ++d) {
3888 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3891 isValidZone =
false;
3894 baseBits += srcBits;
3896 if (!isValidZone)
continue;
3899 if (dimCase[type] > zone) dimCase[type]++;
3905 if (dimCase[type] == zone) {
3912 std::map<dimension_t,int> lowerCase = dimCase;
3932 for (
int iSrc = 0; iSrc < 256; ++iSrc) {
3934 if (!srcDimRgn)
continue;
3935 std::map<dimension_t,int> dimCase;
3936 for (
int d = 0, baseBits = 0; d < tempRgn->
Dimensions; ++d) {
3939 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3940 baseBits += srcBits;
3945 if (!dstDimRgn)
continue;
3953 UpdateVelocityTable();
3971 if (oldType == newType)
return;
3974 throw gig::Exception(
"No dimension with provided old dimension type exists on this region");
3976 throw gig::Exception(
"Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones");
3978 throw gig::Exception(
"There is already a dimension with requested new dimension type on this region");
3980 def->
split_type = __resolveSplitType(newType);
3984 uint8_t bits[8] = {};
3985 for (std::map<dimension_t,int>::const_iterator it = DimCase.begin();
3986 it != DimCase.end(); ++it)
3990 bits[d] = it->second;
3991 goto nextDimCaseSlice;
4018 for (
int i = 0; i < 256; i++) {
4058 if (DimValues[i] <=
pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i])
break;
4067 bits = DimValues[i] & limiter_mask;
4070 dimregidx |= bits << bitpos;
4075 if (!dimreg)
return NULL;
4084 dimregidx |= (bits & limiter_mask) << velbitpos;
4090 int Region::GetDimensionRegionIndexByValue(
const uint DimValues[8]) {
4107 if (DimValues[i] <=
pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i])
break;
4116 bits = DimValues[i] & limiter_mask;
4119 dimregidx |= bits << bitpos;
4125 if (!dimreg)
return -1;
4128 if (dimreg->VelocityTable)
4134 dimregidx |= (bits & limiter_mask) << velbitpos;
4170 if (pSample)
return static_cast<gig::Sample*
>(pSample);
4171 else return static_cast<gig::Sample*
>(pSample = GetSampleFromWavePool(WavePoolTableIndex));
4174 Sample* Region::GetSampleFromWavePool(
unsigned int WavePoolTableIndex,
progress_t* pProgress) {
4175 if ((int32_t)WavePoolTableIndex == -1)
return NULL;
4176 File* file = (
File*) GetParent()->GetParent();
4177 if (!file->pWavePoolTable)
return NULL;
4178 if (WavePoolTableIndex + 1 > file->WavePoolCount)
return NULL;
4182 uint64_t soughtoffset =
4183 uint64_t(file->pWavePoolTable[WavePoolTableIndex]) |
4184 uint64_t(file->pWavePoolTableHi[WavePoolTableIndex]) << 32;
4187 if (sample->ullWavePoolOffset == soughtoffset)
4193 file_offset_t soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
4194 file_offset_t soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
4197 if (sample->ullWavePoolOffset == soughtoffset &&
4198 sample->FileNo == soughtfileno)
return static_cast<gig::Sample*
>(sample);
4229 if (mSamples && mSamples->count((
gig::Sample*)orig->pSample)) {
4230 pSample = mSamples->find((
gig::Sample*)orig->pSample)->second;
4244 for (
int i = 0; i < 256; i++) {
4259 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger(
RIFF::Chunk* _3ewg) {
4265 for (
int i = 0 ; i <
Triggers ; i++) {
4266 pTriggers[i].TriggerPoint = _3ewg->
ReadUint8();
4267 pTriggers[i].Descending = _3ewg->
ReadUint8();
4268 pTriggers[i].VelSensitivity = _3ewg->
ReadUint8();
4270 pTriggers[i].NoteOff = _3ewg->
ReadUint8();
4271 pTriggers[i].Velocity = _3ewg->
ReadUint8();
4272 pTriggers[i].OverridePedal = _3ewg->
ReadUint8();
4277 MidiRuleCtrlTrigger::MidiRuleCtrlTrigger() :
4278 ControllerNumber(0),
4282 void MidiRuleCtrlTrigger::UpdateChunks(uint8_t* pData)
const {
4287 for (
int i = 0 ; i <
Triggers ; i++) {
4288 pData[46 + i * 8] = pTriggers[i].TriggerPoint;
4289 pData[47 + i * 8] = pTriggers[i].Descending;
4290 pData[48 + i * 8] = pTriggers[i].VelSensitivity;
4291 pData[49 + i * 8] = pTriggers[i].Key;
4292 pData[50 + i * 8] = pTriggers[i].NoteOff;
4293 pData[51 + i * 8] = pTriggers[i].Velocity;
4294 pData[52 + i * 8] = pTriggers[i].OverridePedal;
4298 MidiRuleLegato::MidiRuleLegato(
RIFF::Chunk* _3ewg) {
4317 MidiRuleLegato::MidiRuleLegato() :
4319 BypassUseController(false),
4321 BypassController(1),
4324 ReleaseTriggerKey(0),
4331 void MidiRuleLegato::UpdateChunks(uint8_t* pData)
const {
4347 MidiRuleAlternator::MidiRuleAlternator(
RIFF::Chunk* _3ewg) {
4353 Selector = (flags & 2) ? selector_controller :
4354 (flags & 1) ? selector_key_switch : selector_none;
4367 for (
int i = 0 ; i < n ; i++) {
4372 for (
int i = 0 ; i < n ; i++) {
4379 MidiRuleAlternator::MidiRuleAlternator() :
4382 Selector(selector_none),
4387 PlayRange.low = PlayRange.high = 0;
4388 KeySwitchRange.low = KeySwitchRange.high = 0;
4391 void MidiRuleAlternator::UpdateChunks(uint8_t* pData)
const {
4396 (
Selector == selector_controller ? 2 :
4397 (
Selector == selector_key_switch ? 1 : 0));
4406 char* str =
reinterpret_cast<char*
>(pData);
4409 for (
int i = 0 ; i < n ; i++, pos += 32) {
4415 for (
int i = 0 ; i < n ; i++, pos += 49) {
4416 strncpy(&str[pos],
pPatterns[i].Name.c_str(), 16);
4418 memcpy(&pData[pos + 16], &(
pPatterns[i][0]), 32);
4425 Script::Script(ScriptGroup* group,
RIFF::Chunk* ckScri) {
4439 Name.resize(nameSize,
' ');
4440 for (
int i = 0; i < nameSize; ++i)
4443 ckScri->
SetPos(
sizeof(int32_t) + headerSize);
4445 uint32_t scriptSize = uint32_t(ckScri->
GetSize() - ckScri->
GetPos());
4446 data.resize(scriptSize);
4447 for (
int i = 0; i < scriptSize; ++i)
4455 Name =
"Unnamed Script";
4467 s.resize(data.size(),
' ');
4468 memcpy(&s[0], &data[0], data.size());
4479 data.resize(text.size());
4480 memcpy(&data[0], &text[0], text.size());
4507 __calculateCRC(&data[0], data.size(), crc);
4510 const file_offset_t chunkSize = (file_offset_t) 7*
sizeof(int32_t) +
Name.size() + data.size();
4511 if (!pChunk) pChunk = pGroup->pList->
AddSubChunk(CHUNK_ID_SCRI, chunkSize);
4512 else pChunk->
Resize(chunkSize);
4516 store32(&pData[pos], uint32_t(6*
sizeof(int32_t) +
Name.size()));
4517 pos +=
sizeof(int32_t);
4519 pos +=
sizeof(int32_t);
4521 pos +=
sizeof(int32_t);
4523 pos +=
sizeof(int32_t);
4524 store32(&pData[pos],
Bypass ? 1 : 0);
4525 pos +=
sizeof(int32_t);
4526 store32(&pData[pos], crc);
4527 pos +=
sizeof(int32_t);
4528 store32(&pData[pos], (uint32_t)
Name.size());
4529 pos +=
sizeof(int32_t);
4530 for (
int i = 0; i <
Name.size(); ++i, ++pos)
4531 pData[pos] =
Name[i];
4532 for (
int i = 0; i < data.size(); ++i, ++pos)
4533 pData[pos] = data[i];
4543 if (this->pGroup == pGroup)
return;
4546 this->pGroup = pGroup;
4575 void Script::RemoveAllScriptReferences() {
4576 File* pFile = pGroup->pFile;
4586 ScriptGroup::ScriptGroup(File* file,
RIFF::List* lstRTIS) {
4592 ::LoadString(ckName,
Name);
4594 Name =
"Default Group";
4598 ScriptGroup::~ScriptGroup() {
4600 std::list<Script*>::iterator iter = pScripts->begin();
4601 std::list<Script*>::iterator end = pScripts->end();
4602 while (iter != end) {
4637 ::SaveString(CHUNK_ID_LSNM, NULL, pList,
Name, String(
"Unnamed Group"),
true, 64);
4639 for (std::list<Script*>::iterator it = pScripts->begin();
4640 it != pScripts->end(); ++it)
4642 (*it)->UpdateChunks(pProgress);
4655 if (!pScripts) LoadScripts();
4656 std::list<Script*>::iterator it = pScripts->begin();
4657 for (uint i = 0; it != pScripts->end(); ++i, ++it)
4658 if (i == index)
return *it;
4674 if (!pScripts) LoadScripts();
4676 pScripts->push_back(pScript);
4691 if (!pScripts) LoadScripts();
4692 std::list<Script*>::iterator iter =
4693 find(pScripts->begin(), pScripts->end(), pScript);
4694 if (iter == pScripts->end())
4695 throw gig::Exception(
"Could not delete script, could not find given script");
4696 pScripts->erase(iter);
4697 pScript->RemoveAllScriptReferences();
4698 if (pScript->pChunk)
4703 void ScriptGroup::LoadScripts() {
4704 if (pScripts)
return;
4705 pScripts =
new std::list<Script*>;
4711 if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4712 pScripts->push_back(
new Script(
this, ck));
4720 Instrument::Instrument(File* pFile,
RIFF::List* insList, progress_t* pProgress) :
DLS::Instrument((
DLS::File*)pFile, insList) {
4721 static const DLS::Info::string_length_t fixedStringLengths[] = {
4722 { CHUNK_ID_INAM, 64 },
4723 { CHUNK_ID_ISFT, 12 },
4726 pInfo->SetFixedStringLengths(fixedStringLengths);
4729 for (
int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4734 PianoReleaseMode =
false;
4735 DimensionKeyRange.low = 0;
4736 DimensionKeyRange.high = 0;
4737 pMidiRules =
new MidiRule*[3];
4738 pMidiRules[0] = NULL;
4752 uint8_t dimkeystart = _3ewg->
ReadUint8();
4753 PianoReleaseMode = dimkeystart & 0x01;
4754 DimensionKeyRange.low = dimkeystart >> 1;
4755 DimensionKeyRange.high = _3ewg->
ReadUint8();
4766 pMidiRules[i++] =
new MidiRuleCtrlTrigger(_3ewg);
4767 }
else if (id1 == 0) {
4768 pMidiRules[i++] =
new MidiRuleLegato(_3ewg);
4769 }
else if (id1 == 3) {
4770 pMidiRules[i++] =
new MidiRuleAlternator(_3ewg);
4772 pMidiRules[i++] =
new MidiRuleUnknown;
4775 else if (id1 != 0 || id2 != 0) {
4776 pMidiRules[i++] =
new MidiRuleUnknown;
4780 pMidiRules[i] = NULL;
4785 if (pFile->GetAutoLoad()) {
4786 if (!pRegions) pRegions =
new RegionList;
4793 __notify_progress(pProgress, (
float) pRegions->size() / (
float) Regions);
4794 pRegions->push_back(
new Region(
this, rgn));
4799 UpdateRegionKeyTable();
4814 ckSCSL->
SetPos(headerSize);
4815 int unknownSpace = slotSize - 2*
sizeof(uint32_t);
4816 for (
int i = 0; i < slotCount; ++i) {
4817 _ScriptPooolEntry e;
4820 if (unknownSpace) ckSCSL->
SetPos(unknownSpace, RIFF::stream_curpos);
4821 scriptPoolFileOffsets.push_back(e);
4828 __notify_progress(pProgress, 1.0f);
4831 void Instrument::UpdateRegionKeyTable() {
4833 RegionList::iterator iter = pRegions->begin();
4834 RegionList::iterator end = pRegions->end();
4835 for (; iter != end; ++iter) {
4837 const int low = std::max(
int(pRegion->
KeyRange.
low), 0);
4838 const int high = std::min(
int(pRegion->
KeyRange.
high), 127);
4839 for (
int iKey = low; iKey <= high; iKey++) {
4846 for (
int i = 0 ; pMidiRules[i] ; i++) {
4847 delete pMidiRules[i];
4849 delete[] pMidiRules;
4850 if (pScriptRefs)
delete pScriptRefs;
4869 RegionList::iterator iter = pRegions->begin();
4870 RegionList::iterator end = pRegions->end();
4871 for (; iter != end; ++iter)
4872 (*iter)->UpdateChunks(pProgress);
4877 if (!lart) lart = pCkInstrument->
AddSubList(LIST_TYPE_LART);
4890 store16(&pData[0], EffectSend);
4894 const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
4896 pData[10] = dimkeystart;
4899 if (pMidiRules[0] == 0 && _3ewg->
GetSize() >= 34) {
4903 for (
int i = 0 ; pMidiRules[i] ; i++) {
4904 pMidiRules[i]->UpdateChunks(pData);
4915 if (!lst3LS) lst3LS = pCkInstrument->
AddSubList(LIST_TYPE_3LS);
4916 const int slotCount = (int) pScriptRefs->size();
4917 const int headerSize = 3 *
sizeof(uint32_t);
4918 const int slotSize = 2 *
sizeof(uint32_t);
4919 const int totalChunkSize = headerSize + slotCount * slotSize;
4921 if (!ckSCSL) ckSCSL = lst3LS->
AddSubChunk(CHUNK_ID_SCSL, totalChunkSize);
4922 else ckSCSL->
Resize(totalChunkSize);
4925 store32(&pData[pos], headerSize);
4926 pos +=
sizeof(uint32_t);
4927 store32(&pData[pos], slotCount);
4928 pos +=
sizeof(uint32_t);
4929 store32(&pData[pos], slotSize);
4930 pos +=
sizeof(uint32_t);
4931 for (
int i = 0; i < slotCount; ++i) {
4934 int bogusFileOffset = 0;
4935 store32(&pData[pos], bogusFileOffset);
4936 pos +=
sizeof(uint32_t);
4937 store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0);
4938 pos +=
sizeof(uint32_t);
4947 void Instrument::UpdateScriptFileOffsets() {
4949 if (pScriptRefs && pScriptRefs->size() > 0) {
4952 const int slotCount = (int) pScriptRefs->size();
4953 const int headerSize = 3 *
sizeof(uint32_t);
4954 ckSCSL->
SetPos(headerSize);
4955 for (
int i = 0; i < slotCount; ++i) {
4956 uint32_t fileOffset = uint32_t(
4957 (*pScriptRefs)[i].script->pChunk->GetFilePos() -
4958 (*pScriptRefs)[i].script->pChunk->GetPos() -
4963 ckSCSL->
SetPos(
sizeof(uint32_t), RIFF::stream_curpos);
4976 if (!pRegions || pRegions->empty() || Key > 127)
return NULL;
4994 if (!pRegions)
return NULL;
4995 RegionsIterator = pRegions->begin();
4996 return static_cast<gig::Region*
>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5008 if (!pRegions)
return NULL;
5010 return static_cast<gig::Region*
>( (RegionsIterator != pRegions->end()) ? *RegionsIterator : NULL );
5013 Region* Instrument::AddRegion() {
5016 if (!lrgn) lrgn = pCkInstrument->
AddSubList(LIST_TYPE_LRGN);
5019 pRegions->push_back(pNewRegion);
5020 Regions = (uint32_t) pRegions->size();
5022 UpdateRegionKeyTable();
5027 void Instrument::DeleteRegion(Region* pRegion) {
5028 if (!pRegions)
return;
5029 DLS::Instrument::DeleteRegion((
DLS::Region*) pRegion);
5031 UpdateRegionKeyTable();
5062 if (dst && GetParent() != dst->GetParent())
5064 "gig::Instrument::MoveTo() can only be used for moving within "
5065 "the same gig file."
5072 File::InstrumentList& list = *pFile->pInstruments;
5074 File::InstrumentList::iterator itFrom =
5075 std::find(list.begin(), list.end(),
static_cast<DLS::Instrument*
>(
this));
5077 File::InstrumentList::iterator itTo =
5078 std::find(list.begin(), list.end(),
static_cast<DLS::Instrument*
>(dst));
5080 list.splice(itTo, list, itFrom);
5086 this->pCkInstrument,
5087 (
RIFF::Chunk*) ((dst) ? dst->pCkInstrument : NULL)
5102 return pMidiRules[i];
5111 delete pMidiRules[0];
5124 delete pMidiRules[0];
5137 delete pMidiRules[0];
5150 delete pMidiRules[i];
5154 void Instrument::LoadScripts() {
5155 if (pScriptRefs)
return;
5156 pScriptRefs =
new std::vector<_ScriptPooolRef>;
5157 if (scriptPoolFileOffsets.empty())
return;
5159 for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) {
5160 uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset;
5163 for (uint s = 0; group->
GetScript(s); ++s) {
5165 if (script->pChunk) {
5166 uint32_t offset = uint32_t(
5168 script->pChunk->
GetPos() -
5171 if (offset == soughtOffset)
5173 _ScriptPooolRef ref;
5174 ref.script = script;
5175 ref.bypass = scriptPoolFileOffsets[k].bypass;
5176 pScriptRefs->push_back(ref);
5184 scriptPoolFileOffsets.clear();
5201 if (index >= pScriptRefs->size())
return NULL;
5202 return pScriptRefs->at(index).script;
5242 _ScriptPooolRef ref = { pScript, bypass };
5243 pScriptRefs->push_back(ref);
5262 if (index1 >= pScriptRefs->size() || index2 >= pScriptRefs->size())
5264 _ScriptPooolRef tmp = (*pScriptRefs)[index1];
5265 (*pScriptRefs)[index1] = (*pScriptRefs)[index2];
5266 (*pScriptRefs)[index2] = tmp;
5277 if (index >= pScriptRefs->size())
return;
5278 pScriptRefs->erase( pScriptRefs->begin() + index );
5295 for (ssize_t i = pScriptRefs->size() - 1; i >= 0; --i) {
5296 if ((*pScriptRefs)[i].script == pScript) {
5297 pScriptRefs->erase( pScriptRefs->begin() + i );
5317 return uint(pScriptRefs ? pScriptRefs->size() : scriptPoolFileOffsets.size());
5338 return pScriptRefs ? pScriptRefs->at(index).bypass
5339 : scriptPoolFileOffsets.at(index).bypass;
5359 pScriptRefs->at(index).bypass = bBypass;
5361 scriptPoolFileOffsets.at(index).bypass = bBypass;
5388 DLS::Instrument::CopyAssignCore(orig);
5392 EffectSend = orig->EffectSend;
5395 PianoReleaseMode = orig->PianoReleaseMode;
5397 scriptPoolFileOffsets = orig->scriptPoolFileOffsets;
5398 pScriptRefs = orig->pScriptRefs;
5401 for (
int i = 0 ; pMidiRules[i] ; i++) {
5402 delete pMidiRules[i];
5405 pMidiRules[0] = NULL;
5411 RegionList::const_iterator it = orig->pRegions->begin();
5412 for (
int i = 0; i < orig->
Regions; ++i, ++it) {
5413 Region* dstRgn = AddRegion();
5422 UpdateRegionKeyTable();
5437 pNameChunk = ck3gnm;
5438 ::LoadString(pNameChunk,
Name);
5474 _3gri = pFile->pRIFF->
AddSubList(LIST_TYPE_3GRI);
5478 if (!_3gnl) _3gnl = _3gri->
AddSubList(LIST_TYPE_3GNL);
5483 if (strcmp(
static_cast<char*
>(ck->LoadChunkData()),
"") == 0) {
5491 ::SaveString(CHUNK_ID_3GNM, pNameChunk, _3gnl,
Name, String(
"Unnamed Group"),
true, 64);
5508 if (pSample->GetGroup() ==
this)
return pSample;
5526 if (pSample->GetGroup() ==
this)
return pSample;
5546 Group* pOtherGroup = NULL;
5548 if (pOtherGroup !=
this)
break;
5551 "Could not move samples to another group, since there is no "
5552 "other Group. This is a bug, report it!"
5567 0, 2, 19980628 & 0xffff, 19980628 >> 16
5572 0, 3, 20030331 & 0xffff, 20030331 >> 16
5577 0, 4, 20071012 & 0xffff, 20071012 >> 16
5580 static const DLS::Info::string_length_t _FileFixedStringLengths[] = {
5581 { CHUNK_ID_IARL, 256 },
5582 { CHUNK_ID_IART, 128 },
5583 { CHUNK_ID_ICMS, 128 },
5584 { CHUNK_ID_ICMT, 1024 },
5585 { CHUNK_ID_ICOP, 128 },
5586 { CHUNK_ID_ICRD, 128 },
5587 { CHUNK_ID_IENG, 128 },
5588 { CHUNK_ID_IGNR, 128 },
5589 { CHUNK_ID_IKEY, 128 },
5590 { CHUNK_ID_IMED, 128 },
5591 { CHUNK_ID_INAM, 128 },
5592 { CHUNK_ID_IPRD, 128 },
5593 { CHUNK_ID_ISBJ, 128 },
5594 { CHUNK_ID_ISFT, 128 },
5595 { CHUNK_ID_ISRC, 128 },
5596 { CHUNK_ID_ISRF, 128 },
5597 { CHUNK_ID_ITCH, 128 },
5601 File::File() :
DLS::File() {
5603 *pVersion = VERSION_3;
5605 pScriptGroups = NULL;
5606 pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5607 pInfo->ArchivalLocation = String(256,
' ');
5611 pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
5612 pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
5613 pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
5621 pScriptGroups = NULL;
5622 pInfo->SetFixedStringLengths(_FileFixedStringLengths);
5627 std::list<Group*>::iterator iter = pGroups->begin();
5628 std::list<Group*>::iterator end = pGroups->end();
5629 while (iter != end) {
5635 if (pScriptGroups) {
5636 std::list<ScriptGroup*>::iterator iter = pScriptGroups->begin();
5637 std::list<ScriptGroup*>::iterator end = pScriptGroups->end();
5638 while (iter != end) {
5642 delete pScriptGroups;
5647 if (!pSamples) LoadSamples(pProgress);
5648 if (!pSamples)
return NULL;
5649 SamplesIterator = pSamples->begin();
5650 return static_cast<gig::Sample*
>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5654 if (!pSamples)
return NULL;
5656 return static_cast<gig::Sample*
>( (SamplesIterator != pSamples->end()) ? *SamplesIterator : NULL );
5665 if (!pSamples) LoadSamples();
5666 if (!pSamples)
return NULL;
5667 DLS::File::SampleList::iterator it = pSamples->begin();
5668 for (
int i = 0; i < index; ++i) {
5670 if (it == pSamples->end())
return NULL;
5672 if (it == pSamples->end())
return NULL;
5685 if (!pSamples) LoadSamples();
5686 if (!pSamples)
return 0;
5687 return pSamples->size();
5698 if (!pSamples) LoadSamples();
5709 pSamples->push_back(pSample);
5723 if (!pSamples || !pSamples->size())
throw gig::Exception(
"Could not delete sample as there are no samples");
5724 SampleList::iterator iter = find(pSamples->begin(), pSamples->end(), (
DLS::Sample*) pSample);
5725 if (iter == pSamples->end())
throw gig::Exception(
"Could not delete sample, could not find given sample");
5726 if (SamplesIterator != pSamples->end() && *SamplesIterator == pSample) ++SamplesIterator;
5727 pSamples->erase(iter);
5731 SampleList::iterator tmp = SamplesIterator;
5735 for (
Region* region = instrument->GetFirstRegion() ; region ;
5736 region = instrument->GetNextRegion()) {
5738 if (region->GetSample() == pSample) region->SetSample(NULL);
5740 for (
int i = 0 ; i < region->DimensionRegions ; i++) {
5746 SamplesIterator = tmp;
5749 void File::LoadSamples() {
5753 void File::LoadSamples(progress_t* pProgress) {
5756 if (!pGroups) LoadGroups();
5758 if (!pSamples) pSamples =
new SampleList;
5763 int iSampleIndex = 0;
5764 int iTotalSamples = WavePoolCount;
5767 const std::string folder = parentPath(pRIFF->GetFileName());
5768 const std::string baseName = pathWithoutExtension(pRIFF->GetFileName());
5772 std::vector<RIFF::File*> poolFiles;
5773 poolFiles.push_back(pRIFF);
5779 for (
int i = 0; i < n; i++) {
5783 std::string path = concatPath(folder, name);
5789 idExpected.ulData1 = ckXfil->
ReadInt32();
5790 idExpected.usData2 = ckXfil->
ReadInt16();
5791 idExpected.usData3 = ckXfil->
ReadInt16();
5792 ckXfil->
Read(idExpected.abData, 8, 1);
5794 ckDLSID->
Read(&idFound.ulData1, 1, 4);
5795 ckDLSID->
Read(&idFound.usData2, 1, 2);
5796 ckDLSID->
Read(&idFound.usData3, 1, 2);
5797 ckDLSID->
Read(idFound.abData, 8, 1);
5798 if (memcmp(&idExpected, &idFound, 16) != 0)
5799 throw gig::Exception(
"dlsid mismatch for extension file: %s", path.c_str());
5801 poolFiles.push_back(pExtFile);
5802 ExtensionFiles.push_back(pExtFile);
5809 std::string path = baseName +
".gx99";
5813 ckDoxf->
SetPos(132, RIFF::stream_curpos);
5819 idExpected.ulData1 = ckDoxf->
ReadInt32();
5820 idExpected.usData2 = ckDoxf->
ReadInt16();
5821 idExpected.usData3 = ckDoxf->
ReadInt16();
5822 ckDoxf->
Read(idExpected.abData, 8, 1);
5824 ckDLSID->
Read(&idFound.ulData1, 1, 4);
5825 ckDLSID->
Read(&idFound.usData2, 1, 2);
5826 ckDLSID->
Read(&idFound.usData3, 1, 2);
5827 ckDLSID->
Read(idFound.abData, 8, 1);
5828 if (memcmp(&idExpected, &idFound, 16) != 0)
5829 throw gig::Exception(
"dlsid mismatch for GigaPulse file: %s", path.c_str());
5831 poolFiles.push_back(pExtFile);
5832 ExtensionFiles.push_back(pExtFile);
5836 for (
int i = 0; i < poolFiles.size(); i++) {
5847 const float subprogress = (float) iSampleIndex / (
float) iTotalSamples;
5848 __notify_progress(pProgress, subprogress);
5852 pSamples->push_back(
new Sample(
this, wave, waveFileOffset - wvplFileOffset, i, iSampleIndex));
5862 __notify_progress(pProgress, 1.0);
5866 if (!pInstruments) LoadInstruments();
5867 if (!pInstruments)
return NULL;
5868 InstrumentsIterator = pInstruments->begin();
5869 return static_cast<gig::Instrument*
>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5873 if (!pInstruments)
return NULL;
5874 InstrumentsIterator++;
5875 return static_cast<gig::Instrument*
>( (InstrumentsIterator != pInstruments->end()) ? *InstrumentsIterator : NULL );
5887 if (!pInstruments) LoadInstruments();
5888 if (!pInstruments)
return 0;
5889 return pInstruments->size();
5900 if (!pInstruments) {
5906 __divide_progress(pProgress, &subprogress, 3.0f, 0.0f);
5907 __notify_progress(&subprogress, 0.0f);
5910 __notify_progress(&subprogress, 1.0f);
5917 __notify_progress(&subprogress, 0.0f);
5918 LoadInstruments(&subprogress);
5919 __notify_progress(&subprogress, 1.0f);
5929 if (!pInstruments)
return NULL;
5930 InstrumentsIterator = pInstruments->begin();
5931 for (uint i = 0; InstrumentsIterator != pInstruments->end(); i++) {
5932 if (i == index)
return static_cast<gig::Instrument*
>( *InstrumentsIterator );
5933 InstrumentsIterator++;
5946 if (!pInstruments) LoadInstruments();
5963 pInstruments->push_back(pInstrument);
6000 static int iCallCount = -1;
6002 std::map<Group*,Group*> mGroups;
6003 std::map<Sample*,Sample*> mSamples;
6006 for (
int i = 0; pFile->
GetGroup(i); ++i) {
6007 Group* g = AddGroup();
6009 "COPY" + ToString(iCallCount) +
"_" + pFile->
GetGroup(i)->
Name;
6014 for (
int i = 0; pFile->
GetSample(i); ++i) {
6025 dg->
Name =
"COPY" + ToString(iCallCount) +
"_" + sg->
Name;
6026 for (
int iScript = 0; sg->
GetScript(iScript); ++iScript) {
6058 for (
int i = 0; pFile->
GetSample(i); ++i) {
6072 if (!pInstruments)
throw gig::Exception(
"Could not delete instrument as there are no instruments");
6073 InstrumentList::iterator iter = find(pInstruments->begin(), pInstruments->end(), (
DLS::Instrument*) pInstrument);
6074 if (iter == pInstruments->end())
throw gig::Exception(
"Could not delete instrument, could not find given instrument");
6075 pInstruments->erase(iter);
6080 void File::LoadInstruments() {
6081 LoadInstruments(NULL);
6084 void File::LoadInstruments(progress_t* pProgress) {
6085 if (!pInstruments) pInstruments =
new InstrumentList;
6087 if (lstInstruments) {
6088 int iInstrumentIndex = 0;
6094 const float localProgress = (float) iInstrumentIndex / (
float)
Instruments;
6095 __notify_progress(pProgress, localProgress);
6098 progress_t subprogress;
6099 __divide_progress(pProgress, &subprogress,
Instruments, iInstrumentIndex);
6101 pInstruments->push_back(
new Instrument(
this, lstInstr, &subprogress));
6103 pInstruments->push_back(
new Instrument(
this, lstInstr));
6111 __notify_progress(pProgress, 1.0);
6123 int iWaveIndex = GetWaveTableIndexOf(pSample);
6124 if (iWaveIndex < 0)
throw gig::Exception(
"Could not update crc, could not find sample");
6127 _3crc->
SetPos(iWaveIndex * 8);
6133 uint32_t File::GetSampleChecksum(
Sample* pSample) {
6135 int iWaveIndex = GetWaveTableIndexOf(pSample);
6136 if (iWaveIndex < 0)
throw gig::Exception(
"Could not retrieve reference crc of sample, could not resolve sample's wave table index");
6138 return GetSampleChecksumByIndex(iWaveIndex);
6141 uint32_t File::GetSampleChecksumByIndex(
int index) {
6142 if (index < 0)
throw gig::Exception(
"Could not retrieve reference crc of sample, invalid wave pool index of sample");
6145 if (!_3crc)
throw gig::Exception(
"Could not retrieve reference crc of sample, no checksums stored for this file yet");
6147 if (!pData)
throw gig::Exception(
"Could not retrieve reference crc of sample, no checksums stored for this file yet");
6150 size_t pos = index * 8;
6152 throw gig::Exception(
"Could not retrieve reference crc of sample, could not seek to required position in crc chunk");
6154 uint32_t one = load32(&pData[pos]);
6156 throw gig::Exception(
"Could not retrieve reference crc of sample, because reference checksum table is damaged");
6158 return load32(&pData[pos+4]);
6161 int File::GetWaveTableIndexOf(
gig::Sample* pSample) {
6163 File::SampleList::iterator iter = pSamples->begin();
6164 File::SampleList::iterator end = pSamples->end();
6165 for (
int index = 0; iter != end; ++iter, ++index)
6166 if (*iter == pSample)
6179 if (!_3crc)
return false;
6183 if (_3crc->
GetNewSize() != pSamples->size() * 8)
return false;
6185 const file_offset_t n = _3crc->
GetNewSize() / 8;
6188 if (!pData)
return false;
6190 for (file_offset_t i = 0; i < n; ++i) {
6191 uint32_t one = pData[i*2];
6192 if (one != 1)
return false;
6218 bool bRequiresSave =
false;
6223 _3crc = pRIFF->
AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6227 bRequiresSave =
true;
6228 }
else if (_3crc->
GetNewSize() != pSamples->size() * 8) {
6229 _3crc->
Resize(pSamples->size() * 8);
6230 bRequiresSave =
true;
6233 if (bRequiresSave) {
6236 File::SampleList::iterator iter = pSamples->begin();
6237 File::SampleList::iterator end = pSamples->end();
6238 for (; iter != end; ++iter) {
6240 int index = GetWaveTableIndexOf(pSample);
6241 if (index < 0)
throw gig::Exception(
"Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6243 pData[index*2+1] = pSample->CalculateWaveDataChecksum();
6248 pRIFF->
SetMode(RIFF::stream_mode_read_write);
6250 File::SampleList::iterator iter = pSamples->begin();
6251 File::SampleList::iterator end = pSamples->end();
6252 for (; iter != end; ++iter) {
6254 int index = GetWaveTableIndexOf(pSample);
6255 if (index < 0)
throw gig::Exception(
"Could not rebuild crc table for samples, wave table index of a sample could not be resolved");
6256 pSample->
crc = pSample->CalculateWaveDataChecksum();
6262 return bRequiresSave;
6266 if (!pGroups) LoadGroups();
6268 GroupsIterator = pGroups->begin();
6269 return *GroupsIterator;
6273 if (!pGroups)
return NULL;
6275 return (GroupsIterator == pGroups->end()) ? NULL : *GroupsIterator;
6285 if (!pGroups) LoadGroups();
6286 GroupsIterator = pGroups->begin();
6287 for (uint i = 0; GroupsIterator != pGroups->end(); i++) {
6288 if (i == index)
return *GroupsIterator;
6305 if (!pGroups) LoadGroups();
6306 GroupsIterator = pGroups->begin();
6307 for (uint i = 0; GroupsIterator != pGroups->end(); ++GroupsIterator, ++i)
6308 if ((*GroupsIterator)->Name == name)
return *GroupsIterator;
6312 Group* File::AddGroup() {
6313 if (!pGroups) LoadGroups();
6317 pGroups->push_back(pGroup);
6331 if (!pGroups) LoadGroups();
6332 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6333 if (iter == pGroups->end())
throw gig::Exception(
"Could not delete group, could not find given group");
6334 if (pGroups->size() == 1)
throw gig::Exception(
"Cannot delete group, there must be at least one default group!");
6340 pGroups->erase(iter);
6356 if (!pGroups) LoadGroups();
6357 std::list<Group*>::iterator iter = find(pGroups->begin(), pGroups->end(), pGroup);
6358 if (iter == pGroups->end())
throw gig::Exception(
"Could not delete group, could not find given group");
6359 if (pGroups->size() == 1)
throw gig::Exception(
"Cannot delete group, there must be at least one default group!");
6362 pGroups->erase(iter);
6367 void File::LoadGroups() {
6368 if (!pGroups) pGroups =
new std::list<Group*>;
6378 strcmp(
static_cast<char*
>(ck->
LoadChunkData()),
"") == 0)
break;
6380 pGroups->push_back(
new Group(
this, ck));
6387 if (!pGroups->size()) {
6388 Group* pGroup =
new Group(
this, NULL);
6389 pGroup->Name =
"Default Group";
6390 pGroups->push_back(pGroup);
6402 if (!pScriptGroups) LoadScriptGroups();
6403 std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6404 for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6405 if (i == index)
return *it;
6418 if (!pScriptGroups) LoadScriptGroups();
6419 std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6420 for (uint i = 0; it != pScriptGroups->end(); ++i, ++it)
6421 if ((*it)->Name == name)
return *it;
6434 if (!pScriptGroups) LoadScriptGroups();
6436 pScriptGroups->push_back(pScriptGroup);
6437 return pScriptGroup;
6453 if (!pScriptGroups) LoadScriptGroups();
6454 std::list<ScriptGroup*>::iterator iter =
6455 find(pScriptGroups->begin(), pScriptGroups->end(), pScriptGroup);
6456 if (iter == pScriptGroups->end())
6457 throw gig::Exception(
"Could not delete script group, could not find given script group");
6458 pScriptGroups->erase(iter);
6459 for (
int i = 0; pScriptGroup->
GetScript(i); ++i)
6461 if (pScriptGroup->pList)
6464 delete pScriptGroup;
6467 void File::LoadScriptGroups() {
6468 if (pScriptGroups)
return;
6469 pScriptGroups =
new std::list<ScriptGroup*>;
6475 if (lst->GetListType() == LIST_TYPE_RTIS) {
6476 pScriptGroups->push_back(
new ScriptGroup(
this, lst));
6494 bool newFile = pRIFF->
GetSubList(LIST_TYPE_INFO) == NULL;
6511 if (pScriptGroups) {
6513 for (std::list<ScriptGroup*>::iterator it = pScriptGroups->begin();
6514 it != pScriptGroups->end(); ++it)
6516 (*it)->UpdateChunks(pProgress);
6535 if (first != info) {
6550 if (!_3gnl) _3gnl = _3gri->
AddSubList(LIST_TYPE_3GNL);
6556 for (
int i = 0 ; i < 128 ; i++) {
6557 if (i >= pGroups->size()) ::SaveString(CHUNK_ID_3GNM, _3gnm, _3gnl,
"",
"",
true, 64);
6562 std::list<Group*>::iterator iter = pGroups->begin();
6563 std::list<Group*>::iterator end = pGroups->end();
6564 for (; iter != end; ++iter) {
6565 (*iter)->UpdateChunks(pProgress);
6585 int sublen = int(pSamples->size() / 8 + 49);
6590 if (einf->
GetSize() != einfSize) {
6594 }
else if (newFile) {
6595 einf = pRIFF->
AddSubChunk(CHUNK_ID_EINF, einfSize);
6600 std::map<gig::Sample*,int> sampleMap;
6603 sampleMap[pSample] = sampleIdx++;
6606 int totnbusedsamples = 0;
6607 int totnbusedchannels = 0;
6608 int totnbregions = 0;
6609 int totnbdimregions = 0;
6611 int instrumentIdx = 0;
6613 memset(&pData[48], 0, sublen - 48);
6617 int nbusedsamples = 0;
6618 int nbusedchannels = 0;
6619 int nbdimregions = 0;
6622 memset(&pData[(instrumentIdx + 1) * sublen + 48], 0, sublen - 48);
6624 for (
Region* region = instrument->GetFirstRegion() ; region ;
6625 region = instrument->GetNextRegion()) {
6626 for (
int i = 0 ; i < region->DimensionRegions ; i++) {
6629 int sampleIdx = sampleMap[d->
pSample];
6630 int byte = 48 + sampleIdx / 8;
6631 int bit = 1 << (sampleIdx & 7);
6632 if ((pData[(instrumentIdx + 1) * sublen +
byte] & bit) == 0) {
6633 pData[(instrumentIdx + 1) * sublen +
byte] |= bit;
6637 if ((pData[
byte] & bit) == 0) {
6646 nbdimregions += region->DimensionRegions;
6650 store32(&pData[(instrumentIdx + 1) * sublen + 4], nbusedchannels);
6651 store32(&pData[(instrumentIdx + 1) * sublen + 8], nbusedsamples);
6652 store32(&pData[(instrumentIdx + 1) * sublen + 12], 1);
6653 store32(&pData[(instrumentIdx + 1) * sublen + 16], instrument->Regions);
6654 store32(&pData[(instrumentIdx + 1) * sublen + 20], nbdimregions);
6655 store32(&pData[(instrumentIdx + 1) * sublen + 24], nbloops);
6657 store32(&pData[(instrumentIdx + 1) * sublen + 36], instrumentIdx);
6658 store32(&pData[(instrumentIdx + 1) * sublen + 40], (uint32_t) pSamples->size());
6661 totnbregions += instrument->Regions;
6662 totnbdimregions += nbdimregions;
6663 totnbloops += nbloops;
6668 store32(&pData[4], totnbusedchannels);
6669 store32(&pData[8], totnbusedsamples);
6671 store32(&pData[16], totnbregions);
6672 store32(&pData[20], totnbdimregions);
6673 store32(&pData[24], totnbloops);
6676 store32(&pData[40], (uint32_t) pSamples->size());
6696 _3crc->
Resize(pSamples->size() * 8);
6698 _3crc = pRIFF->
AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6705 File::SampleList::iterator iter = pSamples->begin();
6706 File::SampleList::iterator end = pSamples->end();
6707 for (
int index = 0; iter != end; ++iter, ++index) {
6710 pData[index*2+1] = pSample->
crc;
6722 instrument->UpdateScriptFileOffsets();
6761 Exception::Exception(String format, ...) :
DLS::Exception() {
6763 va_start(arg, format);
6764 Message = assemble(format, arg);
6768 Exception::Exception(String format, va_list arg) :
DLS::Exception() {
6769 Message = assemble(format, arg);
6772 void Exception::PrintMessage() {
6773 std::cout <<
"gig::Exception: " << Message << std::endl;
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL.
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file's current instruments, samples and settings to the respective RIFF chunks.
void __ensureMandatoryChunksExist()
Checks if all (for DLS) mandatory chunks exist, if not they will be created.
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
uint32_t Instruments
Reflects the number of available Instrument objects.
virtual void Save(const String &Path, progress_t *pProgress=NULL)
Save changes to another file.
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
String GetFileName()
File name of this DLS file.
void SetFixedStringLengths(const string_length_t *lengths)
Forces specific Info fields to be of a fixed length when being saved to a file.
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
Provides all neccessary information for the synthesis of a DLS Instrument.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Instrument object.
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
Defines Region information of an Instrument.
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Region object.
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
void GenerateDLSID()
Generates a new DLSID for the resource.
Encapsulates sample waves used for playback.
void CopyAssignCore(const Sample *orig)
Make a deep copy of the Sample object given by orig (without the actual sample waveform data however)...
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
void Resize(file_offset_t NewSize)
Resize sample.
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
uint16_t Channels
Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mon...
file_offset_t GetSize() const
Returns sample size.
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise),...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Sample object.
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used,...
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
uint32_t SampleLoops
Reflects the number of sample loops.
sample_loop_t * pSampleLoops
Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
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.
void Resize(file_offset_t NewSize)
Resize chunk.
file_offset_t SetPos(file_offset_t Where, stream_whence_t Whence=stream_start)
Sets the position within the chunk body, thus within the data portion of the chunk (in bytes).
file_offset_t GetFilePos() const
Current, actual offset in file of current chunk data body read/write position.
file_offset_t Write(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Writes WordCount number of data words with given WordSize from the buffer pointed by pData.
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
file_offset_t ReadUint32(uint32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit unsigned integer words and copies it into the buffer pointed by pDat...
file_offset_t GetPos() const
Position within the chunk data body (starting with 0).
file_offset_t ReadUint16(uint16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit unsigned integer words and copies it into the buffer pointed by pDat...
file_offset_t Read(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Reads WordCount number of data words with given WordSize and copies it into a buffer pointed by pData...
file_offset_t ReadInt16(int16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit signed integer words and copies it into the buffer pointed by pData.
uint32_t GetChunkID() const
Chunk ID in unsigned integer representation.
void * LoadChunkData()
Load chunk body into RAM.
file_offset_t ReadInt32(int32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit signed integer words and copies it into the buffer pointed by pData.
List * GetParent() const
Returns pointer to the chunk's parent list chunk.
file_offset_t ReadUint8(uint8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit unsigned integer words and copies it into the buffer pointed by pData...
file_offset_t 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 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
Chunk size in bytes (without header, thus the chunk data body)
File * GetFile() const
Returns pointer to the chunk's File object.
file_offset_t GetNewSize() const
New chunk size if it was modified with Resize(), otherwise value returned will be equal to GetSize().
bool SetMode(stream_mode_t NewMode)
Change file access mode.
int GetFileOffsetSize() const
Returns the current size (in bytes) of file offsets stored in the headers of all chunks of this file.
file_offset_t GetCurrentFileSize() const
Returns the current size of this file (in bytes) as it is currently yet stored on disk.
bool IsNew() const
Returns true if this file has been created new from scratch and has not been stored to disk yet.
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
List * GetFirstSubList()
Returns the first sublist within the list (that is a subchunk with chunk ID "LIST").
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Chunk * GetFirstSubChunk()
Returns the first subchunk within the list (which may be an ordinary chunk as well as a list chunk).
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
Chunk * GetNextSubChunk()
Returns the next subchunk within the list (which may be an ordinary chunk as well as a list chunk).
uint32_t GetListType() const
Returns unsigned integer representation of the list's ID.
List * GetNextSubList()
Returns the next sublist (that is a subchunk with chunk ID "LIST") within the list.
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
Destination container for serialization, and source container for deserialization.
Encapsulates articulation informations of a dimension region.
uint8_t VelocityResponseCurveScaling
0 - 127 (usually you don't have to interpret this parameter, use GetVelocityAttenuation() instead).
vcf_cutoff_ctrl_t VCFCutoffController
Specifies which external controller has influence on the filter cutoff frequency.
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value.
uint8_t VelocityResponseDepth
Dynamic range of velocity affecting amplitude (0 - 4) (usually you don't have to interpret this param...
bool EG2InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released.
void SetVCFCutoffController(vcf_cutoff_ctrl_t controller)
Updates the respective member variable and the lookup table / cache that depends on this value.
eg2_ctrl_t EG2Controller
MIDI Controller which has influence on filter cutoff EG parameters (attack, decay,...
double EG2Release
Release time of the filter cutoff EG (0.000 - 60.000s).
eg1_ctrl_t EG1Controller
MIDI Controller which has influence on sample amplitude EG parameters (attack, decay,...
vcf_type_t VCFType
Defines the general filter characteristic (lowpass, highpass, bandpass, etc.).
bool LFO3Sync
If set to true only one LFO should be used for all voices.
uint8_t VCFVelocityDynamicRange
0x04 = lowest, 0x00 = highest .
lfo3_ctrl_t LFO3Controller
MIDI Controller which controls the sample pitch LFO.
double EG1Decay1
Decay time of the sample amplitude EG (0.000 - 60.000s).
bool PitchTrack
If true: sample will be pitched according to the key position (this will be disabled for drums for ex...
double SampleAttenuation
Sample volume (calculated from DLS::Sampler::Gain)
uint8_t VCFVelocityScale
(0-127) Amount velocity controls VCF cutoff frequency (only if no other VCF cutoff controller is defi...
virtual void CopyAssign(const DimensionRegion *orig)
Make a (semi) deep copy of the DimensionRegion object given by orig and assign it to this object.
uint8_t EG1ControllerDecayInfluence
Amount EG1 Controller has influence on the EG1 Decay time (0 - 3, where 0 means off).
eg_opt_t EG1Options
[gig extension]: Behavior options which should be used for envelope generator 1 (volume amplitude EG)...
uint8_t EG2ControllerDecayInfluence
Amount EG2 Controller has influence on the EG2 Decay time (0 - 3, where 0 means off).
bool EG1InfiniteSustain
If true, instead of going into Decay2 phase, Decay1 level will be hold until note will be released.
double EG2Decay1
Decay time of the filter cutoff EG (0.000 - 60.000s).
bool LFO1FlipPhase
Inverts phase of the sample amplitude LFO wave.
int16_t EG3Depth
Depth of the sample pitch EG (-1200 - +1200).
uint8_t ChannelOffset
Audio output where the audio signal of the dimension region should be routed to (0 - 9).
Sample * pSample
Points to the Sample which is assigned to the dimension region.
uint8_t EG2ControllerAttackInfluence
Amount EG2 Controller has influence on the EG2 Attack time (0 - 3, where 0 means off).
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value.
int16_t LFO3ControlDepth
Controller depth of the sample pitch LFO (-1200 - +1200 cents).
uint8_t EG2ControllerReleaseInfluence
Amount EG2 Controller has influence on the EG2 Release time (0 - 3, where 0 means off).
uint8_t EG1ControllerAttackInfluence
Amount EG1 Controller has influence on the EG1 Attack time (0 - 3, where 0 means off).
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value.
lfo2_ctrl_t LFO2Controller
MIDI Controlle which controls the filter cutoff LFO.
uint8_t VCFKeyboardTrackingBreakpoint
See VCFKeyboardTracking (0 - 127).
bool VCFResonanceDynamic
If true: Increases the resonance Q according to changes of controllers that actually control the VCF ...
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
uint8_t EG1ControllerReleaseInfluence
Amount EG1 Controller has influence on the EG1 Release time (0 - 3, where 0 means off).
uint8_t VCFResonance
Firm internal filter resonance weight.
uint16_t EG1Sustain
Sustain value of the sample amplitude EG (0 - 1000 permille).
dim_bypass_ctrl_t DimensionBypass
If defined, the MIDI controller can switch on/off the dimension in realtime.
bool EG2ControllerInvert
Invert values coming from defined EG2 controller.
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value.
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
bool LFO1Sync
If set to true only one LFO should be used for all voices.
double EG1Attack
Attack time of the sample amplitude EG (0.000 - 60.000s).
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value.
attenuation_ctrl_t AttenuationController
MIDI Controller which has influence on the volume level of the sample (or entire sample group).
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
double LFO1Frequency
Frequency of the sample amplitude LFO (0.10 - 10.00 Hz).
curve_type_t VelocityResponseCurve
Defines a transformation curve to the incoming velocity values affecting amplitude (usually you don't...
uint16_t EG2Sustain
Sustain value of the filter cutoff EG (0 - 1000 permille).
uint16_t LFO2ControlDepth
Controller depth influencing filter cutoff LFO pitch (0 - 1200).
bool VCFKeyboardTracking
If true: VCF cutoff frequence will be dependend to the note key position relative to the defined brea...
uint8_t AttenuationControllerThreshold
0-127
double EG1Release
Release time of the sample amplitude EG (0.000 - 60.000s).
bool NoNoteOffReleaseTrigger
[gig extension]: If true then don't play a release trigger sample on MIDI note-off events.
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value.
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set,...
bool EG1Hold
If true, Decay1 stage should be postponed until the sample reached the sample loop start.
uint8_t ReleaseVelocityResponseDepth
Dynamic range of release velocity affecting envelope time (0 - 4).
curve_type_t ReleaseVelocityResponseCurve
Defines a transformation curve to the incoming release veloctiy values affecting envelope times.
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value.
double EG1Decay2
Only if EG1InfiniteSustain == false: 2nd decay stage time of the sample amplitude EG (0....
bool InvertAttenuationController
Inverts the values coming from the defined Attenuation Controller.
uint16_t SampleStartOffset
Number of samples the sample start should be moved (0 - 2000).
double EG2Decay2
Only if EG2InfiniteSustain == false: 2nd stage decay time of the filter cutoff EG (0....
uint16_t LFO1InternalDepth
Firm pitch of the sample amplitude LFO (0 - 1200 cents).
bool EG1ControllerInvert
Invert values coming from defined EG1 controller.
lfo1_ctrl_t LFO1Controller
MIDI Controller which controls sample amplitude LFO.
bool VCFCutoffControllerInvert
Inverts values coming from the defined cutoff controller.
double LFO3Frequency
Frequency of the sample pitch LFO (0.10 - 10.00 Hz).
uint8_t ReleaseTriggerDecay
0 - 8
double EG3Attack
Attack time of the sample pitch EG (0.000 - 10.000s).
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value.
double LFO2Frequency
Frequency of the filter cutoff LFO (0.10 - 10.00 Hz).
bool SustainDefeat
If true: Sustain pedal will not hold a note.
eg_opt_t EG2Options
[gig extension]: Behavior options which should be used for envelope generator 2 (filter cutoff EG).
bool LFO2FlipPhase
Inverts phase of the filter cutoff LFO wave.
sust_rel_trg_t SustainReleaseTrigger
[gig extension]: Whether a sustain pedal up event shall play release trigger sample.
bool MSDecode
Gigastudio flag: defines if Mid Side Recordings should be decoded.
bool VCFEnabled
If filter should be used.
uint16_t LFO1ControlDepth
Controller depth influencing sample amplitude LFO pitch (0 - 1200 cents).
int8_t Pan
Panorama / Balance (-64..0..63 <-> left..middle..right)
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value.
bool LFO2Sync
If set to true only one LFO should be used for all voices.
uint16_t EG1PreAttack
Preattack value of the sample amplitude EG (0 - 1000 permille).
bool SelfMask
If true: high velocity notes will stop low velocity notes at the same note, with that you can save vo...
uint8_t VCFCutoff
Max. cutoff frequency.
curve_type_t VCFVelocityCurve
Defines a transformation curve for the incoming velocity values, affecting the VCF.
double EG2Attack
Attack time of the filter cutoff EG (0.000 - 60.000s).
uint16_t EG2PreAttack
Preattack value of the filter cutoff EG (0 - 1000 permille).
uint16_t LFO2InternalDepth
Firm pitch of the filter cutoff LFO (0 - 1200 cents).
vcf_res_ctrl_t VCFResonanceController
Specifies which external controller has influence on the filter resonance Q.
int16_t LFO3InternalDepth
Firm depth of the sample pitch LFO (-1200 - +1200 cents).
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File.
Provides convenient access to Gigasampler/GigaStudio .gig files.
virtual void UpdateChunks(progress_t *pProgress)
Apply all the gig file's current instruments, samples, groups and settings to the respective RIFF chu...
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
size_t CountInstruments()
Returns the total amount of instruments of this gig file.
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
ScriptGroup * AddScriptGroup()
Add new instrument script group.
ScriptGroup * GetScriptGroup(uint index)
Get instrument script group (by index).
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
size_t CountSamples()
Returns the total amount of samples of this gig file.
Instrument * AddInstrument()
Add a new instrument definition.
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Sample * GetSample(uint index)
Returns Sample object of index.
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
bool GetAutoLoad()
Returns whether automatic loading is enabled.
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
bool RebuildSampleChecksumTable()
Recalculates CRC32 checksums for all samples and rebuilds this gig file's checksum table with those n...
void DeleteSample(Sample *pSample)
Delete a sample.
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
void AddContentOf(File *pFile)
Add content of another existing file.
static const DLS::version_t VERSION_4
Reflects Gigasampler file format version 4.0 (2007-10-12).
Instrument * GetInstrument(uint index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
Sample * AddSample()
Add a new sample.
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Group * GetGroup(uint index)
Returns the group with the given index.
void DeleteGroupOnly(Group *pGroup)
Delete a group.
void SetAutoLoad(bool b)
Enable / disable automatic loading.
Sample * GetFirstSample(progress_t *pProgress=NULL)
Returns a pointer to the first Sample object of the file, NULL otherwise.
bool VerifySampleChecksumTable()
Checks whether the file's "3CRC" chunk was damaged.
Group of Gigasampler samples.
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
Sample * GetFirstSample()
Returns the first Sample of this Group.
Sample * GetNextSample()
Returns the next Sample of the Group.
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Group object.
virtual ~Group()
Destructor.
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
String Name
Stores the name of this Group.
Provides access to a Gigasampler/GigaStudio instrument.
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
Script * GetScriptOfSlot(uint index)
Get instrument script (gig format extension).
void SetScriptSlotBypassed(uint index, bool bBypass)
Defines whether execution shall be skipped.
virtual void CopyAssign(const Instrument *orig)
Make a (semi) deep copy of the Instrument object given by orig and assign it to this object.
Region * GetNextRegion()
Returns the next Region of the instrument.
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
void SwapScriptSlots(uint index1, uint index2)
Flip two script slots with each other (gig format extension).
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
void MoveTo(Instrument *dst)
Move this instrument at the position before.
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
bool IsScriptSlotBypassed(uint index)
Whether script execution shall be skipped.
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
void RemoveScriptSlot(uint index)
Remove script slot.
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
Region * RegionKeyTable[128]
fast lookup for the corresponding Region of a MIDI key
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
uint ScriptSlotCount() const
Instrument's amount of script slots.
Region * GetFirstRegion()
Returns the first Region of the instrument.
MIDI rule to automatically cycle through specified sequences of different articulations.
uint8_t Controller
CC number for controller selector.
struct gig::MidiRuleAlternator::pattern_t pPatterns[32]
A pattern is a sequence of articulation numbers.
range_t KeySwitchRange
Key range for key switch selector.
bool Polyphonic
If alternator should step forward only when all notes are off.
selector_t Selector
Method by which pattern is chosen.
uint8_t Patterns
Number of alternator patterns.
range_t PlayRange
Key range of the playable keys in the instrument.
uint8_t Articulations
Number of articulations in the instrument.
String pArticulations[32]
Names of the articulations.
bool Chained
If all patterns should be chained together.
MIDI rule for triggering notes by control change events.
uint8_t ControllerNumber
MIDI controller number.
uint8_t Triggers
Number of triggers.
MIDI rule for instruments with legato samples.
uint16_t ThresholdTime
Maximum time (ms) between two notes that should be played legato.
uint8_t LegatoSamples
Number of legato samples per key in each direction (always 12)
uint8_t BypassKey
Key to be used to bypass the sustain note.
uint8_t AltSustain1Key
Key triggering alternate sustain samples.
bool BypassUseController
If a controller should be used to bypass the sustain note.
uint8_t AltSustain2Key
Key triggering a second set of alternate sustain samples.
uint16_t ReleaseTime
Release time.
range_t KeyRange
Key range for legato notes.
uint8_t ReleaseTriggerKey
Key triggering release samples.
uint8_t BypassController
Controller to be used to bypass the sustain note.
Abstract base class for all MIDI rules.
Defines Region information of a Gigasampler/GigaStudio instrument.
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
unsigned int Dimensions
Number of defined dimensions, do not alter!
dimension_def_t pDimensionDefinitions[8]
Defines the five (gig2) or eight (gig3) possible dimensions (the dimension's controller and number of...
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 SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
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...
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
DimensionRegion * GetDimensionRegionByValue(const uint DimValues[8])
Use this method in your audio engine to get the appropriate dimension region with it's articulation d...
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
unsigned int Layers
Amount of defined layers (1 - 32). A value of 1 actually means no layering, a value > 1 means there i...
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
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.
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index).
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks.
uint32_t DimensionRegions
Total number of DimensionRegions this Region contains, do not alter!
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
bool VerifyWaveData(uint32_t *pActually=NULL)
Checks the integrity of this sample's raw audio wave data.
uint32_t LoopFraction
The fractional value specifies a fraction of a sample at which to loop. This allows a loop to be fine...
unsigned long FileNo
File number (> 0 when sample is stored in an extension file, 0 when it's in the gig)
void CopyAssignMeta(const Sample *orig)
Make a (semi) deep copy of the Sample object given by orig (without the actual waveform data) and ass...
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame.
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field....
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset, unsigned long fileNo=0, int index=-1)
Constructor.
void Resize(file_offset_t NewSize)
Resize sample.
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
file_offset_t FrameOffset
Current offset (sample points) in current sample frame (for decompression only).
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors,...
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it's original sample rate.
uint32_t crc
Reflects CRC-32 checksum of the raw sample data at the last time when the sample's raw wave form data...
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
static size_t Instances
Number of instances of class 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).
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...
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 ...
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction.
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...
uint32_t LoopID
Specifies the unique ID that corresponds to one of the defined cue points in the cue point list (only...
static buffer_t InternalDecompressionBuffer
Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples.
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
uint32_t Manufacturer
Specifies the MIDI Manufacturer's Association (MMA) Manufacturer code for the sampler intended to rec...
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0,...
buffer_t GetCache()
Returns current cached sample points.
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Group of instrument scripts (gig format extension).
virtual void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
void DeleteScript(Script *pScript)
Delete an instrument script.
Script * AddScript()
Add new instrument script.
String Name
Name of this script group. For example to be displayed in an instrument editor.
Script * GetScript(uint index)
Get instrument script.
virtual void DeleteChunks()
Remove all RIFF chunks associated with this ScriptGroup object.
Real-time instrument script (gig format extension).
Compression_t Compression
Whether the script was/should be compressed, and if so, which compression algorithm shall be used.
@ COMPRESSION_NONE
Is not compressed at all (default).
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
Language_t Language
Programming language and dialect the script is written in.
Encoding_t Encoding
Format the script's source code text is encoded with.
@ ENCODING_ASCII
Standard 8 bit US ASCII character encoding (default).
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
@ LANGUAGE_NKSP
NKSP stands for "Is Not KSP" (default). Refer to the NKSP Reference Manual for details about this scr...
bool Bypass
Global bypass: if enabled, this script shall not be executed by the sampler for any instrument.
String Name
Arbitrary name of the script, which may be displayed i.e. in an instrument editor.
void DeleteChunks()
Remove all RIFF chunks associated with this Script object.
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
String GetScriptAsText()
Returns the current script (i.e.
void CopyAssign(const Script *orig)
Make a (semi) deep copy of the Script object given by orig and assign it to this object.
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
DLS specific classes and definitions.
stream_whence_t
File stream position dependent to these relations.
uint64_t file_offset_t
Type used by libgig for handling file positioning during file I/O tasks.
Gigasampler/GigaStudio specific classes and definitions.
@ dim_bypass_ctrl_94
Effect 4 Depth (MIDI Controller 94)
@ dim_bypass_ctrl_95
Effect 5 Depth (MIDI Controller 95)
@ dim_bypass_ctrl_none
No controller bypass.
vcf_res_ctrl_t
Defines how the filter resonance is controlled by.
@ vcf_res_ctrl_none
No MIDI controller assigned for filter resonance.
String libraryName()
Returns the name of this C++ library.
@ smpte_format_no_offset
no SMPTE offset
curve_type_t
Defines the shape of a function graph.
@ curve_type_nonlinear
Non-linear curve type.
@ curve_type_unknown
Unknown curve type.
@ curve_type_linear
Linear curve type.
@ curve_type_special
Special curve type.
lfo1_ctrl_t
Defines how LFO1 is controlled by.
@ lfo1_ctrl_internal
Only internally controlled.
sust_rel_trg_t
Defines behaviour of release triggered sample(s) on sustain pedal up event.
@ sust_rel_trg_none
No release triggered sample(s) are played on sustain pedal up (default).
vcf_cutoff_ctrl_t
Defines how the filter cutoff frequency is controlled by.
@ vcf_cutoff_ctrl_none2
The difference between none and none2 is unknown.
@ vcf_cutoff_ctrl_none
No MIDI controller assigned for filter cutoff frequency.
split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
@ split_type_bit
dimension values are already the sought bit number
@ split_type_normal
dimension value between 0-127
String libraryVersion()
Returns version of this C++ library.
@ loop_type_bidirectional
Alternating loop (forward/backward, also known as Ping Pong)
@ loop_type_backward
Loop backward (reverse)
@ loop_type_normal
Loop forward (normal)
lfo3_ctrl_t
Defines how LFO3 is controlled by.
@ lfo3_ctrl_modwheel
Only controlled by external modulation wheel.
lfo2_ctrl_t
Defines how LFO2 is controlled by.
@ lfo2_ctrl_internal
Only internally controlled.
dimension_t
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
@ dimension_keyboard
Dimension for keyswitching.
@ dimension_roundrobinkeyboard
Different samples triggered each time a note is played, any key advances the counter.
@ dimension_samplechannel
If used sample has more than one channel (thus is not mono).
@ dimension_smartmidi
For MIDI tools like legato and repetition mode.
@ dimension_releasetrigger
Special dimension for triggering samples on releasing a key.
@ dimension_velocity
Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined).
@ dimension_random
Different samples triggered each time a note is played, random order.
@ dimension_none
Dimension not in use.
@ dimension_roundrobin
Different samples triggered each time a note is played, dimension regions selected in sequence.
@ dimension_layer
For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers).
vcf_type_t
Defines which frequencies are filtered by the VCF.
@ vcf_type_lowpassturbo
More poles than normal lowpass.
@ vcf_type_lowpass
Standard lowpass filter type.
Every subject of an DLS file and the file itself can have an unique, computer generated ID.
uint16_t low
Low value of range.
uint16_t high
High value of range.
Defines Sample Loop Points.
uint32_t LoopLength
Length of the looping area (in sample points).
uint32_t LoopStart
The start value specifies the offset (in sample points) in the waveform data of the first sample poin...
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
Quadtuple version number ("major.minor.release.build").
Used for indicating the progress of a certain task.
float __range_min
Only for internal usage, do not modify!
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
float __range_max
Only for internal usage, do not modify!
Pointer address and size of a buffer.
file_offset_t NullExtensionSize
The buffer might be bigger than the actual data, if that's the case that unused space at the end of t...
void * pStart
Points to the beginning of the buffer.
file_offset_t Size
Size of the actual data in the buffer in bytes.
uint8_t in_end
End position of fade in.
uint8_t in_start
Start position of fade in.
uint8_t out_end
End postition of fade out.
uint8_t out_start
Start position of fade out.
General dimension definition.
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
uint8_t zones
Number of zones the dimension has.
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...
float zone_size
Intended for internal usage: reflects the size of each zone (128/zones) for normal split types only,...
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
Defines behavior options for envelope generators (gig format extension).
bool AttackHoldCancel
Whether the "attack hold" stage is cancelled when receiving a note-off (default: true).
bool Decay1Cancel
Whether the "decay 1" stage is cancelled when receiving a note-off (default: true).
bool ReleaseCancel
Whether the "release" stage is cancelled when receiving a note-on (default: true).
bool AttackCancel
Whether the "attack" stage is cancelled when receiving a note-off (default: true).
bool Decay2Cancel
Whether the "decay 2" stage is cancelled when receiving a note-off (default: true).
@ type_none
No controller defined.
@ type_velocity
Key Velocity.
@ type_controlchange
Ordinary MIDI control change controller, see field 'controller_number'.
@ type_channelaftertouch
Channel Key Pressure.
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
type_t type
Controller type.
Reflects the current playback state for a sample.
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined).
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.
file_offset_t position
Current position within the sample.
uint8_t high
High value of range.
uint8_t low
Low value of range.