27 #include "Serialization.h" 36 #define GIG_FILE_EXT_VERSION 2 43 #define INITIAL_SAMPLE_BUFFER_SIZE 512000 // 512 kB 46 #define GIG_EXP_DECODE(x) (pow(1.000000008813822, x)) 47 #define GIG_EXP_ENCODE(x) (log(x) / log(1.000000008813822)) 48 #define GIG_PITCH_TRACK_EXTRACT(x) (!(x & 0x01)) 49 #define GIG_PITCH_TRACK_ENCODE(x) ((x) ? 0x00 : 0x01) 50 #define GIG_VCF_RESONANCE_CTRL_EXTRACT(x) ((x >> 4) & 0x03) 51 #define GIG_VCF_RESONANCE_CTRL_ENCODE(x) ((x & 0x03) << 4) 52 #define GIG_EG_CTR_ATTACK_INFLUENCE_EXTRACT(x) ((x >> 1) & 0x03) 53 #define GIG_EG_CTR_DECAY_INFLUENCE_EXTRACT(x) ((x >> 3) & 0x03) 54 #define GIG_EG_CTR_RELEASE_INFLUENCE_EXTRACT(x) ((x >> 5) & 0x03) 55 #define GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(x) ((x & 0x03) << 1) 56 #define GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(x) ((x & 0x03) << 3) 57 #define GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(x) ((x & 0x03) << 5) 59 #define SRLZ(member) \ 60 archive->serializeMember(*this, member, #member); 69 inline int get12lo(
const unsigned char* pSrc)
71 const int x = pSrc[0] | (pSrc[1] & 0x0f) << 8;
72 return x & 0x800 ? x - 0x1000 : x;
75 inline int get12hi(
const unsigned char* pSrc)
77 const int x = pSrc[1] >> 4 | pSrc[2] << 4;
78 return x & 0x800 ? x - 0x1000 : x;
81 inline int16_t get16(
const unsigned char* pSrc)
83 return int16_t(pSrc[0] | pSrc[1] << 8);
86 inline int get24(
const unsigned char* pSrc)
88 const int x = pSrc[0] | pSrc[1] << 8 | pSrc[2] << 16;
89 return x & 0x800000 ? x - 0x1000000 : x;
92 inline void store24(
unsigned char* pDst,
int x)
99 void Decompress16(
int compressionmode,
const unsigned char* params,
100 int srcStep,
int dstStep,
101 const unsigned char* pSrc, int16_t* pDst,
102 file_offset_t currentframeoffset,
103 file_offset_t copysamples)
105 switch (compressionmode) {
107 pSrc += currentframeoffset * srcStep;
108 while (copysamples) {
117 int y = get16(params);
118 int dy = get16(params + 2);
119 while (currentframeoffset) {
123 currentframeoffset--;
125 while (copysamples) {
137 void Decompress24(
int compressionmode,
const unsigned char* params,
138 int dstStep,
const unsigned char* pSrc, uint8_t* pDst,
139 file_offset_t currentframeoffset,
140 file_offset_t copysamples,
int truncatedBits)
142 int y, dy, ddy, dddy;
144 #define GET_PARAMS(params) \ 146 dy = y - get24((params) + 3); \ 147 ddy = get24((params) + 6); \ 148 dddy = get24((params) + 9) 150 #define SKIP_ONE(x) \ 156 #define COPY_ONE(x) \ 158 store24(pDst, y << truncatedBits); \ 161 switch (compressionmode) {
163 pSrc += currentframeoffset * 3;
164 while (copysamples) {
165 store24(pDst, get24(pSrc) << truncatedBits);
174 while (currentframeoffset) {
175 SKIP_ONE(get16(pSrc));
177 currentframeoffset--;
179 while (copysamples) {
180 COPY_ONE(get16(pSrc));
188 while (currentframeoffset > 1) {
189 SKIP_ONE(get12lo(pSrc));
190 SKIP_ONE(get12hi(pSrc));
192 currentframeoffset -= 2;
194 if (currentframeoffset) {
195 SKIP_ONE(get12lo(pSrc));
196 currentframeoffset--;
198 COPY_ONE(get12hi(pSrc));
203 while (copysamples > 1) {
204 COPY_ONE(get12lo(pSrc));
205 COPY_ONE(get12hi(pSrc));
210 COPY_ONE(get12lo(pSrc));
216 while (currentframeoffset) {
217 SKIP_ONE(int8_t(*pSrc++));
218 currentframeoffset--;
220 while (copysamples) {
221 COPY_ONE(int8_t(*pSrc++));
228 const int bytesPerFrame[] = { 4096, 2052, 768, 524, 396, 268 };
229 const int bytesPerFrameNoHdr[] = { 4096, 2048, 768, 512, 384, 256 };
230 const int headerSize[] = { 0, 4, 0, 12, 12, 12 };
231 const int bitsPerSample[] = { 16, 8, 24, 16, 12, 8 };
239 static uint32_t* __initCRCTable() {
240 static uint32_t res[256];
242 for (
int i = 0 ; i < 256 ; i++) {
244 for (
int j = 0 ; j < 8 ; j++) {
245 c = (c & 1) ? 0xedb88320 ^ (c >> 1) : c >> 1;
252 static const uint32_t* __CRCTable = __initCRCTable();
259 inline static void __resetCRC(uint32_t& crc) {
282 static void __calculateCRC(
unsigned char* buf,
size_t bufSize, uint32_t& crc) {
283 for (
size_t i = 0 ; i < bufSize ; i++) {
284 crc = __CRCTable[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
293 inline static void __finalizeCRC(uint32_t& crc) {
315 static int __resolveZoneSize(dimension_def_t& dimension_definition) {
317 ? int(128.0 / dimension_definition.zones) : 0;
347 eg_opt_t::eg_opt_t() {
349 AttackHoldCancel =
true;
352 ReleaseCancel =
true;
357 SRLZ(AttackHoldCancel);
393 static const DLS::Info::string_length_t fixedStringLengths[] = {
394 { CHUNK_ID_INAM, 64 },
408 uint32_t crc = pFile->GetSampleChecksumByIndex(index);
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());
673 const file_offset_t frameSize = bytesPerFrame[mode];
677 ((pCkData->
RemainingBytes() - headerSize[mode]) << 3) / bitsPerSample[mode];
682 pCkData->
SetPos(frameSize, RIFF::stream_curpos);
689 FrameTable =
new file_offset_t[frameOffsets.size()];
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;
1456 return crc == this->
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;
1471 __calculateCRC(&buffer[0], nRead *
FrameSize, crc);
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) {
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));
1795 pParentList = _3ewl;
1799 VelocityTable =
new uint8_t[128];
1800 for (
int k = 0 ; k < 128 ; k++)
1833 if (VelocityTable)
delete [] VelocityTable;
1834 if (pSampleLoops)
delete [] pSampleLoops;
1848 pRegion = pOriginalRegion;
1852 if (pOriginalRegion->GetParent()->GetParent() != orig->pRegion->GetParent()->GetParent()) {
1853 pSample = pOriginalSample;
1856 if (mSamples && mSamples->count(orig->
pSample)) {
1857 pSample = mSamples->find(orig->
pSample)->second;
1862 VelocityTable =
new uint8_t[128];
1863 for (
int k = 0 ; k < 128 ; k++)
1879 SRLZ(VelocityUpperLimit);
1884 SRLZ(EG1InfiniteSustain);
1888 SRLZ(EG1Controller);
1889 SRLZ(EG1ControllerInvert);
1890 SRLZ(EG1ControllerAttackInfluence);
1891 SRLZ(EG1ControllerDecayInfluence);
1892 SRLZ(EG1ControllerReleaseInfluence);
1893 SRLZ(LFO1Frequency);
1894 SRLZ(LFO1InternalDepth);
1895 SRLZ(LFO1ControlDepth);
1896 SRLZ(LFO1Controller);
1897 SRLZ(LFO1FlipPhase);
1903 SRLZ(EG2InfiniteSustain);
1906 SRLZ(EG2Controller);
1907 SRLZ(EG2ControllerInvert);
1908 SRLZ(EG2ControllerAttackInfluence);
1909 SRLZ(EG2ControllerDecayInfluence);
1910 SRLZ(EG2ControllerReleaseInfluence);
1911 SRLZ(LFO2Frequency);
1912 SRLZ(LFO2InternalDepth);
1913 SRLZ(LFO2ControlDepth);
1914 SRLZ(LFO2Controller);
1915 SRLZ(LFO2FlipPhase);
1919 SRLZ(LFO3Frequency);
1920 SRLZ(LFO3InternalDepth);
1921 SRLZ(LFO3ControlDepth);
1922 SRLZ(LFO3Controller);
1926 SRLZ(VCFCutoffController);
1927 SRLZ(VCFCutoffControllerInvert);
1929 SRLZ(VCFVelocityCurve);
1930 SRLZ(VCFVelocityScale);
1931 SRLZ(VCFVelocityDynamicRange);
1933 SRLZ(VCFResonanceDynamic);
1934 SRLZ(VCFResonanceController);
1935 SRLZ(VCFKeyboardTracking);
1936 SRLZ(VCFKeyboardTrackingBreakpoint);
1937 SRLZ(VelocityResponseCurve);
1938 SRLZ(VelocityResponseDepth);
1939 SRLZ(VelocityResponseCurveScaling);
1940 SRLZ(ReleaseVelocityResponseCurve);
1941 SRLZ(ReleaseVelocityResponseDepth);
1942 SRLZ(ReleaseTriggerDecay);
1945 SRLZ(DimensionBypass);
1948 SRLZ(AttenuationController);
1949 SRLZ(InvertAttenuationController);
1950 SRLZ(AttenuationControllerThreshold);
1951 SRLZ(ChannelOffset);
1952 SRLZ(SustainDefeat);
1955 SRLZ(SampleAttenuation);
1958 SRLZ(SustainReleaseTrigger);
1959 SRLZ(NoNoteOffReleaseTrigger);
1971 DLS::Sampler::SetGain(gain);
1972 SampleAttenuation = pow(10.0, -Gain / (20.0 * 655360));
1988 RIFF::Chunk* wsmp = pParentList->GetSubChunk(CHUNK_ID_WSMP);
1990 pData[12] = Crossfade.in_start;
1991 pData[13] = Crossfade.in_end;
1992 pData[14] = Crossfade.out_start;
1993 pData[15] = Crossfade.out_end;
1996 RIFF::Chunk* _3ewa = pParentList->GetSubChunk(CHUNK_ID_3EWA);
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);
2017 store16(&pData[14], LFO1InternalDepth);
2021 store16(&pData[18], LFO3InternalDepth);
2025 store16(&pData[22], LFO1ControlDepth);
2029 store16(&pData[26], LFO3ControlDepth);
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);
2039 store16(&pData[38], EG1Sustain);
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 =
2048 (EG1ControllerInvert ? 0x01 : 0x00) |
2049 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
2050 GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
2051 GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
2052 pData[45] = eg1ctrloptions;
2054 const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
2057 const uint8_t eg2ctrloptions =
2058 (EG2ControllerInvert ? 0x01 : 0x00) |
2059 GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
2060 GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
2061 GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
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);
2075 store16(&pData[62], EG2Sustain);
2077 const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
2078 store32(&pData[64], eg2release);
2082 store16(&pData[70], LFO2ControlDepth);
2084 const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
2085 store32(&pData[72], lfo2freq);
2089 store16(&pData[78], LFO2InternalDepth);
2091 const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
2092 store32(&pData[80], eg1decay2);
2096 store16(&pData[86], EG1PreAttack);
2098 const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
2099 store32(&pData[88], eg2decay2);
2103 store16(&pData[94], EG2PreAttack);
2106 if (VelocityResponseDepth > 4)
throw Exception(
"VelocityResponseDepth must be between 0 and 4");
2107 uint8_t velocityresponse = VelocityResponseDepth;
2108 switch (VelocityResponseCurve) {
2112 velocityresponse += 5;
2115 velocityresponse += 10;
2119 throw Exception(
"Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
2121 pData[96] = velocityresponse;
2125 if (ReleaseVelocityResponseDepth > 4)
throw Exception(
"ReleaseVelocityResponseDepth must be between 0 and 4");
2126 uint8_t releasevelocityresponse = ReleaseVelocityResponseDepth;
2127 switch (ReleaseVelocityResponseCurve) {
2131 releasevelocityresponse += 5;
2134 releasevelocityresponse += 10;
2138 throw Exception(
"Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
2140 pData[97] = releasevelocityresponse;
2143 pData[98] = VelocityResponseCurveScaling;
2145 pData[99] = AttenuationControllerThreshold;
2149 store16(&pData[104], SampleStartOffset);
2154 uint8_t pitchTrackDimensionBypass = GIG_PITCH_TRACK_ENCODE(PitchTrack);
2155 switch (DimensionBypass) {
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;
2180 uint8_t lfo3ctrl = LFO3Controller & 0x07;
2181 if (LFO3Sync) lfo3ctrl |= 0x20;
2182 if (InvertAttenuationController) lfo3ctrl |= 0x80;
2184 pData[112] = lfo3ctrl;
2187 const uint8_t attenctl = EncodeLeverageController(AttenuationController);
2188 pData[113] = attenctl;
2191 uint8_t lfo2ctrl = LFO2Controller & 0x07;
2192 if (LFO2FlipPhase) lfo2ctrl |= 0x80;
2193 if (LFO2Sync) lfo2ctrl |= 0x20;
2195 pData[114] = lfo2ctrl;
2199 uint8_t lfo1ctrl = LFO1Controller & 0x07;
2200 if (LFO1FlipPhase) lfo1ctrl |= 0x80;
2201 if (LFO1Sync) lfo1ctrl |= 0x40;
2203 lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
2204 pData[115] = lfo1ctrl;
2207 const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
2208 : uint16_t(((-EG3Depth) - 1) ^ 0xfff);
2209 store16(&pData[116], eg3depth);
2213 const uint8_t channeloffset = ChannelOffset * 4;
2214 pData[120] = channeloffset;
2217 uint8_t regoptions = 0;
2218 if (MSDecode) regoptions |= 0x01;
2219 if (SustainDefeat) regoptions |= 0x02;
2220 pData[121] = regoptions;
2225 pData[124] = VelocityUpperLimit;
2229 pData[128] = ReleaseTriggerDecay;
2233 const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00;
2234 pData[131] = eg1hold;
2236 const uint8_t vcfcutoff = (VCFEnabled ? 0x80 : 0x00) |
2238 pData[132] = vcfcutoff;
2240 pData[133] = VCFCutoffController;
2242 const uint8_t vcfvelscale = (VCFCutoffControllerInvert ? 0x80 : 0x00) |
2243 (VCFVelocityScale & 0x7f);
2244 pData[134] = vcfvelscale;
2248 const uint8_t vcfresonance = (VCFResonanceDynamic ? 0x00 : 0x80) |
2249 (VCFResonance & 0x7f);
2250 pData[136] = vcfresonance;
2252 const uint8_t vcfbreakpoint = (VCFKeyboardTracking ? 0x80 : 0x00) |
2253 (VCFKeyboardTrackingBreakpoint & 0x7f);
2254 pData[137] = vcfbreakpoint;
2256 const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 +
2257 VCFVelocityCurve * 5;
2258 pData[138] = vcfvelocity;
2261 pData[139] = vcftype;
2263 if (chunksize >= 148) {
2264 memcpy(&pData[140], DimensionUpperLimits, 8);
2269 RIFF::Chunk* lsde = pParentList->GetSubChunk(CHUNK_ID_LSDE);
2270 const int lsdeSize = 4;
2275 if (memcmp(&EG1Options, &defaultOpt,
sizeof(
eg_opt_t)) ||
2276 memcmp(&EG2Options, &defaultOpt,
sizeof(
eg_opt_t)) ||
2277 SustainReleaseTrigger || NoNoteOffReleaseTrigger)
2279 lsde = pParentList->AddSubChunk(CHUNK_ID_LSDE, lsdeSize);
2281 pParentList->MoveSubChunk(lsde, (
RIFF::Chunk*)NULL);
2288 unsigned char* pData = (
unsigned char*) lsde->
LoadChunkData();
2289 eg_opt_t* pEGOpts[2] = { &EG1Options, &EG2Options };
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);
2299 pData[3] =
static_cast<uint8_t
>(SustainReleaseTrigger) | (NoNoteOffReleaseTrigger ? (1<<7) : 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) {
2391 switch (EncodedController) {
2393 case _lev_ctrl_none:
2397 case _lev_ctrl_velocity:
2401 case _lev_ctrl_channelaftertouch:
2407 case _lev_ctrl_modwheel:
2411 case _lev_ctrl_breath:
2415 case _lev_ctrl_foot:
2419 case _lev_ctrl_effect1:
2423 case _lev_ctrl_effect2:
2427 case _lev_ctrl_genpurpose1:
2431 case _lev_ctrl_genpurpose2:
2435 case _lev_ctrl_genpurpose3:
2439 case _lev_ctrl_genpurpose4:
2443 case _lev_ctrl_portamentotime:
2447 case _lev_ctrl_sustainpedal:
2451 case _lev_ctrl_portamento:
2455 case _lev_ctrl_sostenutopedal:
2459 case _lev_ctrl_softpedal:
2463 case _lev_ctrl_genpurpose5:
2467 case _lev_ctrl_genpurpose6:
2471 case _lev_ctrl_genpurpose7:
2475 case _lev_ctrl_genpurpose8:
2479 case _lev_ctrl_effect1depth:
2483 case _lev_ctrl_effect2depth:
2487 case _lev_ctrl_effect3depth:
2491 case _lev_ctrl_effect4depth:
2495 case _lev_ctrl_effect5depth:
2503 case _lev_ctrl_CC3_EXT:
2507 case _lev_ctrl_CC6_EXT:
2511 case _lev_ctrl_CC7_EXT:
2515 case _lev_ctrl_CC8_EXT:
2519 case _lev_ctrl_CC9_EXT:
2523 case _lev_ctrl_CC10_EXT:
2527 case _lev_ctrl_CC11_EXT:
2531 case _lev_ctrl_CC14_EXT:
2535 case _lev_ctrl_CC15_EXT:
2539 case _lev_ctrl_CC20_EXT:
2543 case _lev_ctrl_CC21_EXT:
2547 case _lev_ctrl_CC22_EXT:
2551 case _lev_ctrl_CC23_EXT:
2555 case _lev_ctrl_CC24_EXT:
2559 case _lev_ctrl_CC25_EXT:
2563 case _lev_ctrl_CC26_EXT:
2567 case _lev_ctrl_CC27_EXT:
2571 case _lev_ctrl_CC28_EXT:
2575 case _lev_ctrl_CC29_EXT:
2579 case _lev_ctrl_CC30_EXT:
2583 case _lev_ctrl_CC31_EXT:
2587 case _lev_ctrl_CC68_EXT:
2591 case _lev_ctrl_CC69_EXT:
2595 case _lev_ctrl_CC70_EXT:
2599 case _lev_ctrl_CC71_EXT:
2603 case _lev_ctrl_CC72_EXT:
2607 case _lev_ctrl_CC73_EXT:
2611 case _lev_ctrl_CC74_EXT:
2615 case _lev_ctrl_CC75_EXT:
2619 case _lev_ctrl_CC76_EXT:
2623 case _lev_ctrl_CC77_EXT:
2627 case _lev_ctrl_CC78_EXT:
2631 case _lev_ctrl_CC79_EXT:
2635 case _lev_ctrl_CC84_EXT:
2639 case _lev_ctrl_CC85_EXT:
2643 case _lev_ctrl_CC86_EXT:
2647 case _lev_ctrl_CC87_EXT:
2651 case _lev_ctrl_CC89_EXT:
2655 case _lev_ctrl_CC90_EXT:
2659 case _lev_ctrl_CC96_EXT:
2663 case _lev_ctrl_CC97_EXT:
2667 case _lev_ctrl_CC102_EXT:
2671 case _lev_ctrl_CC103_EXT:
2675 case _lev_ctrl_CC104_EXT:
2679 case _lev_ctrl_CC105_EXT:
2683 case _lev_ctrl_CC106_EXT:
2687 case _lev_ctrl_CC107_EXT:
2691 case _lev_ctrl_CC108_EXT:
2695 case _lev_ctrl_CC109_EXT:
2699 case _lev_ctrl_CC110_EXT:
2703 case _lev_ctrl_CC111_EXT:
2707 case _lev_ctrl_CC112_EXT:
2711 case _lev_ctrl_CC113_EXT:
2715 case _lev_ctrl_CC114_EXT:
2719 case _lev_ctrl_CC115_EXT:
2723 case _lev_ctrl_CC116_EXT:
2727 case _lev_ctrl_CC117_EXT:
2731 case _lev_ctrl_CC118_EXT:
2735 case _lev_ctrl_CC119_EXT:
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;
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;
3044 if (VelocityTable)
delete[] VelocityTable;
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 =
3077 curve, VelocityResponseDepth, VelocityResponseCurveScaling
3079 VelocityResponseCurve = curve;
3087 pVelocityAttenuationTable =
3089 VelocityResponseCurve, depth, VelocityResponseCurveScaling
3091 VelocityResponseDepth = depth;
3099 pVelocityAttenuationTable =
3101 VelocityResponseCurve, VelocityResponseDepth, scaling
3103 VelocityResponseCurveScaling = scaling;
3111 pVelocityReleaseTable = GetReleaseVelocityTable(curve, ReleaseVelocityResponseDepth);
3112 ReleaseVelocityResponseCurve = curve;
3120 pVelocityReleaseTable = GetReleaseVelocityTable(ReleaseVelocityResponseCurve, depth);
3121 ReleaseVelocityResponseDepth = depth;
3129 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, VCFVelocityScale, controller);
3130 VCFCutoffController = controller;
3138 pVelocityCutoffTable = GetCutoffVelocityTable(curve, VCFVelocityDynamicRange, VCFVelocityScale, VCFCutoffController);
3139 VCFVelocityCurve = curve;
3147 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, range, VCFVelocityScale, VCFCutoffController);
3148 VCFVelocityDynamicRange = range;
3156 pVelocityCutoffTable = GetCutoffVelocityTable(VCFVelocityCurve, VCFVelocityDynamicRange, scaling, VCFCutoffController);
3157 VCFVelocityScale = scaling;
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);
3234 for (
int i = 0; i < 256; i++) {
3235 pDimensionRegions[i] = NULL;
3238 File* file = (
File*) GetParent()->GetParent();
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();
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);
3314 DimensionRegions = 1;
3333 pSample = pDimensionRegions[0]->pSample;
3339 for (
int i = 0; i < DimensionRegions; i++) {
3340 pDimensionRegions[i]->UpdateChunks(pProgress);
3343 File* pFile = (
File*) GetParent()->GetParent();
3345 const int iMaxDimensions = versiongt2 ? 8 : 5;
3346 const int iMaxDimensionRegions = versiongt2 ? 256 : 32;
3349 RIFF::Chunk* _3lnk = pCkRegion->GetSubChunk(CHUNK_ID_3LNK);
3351 const int _3lnkChunkSize = versiongt2 ? 1092 : 172;
3352 _3lnk = pCkRegion->AddSubChunk(CHUNK_ID_3LNK, _3lnkChunkSize);
3356 pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3PRG), (
RIFF::Chunk*)NULL);
3361 store32(&pData[0], DimensionRegions);
3363 for (
int i = 0; i < iMaxDimensions; i++) {
3364 pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
3365 pData[5 + i * 8] = pDimensionDefinitions[i].bits;
3366 pData[6 + i * 8] = pDimensionDefinitions[i].dimension ==
dimension_none ? 0 : shift;
3367 pData[7 + i * 8] = (1 << (shift + pDimensionDefinitions[i].bits)) - (1 << shift);
3368 pData[8 + i * 8] = pDimensionDefinitions[i].zones;
3371 shift += pDimensionDefinitions[i].bits;
3375 const int iWavePoolOffset = versiongt2 ? 68 : 44;
3376 for (uint i = 0; i < iMaxDimensionRegions; i++) {
3377 int iWaveIndex = -1;
3378 if (i < DimensionRegions) {
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) {
3383 if (*iter == pDimensionRegions[i]->pSample) {
3389 store32(&pData[iWavePoolOffset + i * 4], iWaveIndex);
3393 void Region::LoadDimensionRegions(
RIFF::List* rgn) {
3396 int dimensionRegionNr = 0;
3400 pDimensionRegions[dimensionRegionNr] =
new DimensionRegion(
this, _3ewl);
3401 dimensionRegionNr++;
3405 if (dimensionRegionNr == 0)
throw gig::Exception(
"No dimension region found.");
3416 void Region::UpdateVelocityTable() {
3419 for (
int i = 0 ; i < Dimensions ; i++) {
3425 if (veldim == -1)
return;
3428 for (
int i = 0 ; i < veldim ; i++) step <<= pDimensionDefinitions[i].bits;
3429 int skipveldim = (step << pDimensionDefinitions[veldim].bits) - step;
3433 for (
int i = 0 ; i < DimensionRegions ; i++) {
3434 const int end = i + step * pDimensionDefinitions[veldim].zones;
3437 if (pDimensionRegions[i]->DimensionUpperLimits[veldim] ||
3438 pDimensionRegions[i]->VelocityUpperLimit) {
3440 uint8_t* table = pDimensionRegions[i]->VelocityTable;
3442 table =
new uint8_t[128];
3443 pDimensionRegions[i]->VelocityTable = table;
3446 int velocityZone = 0;
3447 if (pDimensionRegions[i]->DimensionUpperLimits[veldim]) {
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;
3461 if (pDimensionRegions[i]->VelocityTable) {
3463 pDimensionRegions[i]->VelocityTable = 0;
3470 for (j = 0 ; j < Dimensions ; j++) {
3471 if (j == veldim) i += skipveldim;
3474 if (dim[j] < pDimensionDefinitions[j].zones)
break;
3478 i += ((1 << pDimensionDefinitions[j].bits) -
3479 pDimensionDefinitions[j].zones) << shift;
3482 shift += pDimensionDefinitions[j].bits;
3484 if (j == Dimensions)
break;
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;
3519 if (Dimensions >= iMaxDimensions)
3520 throw gig::Exception(
"Could not add new dimension, max. amount of " + ToString(iMaxDimensions) +
" dimensions already reached");
3522 int iCurrentBits = 0;
3523 for (
int i = 0; i < Dimensions; i++)
3524 iCurrentBits += pDimensionDefinitions[i].bits;
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");
3531 for (
int i = 0; i < Dimensions; i++)
3532 if (pDimensionDefinitions[i].dimension == pDimDef->
dimension)
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++)
3541 bitpos += pDimensionDefinitions[i].bits;
3544 for (
int i = Dimensions ; i > pos ; i--) pDimensionDefinitions[i] = pDimensionDefinitions[i - 1];
3545 for (
int i = 0 ; i < (1 << iCurrentBits) ; i++) {
3546 for (
int j = Dimensions ; j > pos ; j--) {
3547 pDimensionRegions[i]->DimensionUpperLimits[j] =
3548 pDimensionRegions[i]->DimensionUpperLimits[j - 1];
3553 pDimensionDefinitions[pos] = *pDimDef;
3557 __resolveSplitType(pDimensionDefinitions[pos].dimension);
3558 pDimensionDefinitions[pos].zone_size =
3559 __resolveZoneSize(pDimensionDefinitions[pos]);
3566 for (
int i = (1 << iCurrentBits) - (1 << bitpos) ; i >= 0 ; i -= (1 << bitpos)) {
3567 for (
int k = 0 ; k < (1 << bitpos) ; k++) {
3568 pDimensionRegions[(i << pDimDef->
bits) + k] = pDimensionRegions[i + 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);
3576 pDimensionRegions[(i << pDimDef->
bits) + (j << bitpos) + k] =
3582 moveTo = pDimensionRegions[i]->pParentList;
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++) {
3590 pDimensionRegions[((i & ~mask) << pDimDef->
bits) |
3592 (i & mask)]->DimensionUpperLimits[pos] = upperLimit;
3601 UpdateVelocityTable();
3617 int iDimensionNr = -1;
3618 for (
int i = 0; i < Dimensions; i++) {
3619 if (&pDimensionDefinitions[i] == pDimDef) {
3624 if (iDimensionNr < 0)
throw gig::Exception(
"Invalid dimension_def_t pointer");
3628 for (
int i = 0; i < iDimensionNr; i++)
3629 iLowerBits += pDimensionDefinitions[i].bits;
3633 for (
int i = iDimensionNr + 1; i < Dimensions; i++)
3634 iUpperBits += pDimensionDefinitions[i].bits;
3640 for (
int iUpperBit = 0; iUpperBit < 1 << iUpperBits; iUpperBit++) {
3641 for (
int iObsoleteBit = 1; iObsoleteBit < 1 << pDimensionDefinitions[iDimensionNr].bits; iObsoleteBit++) {
3642 for (
int iLowerBit = 0; iLowerBit < 1 << iLowerBits; iLowerBit++) {
3643 int iToDelete = iUpperBit << (pDimensionDefinitions[iDimensionNr].bits + iLowerBits) |
3644 iObsoleteBit << iLowerBits |
3647 _3prg->
DeleteSubChunk(pDimensionRegions[iToDelete]->pParentList);
3648 delete pDimensionRegions[iToDelete];
3649 pDimensionRegions[iToDelete] = NULL;
3657 for (
int iFrom = 2, iTo = 1; iFrom < 256 && iTo < 256 - 1; iTo++) {
3658 if (!pDimensionRegions[iTo]) {
3659 if (iFrom <= iTo) iFrom = iTo + 1;
3660 while (!pDimensionRegions[iFrom] && iFrom < 256) iFrom++;
3661 if (iFrom < 256 && pDimensionRegions[iFrom]) {
3662 pDimensionRegions[iTo] = pDimensionRegions[iFrom];
3663 pDimensionRegions[iFrom] = NULL;
3669 for (
int j = 0 ; j < 256 && pDimensionRegions[j] ; j++) {
3671 for (
int i = iDimensionNr + 1; i < Dimensions; i++) {
3678 for (
int i = iDimensionNr + 1; i < Dimensions; i++) {
3679 pDimensionDefinitions[i - 1] = pDimensionDefinitions[i];
3681 pDimensionDefinitions[Dimensions - 1].dimension =
dimension_none;
3682 pDimensionDefinitions[Dimensions - 1].bits = 0;
3683 pDimensionDefinitions[Dimensions - 1].zones = 0;
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);
3735 for (
int i = 0; i < Dimensions; ++i) {
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]++;
3790 DeleteDimension(oldDef);
3791 AddDimension(&newDef);
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);
3858 for (
int i = 0; i < Dimensions; ++i) {
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) {
3886 const int srcBits = pDimensionDefinitions[d].bits;
3887 dimCase[pDimensionDefinitions[d].dimension] =
3888 (iSrc >> baseBits) & ((1 << srcBits) - 1);
3890 if (dimCase[pDimensionDefinitions[d].dimension] >= pDimensionDefinitions[d].zones) {
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;
3930 DeleteDimension(oldDef);
3931 AddDimension(&newDef);
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");
3977 if (GetDimensionDefinition(newType))
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)
3988 for (
int d = 0; d < Dimensions; ++d) {
3989 if (pDimensionDefinitions[d].dimension == it->first) {
3990 bits[d] = it->second;
3991 goto nextDimCaseSlice;
3998 return GetDimensionRegionByBit(bits);
4011 for (
int i = 0; i < Dimensions; ++i)
4012 if (pDimensionDefinitions[i].dimension == type)
4013 return &pDimensionDefinitions[i];
4018 for (
int i = 0; i < 256; i++) {
4019 if (pDimensionRegions[i])
delete pDimensionRegions[i];
4047 for (uint i = 0; i < Dimensions; i++) {
4053 switch (pDimensionDefinitions[i].split_type) {
4055 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4057 for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4058 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i])
break;
4062 bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4066 const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4067 bits = DimValues[i] & limiter_mask;
4070 dimregidx |= bits << bitpos;
4072 bitpos += pDimensionDefinitions[i].bits;
4075 if (!dimreg)
return NULL;
4081 bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4083 const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4084 dimregidx |= (bits & limiter_mask) << velbitpos;
4085 dimreg = pDimensionRegions[dimregidx & 255];
4090 int Region::GetDimensionRegionIndexByValue(
const uint DimValues[8]) {
4096 for (uint i = 0; i < Dimensions; i++) {
4102 switch (pDimensionDefinitions[i].split_type) {
4104 if (pDimensionRegions[0]->DimensionUpperLimits[i]) {
4106 for (bits = 0 ; bits < pDimensionDefinitions[i].zones ; bits++) {
4107 if (DimValues[i] <= pDimensionRegions[bits << bitpos]->DimensionUpperLimits[i])
break;
4111 bits = uint8_t(DimValues[i] / pDimensionDefinitions[i].zone_size);
4115 const uint8_t limiter_mask = (0xff << pDimensionDefinitions[i].bits) ^ 0xff;
4116 bits = DimValues[i] & limiter_mask;
4119 dimregidx |= bits << bitpos;
4121 bitpos += pDimensionDefinitions[i].bits;
4125 if (!dimreg)
return -1;
4131 bits = uint8_t((DimValues[veldim] & 127) / pDimensionDefinitions[veldim].zone_size);
4133 const uint8_t limiter_mask = (1 << pDimensionDefinitions[veldim].bits) - 1;
4134 dimregidx |= (bits & limiter_mask) << velbitpos;
4151 return pDimensionRegions[((((((DimBits[7] << pDimensionDefinitions[6].bits | DimBits[6])
4152 << pDimensionDefinitions[5].bits | DimBits[5])
4153 << pDimensionDefinitions[4].bits | DimBits[4])
4154 << pDimensionDefinitions[3].bits | DimBits[3])
4155 << pDimensionDefinitions[2].bits | DimBits[2])
4156 << pDimensionDefinitions[1].bits | DimBits[1])
4157 << pDimensionDefinitions[0].bits | DimBits[0]];
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 &&
4229 if (mSamples && mSamples->count((
gig::Sample*)orig->pSample)) {
4230 pSample = mSamples->find((
gig::Sample*)orig->pSample)->second;
4234 for (
int i = Dimensions - 1; i >= 0; --i) {
4235 DeleteDimension(&pDimensionDefinitions[i]);
4244 for (
int i = 0; i < 256; i++) {
4246 pDimensionRegions[i]->CopyAssign(
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 {
4285 pData[36] = Triggers;
4286 pData[40] = ControllerNumber;
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) {
4302 BypassUseController = _3ewg->
ReadUint8();
4317 MidiRuleLegato::MidiRuleLegato() :
4319 BypassUseController(
false),
4321 BypassController(1),
4324 ReleaseTriggerKey(0),
4328 KeyRange.low = KeyRange.high = 0;
4331 void MidiRuleLegato::UpdateChunks(uint8_t* pData)
const {
4334 pData[36] = LegatoSamples;
4335 pData[40] = BypassUseController;
4336 pData[41] = BypassKey;
4337 pData[42] = BypassController;
4338 store16(&pData[43], ThresholdTime);
4339 store16(&pData[47], ReleaseTime);
4340 pData[51] = KeyRange.low;
4341 pData[52] = KeyRange.high;
4342 pData[64] = ReleaseTriggerKey;
4343 pData[65] = AltSustain1Key;
4344 pData[66] = AltSustain2Key;
4347 MidiRuleAlternator::MidiRuleAlternator(
RIFF::Chunk* _3ewg) {
4351 Polyphonic = flags & 8;
4352 Chained = flags & 4;
4353 Selector = (flags & 2) ? selector_controller :
4354 (flags & 1) ? selector_key_switch : selector_none;
4360 KeySwitchRange.low = _3ewg->
ReadUint8();
4361 KeySwitchRange.high = _3ewg->
ReadUint8();
4366 int n = std::min(
int(Articulations), 32);
4367 for (
int i = 0 ; i < n ; i++) {
4371 n = std::min(
int(Patterns), 32);
4372 for (
int i = 0 ; i < n ; i++) {
4375 _3ewg->
Read(&pPatterns[i][0], 1, 32);
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 {
4394 pData[36] = Articulations;
4395 pData[37] = (Polyphonic ? 8 : 0) | (Chained ? 4 : 0) |
4396 (Selector == selector_controller ? 2 :
4397 (Selector == selector_key_switch ? 1 : 0));
4398 pData[38] = Patterns;
4400 pData[43] = KeySwitchRange.low;
4401 pData[44] = KeySwitchRange.high;
4402 pData[45] = Controller;
4403 pData[46] = PlayRange.low;
4404 pData[47] = PlayRange.high;
4406 char* str =
reinterpret_cast<char*
>(pData);
4408 int n = std::min(
int(Articulations), 32);
4409 for (
int i = 0 ; i < n ; i++, pos += 32) {
4410 strncpy(&str[pos], pArticulations[i].c_str(), 32);
4414 n = std::min(
int(Patterns), 32);
4415 for (
int i = 0 ; i < n ; i++, pos += 49) {
4416 strncpy(&str[pos], pPatterns[i].Name.c_str(), 16);
4417 pData[pos + 16] = pPatterns[i].Size;
4418 memcpy(&pData[pos + 16], &(pPatterns[i][0]), 32);
4433 Compression = (Compression_t) ckScri->
ReadUint32();
4434 Encoding = (Encoding_t) ckScri->
ReadUint32();
4435 Language = (Language_t) ckScri->
ReadUint32();
4436 Bypass = (Language_t) ckScri->
ReadUint32() & 1;
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)
4450 Compression = COMPRESSION_NONE;
4451 Encoding = ENCODING_ASCII;
4452 Language = LANGUAGE_NKSP;
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);
4514 uint8_t* pData = (uint8_t*) pChunk->LoadChunkData();
4516 store32(&pData[pos], uint32_t(6*
sizeof(int32_t) + Name.size()));
4517 pos +=
sizeof(int32_t);
4518 store32(&pData[pos], Compression);
4519 pos +=
sizeof(int32_t);
4520 store32(&pData[pos], Encoding);
4521 pos +=
sizeof(int32_t);
4522 store32(&pData[pos], Language);
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;
4545 pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
4575 void Script::RemoveAllScriptReferences() {
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) {
4634 pList = pFile->pRIFF->GetSubList(LIST_TYPE_3LS)->AddSubList(LIST_TYPE_RTIS);
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*>;
4708 for (
RIFF::Chunk* ck = pList->GetFirstSubChunk(); ck;
4709 ck = pList->GetNextSubChunk())
4711 if (ck->GetChunkID() == CHUNK_ID_SCRI) {
4712 pScripts->push_back(
new Script(
this, ck));
4721 static const DLS::Info::string_length_t fixedStringLengths[] = {
4722 { CHUNK_ID_INAM, 64 },
4723 { CHUNK_ID_ISFT, 12 },
4729 for (
int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
4734 PianoReleaseMode =
false;
4735 DimensionKeyRange.low = 0;
4736 DimensionKeyRange.high = 0;
4738 pMidiRules[0] = NULL;
4752 uint8_t dimkeystart = _3ewg->
ReadUint8();
4753 PianoReleaseMode = dimkeystart & 0x01;
4754 DimensionKeyRange.low = dimkeystart >> 1;
4755 DimensionKeyRange.high = _3ewg->
ReadUint8();
4767 }
else if (id1 == 0) {
4769 }
else if (id1 == 3) {
4775 else if (id1 != 0 || id2 != 0) {
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() {
4832 for (
int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
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++) {
4840 RegionKeyTable[iKey] = pRegion;
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);
4891 store32(&pData[2], Attenuation);
4893 store16(&pData[8], PitchbendRange);
4894 const uint8_t dimkeystart = (PianoReleaseMode ? 0x01 : 0x00) |
4895 DimensionKeyRange.low << 1;
4896 pData[10] = dimkeystart;
4897 pData[11] = DimensionKeyRange.high;
4899 if (pMidiRules[0] == 0 && _3ewg->
GetSize() >= 34) {
4903 for (
int i = 0 ; pMidiRules[i] ; i++) {
4904 pMidiRules[i]->UpdateChunks(pData);
4909 if (ScriptSlotCount()) {
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;
4977 return RegionKeyTable[Key];
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());
5337 if (index >= ScriptSlotCount())
return false;
5338 return pScriptRefs ? pScriptRefs->at(index).bypass
5339 : scriptPoolFileOffsets.at(index).bypass;
5357 if (index >= ScriptSlotCount())
return;
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;
5408 while (Regions) DeleteRegion(GetFirstRegion());
5411 RegionList::const_iterator it = orig->pRegions->begin();
5412 for (
int i = 0; i < orig->
Regions; ++i, ++it) {
5413 Region* dstRgn = AddRegion();
5416 static_cast<gig::Region*>(*it),
5422 UpdateRegionKeyTable();
5437 pNameChunk = ck3gnm;
5438 ::LoadString(pNameChunk, Name);
5455 pNameChunk->GetParent()->DeleteSubChunk(pNameChunk);
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;
5547 for (pOtherGroup = pFile->GetFirstGroup(); pOtherGroup; pOtherGroup = pFile->GetNextGroup()) {
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!" 5555 for (
Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
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 },
5603 *pVersion = VERSION_3;
5605 pScriptGroups = NULL;
5611 pRIFF->AddSubChunk(CHUNK_ID_VERS, 8);
5612 pRIFF->AddSubChunk(CHUNK_ID_COLH, 4);
5613 pRIFF->AddSubChunk(CHUNK_ID_DLID, 16);
5621 pScriptGroups = NULL;
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();
5699 __ensureMandatoryChunksExist();
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;
5733 for (
Instrument* instrument = GetFirstInstrument() ; instrument ;
5734 instrument = GetNextInstrument()) {
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++) {
5840 file_offset_t wvplFileOffset = wvpl->
GetFilePos() -
5847 const float subprogress = (float) iSampleIndex / (
float) iTotalSamples;
5848 __notify_progress(pProgress, subprogress);
5851 file_offset_t waveFileOffset = wave->
GetFilePos();
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);
5909 GetFirstSample(&subprogress);
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();
5947 __ensureMandatoryChunksExist();
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) {
6040 Save(GetFileName());
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);
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) {
6162 if (!pSamples) GetFirstSample();
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;
6182 if (!pSamples) GetFirstSample();
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;
6216 if (!pSamples) GetFirstSample();
6218 bool bRequiresSave =
false;
6223 _3crc = pRIFF->
AddSubChunk(CHUNK_ID_3CRC, pSamples->size() * 8);
6226 if (einf && pVersion && pVersion->major > 2) pRIFF->
MoveSubChunk(_3crc, einf);
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();
6257 SetSampleChecksum(pSample, pSample->
crc);
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();
6315 __ensureMandatoryChunksExist();
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!");
6337 DeleteSample(pSample);
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*>;
6377 if (pVersion && pVersion->major > 2 &&
6378 strcmp(static_cast<char*>(ck->
LoadChunkData()),
"") == 0)
break;
6380 pGroups->push_back(
new Group(
this, ck));
6387 if (!pGroups->size()) {
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);
6554 if (pVersion && pVersion->major > 2) {
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);
6586 int einfSize = (Instruments + 1) * sublen;
6590 if (einf->
GetSize() != einfSize) {
6594 }
else if (newFile) {
6595 einf = pRIFF->
AddSubChunk(CHUNK_ID_EINF, einfSize);
6600 std::map<gig::Sample*,int> sampleMap;
6602 for (
Sample* pSample = GetFirstSample(); pSample; pSample = GetNextSample()) {
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);
6615 for (
Instrument* instrument = GetFirstInstrument() ; instrument ;
6616 instrument = GetNextInstrument()) {
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);
6670 store32(&pData[12], Instruments);
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);
6700 if (einf && pVersion && pVersion->major > 2) pRIFF->
MoveSubChunk(_3crc, einf);
6703 uint32_t* pData = (uint32_t*) _3crc->LoadChunkData();
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;
6719 for (
Instrument* instrument = GetFirstInstrument(); instrument;
6720 instrument = GetNextInstrument())
6722 instrument->UpdateScriptFileOffsets();
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;
file_offset_t WriteUint32(uint32_t *pData, file_offset_t WordCount=1)
Writes WordCount number of 32 Bit unsigned integer words from the buffer pointed by pData to the chun...
void SetScriptAsText(const String &text)
Replaces the current script with the new script source code text given by text.
void AddContentOf(File *pFile)
Add content of another existing file.
void MoveAll()
Move all members of this group to another group (preferably the 1st one except this).
bool IsNew() const
Returns true if this file has been created new from scratch and has not been stored to disk yet...
file_offset_t position
Current position within the sample.
Encapsulates articulation informations of a dimension region.
range_t DimensionKeyRange
0-127 (where 0 means C1 and 127 means G9)
sample_loop_t * pSampleLoops
Points to the beginning of a sample loop array, or is NULL if there are no loops defined.
void SetDimensionType(dimension_t oldType, dimension_t newType)
Change type of an existing dimension.
bool reverse
If playback direction is currently backwards (in case there is a pingpong or reverse loop defined)...
Destination container for serialization, and source container for deserialization.
file_offset_t FrameOffset
Current offset (sample points) in current sample frame (for decompression only).
uint32_t Regions
Reflects the number of Region defintions this Instrument has.
Region * GetRegion(unsigned int Key)
Returns the appropriate Region for a triggered note.
void AddSample(Sample *pSample)
Move Sample given by pSample from another Group to this Group.
String GetScriptAsText()
Returns the current script (i.e.
file_offset_t SamplePos
For compressed samples only: stores the current position (in sample points).
MidiRuleAlternator * AddMidiRuleAlternator()
Adds the alternator MIDI rule to the instrument.
Sample * AddSample()
Add a new sample.
file_offset_t SetPos(file_offset_t SampleCount, RIFF::stream_whence_t Whence=RIFF::stream_start)
Sets the position within the sample (in sample points, not in bytes).
Standard lowpass filter type.
Parses DLS Level 1 and 2 compliant files and provides abstract access to the data.
void AddDimension(dimension_def_t *pDimDef)
Einstein would have dreamed of it - create a new dimension.
file_offset_t ReadUint16(uint16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit unsigned integer words and copies it into the buffer pointed by pDat...
stream_whence_t
File stream position dependent to these relations.
uint32_t FineTune
Specifies the fraction of a semitone up from the specified MIDI unity note field. A value of 0x800000...
Chunk * GetFirstSubChunk()
Returns the first subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
file_offset_t SamplesPerFrame
For compressed samples only: number of samples in a full sample frame.
lfo1_ctrl_t
Defines how LFO1 is controlled by.
Group of Gigasampler samples.
uint32_t LoopType
Defines how the waveform samples will be looped (appropriate loop types for the gig format are define...
String Name
Stores the name of this Group.
DimensionRegion * GetDimensionRegionByBit(const uint8_t DimBits[8])
Returns the appropriate DimensionRegion for the given dimension bit numbers (zone index)...
Special dimension for triggering samples on releasing a key.
uint16_t PitchbendRange
Number of semitones pitchbend controller can pitch (default is 2).
Defines behavior options for envelope generators (gig format extension).
Script * AddScript()
Add new instrument script.
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order...
uint32_t LoopSize
Caution: Use the respective fields in the DimensionRegion instead of this one! (Intended purpose: Len...
Instrument * AddInstrument()
Add a new instrument definition.
file_offset_t GetSize() const
Chunk size in bytes (without header, thus the chunk data body)
Script * GetScript(uint index)
Get instrument script.
loop_type_t LoopType
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Only internally controlled.
Sample * GetFirstSample()
Returns a pointer to the first Sample object of the file, NULL otherwise.
virtual void UpdateChunks(progress_t *pProgress)
Apply this script group to the respective RIFF chunks.
Will be thrown whenever a DLS specific error occurs while trying to access a DLS File.
MIDI rule for triggering notes by control change events.
file_offset_t ReadInt32(int32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit signed integer words and copies it into the buffer pointed by pData...
size_t CountInstruments()
Returns the total amount of instruments of this gig file.
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
void(* callback)(progress_t *)
Callback function pointer which has to be assigned to a function for progress notification.
file_offset_t WorstCaseFrameSize
For compressed samples only: size (in bytes) of the largest possible sample frame.
file_offset_t Size
Size of the actual data in the buffer in bytes.
void AddScriptSlot(Script *pScript, bool bypass=false)
Add new instrument script slot (gig format extension).
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Instrument object.
static size_t Instances
Number of instances of class Sample.
dimension values are already the sought bit number
Group * GetGroup() const
Returns pointer to the Group this Sample belongs to.
Instrument * GetFirstInstrument()
Returns a pointer to the first Instrument object of the file, NULL otherwise.
void ReadString(String &s, int size)
Reads a null-padded string of size characters and copies it into the string s.
file_offset_t GetSize() const
Returns sample size.
For MIDI tools like legato and repetition mode.
void CopyAssignWave(const Sample *orig)
Should be called after CopyAssignMeta() and File::Save() sequence.
uint32_t crc
Reflects CRC-32 checksum of the raw sample data at the last time when the sample's raw wave form data...
Defines a controller that has a certain contrained influence on a particular synthesis parameter (use...
sust_rel_trg_t
Defines behaviour of release triggered sample(s) on sustain pedal up event.
uint16_t Channels
Number of channels represented in the waveform data, e.g. 1 for mono, 2 for stereo (defaults to 1=mon...
void SetVCFVelocityScale(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
Defines Region information of a Gigasampler/GigaStudio instrument.
file_offset_t SamplesTotal
Reflects total number of sample points (only if known sample data format is used, 0 otherwise)...
uint32_t LoopPlayCount
Number of times the loop should be played (a value of 0 = infinite).
uint32_t MIDIUnityNote
Specifies the musical note at which the sample will be played at it's original sample rate...
List * GetSubList(uint32_t ListType)
Returns sublist chunk with list type ListType within this chunk list.
void DeleteSubChunk(Chunk *pSubChunk)
Removes a sub chunk.
Defines Sample Loop Points.
Language_t Language
Programming language and dialect the script is written in.
void DeleteMidiRule(int i)
Deletes a MIDI rule from the instrument.
unsigned int Dimensions
Number of defined dimensions, do not alter!
Only controlled by external modulation wheel.
file_offset_t loop_cycles_left
How many times the loop has still to be passed, this value will be decremented with each loop cycle...
bool VerifySampleChecksumTable()
Checks whether the file's "3CRC" chunk was damaged.
MidiRuleCtrlTrigger * AddMidiRuleCtrlTrigger()
Adds the "controller trigger" MIDI rule to the instrument.
List * GetFirstSubList()
Returns the first sublist within the list (that is a subchunk with chunk ID "LIST").
DimensionRegion * GetDimensionRegionByValue(const uint DimValues[8])
Use this method in your audio engine to get the appropriate dimension region with it's articulation d...
Compression_t Compression
Whether the script was/should be compressed, and if so, which compression algorithm shall be used...
Different samples triggered each time a note is played, any key advances the counter.
bool Dithered
For 24-bit compressed samples only: if dithering was used during compression with bit reduction...
Region * GetFirstRegion()
Returns the first Region of the instrument.
String libraryVersion()
Returns version of this C++ library.
uint8_t VelocityUpperLimit
Defines the upper velocity value limit of a velocity split (only if an user defined limit was set...
Will be thrown whenever a gig specific error occurs while trying to access a Gigasampler File...
buffer_t LoadSampleDataWithNullSamplesExtension(uint NullSamplesCount)
Loads (and uncompresses if needed) the whole sample wave into RAM.
static const DLS::version_t VERSION_4
Reflects Gigasampler file format version 4.0 (2007-10-12).
void UpdateChunks(progress_t *pProgress)
Apply this script to the respective RIFF chunks.
void GenerateDLSID()
Generates a new DLSID for the resource.
void SetVCFCutoffController(vcf_cutoff_ctrl_t controller)
Updates the respective member variable and the lookup table / cache that depends on this value...
static const DLS::version_t VERSION_2
Reflects Gigasampler file format version 2.0 (1998-06-28).
Sample * pSample
Points to the Sample which is assigned to the dimension region.
uint FrameSize
Reflects the size (in bytes) of one single sample point (only if known sample data format is used...
buffer_t LoadSampleData()
Loads (and uncompresses if needed) the whole sample wave into RAM.
List * GetParent() const
Returns pointer to the chunk's parent list chunk.
uint32_t LoopStart
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
Group * GetNextGroup()
Returns a pointer to the next Group object of the file, NULL otherwise.
void SetVCFVelocityCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Every subject of an DLS file and the file itself can have an unique, computer generated ID...
virtual void CopyAssign(const Sample *orig)
Make a deep copy of the Sample object given by orig and assign it to this object. ...
void SetAutoLoad(bool b)
Enable / disable automatic loading.
MidiRule * GetMidiRule(int i)
Returns a MIDI rule of the instrument.
smpte_format_t SMPTEFormat
Specifies the Society of Motion Pictures and Television E time format used in the following SMPTEOffs...
uint16_t low
Low value of range.
bool ReleaseCancel
Whether the "release" stage is cancelled when receiving a note-on (default: true).
lfo3_ctrl_t
Defines how LFO3 is controlled by.
void SetFixedStringLengths(const string_length_t *lengths)
Forces specific Info fields to be of a fixed length when being saved to a file.
void RemoveScript(Script *pScript)
Remove reference to given Script (gig format extension).
file_offset_t Read(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Reads WordCount number of data words with given WordSize and copies it into a buffer pointed by pData...
static buffer_t InternalDecompressionBuffer
Buffer used for decompression as well as for truncation of 24 Bit -> 16 Bit samples.
static void DestroyDecompressionBuffer(buffer_t &DecompressionBuffer)
Free decompression buffer, previously created with CreateDecompressionBuffer().
Pointer address and size of a buffer.
bool Decay1Cancel
Whether the "decay 1" stage is cancelled when receiving a note-off (default: true).
dimension_t dimension
Specifies which source (usually a MIDI controller) is associated with the dimension.
bool Bypass
Global bypass: if enabled, this script shall not be executed by the sampler for any instrument...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this ScriptGroup object.
Group * GetFirstGroup()
Returns a pointer to the first Group object of the file, NULL otherwise.
file_offset_t SetPos(file_offset_t Where, stream_whence_t Whence=stream_start)
Sets the position within the chunk body, thus within the data portion of the chunk (in bytes)...
Group * GetGroup(uint index)
Returns the group with the given index.
String Name
Arbitrary name of the script, which may be displayed i.e. in an instrument editor.
Instrument * AddDuplicateInstrument(const Instrument *orig)
Add a duplicate of an existing instrument.
uint ScriptSlotCount() const
Instrument's amount of script slots.
Key Velocity (this is the only dimension in gig2 where the ranges can exactly be defined).
bool Compressed
If the sample wave is compressed (probably just interesting for instrument and sample editors...
void ReleaseSampleData()
Frees the cached sample from RAM if loaded with LoadSampleData() previously.
uint32_t SampleLoops
Reflects the number of sample loops.
More poles than normal lowpass.
void DeleteDimensionZone(dimension_t type, int zone)
Delete one split zone of a dimension (decrement zone amount).
void Resize(file_offset_t NewSize)
Resize sample.
The difference between none and none2 is unknown.
static buffer_t CreateDecompressionBuffer(file_offset_t MaxReadSize)
Allocates a decompression buffer for streaming (compressed) samples with Sample::Read().
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.
void Resize(file_offset_t NewSize)
Resize sample.
uint16_t high
High value of range.
float __range_min
Only for internal usage, do not modify!
unsigned int Layers
Amount of defined layers (1 - 32). A value of 1 actually means no layering, a value > 1 means there i...
void * pStart
Points to the beginning of the buffer.
file_offset_t ReadUint32(uint32_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 32 Bit unsigned integer words and copies it into the buffer pointed by pDat...
Group * pGroup
pointer to the Group this sample belongs to (always not-NULL)
Chunk * GetSubChunk(uint32_t ChunkID)
Returns subchunk with chunk ID ChunkID within this chunk list.
file_offset_t GetPos() const
Returns the current position in the sample (in sample points).
Chunk * GetNextSubChunk()
Returns the next subchunk within the list (which may be an ordinary chunk as well as a list chunk)...
MidiRuleLegato * AddMidiRuleLegato()
Adds the legato MIDI rule to the instrument.
void RemoveScriptSlot(uint index)
Remove script slot.
void DeleteDimension(dimension_def_t *pDimDef)
Delete an existing dimension.
Instrument * GetNextInstrument()
Returns a pointer to the next Instrument object of the file, NULL otherwise.
void DeleteGroupOnly(Group *pGroup)
Delete a group.
uint16_t BitDepth
Size of each sample per channel (only if known sample data format is used, 0 otherwise).
uint32_t LoopID
Specifies the unique ID that corresponds to one of the defined cue points in the cue point list (only...
void DeleteSample(Sample *pSample)
Delete a sample.
bool IsScriptSlotBypassed(uint index)
Whether script execution shall be skipped.
int GetFileOffsetSize() const
Returns the current size (in bytes) of file offsets stored in the headers of all chunks of this file...
static const DLS::version_t VERSION_3
Reflects Gigasampler file format version 3.0 (2003-03-31).
uint32_t LoopLength
Length of the looping area (in sample points).
ScriptGroup * AddScriptGroup()
Add new instrument script group.
DimensionRegion * pDimensionRegions[256]
Pointer array to the 32 (gig2) or 256 (gig3) possible dimension regions (reflects NULL for dimension ...
uint32_t Product
Specifies the MIDI model ID defined by the manufacturer corresponding to the Manufacturer field...
split_type_t
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
uint32_t GetChunkID() const
Chunk ID in unsigned integer representation.
Alternating loop (forward/backward, also known as Ping Pong)
ScriptGroup * GetScriptGroup(uint index)
Get instrument script group (by index).
file_offset_t RemainingBytes() const
Returns the number of bytes left to read in the chunk body.
bool RebuildSampleChecksumTable()
Recalculates CRC32 checksums for all samples and rebuilds this gig file's checksum table with those n...
void SetSampleChecksum(Sample *pSample, uint32_t crc)
Updates the 3crc chunk with the checksum of a sample.
Sample * GetNextSample()
Returns the next Sample of the Group.
Used for indicating the progress of a certain task.
file_offset_t ReadAndLoop(void *pBuffer, file_offset_t SampleCount, playback_state_t *pPlaybackState, DimensionRegion *pDimRgn, buffer_t *pExternalDecompressionBuffer=NULL)
Reads SampleCount number of sample points from the position stored in pPlaybackState into the buffer ...
file_offset_t Write(void *pData, file_offset_t WordCount, file_offset_t WordSize)
Writes WordCount number of data words with given WordSize from the buffer pointed by pData...
uint32_t Loops
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: Numb...
uint32_t GetListType() const
Returns unsigned integer representation of the list's ID.
uint32_t SMPTEOffset
The SMPTE Offset value specifies the time offset to be used for the synchronization / calibration to ...
file_offset_t ReadInt8(int8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit signed integer words and copies it into the buffer pointed by pData...
size_t CountSamples()
Returns the total amount of samples of this gig file.
uint32_t GetWaveDataCRC32Checksum()
Returns the CRC-32 checksum of the sample's raw wave form data at the time when this sample's wave fo...
unsigned long FileNo
File number (> 0 when sample is stored in an extension file, 0 when it's in the gig) ...
void SplitDimensionZone(dimension_t type, int zone)
Divide split zone of a dimension in two (increment zone amount).
Sample * GetFirstSample(progress_t *pProgress=NULL)
Returns a pointer to the first Sample object of the file, NULL otherwise.
Ordinary MIDI control change controller, see field 'controller_number'.
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
vcf_type_t
Defines which frequencies are filtered by the VCF.
Sample(File *pFile, RIFF::List *waveList, file_offset_t WavePoolOffset, unsigned long fileNo=0, int index=-1)
Constructor.
version_t * pVersion
Points to a version_t structure if the file provided a version number else is set to NULL...
void DeleteInstrument(Instrument *pInstrument)
Delete an instrument.
uint32_t LoopStart
The start value specifies the offset (in sample points) in the waveform data of the first sample poin...
virtual void UpdateChunks(progress_t *pProgress)
Update chunks with current group settings.
bool AttackHoldCancel
Whether the "attack hold" stage is cancelled when receiving a note-off (default: true).
String Name
Name of this script group. For example to be displayed in an instrument editor.
file_offset_t * FrameTable
For positioning within compressed samples only: stores the offset values for each frame...
file_offset_t Write(void *pBuffer, file_offset_t SampleCount)
Write sample wave data.
bool GetAutoLoad()
Returns whether automatic loading is enabled.
For layering of up to 8 instruments (and eventually crossfading of 2 or 4 layers).
void * LoadChunkData()
Load chunk body into RAM.
Different samples triggered each time a note is played, random order.
file_offset_t NullExtensionSize
The buffer might be bigger than the actual data, if that's the case that unused space at the end of t...
virtual void CopyAssign(const Region *orig)
Make a (semi) deep copy of the Region object given by orig and assign it to this object.
void SwapScriptSlots(uint index1, uint index2)
Flip two script slots with each other (gig format extension).
Abstract base class for all MIDI rules.
ScriptGroup * GetGroup() const
Returns the script group this script currently belongs to.
void SetVelocityResponseCurveScaling(uint8_t scaling)
Updates the respective member variable and the lookup table / cache that depends on this value...
virtual void UpdateChunks(progress_t *pProgress)
Apply all the gig file's current instruments, samples, groups and settings to the respective RIFF chu...
dimension_t
Defines the type of dimension, that is how the dimension zones (and thus how the dimension regions ar...
file_offset_t SamplesInLastFrame
For compressed samples only: length of the last sample frame.
uint32_t LoopEnd
Caution: Use the respective field in the DimensionRegion instead of this one! (Intended purpose: The ...
bool AttackCancel
Whether the "attack" stage is cancelled when receiving a note-off (default: true).
Different samples triggered each time a note is played, dimension regions selected in sequence...
dimension_def_t pDimensionDefinitions[8]
Defines the five (gig2) or eight (gig3) possible dimensions (the dimension's controller and number of...
uint8_t zones
Number of zones the dimension has.
Effect 5 Depth (MIDI Controller 95)
No release triggered sample(s) are played on sustain pedal up (default).
buffer_t GetCache()
Returns current cached sample points.
void SetVCFVelocityDynamicRange(uint8_t range)
Updates the respective member variable and the lookup table / cache that depends on this value...
vcf_cutoff_ctrl_t
Defines how the filter cutoff frequency is controlled by.
void Resize(file_offset_t NewSize)
Resize chunk.
Encapsulates sample waves of Gigasampler/GigaStudio files used for playback.
virtual void SetGain(int32_t gain)
Updates the respective member variable and updates SampleAttenuation which depends on this value...
List * AddSubList(uint32_t uiListType)
Creates a new list sub chunk.
Group(File *file, RIFF::Chunk *ck3gnm)
Constructor.
file_offset_t Read(void *pBuffer, file_offset_t SampleCount, buffer_t *pExternalDecompressionBuffer=NULL)
Reads SampleCount number of sample points from the current position into the buffer pointed by pBuffe...
virtual void UpdateChunks(progress_t *pProgress)
Apply all sample player options to the respective RIFF chunk.
dimension value between 0-127
virtual void UpdateChunks(progress_t *pProgress)
Apply dimension region settings to the respective RIFF chunks.
String Software
<ISFT-ck>. Identifies the name of the sofware package used to create the file.
String ArchivalLocation
<IARL-ck>. Indicates where the subject of the file is stored.
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
file_offset_t GetNewSize() const
New chunk size if it was modified with Resize(), otherwise value returned will be equal to GetSize()...
Encapsulates sample waves used for playback.
virtual void UpdateChunks(progress_t *pProgress)
Apply Instrument with all its Regions to the respective RIFF chunks.
type_t type
Controller type.
Sample * GetNextSample()
Returns a pointer to the next Sample object of the file, NULL otherwise.
uint controller_number
MIDI controller number if this controller is a control change controller, 0 otherwise.
uint8_t * VelocityTable
For velocity dimensions with custom defined zone ranges only: used for fast converting from velocity ...
void MoveSubChunk(Chunk *pSrc, Chunk *pDst)
Moves a sub chunk witin this list.
uint32_t SamplesPerSecond
Sampling rate at which each channel should be played (defaults to 44100 if Sample was created with In...
File * GetFile() const
Returns pointer to the chunk's File object.
A MIDI rule not yet implemented by libgig.
Sample * GetSample(uint index)
Returns Sample object of index.
size_t CountSubChunks()
Returns number of subchunks within the list (including list chunks).
Real-time instrument script (gig format extension).
bool SetMode(stream_mode_t NewMode)
Change file access mode.
void SetVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
Gigasampler/GigaStudio specific classes and definitions.
float __range_max
Only for internal usage, do not modify!
uint8_t DimensionUpperLimits[8]
gig3: defines the upper limit of the dimension values for this dimension region. In case you wondered...
virtual void CopyAssign(const DimensionRegion *orig)
Make a (semi) deep copy of the DimensionRegion object given by orig and assign it to this object...
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings and all its DimensionRegions to the respective RIFF chunks. ...
uint32_t LoopFraction
The fractional value specifies a fraction of a sample at which to loop. This allows a loop to be fine...
uint32_t TruncatedBits
For 24-bit compressed samples only: number of bits truncated during compression (0, 4 or 6)
Instrument * GetInstrument(uint index, progress_t *pProgress=NULL)
Returns the instrument with the given index.
void CopyAssignCore(const Sample *orig)
Make a deep copy of the Sample object given by orig (without the actual sample waveform data however)...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Group object.
Group of instrument scripts (gig format extension).
file_offset_t GetFilePos() const
Current, actual offset in file of current chunk data body read/write position.
Only internally controlled.
Provides convenient access to Gigasampler/GigaStudio .gig files.
void SetGroup(ScriptGroup *pGroup)
Move this script from its current ScriptGroup to another ScriptGroup given by pGroup.
lfo2_ctrl_t
Defines how LFO2 is controlled by.
Dimension for keyswitching.
MIDI rule for instruments with legato samples.
virtual ~Group()
Destructor.
void SetReleaseVelocityResponseDepth(uint8_t depth)
Updates the respective member variable and the lookup table / cache that depends on this value...
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
Sample * GetFirstSample()
Returns the first Sample of this Group.
dimension_def_t * GetDimensionDefinition(dimension_t type)
Searches in the current Region for a dimension of the given dimension type and returns the precise co...
bool VerifyWaveData(uint32_t *pActually=NULL)
Checks the integrity of this sample's raw audio wave data.
file_offset_t GetCurrentFileSize() const
Returns the current size of this file (in bytes) as it is currently yet stored on disk...
Provides all neccessary information for the synthesis of a DLS Instrument.
Provides access to a Gigasampler/GigaStudio instrument.
void SetScriptSlotBypassed(uint index, bool bBypass)
Defines whether execution shall be skipped.
void DeleteGroup(Group *pGroup)
Delete a group and its samples.
Encoding_t Encoding
Format the script's source code text is encoded with.
buffer_t RAMCache
Buffers samples (already uncompressed) in RAM.
virtual void CopyAssign(const Instrument *orig)
Make a (semi) deep copy of the Instrument object given by orig and assign it to this object...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Sample object.
String libraryName()
Returns the name of this C++ library.
Quadtuple version number ("major.minor.release.build").
bool Decay2Cancel
Whether the "decay 2" stage is cancelled when receiving a note-off (default: true).
void MoveTo(Instrument *dst)
Move this instrument at the position before.
uint32_t SamplePeriod
Specifies the duration of time that passes during the playback of one sample in nanoseconds (normally...
Script * GetScriptOfSlot(uint index)
Get instrument script (gig format extension).
void CopyAssign(const Script *orig)
Make a (semi) deep copy of the Script object given by orig and assign it to this object.
curve_type_t
Defines the shape of a function graph.
uint8_t bits
Number of "bits" (1 bit = 2 splits/zones, 2 bit = 4 splits/zones, 3 bit = 8 splits/zones,...).
file_offset_t GetPos() const
Position within the chunk data body (starting with 0).
No MIDI controller assigned for filter resonance.
virtual void SetKeyRange(uint16_t Low, uint16_t High)
Modifies the key range of this Region and makes sure the respective chunks are in correct order...
DLS specific classes and definitions.
Info * pInfo
Points (in any case) to an Info object, providing additional, optional infos and comments.
uint32_t Manufacturer
Specifies the MIDI Manufacturer's Association (MMA) Manufacturer code for the sampler intended to rec...
virtual void DeleteChunks()
Remove all RIFF chunks associated with this Region object.
file_offset_t ReadInt16(int16_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 16 Bit signed integer words and copies it into the buffer pointed by pData...
MIDI rule to automatically cycle through specified sequences of different articulations.
Reflects the current playback state for a sample.
void DeleteChunks()
Remove all RIFF chunks associated with this Script object.
General dimension definition.
void CopyAssignMeta(const Sample *orig)
Make a (semi) deep copy of the Sample object given by orig (without the actual waveform data) and ass...
No MIDI controller assigned for filter cutoff frequency.
split_type_t split_type
Intended for internal usage: will be used to convert a dimension value into the corresponding dimensi...
virtual void UpdateChunks(progress_t *pProgress)
Apply Region settings to the respective RIFF chunks.
void DeleteScript(Script *pScript)
Delete an instrument script.
If used sample has more than one channel (thus is not mono).
virtual void UpdateChunks(progress_t *pProgress)
Apply sample and its settings to the respective RIFF chunks.
void SetReleaseVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
file_offset_t ReadUint8(uint8_t *pData, file_offset_t WordCount=1)
Reads WordCount number of 8 Bit unsigned integer words and copies it into the buffer pointed by pData...
List * GetNextSubList()
Returns the next sublist (that is a subchunk with chunk ID "LIST") within the list.
Defines Region information of an Instrument.
Effect 4 Depth (MIDI Controller 94)
double GetVelocityAttenuation(uint8_t MIDIKeyVelocity)
Returns the correct amplitude factor for the given MIDIKeyVelocity.
Sample * GetSample()
Returns pointer address to the Sample referenced with this region.
void SetVelocityResponseCurve(curve_type_t curve)
Updates the respective member variable and the lookup table / cache that depends on this value...
Chunk * AddSubChunk(uint32_t uiChunkID, file_offset_t ullBodySize)
Creates a new sub chunk.
void DeleteScriptGroup(ScriptGroup *pGroup)
Delete an instrument script group.
Region * GetNextRegion()
Returns the next Region of the instrument.
virtual void UpdateChunks(progress_t *pProgress)
Apply all the DLS file's current instruments, samples and settings to the respective RIFF chunks...
virtual void UpdateFileOffsets()
Updates all file offsets stored all over the file.