--- libgig/trunk/src/gig.cpp 2006/05/14 07:15:38 864
+++ libgig/trunk/src/gig.cpp 2006/10/24 19:32:47 928
@@ -111,6 +111,13 @@
return x & 0x800000 ? x - 0x1000000 : x;
}
+ inline void store24(unsigned char* pDst, int x)
+ {
+ pDst[0] = x;
+ pDst[1] = x >> 8;
+ pDst[2] = x >> 16;
+ }
+
void Decompress16(int compressionmode, const unsigned char* params,
int srcStep, int dstStep,
const unsigned char* pSrc, int16_t* pDst,
@@ -150,14 +157,11 @@
}
void Decompress24(int compressionmode, const unsigned char* params,
- int dstStep, const unsigned char* pSrc, int16_t* pDst,
+ int dstStep, const unsigned char* pSrc, uint8_t* pDst,
unsigned long currentframeoffset,
unsigned long copysamples, int truncatedBits)
{
- // Note: The 24 bits are truncated to 16 bits for now.
-
int y, dy, ddy, dddy;
- const int shift = 8 - truncatedBits;
#define GET_PARAMS(params) \
y = get24(params); \
@@ -173,14 +177,14 @@
#define COPY_ONE(x) \
SKIP_ONE(x); \
- *pDst = y >> shift; \
+ store24(pDst, y << truncatedBits); \
pDst += dstStep
switch (compressionmode) {
case 2: // 24 bit uncompressed
pSrc += currentframeoffset * 3;
while (copysamples) {
- *pDst = get24(pSrc) >> shift;
+ store24(pDst, get24(pSrc) << truncatedBits);
pDst += dstStep;
pSrc += 3;
copysamples--;
@@ -275,6 +279,7 @@
* is located, 0 otherwise
*/
Sample::Sample(File* pFile, RIFF::List* waveList, unsigned long WavePoolOffset, unsigned long fileNo) : DLS::Sample((DLS::File*) pFile, waveList, WavePoolOffset) {
+ pInfo->UseFixedLengthStrings = true;
Instances++;
FileNo = fileNo;
@@ -307,7 +312,7 @@
// use default values
Manufacturer = 0;
Product = 0;
- SamplePeriod = 1 / SamplesPerSecond;
+ SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
MIDIUnityNote = 64;
FineTune = 0;
SMPTEOffset = 0;
@@ -371,7 +376,7 @@
if (!pCkSmpl) pCkSmpl = pWaveList->AddSubChunk(CHUNK_ID_SMPL, 60);
// update 'smpl' chunk
uint8_t* pData = (uint8_t*) pCkSmpl->LoadChunkData();
- SamplePeriod = 1 / SamplesPerSecond;
+ SamplePeriod = uint32_t(1000000000.0 / SamplesPerSecond + 0.5);
memcpy(&pData[0], &Manufacturer, 4);
memcpy(&pData[4], &Product, 4);
memcpy(&pData[8], &SamplePeriod, 4);
@@ -891,6 +896,10 @@
* have to use an external decompression buffer for EACH
* streaming thread to avoid race conditions and crashes!
*
+ * For 16 bit samples, the data in the buffer will be int16_t
+ * (using native endianness). For 24 bit, the buffer will
+ * contain three bytes per sample, little-endian.
+ *
* @param pBuffer destination buffer
* @param SampleCount number of sample points to read
* @param pExternalDecompressionBuffer (optional) external buffer to use for decompression
@@ -901,27 +910,7 @@
if (SampleCount == 0) return 0;
if (!Compressed) {
if (BitDepth == 24) {
- // 24 bit sample. For now just truncate to 16 bit.
- unsigned char* pSrc = (unsigned char*) ((pExternalDecompressionBuffer) ? pExternalDecompressionBuffer->pStart : this->InternalDecompressionBuffer.pStart);
- int16_t* pDst = static_cast(pBuffer);
- if (Channels == 2) { // Stereo
- unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 6, 1);
- pSrc++;
- for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
- *pDst++ = get16(pSrc);
- pSrc += 3;
- }
- return (pDst - static_cast(pBuffer)) >> 1;
- }
- else { // Mono
- unsigned long readBytes = pCkData->Read(pSrc, SampleCount * 3, 1);
- pSrc++;
- for (unsigned long i = readBytes ; i > 0 ; i -= 3) {
- *pDst++ = get16(pSrc);
- pSrc += 3;
- }
- return pDst - static_cast(pBuffer);
- }
+ return pCkData->Read(pBuffer, SampleCount * FrameSize, 1) / FrameSize;
}
else { // 16 bit
// (pCkData->Read does endian correction)
@@ -951,6 +940,7 @@
unsigned char* pSrc = (unsigned char*) pDecompressionBuffer->pStart;
int16_t* pDst = static_cast(pBuffer);
+ uint8_t* pDst24 = static_cast(pBuffer);
remainingbytes = pCkData->Read(pSrc, assumedsize, 1);
while (remainingsamples && remainingbytes) {
@@ -1032,16 +1022,16 @@
const unsigned char* const param_r = pSrc;
if (mode_r != 2) pSrc += 12;
- Decompress24(mode_l, param_l, 2, pSrc, pDst,
+ Decompress24(mode_l, param_l, 6, pSrc, pDst24,
skipsamples, copysamples, TruncatedBits);
- Decompress24(mode_r, param_r, 2, pSrc + rightChannelOffset, pDst + 1,
+ Decompress24(mode_r, param_r, 6, pSrc + rightChannelOffset, pDst24 + 3,
skipsamples, copysamples, TruncatedBits);
- pDst += copysamples << 1;
+ pDst24 += copysamples * 6;
}
else { // Mono
- Decompress24(mode_l, param_l, 1, pSrc, pDst,
+ Decompress24(mode_l, param_l, 3, pSrc, pDst24,
skipsamples, copysamples, TruncatedBits);
- pDst += copysamples;
+ pDst24 += copysamples * 3;
}
}
else { // 16 bit
@@ -1177,7 +1167,7 @@
RIFF::Chunk* _3ewa = _3ewl->GetSubChunk(CHUNK_ID_3EWA);
if (_3ewa) { // if '3ewa' chunk exists
- _3ewa->ReadInt32(); // unknown, always 0x0000008C ?
+ _3ewa->ReadInt32(); // unknown, always == chunk size ?
LFO3Frequency = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
EG3Attack = (double) GIG_EXP_DECODE(_3ewa->ReadInt32());
_3ewa->ReadInt16(); // unknown
@@ -1457,104 +1447,104 @@
// update '3ewa' chunk with DimensionRegion's current settings
- const uint32_t unknown = 0x0000008C; // unknown, always 0x0000008C ?
+ const uint32_t unknown = _3ewa->GetSize(); // unknown, always chunk size ?
memcpy(&pData[0], &unknown, 4);
const int32_t lfo3freq = (int32_t) GIG_EXP_ENCODE(LFO3Frequency);
memcpy(&pData[4], &lfo3freq, 4);
const int32_t eg3attack = (int32_t) GIG_EXP_ENCODE(EG3Attack);
- memcpy(&pData[4], &eg3attack, 4);
+ memcpy(&pData[8], &eg3attack, 4);
// next 2 bytes unknown
- memcpy(&pData[10], &LFO1InternalDepth, 2);
+ memcpy(&pData[14], &LFO1InternalDepth, 2);
// next 2 bytes unknown
- memcpy(&pData[14], &LFO3InternalDepth, 2);
+ memcpy(&pData[18], &LFO3InternalDepth, 2);
// next 2 bytes unknown
- memcpy(&pData[18], &LFO1ControlDepth, 2);
+ memcpy(&pData[22], &LFO1ControlDepth, 2);
// next 2 bytes unknown
- memcpy(&pData[22], &LFO3ControlDepth, 2);
+ memcpy(&pData[26], &LFO3ControlDepth, 2);
const int32_t eg1attack = (int32_t) GIG_EXP_ENCODE(EG1Attack);
- memcpy(&pData[24], &eg1attack, 4);
+ memcpy(&pData[28], &eg1attack, 4);
const int32_t eg1decay1 = (int32_t) GIG_EXP_ENCODE(EG1Decay1);
- memcpy(&pData[28], &eg1decay1, 4);
+ memcpy(&pData[32], &eg1decay1, 4);
// next 2 bytes unknown
- memcpy(&pData[34], &EG1Sustain, 2);
+ memcpy(&pData[38], &EG1Sustain, 2);
const int32_t eg1release = (int32_t) GIG_EXP_ENCODE(EG1Release);
- memcpy(&pData[36], &eg1release, 4);
+ memcpy(&pData[40], &eg1release, 4);
const uint8_t eg1ctl = (uint8_t) EncodeLeverageController(EG1Controller);
- memcpy(&pData[40], &eg1ctl, 1);
+ memcpy(&pData[44], &eg1ctl, 1);
const uint8_t eg1ctrloptions =
(EG1ControllerInvert) ? 0x01 : 0x00 |
GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG1ControllerAttackInfluence) |
GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG1ControllerDecayInfluence) |
GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG1ControllerReleaseInfluence);
- memcpy(&pData[41], &eg1ctrloptions, 1);
+ memcpy(&pData[45], &eg1ctrloptions, 1);
const uint8_t eg2ctl = (uint8_t) EncodeLeverageController(EG2Controller);
- memcpy(&pData[42], &eg2ctl, 1);
+ memcpy(&pData[46], &eg2ctl, 1);
const uint8_t eg2ctrloptions =
(EG2ControllerInvert) ? 0x01 : 0x00 |
GIG_EG_CTR_ATTACK_INFLUENCE_ENCODE(EG2ControllerAttackInfluence) |
GIG_EG_CTR_DECAY_INFLUENCE_ENCODE(EG2ControllerDecayInfluence) |
GIG_EG_CTR_RELEASE_INFLUENCE_ENCODE(EG2ControllerReleaseInfluence);
- memcpy(&pData[43], &eg2ctrloptions, 1);
+ memcpy(&pData[47], &eg2ctrloptions, 1);
const int32_t lfo1freq = (int32_t) GIG_EXP_ENCODE(LFO1Frequency);
- memcpy(&pData[44], &lfo1freq, 4);
+ memcpy(&pData[48], &lfo1freq, 4);
const int32_t eg2attack = (int32_t) GIG_EXP_ENCODE(EG2Attack);
- memcpy(&pData[48], &eg2attack, 4);
+ memcpy(&pData[52], &eg2attack, 4);
const int32_t eg2decay1 = (int32_t) GIG_EXP_ENCODE(EG2Decay1);
- memcpy(&pData[52], &eg2decay1, 4);
+ memcpy(&pData[56], &eg2decay1, 4);
// next 2 bytes unknown
- memcpy(&pData[58], &EG2Sustain, 2);
+ memcpy(&pData[62], &EG2Sustain, 2);
const int32_t eg2release = (int32_t) GIG_EXP_ENCODE(EG2Release);
- memcpy(&pData[60], &eg2release, 4);
+ memcpy(&pData[64], &eg2release, 4);
// next 2 bytes unknown
- memcpy(&pData[66], &LFO2ControlDepth, 2);
+ memcpy(&pData[70], &LFO2ControlDepth, 2);
const int32_t lfo2freq = (int32_t) GIG_EXP_ENCODE(LFO2Frequency);
- memcpy(&pData[68], &lfo2freq, 4);
+ memcpy(&pData[72], &lfo2freq, 4);
// next 2 bytes unknown
- memcpy(&pData[72], &LFO2InternalDepth, 2);
+ memcpy(&pData[78], &LFO2InternalDepth, 2);
const int32_t eg1decay2 = (int32_t) (EG1InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG1Decay2);
- memcpy(&pData[74], &eg1decay2, 4);
+ memcpy(&pData[80], &eg1decay2, 4);
// next 2 bytes unknown
- memcpy(&pData[80], &EG1PreAttack, 2);
+ memcpy(&pData[86], &EG1PreAttack, 2);
const int32_t eg2decay2 = (int32_t) (EG2InfiniteSustain) ? 0x7fffffff : (int32_t) GIG_EXP_ENCODE(EG2Decay2);
- memcpy(&pData[82], &eg2decay2, 4);
+ memcpy(&pData[88], &eg2decay2, 4);
// next 2 bytes unknown
- memcpy(&pData[88], &EG2PreAttack, 2);
+ memcpy(&pData[94], &EG2PreAttack, 2);
{
if (VelocityResponseDepth > 4) throw Exception("VelocityResponseDepth must be between 0 and 4");
@@ -1572,7 +1562,7 @@
default:
throw Exception("Could not update DimensionRegion's chunk, unknown VelocityResponseCurve selected");
}
- memcpy(&pData[90], &velocityresponse, 1);
+ memcpy(&pData[96], &velocityresponse, 1);
}
{
@@ -1591,16 +1581,16 @@
default:
throw Exception("Could not update DimensionRegion's chunk, unknown ReleaseVelocityResponseCurve selected");
}
- memcpy(&pData[91], &releasevelocityresponse, 1);
+ memcpy(&pData[97], &releasevelocityresponse, 1);
}
- memcpy(&pData[92], &VelocityResponseCurveScaling, 1);
+ memcpy(&pData[98], &VelocityResponseCurveScaling, 1);
- memcpy(&pData[93], &AttenuationControllerThreshold, 1);
+ memcpy(&pData[99], &AttenuationControllerThreshold, 1);
// next 4 bytes unknown
- memcpy(&pData[98], &SampleStartOffset, 2);
+ memcpy(&pData[104], &SampleStartOffset, 2);
// next 2 bytes unknown
@@ -1619,14 +1609,14 @@
default:
throw Exception("Could not update DimensionRegion's chunk, unknown DimensionBypass selected");
}
- memcpy(&pData[102], &pitchTrackDimensionBypass, 1);
+ memcpy(&pData[108], &pitchTrackDimensionBypass, 1);
}
const uint8_t pan = (Pan >= 0) ? Pan : ((-Pan) + 63); // signed 8 bit -> signed 7 bit
- memcpy(&pData[103], &pan, 1);
+ memcpy(&pData[109], &pan, 1);
const uint8_t selfmask = (SelfMask) ? 0x01 : 0x00;
- memcpy(&pData[104], &selfmask, 1);
+ memcpy(&pData[110], &selfmask, 1);
// next byte unknown
@@ -1635,18 +1625,18 @@
if (LFO3Sync) lfo3ctrl |= 0x20; // bit 5
if (InvertAttenuationController) lfo3ctrl |= 0x80; // bit 7
if (VCFType == vcf_type_lowpassturbo) lfo3ctrl |= 0x40; // bit 6
- memcpy(&pData[106], &lfo3ctrl, 1);
+ memcpy(&pData[112], &lfo3ctrl, 1);
}
const uint8_t attenctl = EncodeLeverageController(AttenuationController);
- memcpy(&pData[107], &attenctl, 1);
+ memcpy(&pData[113], &attenctl, 1);
{
uint8_t lfo2ctrl = LFO2Controller & 0x07; // lower 3 bits
if (LFO2FlipPhase) lfo2ctrl |= 0x80; // bit 7
if (LFO2Sync) lfo2ctrl |= 0x20; // bit 5
if (VCFResonanceController != vcf_res_ctrl_none) lfo2ctrl |= 0x40; // bit 6
- memcpy(&pData[108], &lfo2ctrl, 1);
+ memcpy(&pData[114], &lfo2ctrl, 1);
}
{
@@ -1655,64 +1645,64 @@
if (LFO1Sync) lfo1ctrl |= 0x40; // bit 6
if (VCFResonanceController != vcf_res_ctrl_none)
lfo1ctrl |= GIG_VCF_RESONANCE_CTRL_ENCODE(VCFResonanceController);
- memcpy(&pData[109], &lfo1ctrl, 1);
+ memcpy(&pData[115], &lfo1ctrl, 1);
}
const uint16_t eg3depth = (EG3Depth >= 0) ? EG3Depth
: uint16_t(((-EG3Depth) - 1) ^ 0xffff); /* binary complementary for negatives */
- memcpy(&pData[110], &eg3depth, 1);
+ memcpy(&pData[116], &eg3depth, 1);
// next 2 bytes unknown
const uint8_t channeloffset = ChannelOffset * 4;
- memcpy(&pData[113], &channeloffset, 1);
+ memcpy(&pData[120], &channeloffset, 1);
{
uint8_t regoptions = 0;
if (MSDecode) regoptions |= 0x01; // bit 0
if (SustainDefeat) regoptions |= 0x02; // bit 1
- memcpy(&pData[114], ®options, 1);
+ memcpy(&pData[121], ®options, 1);
}
// next 2 bytes unknown
- memcpy(&pData[117], &VelocityUpperLimit, 1);
+ memcpy(&pData[124], &VelocityUpperLimit, 1);
// next 3 bytes unknown
- memcpy(&pData[121], &ReleaseTriggerDecay, 1);
+ memcpy(&pData[128], &ReleaseTriggerDecay, 1);
// next 2 bytes unknown
const uint8_t eg1hold = (EG1Hold) ? 0x80 : 0x00; // bit 7
- memcpy(&pData[124], &eg1hold, 1);
+ memcpy(&pData[131], &eg1hold, 1);
const uint8_t vcfcutoff = (VCFEnabled) ? 0x80 : 0x00 | /* bit 7 */
- (VCFCutoff) ? 0x7f : 0x00; /* lower 7 bits */
- memcpy(&pData[125], &vcfcutoff, 1);
+ (VCFCutoff & 0x7f); /* lower 7 bits */
+ memcpy(&pData[132], &vcfcutoff, 1);
- memcpy(&pData[126], &VCFCutoffController, 1);
+ memcpy(&pData[133], &VCFCutoffController, 1);
const uint8_t vcfvelscale = (VCFCutoffControllerInvert) ? 0x80 : 0x00 | /* bit 7 */
- (VCFVelocityScale) ? 0x7f : 0x00; /* lower 7 bits */
- memcpy(&pData[127], &vcfvelscale, 1);
+ (VCFVelocityScale & 0x7f); /* lower 7 bits */
+ memcpy(&pData[134], &vcfvelscale, 1);
// next byte unknown
const uint8_t vcfresonance = (VCFResonanceDynamic) ? 0x00 : 0x80 | /* bit 7 */
- (VCFResonance) ? 0x7f : 0x00; /* lower 7 bits */
- memcpy(&pData[129], &vcfresonance, 1);
+ (VCFResonance & 0x7f); /* lower 7 bits */
+ memcpy(&pData[136], &vcfresonance, 1);
const uint8_t vcfbreakpoint = (VCFKeyboardTracking) ? 0x80 : 0x00 | /* bit 7 */
- (VCFKeyboardTrackingBreakpoint) ? 0x7f : 0x00; /* lower 7 bits */
- memcpy(&pData[130], &vcfbreakpoint, 1);
+ (VCFKeyboardTrackingBreakpoint & 0x7f); /* lower 7 bits */
+ memcpy(&pData[137], &vcfbreakpoint, 1);
const uint8_t vcfvelocity = VCFVelocityDynamicRange % 5 |
VCFVelocityCurve * 5;
- memcpy(&pData[131], &vcfvelocity, 1);
+ memcpy(&pData[138], &vcfvelocity, 1);
const uint8_t vcftype = (VCFType == vcf_type_lowpassturbo) ? vcf_type_lowpass : VCFType;
- memcpy(&pData[132], &vcftype, 1);
+ memcpy(&pData[139], &vcftype, 1);
}
// get the corresponding velocity table from the table map or create & calculate that table if it doesn't exist yet
@@ -2054,6 +2044,8 @@
// *
Region::Region(Instrument* pInstrument, RIFF::List* rgnList) : DLS::Region((DLS::Instrument*) pInstrument, rgnList) {
+ pInfo->UseFixedLengthStrings = true;
+
// Initialization
Dimensions = 0;
for (int i = 0; i < 256; i++) {
@@ -2119,8 +2111,9 @@
// load sample references
for (uint i = 0; i < DimensionRegions; i++) {
uint32_t wavepoolindex = _3lnk->ReadUint32();
- pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
+ if (file->pWavePoolTable) pDimensionRegions[i]->pSample = GetSampleFromWavePool(wavepoolindex);
}
+ GetSample(); // load global region sample reference
}
// make sure there is at least one dimension region
@@ -2164,11 +2157,12 @@
// update dimension definitions in '3lnk' chunk
uint8_t* pData = (uint8_t*) _3lnk->LoadChunkData();
+ memcpy(&pData[0], &DimensionRegions, 4);
for (int i = 0; i < iMaxDimensions; i++) {
- pData[i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
- pData[i * 8 + 1] = pDimensionDefinitions[i].bits;
+ pData[4 + i * 8] = (uint8_t) pDimensionDefinitions[i].dimension;
+ pData[5 + i * 8] = pDimensionDefinitions[i].bits;
// next 2 bytes unknown
- pData[i * 8 + 4] = pDimensionDefinitions[i].zones;
+ pData[8 + i * 8] = pDimensionDefinitions[i].zones;
// next 3 bytes unknown
}
@@ -2497,12 +2491,13 @@
Sample* Region::GetSampleFromWavePool(unsigned int WavePoolTableIndex, progress_t* pProgress) {
if ((int32_t)WavePoolTableIndex == -1) return NULL;
File* file = (File*) GetParent()->GetParent();
+ if (!file->pWavePoolTable) return NULL;
unsigned long soughtoffset = file->pWavePoolTable[WavePoolTableIndex];
unsigned long soughtfileno = file->pWavePoolTableHi[WavePoolTableIndex];
Sample* sample = file->GetFirstSample(pProgress);
while (sample) {
if (sample->ulWavePoolOffset == soughtoffset &&
- sample->FileNo == soughtfileno) return static_cast(pSample = sample);
+ sample->FileNo == soughtfileno) return static_cast(sample);
sample = file->GetNextSample();
}
return NULL;
@@ -2514,6 +2509,8 @@
// *
Instrument::Instrument(File* pFile, RIFF::List* insList, progress_t* pProgress) : DLS::Instrument((DLS::File*)pFile, insList) {
+ pInfo->UseFixedLengthStrings = true;
+
// Initialization
for (int i = 0; i < 128; i++) RegionKeyTable[i] = NULL;
@@ -2676,9 +2673,11 @@
// *
File::File() : DLS::File() {
+ pInfo->UseFixedLengthStrings = true;
}
File::File(RIFF::File* pRIFF) : DLS::File(pRIFF) {
+ pInfo->UseFixedLengthStrings = true;
}
Sample* File::GetFirstSample(progress_t* pProgress) {