@@ -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 ;
0 commit comments