Improve audio parsing performance.
- Improve the AudReader and WavReader by performing fewer, larger stream reads to consume bytes more efficiently. - Improve ImaAdpcmReader.LoadImaAdpcmSound by accepting an output buffer rather than allocating a new array. - Improve StreamExts.ReadAllBytes by using MemoryStream.CopyTo. This internally rents a much larger buffer from the array pool, allowing for fewer, larger stream reads.
This commit is contained in:
committed by
Gustas Kažukauskas
parent
b429ca7879
commit
8b8651dcf7
@@ -101,6 +101,7 @@ namespace OpenRA.Mods.Cnc.FileFormats
|
||||
{
|
||||
readonly int outputSize;
|
||||
int dataSize;
|
||||
byte[] inputBuffer;
|
||||
|
||||
int currentSample;
|
||||
int baseOffset;
|
||||
@@ -121,9 +122,12 @@ namespace OpenRA.Mods.Cnc.FileFormats
|
||||
return true;
|
||||
|
||||
var chunk = AudChunk.Read(baseStream);
|
||||
var input = EnsureArraySize(ref inputBuffer, chunk.CompressedSize);
|
||||
baseStream.ReadBytes(input);
|
||||
|
||||
for (var n = 0; n < chunk.CompressedSize; n++)
|
||||
{
|
||||
var b = baseStream.ReadUInt8();
|
||||
var b = input[n];
|
||||
|
||||
var t = ImaAdpcmReader.DecodeImaAdpcmSample(b, ref index, ref currentSample);
|
||||
data.Enqueue((byte)t);
|
||||
@@ -144,6 +148,13 @@ namespace OpenRA.Mods.Cnc.FileFormats
|
||||
|
||||
return dataSize <= 0;
|
||||
}
|
||||
|
||||
static Span<byte> EnsureArraySize(ref byte[] array, int desiredSize)
|
||||
{
|
||||
if (array == null || array.Length < desiredSize)
|
||||
array = new byte[desiredSize];
|
||||
return array.AsSpan(..desiredSize);
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WestwoodCompressedAudStream : ReadOnlyAdapterStream
|
||||
|
||||
@@ -225,23 +225,25 @@ namespace OpenRA.Mods.Cnc.FileFormats
|
||||
}
|
||||
}
|
||||
|
||||
static byte[] GetAudioData(bool compressed, MemoryStream audio, ref int adpcmIndex)
|
||||
{
|
||||
var audioArray = audio.ToArray();
|
||||
if (!compressed)
|
||||
return audioArray;
|
||||
|
||||
var result = new byte[audio.Length * 4];
|
||||
ImaAdpcmReader.LoadImaAdpcmSound(audioArray, ref adpcmIndex, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (AudioChannels == 1)
|
||||
AudioData = compressed ? ImaAdpcmReader.LoadImaAdpcmSound(audio1.ToArray(), ref adpcmIndex) : audio1.ToArray();
|
||||
AudioData = GetAudioData(compressed, audio1, ref adpcmIndex);
|
||||
else
|
||||
{
|
||||
byte[] leftData, rightData;
|
||||
if (!compressed)
|
||||
{
|
||||
leftData = audio1.ToArray();
|
||||
rightData = audio2.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
adpcmIndex = 0;
|
||||
leftData = ImaAdpcmReader.LoadImaAdpcmSound(audio1.ToArray(), ref adpcmIndex);
|
||||
adpcmIndex = 0;
|
||||
rightData = ImaAdpcmReader.LoadImaAdpcmSound(audio2.ToArray(), ref adpcmIndex);
|
||||
}
|
||||
adpcmIndex = 0;
|
||||
var leftData = GetAudioData(compressed, audio1, ref adpcmIndex);
|
||||
adpcmIndex = 0;
|
||||
var rightData = GetAudioData(compressed, audio2, ref adpcmIndex);
|
||||
|
||||
AudioData = new byte[rightData.Length + leftData.Length];
|
||||
var rightIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user