Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 0 additions & 33 deletions Codecs/Codec.ImaAdpcm/ImaAdpcmCodec.Encode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ public static partial class ImaAdpcmCodec {

private const int WaveHeaderBytesPerChannel = 4;
private const int WaveStereoGroupBytesPerChannel = 4;
private const int QuickTimePacketBytes = 34;
private const int QuickTimeSamplesPerPacket = 64;

/// <summary>
/// Encodes interleaved 16-bit PCM into Microsoft/IMA WAV ADPCM blocks.
Expand Down Expand Up @@ -132,35 +130,4 @@ private static void ValidateWaveLayout(ReadOnlySpan<short> interleaved, int chan

private static short GetSample(ReadOnlySpan<short> interleaved, int frames, int channels, int frame, int channel, short fallback)
=> frame < frames ? interleaved[frame * channels + channel] : fallback;

private static int StartIndexFor(int delta) {
var index = 0;
while (index < StepTable.Length - 1 && StepTable[index] < delta)
++index;
return index;
}

private static byte EncodeNibble(short sample, ref int predictor, ref int index) {
var step = StepTable[index];
var delta = (int)sample - predictor;
byte nibble = 0;
if (delta < 0) {
nibble = 8;
delta = -delta;
}

if (delta >= step) {
nibble |= 4;
delta -= step;
}
if (delta >= step >> 1) {
nibble |= 2;
delta -= step >> 1;
}
if (delta >= step >> 2)
nibble |= 1;

DecodeNibble(nibble, ref predictor, ref index);
return nibble;
}
}
17 changes: 8 additions & 9 deletions Codecs/Codec.MsAdpcm/MsAdpcmCodec.Encode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,18 @@ public static byte[] Encode(ReadOnlySpan<short> interleaved, int channels, int b
for (var i = 0; i < dataBytes; ++i) {
var frame = baseFrame + 2 + i * 2;
var highSample = GetSample(interleaved, frames, channels, frame, 0, (short)sample1[0]);
var high = EncodeNibble(highSample, ref predictorIndex[0], ref delta[0], ref sample1[0], ref sample2[0]);
var high = SearchNibble(highSample, predictorIndex[0], ref delta[0], ref sample1[0], ref sample2[0]);
var lowSample = GetSample(interleaved, frames, channels, frame + 1, 0, (short)sample1[0]);
var low = EncodeNibble(lowSample, ref predictorIndex[0], ref delta[0], ref sample1[0], ref sample2[0]);
var low = SearchNibble(lowSample, predictorIndex[0], ref delta[0], ref sample1[0], ref sample2[0]);
output[p + i] = (byte)(high << 4 | low);
}
} else {
for (var i = 0; i < dataBytes; ++i) {
var frame = baseFrame + 2 + i;
var leftSample = GetSample(interleaved, frames, channels, frame, 0, (short)sample1[0]);
var left = EncodeNibble(leftSample, ref predictorIndex[0], ref delta[0], ref sample1[0], ref sample2[0]);
var left = SearchNibble(leftSample, predictorIndex[0], ref delta[0], ref sample1[0], ref sample2[0]);
var rightSample = GetSample(interleaved, frames, channels, frame, 1, (short)sample1[1]);
var right = EncodeNibble(rightSample, ref predictorIndex[1], ref delta[1], ref sample1[1], ref sample2[1]);
var right = SearchNibble(rightSample, predictorIndex[1], ref delta[1], ref sample1[1], ref sample2[1]);
output[p + i] = (byte)(left << 4 | right);
}
}
Expand Down Expand Up @@ -130,7 +130,7 @@ private static void SelectInitialState(

for (var sampleIndex = 2; sampleIndex < lookAhead; ++sampleIndex) {
var target = GetSample(interleaved, frames, channels, baseFrame + sampleIndex, channel, (short)s1);
EncodeNibble(target, ref statePredictor, ref stateDelta, ref s1, ref s2);
SearchNibble(target, statePredictor, ref stateDelta, ref s1, ref s2);
var difference = (long)target - s1;
error += difference * difference;
if (error >= bestError)
Expand All @@ -151,16 +151,15 @@ private static void SelectInitialState(
private static short GetSample(ReadOnlySpan<short> interleaved, int frames, int channels, int frame, int channel, short fallback)
=> frame < frames ? interleaved[frame * channels + channel] : fallback;

private static int EncodeNibble(short sample, ref int predictorIndex, ref int delta, ref int sample1, ref int sample2) {
private static int SearchNibble(short sample, int predictorIndex, ref int delta, ref int sample1, ref int sample2) {
var bestNibble = 0;
var bestError = int.MaxValue;

for (var nibble = 0; nibble < 16; ++nibble) {
var testPredictorIndex = predictorIndex;
var testDelta = delta;
var testSample1 = sample1;
var testSample2 = sample2;
var reconstructed = DecodeNibble(nibble, ref testPredictorIndex, ref testDelta, ref testSample1, ref testSample2);
var reconstructed = DecodeNibble((byte)nibble, predictorIndex, ref testDelta, ref testSample1, ref testSample2);
var error = Math.Abs((int)sample - reconstructed);
if (error >= bestError)
continue;
Expand All @@ -170,7 +169,7 @@ private static int EncodeNibble(short sample, ref int predictorIndex, ref int de
break;
}

DecodeNibble(bestNibble, ref predictorIndex, ref delta, ref sample1, ref sample2);
DecodeNibble((byte)bestNibble, predictorIndex, ref delta, ref sample1, ref sample2);
return bestNibble;
}
}