Skip to content

Commit e1e339b

Browse files
authored
PCM and ADX bug fixes.
1 parent a228c43 commit e1e339b

File tree

3 files changed

+38
-10
lines changed

3 files changed

+38
-10
lines changed

CriCodecs/adx.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,19 @@ struct Loop{
110110
unsigned short AlignmentSamples;
111111
unsigned short LoopCount;
112112
ADXLoop *Loops;
113+
Loop(){
114+
Loops = NULL;
115+
}
116+
~Loop(){
117+
if(Loops != NULL)
118+
delete[] Loops;
119+
}
113120
char loadLoops(unsigned char* data, unsigned short &DataOffset, unsigned int &BaseOffset){
114121
AlignmentSamples = ReadUnsignedShortBE(data+0);
115122
LoopCount = ReadUnsignedShortBE(data+2);
116123
if(!LoopCount)
117124
return 0;
118-
else if(BaseOffset + 4 + (LoopCount * sizeof(ADXLoop)) <= DataOffset - 2)
125+
else if(BaseOffset + 4 + (LoopCount * sizeof(ADXLoop)) >= DataOffset - 2)
119126
return -8;
120127
Loops = new ADXLoop[LoopCount];
121128
for(unsigned int i = 0, offset = 4; i < LoopCount; i++, offset+=sizeof(ADXLoop))
@@ -266,6 +273,7 @@ struct ChannelFrame{
266273
History.Previous2 = Original2;
267274
for(unsigned int i = 0; i < SamplesPerBlock; i++)
268275
WriteBits(Samples[i]);
276+
delete[] Samples;
269277
}
270278
};
271279

@@ -278,10 +286,20 @@ struct ADX{
278286
unsigned int SamplesPerBlock;
279287
int *Coefficients;
280288
ChannelFrame *Channels;
289+
ADPCMHistory *History;
281290
short *PCMData;
282291
unsigned int size;
292+
ADX(){
293+
Coefficients = NULL;
294+
Channels = NULL;
295+
History = NULL;
296+
}
297+
~ADX(){
298+
if(Coefficients != NULL) delete[] Coefficients;
299+
if(Channels != NULL) delete[] Channels;
300+
if(History != NULL) delete[] History;
301+
}
283302
char loadHeader(unsigned char* data){
284-
ADPCMHistory *History;
285303
unsigned int BaseOffset = sizeof(ADXHeader);
286304
Header.loadHeader(data);
287305

@@ -367,10 +385,18 @@ struct ADX{
367385
return AdxErrorCode;
368386

369387
unsigned int BaseOffset = Header.DataOffset + 4;
370-
unsigned int Blocks = Header.SampleCount / SamplesPerBlock;
388+
unsigned int Blocks = ceilf((float)Header.SampleCount / (float)SamplesPerBlock);
371389
unsigned int HeaderSize = 44;
372390
BitReader Reader;
373391
CalculateCoefficients(Coefficients, Header.HighpassFrequency, Header.SampleRate);
392+
393+
if(Looping){
394+
wav.wav.chunks.Looping = 1;
395+
wav.wav.chunks.WAVEsmpl.Loops = new smplloop[1]; // Could be LoopPoints.LoopCount, but not really logical and the PCM module doesn't support it.
396+
wav.wav.chunks.WAVEsmpl.Loops[0].Start = LoopPoints.Loops[0].LoopStartSample;
397+
wav.wav.chunks.WAVEsmpl.Loops[0].End = LoopPoints.Loops[0].LoopEndSample;
398+
}
399+
wav.wav.chunks.WAVEdata.size = Header.SampleCount * Header.Channels * sizeof(short);
374400
wav.GetWaveBuffer(Header.SampleCount, Header.Channels, Header.SampleRate, Looping);
375401
PCMData = wav.PCM_16;
376402

@@ -421,12 +447,14 @@ struct ADX{
421447
BitsPerBlock = DataBlockSize * 8;
422448
SamplesPerBlock = BitsPerBlock / BitDepth;
423449
unsigned int SamplesPerChannel = SampleCount / ChannelCount, Frames, Blocks, HeaderSize;
450+
bool own = false;
424451

425452
if(SamplesPerChannel % SamplesPerBlock != 0){
426453
unsigned int SamplesNeeded = GetNextMultiple(SamplesPerChannel, DataBlockSize) * ChannelCount;
427454
SamplesPerChannel = SamplesNeeded / ChannelCount;
428455
Frames = SamplesPerChannel / SamplesPerBlock;
429456
PCMData = new short[SamplesNeeded];
457+
own = true;
430458
memcpy(PCMData, PCMMain.Get_PCM16(), SampleCount * sizeof(short));
431459
memset(PCMData+SampleCount, 0, (SamplesNeeded-SampleCount) * sizeof(short));
432460
}else{
@@ -454,7 +482,7 @@ struct ADX{
454482

455483
Blocks = Frames * ChannelCount;
456484
HeaderSize = sizeof(ADXHeader) + 6; /* 6 is CRIString length. */
457-
if(AdxVersion == 0x04 || AdxVersion == 0x5)
485+
if(AdxVersion == 0x04 || AdxVersion == 0x05)
458486
HeaderSize += (Header.Channels > 1 ? sizeof(ADPCMHistory) * Header.Channels : sizeof(ADPCMHistory) * 2);
459487
if(Looping)
460488
HeaderSize += 4 + PCMMain.wav.chunks.WAVEsmpl.NumberofSampleLoops * sizeof(ADXLoop);
@@ -476,17 +504,17 @@ struct ADX{
476504
memset(AdxData+BlocksOffset, 0, BlockSize);
477505
WriteShortBE(AdxData+BlocksOffset+0, 0x8001);
478506
WriteShortBE(AdxData+BlocksOffset+2, BlockSize - 4);
507+
508+
if(own) delete[] PCMData;
479509
return 0;
480510
}
481511
unsigned char* GetADX(PCM &PCMMain, unsigned int BitDepth = 4, unsigned int BlockSize = 0x12, unsigned int EncodingMode = 3, unsigned short HighpassFrequency = 500, unsigned int Filter = 0, unsigned int AdxVersion = 4, bool ForceNoLooping = 0){
482512
unsigned char *ADXData;
483513
AdxErrorCode = Encode(PCMMain, ADXData, BitDepth, BlockSize, EncodingMode, HighpassFrequency, Filter, AdxVersion, ForceNoLooping);
484514
return ADXData;
485515
}
486-
PCM GetWAVE(unsigned char* data){
487-
PCM PCMObject;
516+
void GetWAVE(unsigned char* data, PCM &PCMObject){
488517
AdxErrorCode = Decode(data, PCMObject);
489-
return PCMObject;
490518
}
491519
};
492520

@@ -523,7 +551,7 @@ static PyObject* AdxDecode(PyObject* self, PyObject* args){
523551
unsigned char* data = (unsigned char *)PyBytes_AsString(args);
524552
ADX adx;
525553
PCM wav;
526-
wav = adx.GetWAVE(data);
554+
adx.GetWAVE(data, wav);
527555
if(AdxErrorCode){
528556
PyAdxSetError(AdxErrorCode);
529557
return NULL;

CriCodecs/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
setup(
44
name="CriCodecs",
5-
version="0.2.4",
5+
version="0.2.5",
66
ext_modules=[Extension('CriCodecs', ["adx.cpp", "CriCodecs.cpp", "crilayla.cpp", "hca.cpp"])]
77
)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name="PyCriCodecs",
6-
version="0.4.8",
6+
version="0.4.9",
77
description="Python frontend with a C++ backend of managing Criware files of all kinds.",
88
packages=["PyCriCodecs"],
99
ext_modules=[Extension(

0 commit comments

Comments
 (0)