using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace NOLFPS2WAVRipper
{
class Program
{
static string riffFileHeaderString = "52494646"; //ANSI : RIFF
static string waveFileHeaderString = "57415645666D7420"; //ANSI : WAVEFmt
static string sourceFile = @"E:\LITH_PS2.REZ";
static string workDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
static void Main(string[] args)
{
if(args.Count() >= 1)
{
sourceFile = args[0];
}
BinaryReader reader = new BinaryReader(File.OpenRead(sourceFile));
List<Tuple<long, long>> workersPositions = new List<Tuple<long, long>>();
while(reader.BaseStream.Position < reader.BaseStream.Length)
{
var startPos = reader.BaseStream.Position;
if(workersPositions.Any())
{
startPos = workersPositions.Last().Item2;
}
if(reader.BaseStream.Position < reader.BaseStream.Length)
{
long chunkSize = reader.BaseStream.Length / 100;
long endPosition = startPos + chunkSize;
if(endPosition > reader.BaseStream.Length)
{
endPosition = reader.BaseStream.Length;
}
var workerPart = new Tuple<long, long>(startPos, endPosition);
workersPositions.Add(workerPart);
reader.BaseStream.Position = endPosition;
}
}
reader.Close();
reader.Dispose();
int workerId = 1;
Parallel.ForEach(workersPositions, (currentStartAndEndTuple) =>
{
workerId++;
GetAudioDataToFiles(currentStartAndEndTuple, workerId);
});
}
private static void GetAudioDataToFiles(Tuple<long, long> startAndEndPositions, int workerId)
{
BinaryReader reader = new BinaryReader(File.OpenRead(sourceFile));
reader.BaseStream.Position = startAndEndPositions.Item1;
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
if(reader.BaseStream.Position >= startAndEndPositions.Item2)
{
break;
}
string readerHeadToString = "";
MemoryStream riffheaderMemoryStream = new MemoryStream();
while (readerHeadToString.Count() != riffFileHeaderString.Count())
{
if (reader.BaseStream.Position < reader.BaseStream.Length)
{
byte readByte = reader.ReadByte();
string readByteToHex = readByte.ToString("X2");
readerHeadToString += readByteToHex;
riffheaderMemoryStream.WriteByte(readByte);
}
else
{
break;
}
}
if (readerHeadToString.ToLower() == riffFileHeaderString.ToLower())
{
byte[] chunkSizeData = new byte[8];
MemoryStream waveFileData = new MemoryStream();
riffheaderMemoryStream.WriteTo(waveFileData);
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
for (int i = 0; i < 4; i++)
{
byte chunkSizeFieldByte = reader.ReadByte();
chunkSizeData[i] = chunkSizeFieldByte;
waveFileData.WriteByte(chunkSizeFieldByte);
}
long calculatedChunkSize = 8; // RIFF + ChunkSize fields' length not included in ChunkSize count
calculatedChunkSize += BitConverter.ToInt64(chunkSizeData, 0);
string nextHeigtBytesToString = "";
for (int i = 0; i < 8; i++)
{
if (reader.BaseStream.Position < reader.BaseStream.Length)
{
byte waveFmtHeaderFieldByte = reader.ReadByte();
string readByteToHex = waveFmtHeaderFieldByte.ToString("X2");
nextHeigtBytesToString += readByteToHex;
waveFileData.WriteByte(waveFmtHeaderFieldByte);
}
}
//Is a RIFF file, but not a WAVE file. Discard.
if (nextHeigtBytesToString.ToLower() != waveFileHeaderString.ToLower())
{
waveFileData.Dispose();
waveFileData = new MemoryStream();
continue;
}
long currentReaderPosition = reader.BaseStream.Position;
Console.WriteLine(String.Format("[Worker N°{0}] - Processing RIFF WAVEFmt file...", workerId));
Console.Write(String.Format("[Worker N°{0}] - Position : ", workerId));
var startPosition = reader.BaseStream.Position - 8;
Console.Write(startPosition.ToString("X") + Environment.NewLine);
var endPosition = reader.BaseStream.Position + calculatedChunkSize;
Console.WriteLine(String.Format("[Worker N°{0}] - Calculated End : {1}", workerId, endPosition.ToString("X")));
while (reader.BaseStream.Position < endPosition)
{
if (reader.BaseStream.Position < reader.BaseStream.Length)
{
waveFileData.WriteByte(reader.ReadByte());
}
else
{
break;
}
}
string filePath = String.Format(@"{0}\{1}-{2}.WAV", workDir, startPosition.ToString("X"), endPosition.ToString("X"));
if(File.Exists(filePath) == false)
{
try
{
FileStream fileStream = File.OpenWrite(filePath);
waveFileData.WriteTo(fileStream);
fileStream.Close();
fileStream.Dispose();
}
catch
{
}
}
Console.WriteLine(String.Format("[Worker N°{0}] - End Position : {1}", workerId, reader.BaseStream.Position.ToString("X")));
break;
}
waveFileData.Close();
waveFileData.Dispose();
}
}
reader.Close();
reader.Dispose();
}
}
}
(Pour traiter les voix : il va falloir que tu m'expliques comment les découper pour en faire des fichiers. Si c'est forcément via Skype, ce sera quand j'aurais fini d'emménager
)Pour de meilleurs performances, ça utilise le parallélisme (donc tous les coeurs du CPU sont utilisés). Le chiffre 100 au début pour partitionner le fichier est arbitraire, c'est du pifomètre pour avoir des partitions de travail ni trop grosses, ni trop petites.
Ça se lit bien avec ffmpeg. Et ffprobe les reconnaît. Exemple :
> ffprobe 1CDBA808-1D84DFB6.WAV
ffprobe version N-84814-gad7aff0 Copyright (c) 2007-2017 the FFmpeg developers
built with gcc 6.3.0 (GCC)
configuration: --enable-gpl --enable-version3 --enable-cuda --enable-cuvid --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --enable-zlib
libavutil 55. 52.100 / 55. 52.100
libavcodec 57. 86.103 / 57. 86.103
libavformat 57. 68.100 / 57. 68.100
libavdevice 57. 3.101 / 57. 3.101
libavfilter 6. 78.101 / 6. 78.101
libswscale 4. 3.101 / 4. 3.101
libswresample 2. 4.100 / 2. 4.100
libpostproc 54. 2.100 / 54. 2.100
Input #0, wav, from '1CDBA808-1D84DFB6.WAV':
Duration: 00:03:51.04, bitrate: 384 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 24000 Hz, 1 channels, s16, 384 kb/s


.
.
)
Commentaire