| 7 |
|
{ |
| 8 |
|
#region Private data |
| 9 |
|
private bool convert_to_PCM; |
| 10 |
+ |
private bool do_pc_demo_test; |
| 11 |
|
|
| 12 |
|
private const int fcc_RIFF = 0x46464952; |
| 13 |
|
private const int fcc_WAVE = 0x45564157; |
| 86 |
|
}; |
| 87 |
|
#endregion |
| 88 |
|
|
| 89 |
< |
public WavExporter(InstanceFileManager fileManager, string outputDirPath, bool convertToPCM = false) |
| 89 |
> |
public WavExporter(InstanceFileManager fileManager, string outputDirPath, bool convertToPCM = false, bool noDemo = false) |
| 90 |
|
: base(fileManager, outputDirPath) |
| 91 |
|
{ |
| 92 |
|
convert_to_PCM = convertToPCM; |
| 93 |
+ |
do_pc_demo_test = !noDemo; |
| 94 |
|
} |
| 95 |
|
|
| 96 |
|
private static void ClampToRange(ref int value, int lower, int upper) |
| 148 |
|
|
| 149 |
|
protected override void ExportInstance(InstanceDescriptor descriptor) |
| 150 |
|
{ |
| 151 |
< |
var sound = SoundData.Read(descriptor); |
| 151 |
> |
var sound = SoundData.Read(descriptor, do_pc_demo_test); |
| 152 |
|
|
| 153 |
|
using (var stream = File.Create(Path.Combine(OutputDirPath, descriptor.FullName + ".wav"))) |
| 154 |
|
using (var writer = new BinaryWriter(stream)) |
| 163 |
|
paddingBytes = blockSizeADPCM - leftoverBytes; |
| 164 |
|
var samplesPerBlock = 2 + (blockSizeADPCM - sound.ChannelCount * 7) * 8 / sound.ChannelCount / 4; |
| 165 |
|
|
| 166 |
< |
Int32 sampleCount = sampleCount = wholeBlocks * samplesPerBlock + leftoverSamples; |
| 167 |
< |
|
| 166 |
> |
Int32 sampleCount = sampleCount = wholeBlocks * samplesPerBlock + leftoverSamples; |
| 167 |
> |
|
| 168 |
|
if (sound.IsIMA4) // IMA4 ADPCM format |
| 169 |
|
{ |
| 170 |
|
blockSizeADPCM = 34 * sound.ChannelCount; |
| 171 |
|
samplesPerBlock = 64; |
| 172 |
|
sampleCount = (sound.Data.Length / blockSizeADPCM) * samplesPerBlock; |
| 173 |
|
} |
| 172 |
– |
|
| 174 |
|
if (!convert_to_PCM) |
| 175 |
|
{ |
| 176 |
|
if (sound.IsIMA4) |
| 177 |
|
{ |
| 178 |
< |
throw new NotSupportedException("Transcoding from Mac/demo ADPCM to PC ADPCM not supported! Please use -extract:pcm"); |
| 178 |
> |
throw new NotSupportedException("Transcoding from IMA4 ADPCM (Mac) to MS ADPCM (PC) not supported! Please use -extract:pcm"); |
| 179 |
|
} |
| 180 |
|
var format = (byte[])formatTemplate_ADPCM.Clone(); |
| 181 |
|
var fact = (byte[])factTemplate.Clone(); // needed for ADPCM (to specify the actual sample count) |
| 271 |
|
if (predictorL > 32767) predictorL -= 65536; |
| 272 |
|
} |
| 273 |
|
stepIndexL = headerLoL & 0x7f; |
| 274 |
+ |
if (stepIndexL > 88) |
| 275 |
+ |
Console.WriteLine("Block {0} (L): Initial IMA4 step index is {1}, clamping to 88.", block, stepIndexL); |
| 276 |
+ |
ClampToRange(ref stepIndexL, 0, 88); |
| 277 |
+ |
|
| 278 |
|
for (int b = 0; b < 32; b++) |
| 279 |
|
{ |
| 280 |
|
Byte nibblesL = sound.Data[pos++]; |
| 295 |
|
if (predictorR > 32767) predictorR -= 65536; |
| 296 |
|
} |
| 297 |
|
stepIndexR = headerLoR & 0x7f; |
| 298 |
+ |
if (stepIndexR > 88) |
| 299 |
+ |
Console.WriteLine("Block {0} (R): Initial IMA4 step index is {1}, clamping to 88.", block, stepIndexR); |
| 300 |
+ |
ClampToRange(ref stepIndexR, 0, 88); |
| 301 |
|
|
| 302 |
|
for (int b = 0; b < 32; b++) |
| 303 |
|
{ |
| 367 |
|
samplesR[iSampleR++] = sample1R; |
| 368 |
|
} |
| 369 |
|
} |
| 370 |
< |
// read pair of nibbles |
| 371 |
< |
Byte nibbles = sound.Data[pos++]; |
| 372 |
< |
Byte nibbleHi = (Byte)(nibbles >> 4); |
| 373 |
< |
Byte nibbleLo = (Byte)(nibbles & 0xF); |
| 374 |
< |
samplesL[iSampleL++] = NibbletoSampleMSADPCM(ref sample1L, ref sample2L, ref deltaL, pred_indexL, nibbleHi); |
| 375 |
< |
if (sound.ChannelCount == 2) |
| 376 |
< |
samplesR[iSampleR++] = NibbletoSampleMSADPCM(ref sample1R, ref sample2R, ref deltaR, pred_indexR, nibbleLo); |
| 377 |
< |
else |
| 378 |
< |
samplesL[iSampleL++] = NibbletoSampleMSADPCM(ref sample1L, ref sample2L, ref deltaL, pred_indexL, nibbleLo); |
| 370 |
> |
else // read pair of nibbles |
| 371 |
> |
{ |
| 372 |
> |
Byte nibbles = sound.Data[pos++]; |
| 373 |
> |
Byte nibbleHi = (Byte)(nibbles >> 4); |
| 374 |
> |
Byte nibbleLo = (Byte)(nibbles & 0xF); |
| 375 |
> |
samplesL[iSampleL++] = NibbletoSampleMSADPCM(ref sample1L, ref sample2L, ref deltaL, pred_indexL, nibbleHi); |
| 376 |
> |
if (sound.ChannelCount == 2) |
| 377 |
> |
samplesR[iSampleR++] = NibbletoSampleMSADPCM(ref sample1R, ref sample2R, ref deltaR, pred_indexR, nibbleLo); |
| 378 |
> |
else |
| 379 |
> |
samplesL[iSampleL++] = NibbletoSampleMSADPCM(ref sample1L, ref sample2L, ref deltaL, pred_indexL, nibbleLo); |
| 380 |
> |
} |
| 381 |
|
} |
| 382 |
|
} |
| 383 |
|
writer.Write(fcc_data); |