make discohawk extractor reuse ffmpeg code from disc system and encode raw pcm to remove dependency on wavefile headers libs

This commit is contained in:
zeromus 2011-09-04 05:53:09 +00:00
parent 1d0e995546
commit 290cf76223
7 changed files with 13 additions and 269 deletions

View File

@ -47,7 +47,7 @@ namespace BizHawk.DiscSystem
return false;
}
string Run(params string[] args)
public string Run(params string[] args)
{
args = Escape(args);
StringBuilder sbCmdline = new StringBuilder();

View File

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizHawk.DiscSystem;
using WaveLibrary;
using System.IO;
using System.Diagnostics;
@ -21,42 +20,29 @@ namespace BizHawk
if (track.TrackType != ETrackType.Audio)
continue;
var wave = new WaveFile(2, 16, 44100);
var waveData = new byte[track.length_aba * 2352];
int startLba = track.Indexes[1].LBA;
for (int sector = 0; sector < track.length_aba; sector++)
disc.ReadLBA_2352(startLba + sector, waveData, sector * 2352);
wave.SetData(waveData, waveData.Length / 4);
string waveFilePath = Path.Combine(path, "__temp.wav");
wave.WriteFile(waveFilePath);
string tempfile = Path.GetTempFileName();
Encode(waveFilePath, string.Format("{0} - Track {1:D2}.mp3", Path.Combine(path, filebase), track.num));
File.Delete(waveFilePath);
try
{
File.WriteAllBytes(tempfile, waveData);
Encode(tempfile, string.Format("{0} - Track {1:D2}.mp3", Path.Combine(path, filebase), track.num));
}
finally
{
File.Delete(tempfile);
}
}
}
static void Encode(string wavePath, string mp3Path)
{
var args = Escape("-i", wavePath, "-ab", "192k", mp3Path);
StringBuilder sbCmdline = new StringBuilder();
for (int i = 0; i < args.Length; i++)
{
sbCmdline.Append(args[i]);
if (i != args.Length - 1) sbCmdline.Append(' ');
}
ProcessStartInfo oInfo = new ProcessStartInfo(FFmpegPath, sbCmdline.ToString());
oInfo.UseShellExecute = false;
oInfo.CreateNoWindow = true;
oInfo.RedirectStandardOutput = true;
oInfo.RedirectStandardError = true;
Process proc = System.Diagnostics.Process.Start(oInfo);
proc.WaitForExit();
string result = proc.StandardError.ReadToEnd();
var ffmpeg = new FFMpeg();
ffmpeg.Run("-f", "s16le", "-ar", "44100", "-ac", "2", "-i", wavePath, "-f", "mp3", "-ab", "192k", mp3Path);
}
static string[] Escape(params string[] args)

View File

@ -94,10 +94,6 @@
<Compile Include="ProgressDialog.Designer.cs">
<DependentUpon>ProgressDialog.cs</DependentUpon>
</Compile>
<Compile Include="Wave\WavedataSubChunk.cs" />
<Compile Include="Wave\WaveFile.cs" />
<Compile Include="Wave\WavefmtSubChunk.cs" />
<Compile Include="Wave\WaveHeader.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />

View File

