diff --git a/Cavern.Format/Output/AudioWriter.cs b/Cavern.Format/Output/AudioWriter.cs index d9590c92..f46e68c0 100644 --- a/Cavern.Format/Output/AudioWriter.cs +++ b/Cavern.Format/Output/AudioWriter.cs @@ -165,8 +165,8 @@ public void WriteOffset(float[][] samples, int period) { float[] empty = new float[samples[0].Length]; float[][] holder = new float[samples.Length][]; WriteHeader(); - for (int curPeriod = 0; curPeriod < period; ++curPeriod) { - for (int channel = 0; channel < holder.Length; ++channel) { + for (int curPeriod = 0; curPeriod < period; curPeriod++) { + for (int channel = 0; channel < holder.Length; channel++) { holder[channel] = channel % period == curPeriod ? samples[channel] : empty; } WriteBlock(holder, 0, holder[0].Length); @@ -181,7 +181,7 @@ public void WriteOffset(float[][] samples, int period) { /// Output channel count public void WriteForEachChannel(float[] samples, int channelCount) { float[][] holder = new float[channelCount][]; - for (int channel = 0; channel < channelCount; ++channel) { + for (int channel = 0; channel < channelCount; channel++) { holder[channel] = samples; } WriteOffset(holder); diff --git a/Cavern.Format/Output/LimitlessAudioFormatWriter.cs b/Cavern.Format/Output/LimitlessAudioFormatWriter.cs index 33a97d74..5c39495f 100644 --- a/Cavern.Format/Output/LimitlessAudioFormatWriter.cs +++ b/Cavern.Format/Output/LimitlessAudioFormatWriter.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Runtime.CompilerServices; using Cavern.Format.Common; using Cavern.Format.Consts; @@ -94,9 +95,20 @@ public static void Write(string path, float[][] data, int sampleRate, BitDepth b /// Output sample rate /// Output bit depth /// Output channel information + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteOffset(string path, float[][] data, int sampleRate, BitDepth bits, Channel[] channels) => + WriteOffset(path, data, sampleRate, bits, channels, channels.Length); + + /// + /// Export an audio file to be played back channel after channel, but some channels play simultaneously. + /// + /// Output file name + /// Samples to write in the file + /// Output sample rate + /// Output bit depth + /// Output channel information /// Channels separated by this many channels are played simultaneously - public static void WriteOffset(string path, float[][] data, int sampleRate, BitDepth bits, Channel[] channels, - int period = -1) { + public static void WriteOffset(string path, float[][] data, int sampleRate, BitDepth bits, Channel[] channels, int period) { LimitlessAudioFormatWriter writer = new LimitlessAudioFormatWriter(path, data[0].LongLength, sampleRate, bits, channels); writer.WriteOffset(data, period); } @@ -123,12 +135,12 @@ internal void WriteHeader(bool objectMode, int objectCount) { writer.WriteAny(qualityByte); writer.WriteAny(objectMode ? (byte)1 : (byte)0); // Mode writer.WriteAny(ChannelCount); // Channel/object count - for (int channel = 0; channel < objectCount; ++channel) { // Audible channel/object info + for (int channel = 0; channel < objectCount; channel++) { // Audible channel/object info writer.WriteAny(channels[channel].X); // Rotation on vertical axis writer.WriteAny(channels[channel].Y); // Rotation on horizontal axis writer.WriteAny(channels[channel].LFE ? (byte)1 : (byte)0); // Low frequency } - for (int channel = objectCount; channel < ChannelCount; ++channel) { // Positional track markers + for (int channel = objectCount; channel < ChannelCount; channel++) { // Positional track markers writer.WriteAny(float.NaN); // Marker writer.WriteAny(0); // Reserved writer.WriteAny((byte)0); // Reserved @@ -185,7 +197,7 @@ public override void WriteBlock(float[][] samples, long from, long to) { /// Samples to dump from the void DumpBlock(long until) { bool[] toWrite = new bool[ChannelCount]; - for (int channel = 0; channel < ChannelCount; ++channel) { + for (int channel = 0; channel < ChannelCount; channel++) { for (int sample = channel; !toWrite[channel] && sample < cache.Length; sample += ChannelCount) { if (cache[sample] != 0) { toWrite[channel] = true; @@ -193,7 +205,7 @@ void DumpBlock(long until) { } } byte[] layoutBytes = new byte[(ChannelCount & 7) == 0 ? ChannelCount >> 3 : ((ChannelCount >> 3) + 1)]; - for (int channel = 0; channel < ChannelCount; ++channel) { + for (int channel = 0; channel < ChannelCount; channel++) { if (toWrite[channel]) { layoutBytes[channel >> 3] += (byte)(1 << (channel & 7)); } diff --git a/Cavern.Format/Output/RIFFWaveWriter.cs b/Cavern.Format/Output/RIFFWaveWriter.cs index c691602a..db545376 100644 --- a/Cavern.Format/Output/RIFFWaveWriter.cs +++ b/Cavern.Format/Output/RIFFWaveWriter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.CompilerServices; using Cavern.Channels; using Cavern.Format.Common; @@ -116,8 +117,19 @@ public static void Write(string path, float[][] data, int sampleRate, BitDepth b /// Samples to write in the file /// Output sample rate /// Output bit depth + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteOffset(string path, float[][] data, int sampleRate, BitDepth bits) => + WriteOffset(path, data, sampleRate, bits, data.Length); + + /// + /// Export an audio file to be played back channel after channel, but some channels play simultaneously. + /// + /// Output file name + /// Samples to write in the file + /// Output sample rate + /// Output bit depth /// Channels separated by this many channels are played simultaneously - public static void WriteOffset(string path, float[][] data, int sampleRate, BitDepth bits, int period = -1) { + public static void WriteOffset(string path, float[][] data, int sampleRate, BitDepth bits, int period) { RIFFWaveWriter writer = new RIFFWaveWriter(path, data.Length, data[0].LongLength, sampleRate, bits); writer.WriteOffset(data, period); } @@ -267,7 +279,7 @@ public override void WriteBlock(float[][] samples, long from, long to) { switch (Bits) { case BitDepth.Int8: while (from < to) { - for (int channel = 0; channel < samples.Length; ++channel) { + for (int channel = 0; channel < samples.Length; channel++) { writer.WriteAny((sbyte)(samples[channel][from] * sbyte.MaxValue)); } ++from; @@ -275,7 +287,7 @@ public override void WriteBlock(float[][] samples, long from, long to) { break; case BitDepth.Int16: while (from < to) { - for (int channel = 0; channel < samples.Length; ++channel) { + for (int channel = 0; channel < samples.Length; channel++) { writer.WriteAny((short)(samples[channel][from] * short.MaxValue)); } ++from; @@ -283,7 +295,7 @@ public override void WriteBlock(float[][] samples, long from, long to) { break; case BitDepth.Int24: while (from < to) { - for (int channel = 0; channel < samples.Length; ++channel) { + for (int channel = 0; channel < samples.Length; channel++) { int src = (int)(samples[channel][from] * BitConversions.int24Max); writer.WriteAny((short)src); writer.WriteAny((byte)(src >> 16)); @@ -293,7 +305,7 @@ public override void WriteBlock(float[][] samples, long from, long to) { break; case BitDepth.Float32: while (from < to) { - for (int channel = 0; channel < samples.Length; ++channel) { + for (int channel = 0; channel < samples.Length; channel++) { writer.WriteAny(samples[channel][from]); } ++from; @@ -302,6 +314,15 @@ public override void WriteBlock(float[][] samples, long from, long to) { } } + /// + /// Append an extra chunk to the file, without considering its alignment to even bytes. + /// + /// 4 byte identifier of the chunk + /// Raw data of the chunk + /// The has a different byte order in the file to memory, + /// refer to for samples. + public void WriteChunk(int id, byte[] data) => WriteChunk(id, data, false); + /// /// Append an extra chunk to the file. /// @@ -310,7 +331,7 @@ public override void WriteBlock(float[][] samples, long from, long to) { /// Some RIFF readers only work if all chunks start at an even byte, this is for their support /// The has a different byte order in the file to memory, /// refer to for samples. - public void WriteChunk(int id, byte[] data, bool dwordPadded = false) { + public void WriteChunk(int id, byte[] data, bool dwordPadded) { writer.WriteAny(id); if (data.LongLength > uint.MaxValue) { largeChunkSizes ??= new List>();