Skip to content

Commit 0bd67a6

Browse files
authored
4.11: ADX Loop Point Write Fix.
The offsets were swapped on the loop write function, fixed the order, also fixed the values written on these offsets to be the proper ones (tested lazily).
1 parent e1e339b commit 0bd67a6

File tree

4 files changed

+16
-20
lines changed

4 files changed

+16
-20
lines changed

CriCodecs/adx.cpp

+13-17
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,16 @@ struct ADXLoop{
9191
LoopEndSample = ReadUnsignedIntBE(data+12);
9292
LoopEndByte = ReadUnsignedIntBE(data+16);
9393
}
94-
void writeLoop(unsigned char* data, unsigned int AlignmentSamples, smplloop Loop, unsigned int BlockSize, unsigned int Index, unsigned int Channels, unsigned int HeaderSize){
95-
unsigned int DataBlockSize = BlockSize - 2;
94+
void writeLoop(unsigned char* data, unsigned int AlignmentSamples, smplloop Loop, unsigned int BlockSize, unsigned int Index, unsigned int Channels, unsigned int HeaderSize, unsigned int SamplesPerFrame){
9695
unsigned int start = Loop.Start + AlignmentSamples;
97-
unsigned int end = Loop.End + AlignmentSamples;
98-
start = ((start - (start % (DataBlockSize * Channels))) / (DataBlockSize * Channels)) * BlockSize * Channels + HeaderSize + (start % (DataBlockSize * Channels)) * Channels;
99-
end = ((end - (end % (DataBlockSize * Channels))) / (DataBlockSize * Channels)) * BlockSize * Channels + HeaderSize + (end % (DataBlockSize * Channels)) * Channels;
96+
unsigned int end = Loop.End + AlignmentSamples;
97+
start = HeaderSize + ((start / SamplesPerFrame) * BlockSize) * Channels;
98+
end = HeaderSize + GetNextMultiple(((end / SamplesPerFrame) * BlockSize + (end % SamplesPerFrame) / BlockSize), BlockSize) * Channels;
10099
WriteShortBE(data+0, Index);
101100
WriteShortBE(data+2, 1); /* Enable all loops. */
102101
WriteIntBE(data+4, Loop.Start + AlignmentSamples);
103-
WriteIntBE(data+8, Loop.End + AlignmentSamples);
104-
WriteIntBE(data+12, start);
102+
WriteIntBE(data+8, start);
103+
WriteIntBE(data+12, Loop.End + AlignmentSamples);
105104
WriteIntBE(data+16, end);
106105
}
107106
};
@@ -129,19 +128,16 @@ struct Loop{
129128
Loops[i].loadLoop(data+offset);
130129
return 0;
131130
}
132-
void writeLoops(unsigned char* data, unsigned int NumberOfLoops, unsigned int ChannelCount, smpl &PCMsmpl, unsigned int BlockSize, unsigned int HeaderSize){
131+
void writeLoops(unsigned char* data, unsigned int NumberOfLoops, unsigned int ChannelCount, smpl &PCMsmpl, unsigned int BlockSize, unsigned int SamplesPerFrame, unsigned int HeaderSize){
133132
LoopCount = NumberOfLoops;
134133
unsigned int start = PCMsmpl.Loops[0].Start;
135134
unsigned int SamplesInFrame = (BlockSize - 2) * 2;
136-
if(start % SamplesInFrame == 0)
137-
AlignmentSamples = start;
138-
else
139-
AlignmentSamples = start + (SamplesInFrame - start % SamplesInFrame) - start;
135+
AlignmentSamples = GetNextMultiple(start, ChannelCount == 1 ? SamplesInFrame * 2 : SamplesInFrame);
140136
WriteShortBE(data+0, AlignmentSamples);
141137
WriteShortBE(data+2, LoopCount);
142138
Loops = new ADXLoop[LoopCount]; /* From what I've seen, ADX doesn't support more than one loop, but this code is already generic as is, so I will allow more customizability. */
143139
for(unsigned int i = 0, offset = 4; i < LoopCount; i++, offset+=sizeof(ADXLoop)){
144-
Loops[i].writeLoop(data+offset, AlignmentSamples, PCMsmpl.Loops[i], BlockSize, i, ChannelCount, HeaderSize);
140+
Loops[i].writeLoop(data+offset, AlignmentSamples, PCMsmpl.Loops[i], BlockSize, i, ChannelCount, HeaderSize, SamplesPerFrame);
145141
}
146142
}
147143
};
@@ -363,6 +359,8 @@ struct ADX{
363359
void writeHeader(unsigned char*& AdxData, unsigned int HeaderSize, PCM &PCMMain, unsigned int BitDepth, unsigned int BlockSize, unsigned int EncodingMode, unsigned short HighpassFrequency, unsigned int SamplesPerChannel, unsigned int AdxVersion){
364360
Header.writeHeader(AdxData, HeaderSize-4, EncodingMode, BlockSize, BitDepth, PCMMain.wav.chunks.WAVEfmt.Channels, PCMMain.wav.chunks.WAVEfmt.SampleRate, SamplesPerChannel, EncodingMode == 2 ? 0 : HighpassFrequency, AdxVersion, 0);
365361
unsigned int BaseOffset = sizeof(ADXHeader);
362+
unsigned int FrameSizeBytes = (BlockSize - 2) * 8;
363+
unsigned int SamplesPerFrame = FrameSizeBytes / BitDepth;
366364

367365
if(AdxVersion == 0x04 || AdxVersion == 0x05){
368366
WriteIntBE(AdxData+BaseOffset, 0); /* Padding */
@@ -372,7 +370,7 @@ struct ADX{
372370
}
373371

374372
if(Looping){
375-
LoopPoints.writeLoops(AdxData+BaseOffset, PCMMain.wav.chunks.WAVEsmpl.NumberofSampleLoops, PCMMain.wav.chunks.WAVEfmt.Channels, PCMMain.wav.chunks.WAVEsmpl, BlockSize, HeaderSize);
373+
LoopPoints.writeLoops(AdxData+BaseOffset, PCMMain.wav.chunks.WAVEsmpl.NumberofSampleLoops, PCMMain.wav.chunks.WAVEfmt.Channels, PCMMain.wav.chunks.WAVEsmpl, BlockSize, SamplesPerFrame, HeaderSize);
376374
BaseOffset += 4 + (sizeof(ADXLoop) * PCMMain.wav.chunks.WAVEsmpl.NumberofSampleLoops);
377375
}
378376

@@ -451,8 +449,7 @@ struct ADX{
451449

452450
if(SamplesPerChannel % SamplesPerBlock != 0){
453451
unsigned int SamplesNeeded = GetNextMultiple(SamplesPerChannel, DataBlockSize) * ChannelCount;
454-
SamplesPerChannel = SamplesNeeded / ChannelCount;
455-
Frames = SamplesPerChannel / SamplesPerBlock;
452+
Frames = (SamplesNeeded / ChannelCount) / SamplesPerBlock;
456453
PCMData = new short[SamplesNeeded];
457454
own = true;
458455
memcpy(PCMData, PCMMain.Get_PCM16(), SampleCount * sizeof(short));
@@ -461,7 +458,6 @@ struct ADX{
461458
PCMData = PCMMain.Get_PCM16();
462459
Frames = SamplesPerChannel / SamplesPerBlock;
463460
}
464-
465461
Coefficients = new int[2];
466462
if(EncodingMode == 2){
467463
Coefficients[0] = (int)StaticCoefficients[Filter * 2 + 0];

CriCodecs/setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

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

PyCriCodecs/adx.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import CriCodecs
22

33
class ADX:
4-
"""ADX Modules for decoding and encoding ADX files, pass the either `adx file` or `wav file` in bytes to either `decode` or `encode` respectively."""
4+
"""ADX Module for decoding and encoding ADX files, pass the either `adx file` or `wav file` in bytes to either `decode` or `encode` respectively."""
55

66
# Decodes ADX to WAV.
77
def decode(data: bytes) -> bytes:

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name="PyCriCodecs",
6-
version="0.4.9",
6+
version="0.4.11",
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)