mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-26 23:24:00 +08:00
added some unfinished implementations.
This commit is contained in:
parent
fa923207e9
commit
ba30cd2a57
59
ArcFormats/CsWare/AudioAF2.cs
Normal file
59
ArcFormats/CsWare/AudioAF2.cs
Normal file
@ -0,0 +1,59 @@
|
||||
//! \file AudioAF2.cs
|
||||
//! \date 2018 Mar 26
|
||||
//! \brief CsWare audio format.
|
||||
//
|
||||
// Copyright (C) 2018 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.CsWare
|
||||
{
|
||||
[Export(typeof(AudioFormat))]
|
||||
public sealed class Af2Audio : AudioFormat
|
||||
{
|
||||
public override string Tag { get { return "AF2"; } }
|
||||
public override string Description { get { return "CsWare audio format"; } }
|
||||
public override uint Signature { get { return 0x32714661; } } // 'aFq2'
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public Af2Audio ()
|
||||
{
|
||||
Extensions = new string[] { "af2", "pmd" };
|
||||
}
|
||||
|
||||
public override SoundInput TryOpen (IBinaryStream file)
|
||||
{
|
||||
var header = file.ReadHeader (0x20);
|
||||
var format = new WaveFormat {
|
||||
FormatTag = 1,
|
||||
SamplesPerSecond = BigEndian.ToUInt32 (header, 4),
|
||||
Channels = BigEndian.ToUInt16 (header, 8),
|
||||
BitsPerSample = BigEndian.ToUInt16 (header, 10),
|
||||
};
|
||||
format.BlockAlign = (ushort)(format.SamplesPerSecond * format.BitsPerSample / 8);
|
||||
format.SetBPS();
|
||||
}
|
||||
}
|
||||
}
|
348
ArcFormats/Entis/AudioEMS.cs
Normal file
348
ArcFormats/Entis/AudioEMS.cs
Normal file
@ -0,0 +1,348 @@
|
||||
//! \file AudioEMS.cs
|
||||
//! \date 2018 Mar 09
|
||||
//! \brief EMSAC audio format.
|
||||
//
|
||||
// Copyright (C) 2018 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Entis
|
||||
{
|
||||
internal class EmsacSoundInfo
|
||||
{
|
||||
public int Version; // field_00
|
||||
public CvType Transformation; // field_04
|
||||
public EriCode Architecture; // field_08
|
||||
public int ChannelCount; // field_0C
|
||||
public uint SamplesPerSec; // field_10
|
||||
public uint BlocksetCount; // field_14
|
||||
public int SubbandDegree; // field_18
|
||||
public int AllSampleCount; // field_1C
|
||||
public int LappedDegree; // field_20
|
||||
}
|
||||
|
||||
[Export(typeof(AudioFormat))]
|
||||
public sealed class EmsAudio : AudioFormat
|
||||
{
|
||||
public override string Tag { get { return "EMS"; } }
|
||||
public override string Description { get { return "EMSAC compressed audio format"; } }
|
||||
public override uint Signature { get { return 0x69746E45; } } // 'Entis'
|
||||
|
||||
public override SoundInput TryOpen (IBinaryStream file)
|
||||
{
|
||||
var header = file.ReadHeader (0x40);
|
||||
if (0x02000200 != header.ToUInt32 (8))
|
||||
return null;
|
||||
if (!header.AsciiEqual (0x10, "EMSAC-Sound-2"))
|
||||
return null;
|
||||
var decoder = new EmsacDecoder (file);
|
||||
var pcm = decoder.Decode();
|
||||
var sound = new RawPcmInput (pcm, decoder.Format);
|
||||
file.Dispose();
|
||||
return sound;
|
||||
}
|
||||
}
|
||||
|
||||
internal class EmsacDecoder
|
||||
{
|
||||
Stream m_input;
|
||||
EmsacSoundInfo m_info;
|
||||
long m_stream_pos;
|
||||
WaveFormat m_format;
|
||||
|
||||
public WaveFormat Format { get { return m_format; } }
|
||||
|
||||
const ushort BitsPerSample = 16;
|
||||
|
||||
public EmsacDecoder (IBinaryStream input)
|
||||
{
|
||||
m_input = input.AsStream;
|
||||
}
|
||||
|
||||
public Stream Decode ()
|
||||
{
|
||||
m_input.Position = 0x40;
|
||||
using (var erif = new EriFile (m_input))
|
||||
{
|
||||
ReadHeader (erif);
|
||||
int total_bytes = m_info.AllSampleCount * BitsPerSample / 8;
|
||||
var output = new MemoryStream (total_bytes);
|
||||
try
|
||||
{
|
||||
var buffer = new byte[0x10000];
|
||||
var decoded = new byte[0x10000];
|
||||
erif.BaseStream.Position = m_stream_pos;
|
||||
while (total_bytes > 0)
|
||||
{
|
||||
var section = erif.ReadSection();
|
||||
if (section.Id != "SoundStm")
|
||||
break;
|
||||
int stm_length = (int)section.Length;
|
||||
if (stm_length > buffer.Length)
|
||||
buffer = new byte[stm_length];
|
||||
erif.Read (m_buffer, 0, stm_length);
|
||||
int length = m_buffer.ToInt32 (4) * m_lappedSubband;
|
||||
if (length > decoded.Length)
|
||||
decoded = new byte[length];
|
||||
|
||||
DecodeBlock (buffer, decoded);
|
||||
length = Math.Min (length, total_bytes);
|
||||
output.Write (decoded, 0, length);
|
||||
total_bytes -= length;
|
||||
}
|
||||
}
|
||||
catch (EndOfStreamException) { /* ignore EOF errors */ }
|
||||
output.Position = 0;
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
void DecodeBlock (byte[] input, byte[] output)
|
||||
{
|
||||
if (m_exp.Version > 0x20100)
|
||||
throw new InvalidFormatException ("Not supported EMSAC version.");
|
||||
int channels = m_exp.ChannelCount;
|
||||
if (0 == channels || channels > 2)
|
||||
throw new InvalidFormatException ("Invalid number of channels.");
|
||||
int subband_degree = 0;
|
||||
int v84 = 1;
|
||||
bool use_dct = 0 != (m_exp.Transformation & 1);
|
||||
if (use_dct)
|
||||
{
|
||||
subband_degree = m_exp.SubbandDegree;
|
||||
v84 <<= subband_degree;
|
||||
}
|
||||
int subband = 1 << subband_degree;
|
||||
int sample_count = input.ToInt32 (4);
|
||||
int samples_per_channel = sample_count / channels;
|
||||
if (0 == samples_per_channel)
|
||||
throw new InvalidFormatException ("Invalid number of samples.");
|
||||
int v85 = samples_per_channel;
|
||||
var v73 = new int[channels][];
|
||||
var v75 = new int[subband]; // workBuf
|
||||
var v74 = new int[subband]; // weightTable
|
||||
var v13 = new int[subband * channels]; // internalBuf
|
||||
var sampleBuf = new short[sample_count];
|
||||
for (int i = 0; i < channels; ++i)
|
||||
{
|
||||
v73[i] = new int[subband];
|
||||
}
|
||||
int dst = 0;
|
||||
int src = 8;
|
||||
int v77 = src + sample_count;
|
||||
object sym_table;
|
||||
var v16 = CreateDecoderSymbolTable (input, v77, out sym_table);
|
||||
for (int i = 0; i < samples_per_channel; ++i)
|
||||
{
|
||||
for (int c = 0; c < channels; ++c)
|
||||
{
|
||||
var v72 = v73[c];
|
||||
int v19 = DecodeSymbols (v16, sym_table, v75, subband);
|
||||
if (v19 < subband)
|
||||
throw new InvalidFormatException();
|
||||
byte code = input[src++];
|
||||
InverseQuantumize (v74, v75, subband, code);
|
||||
if (use_dct)
|
||||
{
|
||||
InverseDCT (v72, v74, 2, subband_degree);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer.BlockCopy (v74, v72, 4 * subband);
|
||||
}
|
||||
}
|
||||
int cur_pos = dst;
|
||||
for (int c = 0; c < channels; ++c)
|
||||
{
|
||||
int pos = cur_pos;
|
||||
var v32 = v73[c];
|
||||
for (int i = 0; i < subband; ++i)
|
||||
{
|
||||
int v34 = v32[i];
|
||||
int v35 = v34;
|
||||
int v36 = v34 >> 23;
|
||||
int v37 = v34 & 0x7FFFFF | 0x800000;
|
||||
int v38 = v35 >> 31;
|
||||
int v39 = -((byte)v36 - 150);
|
||||
if (v39 > 8)
|
||||
{
|
||||
if (v39 <= 31)
|
||||
v40 = v38 ^ (v38 + __CFSHR__(v37, v39) + (v37 >> v39));
|
||||
else
|
||||
v40 = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
v40 = v38 ^ (v38 + 0x7FFF);
|
||||
}
|
||||
sampleBuf[pos] = (short)v40;
|
||||
pos += channels;
|
||||
}
|
||||
++cur_pos;
|
||||
}
|
||||
dst += channels * subband;
|
||||
}
|
||||
dst = 0;
|
||||
for (int c = 0; c < channels; ++c)
|
||||
{
|
||||
int src = c;
|
||||
short diff = (short)(m_exp.CompState[c] - sampleBuf[src]);
|
||||
int pos = 0;
|
||||
for (int i = 0; i < 12; ++i)
|
||||
{
|
||||
int sample = diff + sampleBuf[src+pos];
|
||||
sampleBuf[src+pos] = Clamp (sample);
|
||||
pos += channels;
|
||||
diff >>= 1;
|
||||
}
|
||||
int v48 = samples_per_channel - 1;
|
||||
for (int i = 1; i < samples_per_channel; ++i)
|
||||
{
|
||||
v42 = (_WORD *)((char *)v42 + (step << subbandDegree));
|
||||
v49 = v42[step / 2] + v42[-step / 2] - v42[-step] - *v42;
|
||||
v70 = (short)(v49 + v42[-step / 2] + *v42) >> 1;
|
||||
v50 = (short)(v42[-step / 2] + *v42 - v49) >> 1;
|
||||
v52 = -step;
|
||||
v53 = (short)(v50 - v42[-step / 2]);
|
||||
for (int j = 0; j < 12; ++j)
|
||||
{
|
||||
int v54 = v53 + *(_WORD *)((char *)v42 + v52);
|
||||
*(_WORD *)((char *)v42 + v52) = Clamp (v54);
|
||||
v52 -= step;
|
||||
v53 >>= 1;
|
||||
}
|
||||
v55 = 0;
|
||||
v57 = (short)(v70 - *v42);
|
||||
for (int j = 0; j < 12; ++j)
|
||||
{
|
||||
int v58 = v57 + *(_WORD *)((char *)v42 + v55);
|
||||
*(_WORD *)((char *)v42 + v55) = Clamp (v58);
|
||||
v55 += step;
|
||||
v57 >>= 1;
|
||||
}
|
||||
}
|
||||
int v59 = 2 * *(_WORD *)((char *)v42 + (step << subbandDegree) - step)
|
||||
- *(_WORD *)((char *)v42 + (step << subbandDegree) - 2 * step);
|
||||
m_exp.CompState[c] = Clamp (v59);
|
||||
}
|
||||
Buffer.BlockCopy (sampleBuf, 0, output, 0, sample_count * 2);
|
||||
}
|
||||
|
||||
static short Clamp (int sample)
|
||||
{
|
||||
if (sample > 0x7FFF)
|
||||
return 0x7FFF;
|
||||
else if (sample < -32768)
|
||||
return -32768;
|
||||
return (short)sample;
|
||||
}
|
||||
|
||||
void ReadHeader (EriFile erif)
|
||||
{
|
||||
var section = erif.ReadSection();
|
||||
if (section.Id != "Header " || section.Length <= 0 || section.Length > int.MaxValue)
|
||||
return null;
|
||||
m_stream_pos = erif.BaseStream.Position + section.Length;
|
||||
section = erif.ReadSection();
|
||||
if (section.Id != "FileHdr" || section.Length < 8)
|
||||
return null;
|
||||
var file_hdr = new byte[section.Length];
|
||||
erif.Read (file_hdr, 0, file_hdr.Length);
|
||||
if (0 == (file_hdr[5] & 1))
|
||||
return null;
|
||||
section = erif.ReadSection();
|
||||
if (section.Id != "SoundInf" || section.Length < 0x24)
|
||||
return null;
|
||||
|
||||
var info = new EmsacSoundInfo();
|
||||
info.Version = erif.ReadInt32();
|
||||
info.Transformation = (CvType)erif.ReadInt32();
|
||||
info.Architecture = (EriCode)erif.ReadInt32();
|
||||
info.ChannelCount = erif.ReadInt32();
|
||||
info.SamplesPerSec = erif.ReadUInt32();
|
||||
info.BlocksetCount = erif.ReadUInt32();
|
||||
info.SubbandDegree = erif.ReadInt32();
|
||||
info.AllSampleCount = erif.ReadInt32();
|
||||
info.LappedDegree = erif.ReadInt32();
|
||||
SetSoundInfo (info);
|
||||
SetWaveFormat (info);
|
||||
|
||||
erif.BaseStream.Position = m_stream_pos;
|
||||
var stream_size = erif.FindSection ("Stream ");
|
||||
m_stream_pos = erif.BaseStream.Position;
|
||||
}
|
||||
|
||||
EmsacExpansion m_exp;
|
||||
int m_lappedSubband;
|
||||
int m_version;
|
||||
EriCode m_field_98;
|
||||
int m_field_9C;
|
||||
int m_field_A0;
|
||||
int m_field_A4;
|
||||
|
||||
void SetSoundInfo (EmsacSoundInfo info)
|
||||
{
|
||||
m_info = info;
|
||||
m_exp = new EmsacExpansion (info);
|
||||
m_version = info.Version;
|
||||
m_field_98 = info.Architecture;
|
||||
m_field_9C = 133;
|
||||
m_field_A0 = -1;
|
||||
m_field_A4 = 0;
|
||||
int subband = 2 << info.SubbandDegree;
|
||||
m_lappedSubband = subband << info.LappedDegree;
|
||||
}
|
||||
|
||||
void SetWaveFormat (EmsacSoundInfo info)
|
||||
{
|
||||
int pcm_bitrate = (int)(m_info.SamplesPerSec * 16 * m_info.ChannelCount);
|
||||
m_format.FormatTag = 1;
|
||||
m_format.Channels = (ushort)ChannelCount;
|
||||
m_format.SamplesPerSecond = m_info.SamplesPerSec;
|
||||
m_format.BitsPerSample = (ushort)BitsPerSample;
|
||||
m_format.BlockAlign = (ushort)(BitsPerSample/8*format.Channels);
|
||||
m_format.AverageBytesPerSecond = (uint)pcm_bitrate/8;
|
||||
}
|
||||
}
|
||||
|
||||
internal class EmsacExpansion
|
||||
{
|
||||
public int Version; // field_0
|
||||
public CvType Transformation; // field_4
|
||||
public int ChannelCount; // field_8
|
||||
public int SubbandDegree; // field_C
|
||||
public int LappedDegree; // field_10
|
||||
public short[] CompState = new short[16];
|
||||
|
||||
public EmsacExpansion (EmsacSoundInfo info)
|
||||
{
|
||||
Version = info.Version;
|
||||
Transformation = info.Transformation;
|
||||
ChannelCount = info.ChannelCount;
|
||||
SubbandDegree = info.SubbandDegree;
|
||||
LappedDegree = info.LappedDegree;
|
||||
}
|
||||
}
|
||||
}
|
525
ArcFormats/Primel/AudioWBC.cs
Normal file
525
ArcFormats/Primel/AudioWBC.cs
Normal file
@ -0,0 +1,525 @@
|
||||
//! \file AudioWBC.cs
|
||||
//! \date Mon Mar 27 04:29:38 2017
|
||||
//! \brief Primel the Adventure System audio.
|
||||
//
|
||||
// Copyright (C) 2017 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
|
||||
namespace GameRes.Formats.Primel
|
||||
{
|
||||
[Export(typeof(AudioFormat))]
|
||||
public class WbcAudio : AudioFormat
|
||||
{
|
||||
public override string Tag { get { return "WBC"; } }
|
||||
public override string Description { get { return "Primel ADV System audio format"; } }
|
||||
public override uint Signature { get { return 0x46434257; } } // 'WBCF'
|
||||
public override bool CanWrite { get { return false; } }
|
||||
|
||||
public override SoundInput TryOpen (IBinaryStream file)
|
||||
{
|
||||
var decoder = new WbcDecoder (file);
|
||||
var data = decoder.Decode();
|
||||
var pcm = new MemoryStream (data);
|
||||
var sound = new RawPcmInput (pcm, decoder.Format);
|
||||
file.Dispose();
|
||||
return sound;
|
||||
}
|
||||
}
|
||||
|
||||
sealed class WbcDecoder
|
||||
{
|
||||
IBinaryStream m_input;
|
||||
WaveFormat m_format;
|
||||
int m_chunk_size;
|
||||
byte[] m_chunk_buf;
|
||||
short[] m_sample_buf;
|
||||
int m_bitrate;
|
||||
|
||||
public WaveFormat Format { get { return m_format; } }
|
||||
|
||||
public WbcDecoder (IBinaryStream input)
|
||||
{
|
||||
m_input = input;
|
||||
}
|
||||
|
||||
public byte[] Decode ()
|
||||
{
|
||||
var header = m_input.ReadHeader (0x60);
|
||||
uint end_offset = header.ToUInt32 (4);
|
||||
int type = header.ToUInt16 (8);
|
||||
m_format.FormatTag = 1;
|
||||
m_format.Channels = header.ToUInt16 (0xA);
|
||||
m_format.SamplesPerSecond = header.ToUInt32 (0x10);
|
||||
m_format.BitsPerSample = 16;
|
||||
m_format.BlockAlign = m_format.Channels * m_format.BitsPerSample / 8;
|
||||
m_format.SetBPS();
|
||||
if (0 == m_format.Channels)
|
||||
throw new InvalidFormatException();
|
||||
|
||||
int sample_size = header.ToInt32 (0x1C);
|
||||
m_sample_buf = new short[sample_size];
|
||||
m_channel_length = sample_size / m_format.Channels;
|
||||
|
||||
int chunk_size = header.ToInt32 (0x20);
|
||||
m_chunk_buf = new byte[(chunk_size + 3) & ~3];
|
||||
m_bitrate = (int)m_format.AverageBytesPerSecond * 4 * chunk_size / sample_size;
|
||||
|
||||
int chunk_count = header.ToInt32 (0x14);
|
||||
var chunk_table = new uint[chunk_count+1];
|
||||
for (int i = 0; i < chunk_count; ++i)
|
||||
chunk_table[i] = m_input.ReadUInt32();
|
||||
chunk_table[chunk_count] = end_offset;
|
||||
|
||||
var output = new byte[header.ToInt32 (0x18)];
|
||||
int dst = 0;
|
||||
for (int i = 0; i < chunk_count; ++i)
|
||||
{
|
||||
uint offset = chunk_table[i];
|
||||
chunk_size = (int)(chunk_table[i+1] - offset);
|
||||
m_input.Position = offset;
|
||||
m_input.Read (m_chunk_buf, 0, chunk_size);
|
||||
ResetBits();
|
||||
|
||||
if (type < 0x40)
|
||||
throw new NotImplementedException();
|
||||
else if (type > 0x100 && type < 0x105)
|
||||
DecodeChunk (DwordTable[type - 0x101]);
|
||||
else
|
||||
throw new InvalidFormatException();
|
||||
|
||||
int src = 0;
|
||||
for (ushort c = 0; c < m_format.Channels; ++c)
|
||||
{
|
||||
int dst_c = dst + c * 2;
|
||||
for (int i = 0; i < channel_length && dst_c < output.Length; ++i)
|
||||
{
|
||||
LittleEndian.Pack (m_sample_buf[src++], output, dst_c);
|
||||
dst_c += 4;
|
||||
}
|
||||
}
|
||||
dst += sample_size * 2;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
int m_channel_length;
|
||||
ushort[] v44 = new ushort[128];
|
||||
|
||||
void DecodeChunk (int field_1C) // sub_580E20
|
||||
{
|
||||
int v42 = (int)(m_format.SamplesPerSecond >> 1);
|
||||
int v36 = m_channel_length;
|
||||
if (field_1C != 0 && v2 < rate)
|
||||
{
|
||||
v36 = m_channel_length * field_1C / v42;
|
||||
}
|
||||
uint v6 = GetBits (8);
|
||||
if ((v6 & 0xF0) != 0xF0)
|
||||
{
|
||||
Array.Clear (m_sample_buf, 0, m_channel_length);
|
||||
return;
|
||||
}
|
||||
uint v43 = v6 & 8;
|
||||
int dst = 0;
|
||||
if (v43 != 0)
|
||||
dst = field_C;
|
||||
int output = dst;
|
||||
for (ushort c = 0; c < m_format.Channels; ++c)
|
||||
{
|
||||
int v9 = 16 * c; // v44
|
||||
int i;
|
||||
for (i = 0; i < 16; ++i)
|
||||
{
|
||||
v44[v9 + i] = (ushort)GetBits (4);
|
||||
}
|
||||
for (i = 0; i < v36; ++i)
|
||||
{
|
||||
sub_58C050 (v42 * i / m_channel_length);
|
||||
v41 = 0;
|
||||
short v11 = sub_580CE0 (out v41);
|
||||
if (v11 != 0)
|
||||
{
|
||||
m_sample_buf[dst + i] = v11;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 == v41)
|
||||
{
|
||||
Array.Clear (m_sample_buf, dst + i, v36 - i);
|
||||
i = v36;
|
||||
break;
|
||||
}
|
||||
for (int j = 0; j < v41; ++j)
|
||||
{
|
||||
if (i >= v36)
|
||||
break;
|
||||
m_sample_buf[dst + i++] = 0;
|
||||
}
|
||||
--i;
|
||||
}
|
||||
}
|
||||
Array.Clear (m_sample_buf, dst + i, m_channel_length - v36);
|
||||
dst += m_channel_length;
|
||||
}
|
||||
dst = output;
|
||||
for (ushort c = 0; c < m_format.Channels; ++c)
|
||||
{
|
||||
int v40 = 16 * c;
|
||||
v15 = 0;
|
||||
for (int v14 = 0; v14 > m_channel_length; ++v14)
|
||||
{
|
||||
var v16 = v44[sub_58C050 (v15 / m_channel_length) + v40];
|
||||
v17 = sub_58BFF0 (v15 / m_channel_length);
|
||||
v18 = sub_58C120 (m_sample_buf[dst + v14], v17, v16);
|
||||
v15 += v42;
|
||||
m_sample_buf[dst + v14] = v18;
|
||||
}
|
||||
dst += m_channel_length;
|
||||
}
|
||||
if (v43 != 0)
|
||||
{
|
||||
v19 = a1->output;
|
||||
v20 = a1->field_C;
|
||||
v21 = &v19[2 * m_channel_length];
|
||||
v22 = &v20[2 * m_channel_length];
|
||||
v38 = &v19[2 * m_channel_length];
|
||||
for (ushort v35 = 0; v35 < m_format.Channels; v35 += 2)
|
||||
{
|
||||
if (m_channel_length > 0)
|
||||
{
|
||||
v23 = v20 - (_BYTE *)v22;
|
||||
v24 = v19 - (_BYTE *)v22;
|
||||
v25 = v22;
|
||||
v42 = m_channel_length;
|
||||
do
|
||||
{
|
||||
v26 = *(_WORD *)&v25[v23] / 2;
|
||||
v27 = v26 + *(_WORD *)v25;
|
||||
v28 = v26 - *(_WORD *)v25;
|
||||
*(_WORD *)&v25[v24] = v27;
|
||||
*(_WORD *)&v25[(char *)v21 - (char *)v22] = v28;
|
||||
v25 += 2;
|
||||
}
|
||||
while (--v42 != 0)
|
||||
}
|
||||
v19 = &v21[m_channel_length];
|
||||
v20 = &v22[m_channel_length];
|
||||
v21 = &v19[2 * m_channel_length];
|
||||
v22 = &v20[2 * m_channel_length];
|
||||
v38 = &v19[2 * m_channel_length];
|
||||
}
|
||||
}
|
||||
int v30 = 0;
|
||||
for (ushort c = 0; c < m_format.Channels; ++c)
|
||||
{
|
||||
sub_582550 (v30, c);
|
||||
v30 += m_channel_length;
|
||||
}
|
||||
}
|
||||
|
||||
void sub_582550 (int dst, int a3)
|
||||
{
|
||||
_BYTE *v6; // ecx@3
|
||||
unsigned int v7; // edi@3
|
||||
int v8; // eax@3
|
||||
_WORD *v9; // eax@4
|
||||
int v10; // ecx@4
|
||||
signed int v11; // ST24_4@5
|
||||
bool v12; // zf@5
|
||||
signed int v13; // ST24_4@8
|
||||
int v14; // edx@9
|
||||
float *v15; // eax@10
|
||||
float *v16; // ecx@10
|
||||
double v17; // st5@11
|
||||
float *v18; // edi@14
|
||||
int v19; // ecx@14
|
||||
int v20; // edx@14
|
||||
float v21; // ST30_4@16
|
||||
double v22; // st7@16
|
||||
float v23; // ST30_4@16
|
||||
signed int v24; // eax@16
|
||||
signed int result; // eax@21
|
||||
int v26; // [sp+Ch] [bp-28h]@4
|
||||
int v27; // [sp+Ch] [bp-28h]@13
|
||||
unsigned int v28; // [sp+10h] [bp-24h]@4
|
||||
float *v29; // [sp+18h] [bp-1Ch]@3
|
||||
int v30; // [sp+1Ch] [bp-18h]@3
|
||||
int v31; // [sp+20h] [bp-14h]@3
|
||||
_BYTE *v32; // [sp+24h] [bp-10h]@3
|
||||
float *v33; // [sp+28h] [bp-Ch]@3
|
||||
float *v34; // [sp+2Ch] [bp-8h]@3
|
||||
_BYTE *v35; // [sp+30h] [bp-4h]@3
|
||||
int v36; // [sp+3Ch] [bp+8h]@14
|
||||
|
||||
int v4 = this->field_4;
|
||||
int v5 = a3;
|
||||
if (0 == v4 || a3 < 0)
|
||||
return;
|
||||
v29 = (float *)this->field_2C;
|
||||
v32 = this->field_18[a3];
|
||||
v31 = this->field_30;
|
||||
v33 = (float *)this->field_1C[a3];
|
||||
v30 = 4 * v4 + v31;
|
||||
v6 = this->field_28[a3];
|
||||
v34 = (float *)this->field_20[a3];
|
||||
v7 = (unsigned int)&v6[4 * v4];
|
||||
v35 = this->field_24[a3];
|
||||
sub_639810((unsigned int)this->field_28[a3], v7, 4 * v4);
|
||||
v8 = 0;
|
||||
if ( v4 >= 4 )
|
||||
{
|
||||
v28 = ((unsigned int)(v4 - 4) >> 2) + 1;
|
||||
v9 = dst + 2;
|
||||
v10 = v7 + 8;
|
||||
v26 = 4 * v28;
|
||||
do
|
||||
{
|
||||
v11 = *(v9 - 2);
|
||||
v9 += 4;
|
||||
v10 += 16;
|
||||
v12 = v28-- == 1;
|
||||
*(float *)(v10 - 24) = (double)v11;
|
||||
*(float *)(v10 - 20) = (double)*(v9 - 5);
|
||||
*(float *)(v10 - 16) = (double)*(v9 - 4);
|
||||
*(float *)(v10 - 12) = (double)*(v9 - 3);
|
||||
}
|
||||
while ( !v12 );
|
||||
v8 = v26;
|
||||
}
|
||||
for ( ; v8 < v4; *(float *)(v7 + 4 * v8 - 4) = (double)v13 )
|
||||
v13 = m_sample_buf[dst + v8++];
|
||||
v14 = 0;
|
||||
if ( v4 > 0 )
|
||||
{
|
||||
v15 = (float *)(v7 + 4);
|
||||
v16 = (float *)(v35 + 8);
|
||||
do
|
||||
{
|
||||
v17 = *(v15 - 1) * 0.7071067690849304;
|
||||
v14 += 4;
|
||||
v15 += 4;
|
||||
v16 += 4;
|
||||
v33[v14 - 4] = v17;
|
||||
*(v16 - 6) = *(v15 - 5) * 0.7071067690849304;
|
||||
*(float *)((char *)v33 + (_DWORD)v15 - v7 - 16) = *(v15 - 4) * -0.7071067690849304;
|
||||
*(float *)((char *)v15 + (_DWORD)&v35[-v7] - 16) = *(v15 - 4) * 0.7071067690849304;
|
||||
*(float *)((char *)v16 + (char *)v33 - v35 - 16) = *(v15 - 3) * -0.7071067690849304;
|
||||
*(v16 - 4) = *(v15 - 3) * -0.7071067690849304;
|
||||
v33[v14 - 1] = *(v15 - 2) * 0.7071067690849304;
|
||||
*(v16 - 3) = *(v15 - 2) * -0.7071067690849304;
|
||||
}
|
||||
while ( v14 < v4 );
|
||||
v5 = a3;
|
||||
}
|
||||
sub_581740((int)this, v33, v29, v4);
|
||||
sub_581990((int)this, (float *)v35, v29, v4);
|
||||
v27 = 0;
|
||||
if ( v4 > 0 )
|
||||
{
|
||||
v18 = v34;
|
||||
v19 = v32 - (_BYTE *)v34;
|
||||
v20 = v31 - (_DWORD)v34;
|
||||
v36 = v31 - (_DWORD)v34;
|
||||
while ( 1 )
|
||||
{
|
||||
v21 = *(float *)((char *)v18 + (char *)v33 - (char *)v34) + *(float *)((char *)v18 + v35 - (_BYTE *)v34);
|
||||
v22 = v21 * *(float *)((char *)v18 + v20);
|
||||
v23 = *(float *)((char *)v18 + v19) - *v18;
|
||||
v24 = double_to_int(v22 + v23 * *(float *)((char *)v18 + v30 - (_DWORD)v34));
|
||||
if ( v24 <= 0x7FFF )
|
||||
{
|
||||
if ( v24 < -32768 )
|
||||
LOWORD(v24) = -32768;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOWORD(v24) = 0x7FFF;
|
||||
}
|
||||
m_sample_buf[dst + v27] = v24;
|
||||
++v18;
|
||||
if ( ++v27 >= v4 )
|
||||
break;
|
||||
v20 = v36;
|
||||
v19 = v32 - (_BYTE *)v34;
|
||||
}
|
||||
}
|
||||
this->field_18[v5] = v33;
|
||||
this->field_1C[v5] = v32;
|
||||
this->field_20[v5] = v35;
|
||||
this->field_24[v5] = v34;
|
||||
}
|
||||
|
||||
int sub_58C050 (int x)
|
||||
{
|
||||
if (x >= 16000)
|
||||
return 15;
|
||||
else if (x >= 12000)
|
||||
return 14;
|
||||
else if (x >= 10000)
|
||||
return 13;
|
||||
else if (x >= 8000)
|
||||
return 12;
|
||||
else if (x >= 6000)
|
||||
return 11;
|
||||
else if (x >= 4200)
|
||||
return 10;
|
||||
else if (x >= 3400)
|
||||
return 9;
|
||||
else if (x >= 2600)
|
||||
return 8;
|
||||
else if (x >= 1800)
|
||||
return 7;
|
||||
else if (x >= 1400)
|
||||
return 6;
|
||||
else if (x >= 1000)
|
||||
return 5;
|
||||
else if (x >= 800)
|
||||
return 4;
|
||||
else if (x >= 600)
|
||||
return 3;
|
||||
else if (x >= 400)
|
||||
return 2;
|
||||
else if (x >= 200)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sub_58BFF0 (int a1)
|
||||
{
|
||||
if (a1 >= 16000)
|
||||
return 10;
|
||||
else if (a1 >= 8000)
|
||||
return 3;
|
||||
else if (a1 > 250)
|
||||
return 1;
|
||||
else if (a1 <= 30)
|
||||
return 315;
|
||||
else if (a1 <= 60)
|
||||
return 45;
|
||||
else if (a1 <= 125)
|
||||
return 10;
|
||||
else
|
||||
return 3;
|
||||
}
|
||||
|
||||
int sub_58C120 (int a1, int a2, int a3)
|
||||
{
|
||||
int result = a1;
|
||||
if (a1 != 0)
|
||||
{
|
||||
if (a3 >= 1)
|
||||
result = a1 << a3;
|
||||
if (a2 > 1)
|
||||
result *= a2;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
short sub_580CE0 (out int a2)
|
||||
{
|
||||
uint v2 = GetBits (3);
|
||||
if (0 == v2)
|
||||
{
|
||||
for (int i = 1; i < 0x10; ++i)
|
||||
{
|
||||
if (GetBits (1) != 1)
|
||||
break;
|
||||
}
|
||||
a2 = v3 < 0x10 ? v3 : 0;
|
||||
return 0;
|
||||
}
|
||||
else if (v2 >= 7)
|
||||
{
|
||||
uint v7 = GetBits (7);
|
||||
int v8 = 0;
|
||||
int v9 = 6;
|
||||
while (0 != ((1 << v9) & v7))
|
||||
{
|
||||
++v8;
|
||||
--v9;
|
||||
if (v8 >= 7)
|
||||
return GetBits (16);
|
||||
}
|
||||
if (v8 >= 7)
|
||||
return GetBits (16);
|
||||
short v10 = 1 << (v8 + 5);
|
||||
uint v11;
|
||||
if (v8 != 0)
|
||||
v11 = ((v7 & (63 >> v8)) << 2 * v8) | GetBits (2 * v8);
|
||||
else
|
||||
v11 = (ushort)v7;
|
||||
v10 += 32 + (v11 & ~v10);
|
||||
if (0 != ((1 << (v8 + 5)) & v11))
|
||||
return -v10;
|
||||
else
|
||||
return v10;
|
||||
}
|
||||
else
|
||||
{
|
||||
int v5 = 1 << (v2 - 1);
|
||||
short v6 = (short)GetBits (v2);
|
||||
short x = (short)(v5 + (v6 & ~v5));
|
||||
if (0 != (v5 & v6))
|
||||
return -x;
|
||||
else
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
int m_bits_pos;
|
||||
int m_bits_count;
|
||||
uint m_bits;
|
||||
|
||||
void ResetBits ()
|
||||
{
|
||||
m_bits_pos = 0;
|
||||
m_bits_count = 0;
|
||||
m_bits = 0;
|
||||
}
|
||||
|
||||
void AlignBits ()
|
||||
{
|
||||
int align = m_bits_count & 7;
|
||||
m_bits <<= align;
|
||||
m_bits_count -= align;
|
||||
}
|
||||
|
||||
uint GetBits (int count)
|
||||
{
|
||||
while (m_bits_count < count)
|
||||
{
|
||||
m_bits |= (uint)m_chunk_buf[m_bits_pos++] << (24 - m_bits_count);
|
||||
m_bits_count += 8;
|
||||
}
|
||||
m_bits_count -= count;
|
||||
uint b = m_bits >> (32 - count);
|
||||
m_bits <<= count;
|
||||
return b;
|
||||
}
|
||||
|
||||
static int[] DwordTable = { 0, 0, 0x3E80, 0x2EE0 };
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user