diff --git a/Source/CsbBuilder/App.config b/Source/CsbBuilder/App.config index bbfefd3..8c267bf 100644 --- a/Source/CsbBuilder/App.config +++ b/Source/CsbBuilder/App.config @@ -1,6 +1,18 @@  + + +
+ + + + + + False + + + \ No newline at end of file diff --git a/Source/CsbBuilder/Audio/AdxConverter.cs b/Source/CsbBuilder/Audio/AdxConverter.cs deleted file mode 100644 index be27156..0000000 --- a/Source/CsbBuilder/Audio/AdxConverter.cs +++ /dev/null @@ -1,235 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.IO; - -using SonicAudioLib.IO; -using NAudio.Wave; - -namespace CsbBuilder.Audio -{ - public struct AdxHeader - { - public ushort Identifier; - public ushort DataPosition; - public byte EncodeType; - public byte BlockLength; - public byte SampleBitdepth; - public byte ChannelCount; - public uint SampleRate; - public uint SampleCount; - public ushort CutoffFrequency; - public byte Version; - public byte Flags; - public bool LoopEnabled; - public uint LoopBeginSampleIndex; - public uint LoopBeginByteIndex; - public uint LoopEndSampleIndex; - public uint LoopEndByteIndex; - } - - public static class AdxConverter - { - public static void ConvertToWav(string sourceFileName) - { - ConvertToWav(sourceFileName, Path.ChangeExtension(sourceFileName, "wav")); - } - - public static void ConvertToWav(string sourceFileName, string destinationFileName) - { - BufferedWaveProvider provider = Decode(sourceFileName, 1.0, 0.0); - - using (WaveFileWriter writer = new WaveFileWriter(destinationFileName, provider.WaveFormat)) - { - int num; - - byte[] buffer = new byte[32767]; - while ((num = provider.Read(buffer, 0, buffer.Length)) != 0) - { - writer.Write(buffer, 0, num); - } - } - - provider.ClearBuffer(); - } - - public static AdxHeader LoadHeader(string sourceFileName) - { - using (Stream source = File.OpenRead(sourceFileName)) - { - return ReadHeader(source); - } - } - - public static AdxHeader ReadHeader(Stream source) - { - AdxHeader header = new AdxHeader(); - header.Identifier = EndianStream.ReadUInt16BE(source); - header.DataPosition = EndianStream.ReadUInt16BE(source); - header.EncodeType = EndianStream.ReadByte(source); - header.BlockLength = EndianStream.ReadByte(source); - header.SampleBitdepth = EndianStream.ReadByte(source); - header.ChannelCount = EndianStream.ReadByte(source); - header.SampleRate = EndianStream.ReadUInt32BE(source); - header.SampleCount = EndianStream.ReadUInt32BE(source); - header.CutoffFrequency = EndianStream.ReadUInt16BE(source); - header.Version = EndianStream.ReadByte(source); - header.Flags = EndianStream.ReadByte(source); - source.Seek(4, SeekOrigin.Current); - header.LoopEnabled = EndianStream.ReadUInt32BE(source) > 0; - header.LoopBeginSampleIndex = EndianStream.ReadUInt32BE(source); - header.LoopBeginByteIndex = EndianStream.ReadUInt32BE(source); - header.LoopEndSampleIndex = EndianStream.ReadUInt32BE(source); - header.LoopEndByteIndex = EndianStream.ReadUInt32BE(source); - return header; - } - - public static BufferedWaveProvider Decode(string sourceFileName, double volume, double pitch) - { - using (Stream source = File.OpenRead(sourceFileName)) - { - return Decode(source, volume, pitch); - } - } - - private static void CalculateCoefficients(double cutoffFrequency, double sampleRate, out short coef1, out short coef2) - { - double a = Math.Sqrt(2.0); - double b = a - Math.Cos(cutoffFrequency * 6.2831855 / sampleRate); - double c = (b - Math.Sqrt((b - (a - 1.0)) * (a - 1.0 + b))) / (a - 1.0); - - coef1 = (short)(8192.0 * c); - coef2 = (short)(c * c * -4096.0); - } - - // https://wiki.multimedia.cx/index.php/CRI_ADX_ADPCM - public static BufferedWaveProvider Decode(Stream source, double volume, double pitch) - { - AdxHeader header = ReadHeader(source); - - WaveFormat waveFormat = new WaveFormat((int)header.SampleRate, 16, header.ChannelCount); - BufferedWaveProvider provider = new BufferedWaveProvider(waveFormat); - provider.BufferLength = (int)(header.SampleCount * header.ChannelCount * 2); - - provider.ReadFully = false; - provider.DiscardOnBufferOverflow = true; - - short firstHistory1 = 0; - short firstHistory2 = 0; - short secondHistory1 = 0; - short secondHistory2 = 0; - - CalculateCoefficients(header.CutoffFrequency, header.SampleRate, out short coef1, out short coef2); - - source.Seek(header.DataPosition + 4, SeekOrigin.Begin); - - if (header.ChannelCount == 1) - { - for (int i = 0; i < header.SampleCount / 32; i++) - { - byte[] block = EndianStream.ReadBytes(source, header.BlockLength); - foreach (short sampleShort in DecodeBlock(block, ref firstHistory1, ref firstHistory2, coef1, coef2)) - { - double sample = (double)sampleShort * volume; - - if (sample > short.MaxValue) - { - sample = short.MaxValue; - } - - if (sample < short.MinValue) - { - sample = short.MinValue; - } - - provider.AddSamples(BitConverter.GetBytes((short)sample), 0, 2); - } - } - } - - else if (header.ChannelCount == 2) - { - for (int i = 0; i < header.SampleCount / 32; i++) - { - byte[] blockLeft = EndianStream.ReadBytes(source, header.BlockLength); - byte[] blockRight = EndianStream.ReadBytes(source, header.BlockLength); - - short[] samplesLeft = DecodeBlock(blockLeft, ref firstHistory1, ref firstHistory2, coef1, coef2); - short[] samplesRight = DecodeBlock(blockRight, ref secondHistory1, ref secondHistory2, coef1, coef2); - - for (int j = 0; j < 32; j++) - { - double newSampleLeft = samplesLeft[j] * volume; - double newSampleRight = samplesRight[j] * volume; - - if (newSampleLeft > short.MaxValue) - { - newSampleLeft = short.MaxValue; - } - - if (newSampleLeft < short.MinValue) - { - newSampleLeft = short.MinValue; - } - - if (newSampleRight > short.MaxValue) - { - newSampleRight = short.MaxValue; - } - - if (newSampleRight < short.MinValue) - { - newSampleRight = short.MinValue; - } - - samplesLeft[j] = (short)newSampleLeft; - samplesRight[j] = (short)newSampleRight; - - byte[] sampleLeft = BitConverter.GetBytes(samplesLeft[j]); - byte[] sampleRight = BitConverter.GetBytes(samplesRight[j]); - - provider.AddSamples(new byte[] { sampleLeft[0], sampleLeft[1], sampleRight[0], sampleRight[1] }, 0, 4); - } - } - } - - return provider; - } - - public static short[] DecodeBlock(byte[] block, ref short history1, ref short history2, short coef1, short coef2) - { - int scale = (block[0] << 8 | block[1]) + 1; - - short[] samples = new short[32]; - - for (int i = 0; i < 32; i++) - { - int sampleByte = block[2 + i / 2]; - int sampleNibble = ((i & 1) != 0 ? (sampleByte & 7) - (sampleByte & 8) : ((sampleByte & 0x70) - (sampleByte & 0x80)) >> 4); - int sampleDelta = sampleNibble * scale; - int predictedSample12 = coef1 * history1 + coef2 * history2; - int predictedSample = predictedSample12 >> 12; - - int sampleRaw = predictedSample + sampleDelta; - - if (sampleRaw > short.MaxValue) - { - sampleRaw = short.MaxValue; - } - - else if (sampleRaw < short.MinValue) - { - sampleRaw = short.MinValue; - } - - samples[i] = (short)sampleRaw; - - history2 = history1; - history1 = (short)sampleRaw; - } - - return samples; - } - } -} diff --git a/Source/CsbBuilder/Audio/AdxFileReader.cs b/Source/CsbBuilder/Audio/AdxFileReader.cs new file mode 100644 index 0000000..a383bf4 --- /dev/null +++ b/Source/CsbBuilder/Audio/AdxFileReader.cs @@ -0,0 +1,478 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +using SonicAudioLib.IO; + +using NAudio.Wave; +using NAudio.Wave.SampleProviders; + +namespace CsbBuilder.Audio +{ + public struct AdxHeader + { + public ushort Identifier; + public ushort DataPosition; + public byte EncodeType; + public byte BlockLength; + public byte SampleBitdepth; + public byte ChannelCount; + public uint SampleRate; + public uint SampleCount; + public ushort CutoffFrequency; + public ushort Version; + public short[][] SampleHistories; + } + + public class AdxFileReader : WaveStream + { + private class SampleHistory + { + public short Sample1 = 0; + public short Sample2 = 0; + } + + private Stream source; + + private AdxHeader header; + private WaveFormat waveFormat; + + private short coef1; + private short coef2; + + private SampleHistory[] histories; + + private int sampleCount; + private int readSamples; + + private byte[] previousSamples; + + private double volume = 1; + private double pitch = 0; + private long delayTime = 0; + private DateTime startTime; + + public override WaveFormat WaveFormat + { + get + { + return waveFormat; + } + } + + public override long Length + { + get + { + return sampleCount * 2; + } + } + + public override long Position + { + get + { + return readSamples * 2; + } + + set + { + throw new NotImplementedException(); + } + } + + public bool IsFinished + { + get + { + return readSamples >= sampleCount; + } + } + + public bool IsLoopEnabled { get; set; } + + public double Volume + { + set + { + volume = value; + } + } + + public double Pitch + { + set + { + pitch = value; + } + } + + public int DelayTime + { + set + { + startTime = DateTime.Now; + delayTime = value * 10000; + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + if (IsFinished && !IsLoopEnabled) + { + return 0; + } + + if (delayTime > 0) + { + if ((DateTime.Now - startTime).Ticks < delayTime) + { + return count; + } + + delayTime = 0; + } + + int length = count; + + while ((length % (header.ChannelCount * 64)) != 0) + { + length++; + } + + byte[] samples = new byte[length]; + + int currentLength = 0; + + while (currentLength < length) + { + int sampleLength = GetNextSamples(samples, currentLength); + + if (sampleLength < 0) + { + count = count > currentLength ? currentLength : count; + break; + } + + currentLength = sampleLength; + } + + if (previousSamples != null) + { + samples = previousSamples.Concat(samples).ToArray(); + length = samples.Length; + } + + if (length > count) + { + previousSamples = samples.Skip(count).ToArray(); + } + + else if (length < count) + { + previousSamples = null; + count = length; + } + + else + { + previousSamples = null; + } + + Array.Copy(samples, 0, buffer, offset, count); + + return count; + } + + private int GetNextSamples(byte[] destination, int startIndex) + { + short[][] channelSamples = new short[header.ChannelCount][]; + + for (int i = 0; i < header.ChannelCount; i++) + { + if (!DecodeBlock(i, out short[] samples)) + { + if (IsLoopEnabled) + { + Reset(); + DecodeBlock(i, out samples); + } + + else + { + readSamples = sampleCount; + return -1; + } + } + + channelSamples[i] = samples; + } + + int position = startIndex; + + for (int i = 0; i < 32; i++) + { + for (int j = 0; j < header.ChannelCount; j++) + { + short sample = (short)(channelSamples[j][i] * volume); + + destination[position++] = (byte)sample; + destination[position++] = (byte)(sample >> 8); + } + } + + return position; + } + + private bool DecodeBlock(int c, out short[] samples) + { + int scale = EndianStream.ReadUInt16BE(source) + 1; + + // There seems to be a null sample block at the end of every adx file. + // It always added a half second delay between intro and loop, so + // I wanted to get rid of it. + if (scale > short.MaxValue + 1) + { + samples = null; + return false; + } + + samples = new short[32]; + + int sampleByte = 0; + + SampleHistory history = histories[c]; + for (int i = 0; i < 32; i++) + { + if ((i % 2) == 0) + { + sampleByte = source.ReadByte(); + } + + int sample = ((i & 1) != 0 ? + (sampleByte & 7) - (sampleByte & 8) : + ((sampleByte & 0x70) - (sampleByte & 0x80)) >> 4) * scale + + ((coef1 * history.Sample1 + coef2 * history.Sample2) >> 12); + + sample = sample > short.MaxValue ? short.MaxValue : sample < short.MinValue ? short.MinValue : sample; + + samples[i] = (short)sample; + + history.Sample2 = history.Sample1; + history.Sample1 = (short)sample; + + readSamples++; + } + + return true; + } + + public void Reset() + { + source.Seek(header.DataPosition + 4, SeekOrigin.Begin); + readSamples = 0; + } + + public void ReplaceHistories(AdxFileReader reader) + { + histories = reader.histories; + } + + public static AdxHeader LoadHeader(string sourceFileName) + { + using (Stream source = File.OpenRead(sourceFileName)) + { + return ReadHeader(source); + } + } + + public static AdxHeader ReadHeader(Stream source) + { + AdxHeader header = new AdxHeader(); + header.Identifier = EndianStream.ReadUInt16BE(source); + header.DataPosition = EndianStream.ReadUInt16BE(source); + header.EncodeType = EndianStream.ReadByte(source); + header.BlockLength = EndianStream.ReadByte(source); + header.SampleBitdepth = EndianStream.ReadByte(source); + header.ChannelCount = EndianStream.ReadByte(source); + header.SampleRate = EndianStream.ReadUInt32BE(source); + header.SampleCount = EndianStream.ReadUInt32BE(source); + header.CutoffFrequency = EndianStream.ReadUInt16BE(source); + header.Version = EndianStream.ReadUInt16BE(source); + return header; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + source.Close(); + } + + base.Dispose(disposing); + } + + public AdxFileReader(string fileName) : this(File.OpenRead(fileName)) + { + } + + public AdxFileReader(Stream source) + { + this.source = source; + + header = AdxFileReader.ReadHeader(this.source); + source.Seek(header.DataPosition + 4, SeekOrigin.Begin); + + // Calculate coefficients + double a = Math.Sqrt(2.0); + double b = a - Math.Cos(header.CutoffFrequency * Math.PI * 2.0 / header.SampleRate); + double c = (b - Math.Sqrt((b - (a - 1.0)) * (a - 1.0 + b))) / (a - 1.0); + + coef1 = (short)(8192.0 * c); + coef2 = (short)(c * c * -4096.0); + + histories = new SampleHistory[header.ChannelCount]; + for (int i = 0; i < histories.Length; i++) + { + histories[i] = new SampleHistory(); + } + + sampleCount = (int)(header.SampleCount * header.ChannelCount); + waveFormat = new WaveFormat((int)header.SampleRate, 16, header.ChannelCount); + } + } + + public class ExtendedAdxFileReader : WaveStream + { + private List readers = new List(); + private int currentIndex = 0; + + public override long Length + { + get + { + long totalLength = 0; + + foreach (AdxFileReader reader in readers) + { + totalLength += reader.Length; + } + + return totalLength; + } + } + + public override long Position + { + get + { + long position = 0; + + foreach (AdxFileReader reader in readers) + { + if (reader == readers[currentIndex]) + { + position += reader.Position; + break; + } + + position += reader.Length; + } + + return position; + } + + set + { + throw new NotImplementedException(); + } + } + + public override WaveFormat WaveFormat + { + get + { + return readers[currentIndex].WaveFormat; + } + } + + public double Volume + { + set + { + readers.ForEach(reader => reader.Volume = value); + } + } + + public double Pitch + { + set + { + readers.ForEach(reader => reader.Pitch = value); + } + } + + public int DelayTime + { + set + { + readers.First().DelayTime = value; + } + } + + public override int Read(byte[] buffer, int offset, int count) + { + int num = readers[currentIndex].Read(buffer, 0, count); + + if ((num < count) && !readers[currentIndex].IsLoopEnabled) + { + currentIndex++; + + readers[currentIndex].ReplaceHistories(readers[currentIndex - 1]); + + int num2 = readers[currentIndex].Read(buffer, num, count - num); + return num + num2; + } + + else if (readers[currentIndex].IsFinished && !readers[currentIndex].IsLoopEnabled) + { + currentIndex++; + + readers[currentIndex].ReplaceHistories(readers[currentIndex - 1]); + + num = readers[currentIndex].Read(buffer, 0, count); + } + + return num; + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + readers.ForEach(reader => reader.Dispose()); + } + + base.Dispose(disposing); + } + + public ExtendedAdxFileReader(params string[] fileNames) : this(fileNames.Select(fileName => File.OpenRead(fileName)).ToArray()) + { + } + + public ExtendedAdxFileReader(params Stream[] sources) + { + foreach (Stream source in sources) + { + readers.Add(new AdxFileReader(source)); + } + + // The last one is the one to loop + readers.Last().IsLoopEnabled = true; + } + } +} diff --git a/Source/CsbBuilder/Builder/CsbBuilder.cs b/Source/CsbBuilder/Builder/CsbBuilder.cs index 4e5e2f0..87b9046 100644 --- a/Source/CsbBuilder/Builder/CsbBuilder.cs +++ b/Source/CsbBuilder/Builder/CsbBuilder.cs @@ -307,11 +307,11 @@ namespace CsbBuilder.Builder }); // Finally, serialize the CSB file. - CriTableSerializer.Serialize(outputFileName, cueSheetTables, CriTableWriterSettings.AdxSettings); + CriTableSerializer.Serialize(outputFileName, cueSheetTables, CriTableWriterSettings.AdxSettings, MainForm.Settings.BufferSize); if (cpkArchive.Count > 0) { - cpkArchive.Save(Path.ChangeExtension(outputFileName, "cpk")); + cpkArchive.Save(Path.ChangeExtension(outputFileName, "cpk"), MainForm.Settings.BufferSize); } foreach (FileInfo junk in junks) diff --git a/Source/CsbBuilder/CreateNewProjectForm.cs b/Source/CsbBuilder/CreateNewProjectForm.cs index 6006d22..a6da91a 100644 --- a/Source/CsbBuilder/CreateNewProjectForm.cs +++ b/Source/CsbBuilder/CreateNewProjectForm.cs @@ -30,7 +30,7 @@ namespace CsbBuilder maskedTextBox1.Text = Path.GetFileNameWithoutExtension(name); string directoryName = Path.GetDirectoryName(name); - maskedTextBox2.Text = !string.IsNullOrEmpty(directoryName) ? Path.ChangeExtension(name, null) : Path.Combine(Program.ProjectsPath, name); + maskedTextBox2.Text = !string.IsNullOrEmpty(directoryName) && MainForm.Settings.ImportedCsbProjectDirectory == Settings.ProjectDirectory.DirectoryOfCsb ? Path.ChangeExtension(name, null) : Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), MainForm.Settings.ProjectsDirectory, Path.GetFileNameWithoutExtension(name)); } public CreateNewProjectForm() diff --git a/Source/CsbBuilder/CsbBuilder.csproj b/Source/CsbBuilder/CsbBuilder.csproj index 2ec849b..59f301e 100644 --- a/Source/CsbBuilder/CsbBuilder.csproj +++ b/Source/CsbBuilder/CsbBuilder.csproj @@ -53,6 +53,7 @@ + @@ -74,9 +75,9 @@ CreateNewProjectForm.cs - + Form @@ -107,6 +108,12 @@ SetReferenceForm.cs + + Form + + + SettingsForm.cs + ExceptionForm.cs @@ -132,16 +139,10 @@ SetReferenceForm.cs + + SettingsForm.cs + - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - @@ -223,6 +224,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Source/SonicAudioCmd/Program.cs b/Source/SonicAudioCmd/Program.cs index e0eea1c..b312815 100644 --- a/Source/SonicAudioCmd/Program.cs +++ b/Source/SonicAudioCmd/Program.cs @@ -20,11 +20,28 @@ namespace SonicAudioCmd { static void Main(string[] args) { - CriTable table = new CriTable(); - table.Load("test.utf"); + try + { + CriCpkArchive archive = new CriCpkArchive(); + archive.Load(args[0]); - Console.WriteLine(table.Rows[0]["testField"]); - Console.ReadLine(); + using (Stream source = File.OpenRead(args[0])) + { + foreach (CriCpkEntry entry in archive) + { + using (Stream destination = File.Create(entry.Name)) + { + EndianStream.CopyPartTo(source, destination, entry.Position, entry.Length, ushort.MaxValue); + } + } + } + } + + catch (Exception exception) + { + Console.WriteLine(exception); + Console.ReadLine(); + } } } } diff --git a/Source/SonicAudioLib/CriMw/CriTableWriter.cs b/Source/SonicAudioLib/CriMw/CriTableWriter.cs index 70d3e96..b520539 100644 --- a/Source/SonicAudioLib/CriMw/CriTableWriter.cs +++ b/Source/SonicAudioLib/CriMw/CriTableWriter.cs @@ -473,7 +473,7 @@ namespace SonicAudioLib.CriMw private void WriteModule(ModuleBase module) { WriteUInt32((uint)vldPool.Put(module)); - WriteUInt32((uint)module.CalculateLength()); + WriteUInt32(0); } private void WriteGuid(Guid guid) diff --git a/Source/SonicAudioLib/CriMw/Serialization/CriTableSerializer.cs b/Source/SonicAudioLib/CriMw/Serialization/CriTableSerializer.cs index f9ff63f..27c252e 100644 --- a/Source/SonicAudioLib/CriMw/Serialization/CriTableSerializer.cs +++ b/Source/SonicAudioLib/CriMw/Serialization/CriTableSerializer.cs @@ -25,7 +25,12 @@ namespace SonicAudioLib.CriMw.Serialization public static void Serialize(string destinationFileName, List objects, CriTableWriterSettings settings) { - using (Stream destination = File.Create(destinationFileName)) + Serialize(destinationFileName, objects, settings, 4096); + } + + public static void Serialize(string destinationFileName, List objects, CriTableWriterSettings settings, int bufferSize) + { + using (Stream destination = File.Create(destinationFileName, bufferSize)) { Serialize(destination, objects, settings); } @@ -226,7 +231,12 @@ namespace SonicAudioLib.CriMw.Serialization public static List Deserialize(string sourceFileName) { - return Deserialize(sourceFileName, typeof(T)).OfType().ToList(); + return Deserialize(sourceFileName, 4096); + } + + public static List Deserialize(string sourceFileName, int bufferSize) + { + return Deserialize(sourceFileName, typeof(T), bufferSize).OfType().ToList(); } public static List Deserialize(Stream source) @@ -247,14 +257,14 @@ namespace SonicAudioLib.CriMw.Serialization } } - public static ArrayList Deserialize(string sourceFileName, Type type) + public static ArrayList Deserialize(string sourceFileName, Type type, int bufferSize) { if (!File.Exists(sourceFileName)) { return new ArrayList(); } - using (Stream source = File.OpenRead(sourceFileName)) + using (Stream source = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize)) { return Deserialize(source, type); } @@ -314,6 +324,8 @@ namespace SonicAudioLib.CriMw.Serialization value = Convert.ChangeType(value, Enum.GetUnderlyingType(propertyInfo.PropertyType)); } + value = Convert.ChangeType(value, propertyInfo.PropertyType); + propertyInfo.SetValue(obj, value); } diff --git a/Source/SonicAudioLib/IO/Substream.cs b/Source/SonicAudioLib/IO/Substream.cs index 0ff8c92..6304c74 100644 --- a/Source/SonicAudioLib/IO/Substream.cs +++ b/Source/SonicAudioLib/IO/Substream.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; namespace SonicAudioLib.IO { @@ -170,10 +171,10 @@ namespace SonicAudioLib.IO /// public byte[] ToArray() { - using (MemoryStream memoryStream = new MemoryStream()) + using (MemoryStream destination = new MemoryStream()) { - CopyTo(memoryStream); - return memoryStream.ToArray(); + CopyTo(destination); + return destination.ToArray(); } } diff --git a/Source/SonicAudioLib/IO/VldPool.cs b/Source/SonicAudioLib/IO/VldPool.cs index 545feaa..118e49b 100644 --- a/Source/SonicAudioLib/IO/VldPool.cs +++ b/Source/SonicAudioLib/IO/VldPool.cs @@ -95,7 +95,7 @@ namespace SonicAudioLib.IO length = Helpers.Align(length, align); long position = length; - length += module.CalculateLength(); + length += 0; items.Add(module); return position; diff --git a/Source/SonicAudioLib/Module/ModuleBase.cs b/Source/SonicAudioLib/Module/ModuleBase.cs index 7029627..85542a1 100644 --- a/Source/SonicAudioLib/Module/ModuleBase.cs +++ b/Source/SonicAudioLib/Module/ModuleBase.cs @@ -11,14 +11,19 @@ namespace SonicAudioLib.Module public abstract void Read(Stream source); public abstract void Write(Stream destination); - public virtual void Load(string sourceFileName) + public virtual void Load(string sourceFileName, int bufferSize) { - using (Stream source = File.OpenRead(sourceFileName)) + using (Stream source = new FileStream(sourceFileName, FileMode.Open, FileAccess.Read, FileShare.None, bufferSize)) { Read(source); } } + public virtual void Load(string sourceFileName) + { + Load(sourceFileName, 4096); + } + public virtual void Load(byte[] sourceByteArray) { using (Stream source = new MemoryStream(sourceByteArray)) @@ -29,7 +34,12 @@ namespace SonicAudioLib.Module public virtual void Save(string destinationFileName) { - using (Stream destination = File.Create(destinationFileName)) + Save(destinationFileName, 4096); + } + + public virtual void Save(string destinationFileName, int bufferSize) + { + using (Stream destination = File.Create(destinationFileName, bufferSize)) { Write(destination); } @@ -43,10 +53,5 @@ namespace SonicAudioLib.Module return destination.ToArray(); } } - - public virtual long CalculateLength() - { - return -1; - } } }