@ -1,97 +0,0 @@
/* Wave File Library
* A simple library to write a wave file
*
* Garrett Hoofman
* 10/21/08
* http://www.visionsofafar.com
* */
/* Wave File Format
Reference : http://ccrma.stanford.edu/CCRMA/Courses/422/projects/WaveFormat/
The canonical WAVE format starts with the RIFF header:
0 4 ChunkID Contains the letters "RIFF" in ASCII form
(0x52494646 big-endian form).
4 4 ChunkSize 36 + SubChunk2Size, or more precisely:
4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
This is the size of the rest of the chunk
following this number. This is the size of the
entire file in bytes minus 8 bytes for the
two fields not included in this count:
ChunkID and ChunkSize.
8 4 Format Contains the letters "WAVE"
(0x57415645 big-endian form).
The "WAVE" format consists of two subchunks: "fmt " and "data":
The "fmt " subchunk describes the sound data's format:
12 4 Subchunk1ID Contains the letters "fmt "
(0x666d7420 big-endian form).
16 4 Subchunk1Size 16 for PCM. This is the size of the
rest of the Subchunk which follows this number.
20 2 AudioFormat PCM = 1 (i.e. Linear quantization)
Values other than 1 indicate some
form of compression.
22 2 NumChannels Mono = 1, Stereo = 2, etc.
24 4 SampleRate 8000, 44100, etc.
28 4 ByteRate == SampleRate * NumChannels * BitsPerSample/8
32 2 BlockAlign == NumChannels * BitsPerSample/8
The number of bytes for one sample including
all channels. I wonder what happens when
this number isn't an integer?
34 2 BitsPerSample 8 bits = 8, 16 bits = 16, etc.
2 ExtraParamSize if PCM, then doesn't exist
X ExtraParams space for extra parameters
The "data" subchunk contains the size of the data and the actual sound:
36 4 Subchunk2ID Contains the letters "data"
(0x64617461 big-endian form).
40 4 Subchunk2Size == NumSamples * NumChannels * BitsPerSample/8
This is the number of bytes in the data.
You can also think of this as the size
of the read of the subchunk following this
number.
44 * Data The actual sound data.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace WaveLibrary
{
public class WaveFile
{
WaveHeader header;
WavefmtSubChunk fmt;
WavedataSubChunk data;
public WaveFile(int channels, int bitsPerSample, int sampleRate)
{
header = new WaveHeader();
fmt = new WavefmtSubChunk(channels, bitsPerSample, sampleRate);
}
public void SetData(byte[] SoundData, int numSamples)
{
data = new WavedataSubChunk(numSamples, fmt.NumChannels, fmt.BitsPerSample, SoundData);
}
public void WriteFile(string file)
{
FileStream fs = File.Create(file);
//Set the total file chunk size
//Has to be set here because we might not know what the actual Data size was until now
header.SetChunkSize(fmt.Size, data.Size);
header.WriteHeader(fs);
fmt.Writefmt(fs);
data.WriteData(fs);
fs.Close();
fs.Dispose();
}
public int NumChannels { get { return fmt.NumChannels; }}
public int BitsPerSample { get { return fmt.BitsPerSample; }}
}
}

View File

@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace WaveLibrary
{
class WaveHeader
{
string ChunkID = "RIFF";
int ChunkSize = 0;
string Format = "WAVE"; //Specifiy WAVE, AVI could also be used for a RIFF format
public WaveHeader()
{
}
public void SetChunkSize(int fmtSubChunkSize, int dataSubChunkSize)
{
ChunkSize = 4 + (8 + fmtSubChunkSize) + (8 + dataSubChunkSize);
}
public void WriteHeader(FileStream fs)
{
//ChunkID
byte[] riff = Encoding.ASCII.GetBytes(ChunkID);
fs.Write(riff, 0, riff.Length);
//Chunk Size
byte[] chunkSize = BitConverter.GetBytes(ChunkSize);
fs.Write(chunkSize, 0, chunkSize.Length);
//Data Type
byte[] wave = Encoding.ASCII.GetBytes(Format);
fs.Write(wave, 0, wave.Length);
}
public int Chunk_Size { get { return ChunkSize; }}
}
}

View File

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace WaveLibrary
{
class WavedataSubChunk
{
string SubChunk2ID = "data";
int SubChunk2Size;
byte[] SoundData;
public WavedataSubChunk(int NumSamples, int NumChannels, int BitsPerSample, byte[] SoundData)
{
SubChunk2Size = NumSamples * NumChannels * (BitsPerSample / 8);
this.SoundData = SoundData;
}
public void WriteData(FileStream fs)
{
//Chunk ID
byte[] _subChunk2ID = Encoding.ASCII.GetBytes(SubChunk2ID);
fs.Write(_subChunk2ID, 0, _subChunk2ID.Length);
//Chunk Size
byte[] _subChunk2Size = BitConverter.GetBytes(SubChunk2Size);
fs.Write(_subChunk2Size, 0, _subChunk2Size.Length);
//Wave Sound Data
fs.Write(SoundData, 0, SoundData.Length);
}
public int Size { get { return SubChunk2Size; } }
}
}

View File

@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace WaveLibrary
{
class WavefmtSubChunk
{
string SubChunk1ID = "fmt ";
int Subchunk1Size = 16; //For PCM
int AudioFormat = 1; //For no compression
public int NumChannels = 2; //1 For Mono, 2 For Stereo
int SampleRate = 22050;
int ByteRate;
int BlockAlign;
public int BitsPerSample = 16;
public WavefmtSubChunk(int channels, int bitsPerSamples, int sampleRate)
{
BitsPerSample = bitsPerSamples;
NumChannels = channels;
SampleRate = sampleRate;
ByteRate = SampleRate * NumChannels * (BitsPerSample / 8);
BlockAlign = NumChannels * (BitsPerSample / 8);
}
public void Writefmt(FileStream fs)
{
//Chunk ID
byte[] _subchunk1ID = Encoding.ASCII.GetBytes(SubChunk1ID);
fs.Write(_subchunk1ID, 0, _subchunk1ID.Length);
//Chunk Size
byte[] _subchunk1Size = BitConverter.GetBytes(Subchunk1Size);
fs.Write(_subchunk1Size, 0, _subchunk1Size.Length);
//Audio Format (PCM)
byte[] _audioFormat = BitConverter.GetBytes(AudioFormat);
fs.Write(_audioFormat, 0, 2);
//Number of Channels (1 or 2)
byte[] _numChannels = BitConverter.GetBytes(NumChannels);
fs.Write(_numChannels, 0, 2);
//Sample Rate
byte[] _sampleRate = BitConverter.GetBytes(SampleRate);
fs.Write(_sampleRate, 0, _sampleRate.Length);
//Byte Rate
byte[] _byteRate = BitConverter.GetBytes(ByteRate);
fs.Write(_byteRate, 0, _byteRate.Length);
//Block Align
byte[] _blockAlign = BitConverter.GetBytes(BlockAlign);
fs.Write(_blockAlign, 0, 2);
//Bits Per Sample
byte[] _bitsPerSample = BitConverter.GetBytes(BitsPerSample);
fs.Write(_bitsPerSample, 0, 2);
}
public int Size { get { return Subchunk1Size; } }
}
}