diff --git a/Sources/Accord.Audio.DirectSound/Accord.Audio.DirectSound.csproj b/Sources/Accord.Audio.DirectSound/Accord.Audio.DirectSound.csproj
index a8e4add72..39efafceb 100644
--- a/Sources/Accord.Audio.DirectSound/Accord.Audio.DirectSound.csproj
+++ b/Sources/Accord.Audio.DirectSound/Accord.Audio.DirectSound.csproj
@@ -12,7 +12,8 @@
True
DEBUG;TRACE
$(SolutionDir)..\Debug\
-
+
+
TRACE;NET35
@@ -40,8 +41,6 @@
v4.5
-
-
@@ -80,7 +79,6 @@
-
@@ -99,9 +97,9 @@
+
-
-
+
diff --git a/Sources/Accord.Audio.DirectSound/WaveDecoder.cs b/Sources/Accord.Audio.DirectSound/Formats/WaveDecoder.cs
similarity index 100%
rename from Sources/Accord.Audio.DirectSound/WaveDecoder.cs
rename to Sources/Accord.Audio.DirectSound/Formats/WaveDecoder.cs
diff --git a/Sources/Accord.Audio.DirectSound/WaveEncoder.cs b/Sources/Accord.Audio.DirectSound/Formats/WaveEncoder.cs
similarity index 98%
rename from Sources/Accord.Audio.DirectSound/WaveEncoder.cs
rename to Sources/Accord.Audio.DirectSound/Formats/WaveEncoder.cs
index ba1199204..470466093 100644
--- a/Sources/Accord.Audio.DirectSound/WaveEncoder.cs
+++ b/Sources/Accord.Audio.DirectSound/Formats/WaveEncoder.cs
@@ -45,6 +45,7 @@ namespace Accord.Audio.Formats
///
///
///
+ [FormatEncoder("wav")]
public class WaveEncoder : IAudioEncoder
{
private Stream waveStream;
@@ -273,7 +274,7 @@ public void Encode(Signal signal)
}
// Update counters
- numberOfSamples += signal.Samples;
+ numberOfSamples += signal.NumberOfSamples;
numberOfFrames += signal.Length;
bytes += signal.RawData.Length;
duration += (int)signal.Duration.TotalMilliseconds;
@@ -339,7 +340,7 @@ private void firstWriteHeaders()
private void initialize(Signal signal)
{
- this.channels = signal.Channels;
+ this.channels = signal.NumberOfChannels;
this.sampleRate = signal.SampleRate;
this.sampleFormat = signal.SampleFormat;
this.bitsPerSample = Signal.GetSampleSize(signal.SampleFormat);
diff --git a/Sources/Accord.Audio/Accord.Audio.csproj b/Sources/Accord.Audio/Accord.Audio.csproj
index 9201559cd..797d89e98 100644
--- a/Sources/Accord.Audio/Accord.Audio.csproj
+++ b/Sources/Accord.Audio/Accord.Audio.csproj
@@ -58,10 +58,12 @@
+
+
@@ -100,7 +102,7 @@
-
+
diff --git a/Sources/Accord.Audio/AudioSourceMixer.cs b/Sources/Accord.Audio/AudioSourceMixer.cs
index 41493ec36..5b9e8ec95 100644
--- a/Sources/Accord.Audio/AudioSourceMixer.cs
+++ b/Sources/Accord.Audio/AudioSourceMixer.cs
@@ -370,7 +370,7 @@ private unsafe void WorkerThread()
short* src = (short*)signal.Data.ToPointer();
- if (signal.Channels < channels)
+ if (signal.NumberOfChannels < channels)
{
for (int j = 0; j < frameSize; j += 2, src++)
{
diff --git a/Sources/Accord.Audio/ComplexFilters/Base/BaseComplexFilter.cs b/Sources/Accord.Audio/ComplexFilters/Base/BaseComplexFilter.cs
index bc2e7c5d9..41b9ee88c 100644
--- a/Sources/Accord.Audio/ComplexFilters/Base/BaseComplexFilter.cs
+++ b/Sources/Accord.Audio/ComplexFilters/Base/BaseComplexFilter.cs
@@ -37,7 +37,7 @@ public abstract class BaseComplexFilter : IComplexFilter
public ComplexSignal Apply(ComplexSignal complexSignal)
{
// get number of channels and samples
- int channels = complexSignal.Channels;
+ int channels = complexSignal.NumberOfChannels;
int samples = complexSignal.Length;
// retrieve other information
diff --git a/Sources/Accord.Audio/ComplexFilters/CombFilter.cs b/Sources/Accord.Audio/ComplexFilters/CombFilter.cs
index 1e3d238c5..b7e32cd16 100644
--- a/Sources/Accord.Audio/ComplexFilters/CombFilter.cs
+++ b/Sources/Accord.Audio/ComplexFilters/CombFilter.cs
@@ -114,7 +114,7 @@ private void generateBaseSignal()
///
protected override void ProcessFilter(ComplexSignal sourceData, ComplexSignal destinationData)
{
- int samples = sourceData.Samples;
+ int samples = sourceData.NumberOfSamples;
unsafe
{
diff --git a/Sources/Accord.Audio/ComplexFilters/EnvelopeFilter.cs b/Sources/Accord.Audio/ComplexFilters/EnvelopeFilter.cs
index 5176f30ed..49e62275f 100644
--- a/Sources/Accord.Audio/ComplexFilters/EnvelopeFilter.cs
+++ b/Sources/Accord.Audio/ComplexFilters/EnvelopeFilter.cs
@@ -63,7 +63,7 @@ protected unsafe override void ProcessFilter(ComplexSignal sourceData, ComplexSi
if (sourceData.Status != ComplexSignalStatus.Analytic)
throw new ArgumentException("Signal must be in analytic form.", "sourceData");
- int samples = sourceData.Samples;
+ int samples = sourceData.NumberOfSamples;
Complex* src = (Complex*)sourceData.Data.ToPointer();
Complex* dst = (Complex*)destinationData.Data.ToPointer();
diff --git a/Sources/Accord.Audio/Filters/AddFilter.cs b/Sources/Accord.Audio/Filters/AddFilter.cs
index b525247e1..57b768f28 100644
--- a/Sources/Accord.Audio/Filters/AddFilter.cs
+++ b/Sources/Accord.Audio/Filters/AddFilter.cs
@@ -69,7 +69,7 @@ public AddFilter(Signal overlaySignal)
protected unsafe override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
+ int channels = sourceData.NumberOfChannels;
int length = sourceData.Length;
if (format == SampleFormat.Format32BitIeeeFloat)
diff --git a/Sources/Accord.Audio/Filters/Base/BaseFilter.cs b/Sources/Accord.Audio/Filters/Base/BaseFilter.cs
index 8c30967f2..aeea5bc3b 100644
--- a/Sources/Accord.Audio/Filters/Base/BaseFilter.cs
+++ b/Sources/Accord.Audio/Filters/Base/BaseFilter.cs
@@ -64,8 +64,8 @@ public Signal Apply(Signal signal)
CheckSourceFormat(signal.SampleFormat);
// get number of channels and samples
- int channels = signal.Channels;
- int samples = signal.Length;
+ int channels = signal.NumberOfChannels;
+ int samples = signal.NumberOfFrames;
// retrieve other information
int rate = signal.SampleRate;
diff --git a/Sources/Accord.Audio/Filters/Base/BaseInPlaceFilter.cs b/Sources/Accord.Audio/Filters/Base/BaseInPlaceFilter.cs
index 4d1a90bdb..2dd5aa970 100644
--- a/Sources/Accord.Audio/Filters/Base/BaseInPlaceFilter.cs
+++ b/Sources/Accord.Audio/Filters/Base/BaseInPlaceFilter.cs
@@ -64,8 +64,8 @@ public Signal Apply(Signal signal)
CheckSourceFormat(signal.SampleFormat);
// get number of channels and samples
- int channels = signal.Channels;
- int samples = signal.Length;
+ int channels = signal.NumberOfChannels;
+ int samples = signal.NumberOfFrames;
// retrieve other information
int rate = signal.SampleRate;
diff --git a/Sources/Accord.Audio/Filters/EnvelopeFilter.cs b/Sources/Accord.Audio/Filters/EnvelopeFilter.cs
index e9e2aa513..4ec894e70 100644
--- a/Sources/Accord.Audio/Filters/EnvelopeFilter.cs
+++ b/Sources/Accord.Audio/Filters/EnvelopeFilter.cs
@@ -67,7 +67,7 @@ public EnvelopeFilter(float alpha)
protected unsafe override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
+ int channels = sourceData.NumberOfChannels;
int length = sourceData.Length;
if (format == SampleFormat.Format32BitIeeeFloat)
diff --git a/Sources/Accord.Audio/Filters/ExtractChannel.cs b/Sources/Accord.Audio/Filters/ExtractChannel.cs
index 9315455ad..8773884f4 100644
--- a/Sources/Accord.Audio/Filters/ExtractChannel.cs
+++ b/Sources/Accord.Audio/Filters/ExtractChannel.cs
@@ -72,7 +72,7 @@ protected override Signal NewSignal(int channels, int samples, int rate, SampleF
protected unsafe override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
+ int channels = sourceData.NumberOfChannels;
int length = sourceData.Length;
if (Channel < 0 || Channel > channels)
diff --git a/Sources/Accord.Audio/Filters/HighPassFilter.cs b/Sources/Accord.Audio/Filters/HighPassFilter.cs
index 1f11a636b..58334f43f 100644
--- a/Sources/Accord.Audio/Filters/HighPassFilter.cs
+++ b/Sources/Accord.Audio/Filters/HighPassFilter.cs
@@ -89,7 +89,7 @@ public HighPassFilter(float alpha)
protected override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
+ int channels = sourceData.NumberOfChannels;
int length = sourceData.Length;
if (format == SampleFormat.Format32BitIeeeFloat)
diff --git a/Sources/Accord.Audio/Filters/LowPassFilter.cs b/Sources/Accord.Audio/Filters/LowPassFilter.cs
index 31468931e..77c062c71 100644
--- a/Sources/Accord.Audio/Filters/LowPassFilter.cs
+++ b/Sources/Accord.Audio/Filters/LowPassFilter.cs
@@ -96,7 +96,7 @@ public LowPassFilter(float alpha)
protected override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
+ int channels = sourceData.NumberOfChannels;
int length = sourceData.Length;
if (format == SampleFormat.Format32BitIeeeFloat)
diff --git a/Sources/Accord.Audio/Filters/MonoFilter.cs b/Sources/Accord.Audio/Filters/MonoFilter.cs
index 8aa8e8e44..55f69a540 100644
--- a/Sources/Accord.Audio/Filters/MonoFilter.cs
+++ b/Sources/Accord.Audio/Filters/MonoFilter.cs
@@ -22,6 +22,7 @@
namespace Accord.Audio.Filters
{
+ using Accord.Diagnostics;
using System;
using System.Collections.Generic;
@@ -61,8 +62,11 @@ protected override Signal NewSignal(int channels, int samples, int rate, SampleF
protected unsafe override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
- int length = sourceData.Length;
+ int channels = sourceData.NumberOfChannels;
+ int length = sourceData.NumberOfFrames;
+
+ Debug.Assert(sourceData.NumberOfFrames == destinationData.NumberOfSamples);
+ Debug.Assert(destinationData.NumberOfChannels == 1);
if (format == SampleFormat.Format32BitIeeeFloat)
{
diff --git a/Sources/Accord.Audio/Filters/VolumeFilter.cs b/Sources/Accord.Audio/Filters/VolumeFilter.cs
index 5da55fefe..2617a7252 100644
--- a/Sources/Accord.Audio/Filters/VolumeFilter.cs
+++ b/Sources/Accord.Audio/Filters/VolumeFilter.cs
@@ -59,7 +59,7 @@ public VolumeFilter(float volume)
protected override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int channels = sourceData.Channels;
+ int channels = sourceData.NumberOfChannels;
int length = sourceData.Length;
if (format == SampleFormat.Format32BitIeeeFloat)
diff --git a/Sources/Accord.Audio/Filters/WaveRectifier.cs b/Sources/Accord.Audio/Filters/WaveRectifier.cs
index f98750e1d..527c97593 100644
--- a/Sources/Accord.Audio/Filters/WaveRectifier.cs
+++ b/Sources/Accord.Audio/Filters/WaveRectifier.cs
@@ -58,7 +58,7 @@ public WaveRectifier(bool halfRectificationOnly)
protected unsafe override void ProcessFilter(Signal sourceData, Signal destinationData)
{
SampleFormat format = sourceData.SampleFormat;
- int samples = sourceData.Samples;
+ int samples = sourceData.NumberOfSamples;
if (format == SampleFormat.Format32BitIeeeFloat)
{
diff --git a/Sources/Accord.Audio/Formats/AudioDecoder.cs b/Sources/Accord.Audio/Formats/AudioDecoder.cs
index c0ec7db73..d52c83220 100644
--- a/Sources/Accord.Audio/Formats/AudioDecoder.cs
+++ b/Sources/Accord.Audio/Formats/AudioDecoder.cs
@@ -36,7 +36,7 @@ namespace Accord.Audio.Formats
///
///
/// The class represent a help class, which simplifies decoding of audio
- /// files finding appropriate image decoder automatically (using list of registered
+ /// files finding appropriate audio decoder automatically (using list of registered
/// audio decoders). Instead of using required audio decoder directly, users may use this
/// class, which will find required decoder by file's extension.
///
@@ -84,7 +84,7 @@ public static Signal DecodeFromFile(string fileName, out FrameInfo frameInfo)
{
string fileExtension = FormatDecoderAttribute.GetNormalizedExtension(fileName);
- IAudioDecoder decoder = FormatDecoderAttribute.GetDecoder(fileExtension, decoderTypes, decoders.Value);
+ IAudioDecoder decoder = FormatDecoderAttribute.GetDecoders(fileExtension, decoderTypes, decoders.Value);
if (decoder != null)
{
@@ -99,14 +99,15 @@ public static Signal DecodeFromFile(string fileName, out FrameInfo frameInfo)
decoder.Close();
- frameInfo = new FrameInfo(signal.Channels, signal.SampleRate, Signal.GetSampleSize(signal.SampleFormat), 0, signal.Length);
+ frameInfo = new FrameInfo(signal.NumberOfChannels, signal.SampleRate, Signal.GetSampleSize(signal.SampleFormat), 0, signal.Length);
return signal;
}
}
throw new ArgumentException(String.Format("No suitable decoder has been found for the file format {0}. If ", fileExtension) +
- "you are trying to decode .wav files, please add a reference to Accord.Audio.DirectSouond.", "fileName");
+ "you are trying to decode .wav files, please add a reference to Accord.Audio.DirectSound. You might need to instantiate" +
+ "at least one type from this assembly to make sure it has been loaded in the AppDomain of your applicatoin.", "fileName");
}
}
diff --git a/Sources/Accord.Audio/Formats/AudioEncoder.cs b/Sources/Accord.Audio/Formats/AudioEncoder.cs
new file mode 100644
index 0000000000..627479899
--- /dev/null
+++ b/Sources/Accord.Audio/Formats/AudioEncoder.cs
@@ -0,0 +1,91 @@
+// Accord Audio Library
+// The Accord.NET Framework
+// http://accord-framework.net
+//
+// Copyright © César Souza, 2009-2017
+// cesarsouza at gmail.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+namespace Accord.Audio.Formats
+{
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using System.Threading;
+ using System.Threading.Tasks;
+ using Accord.Compat;
+
+ ///
+ /// Audio encoder to encode different custom audio file formats.
+ ///
+ ///
+ /// The class represent a help class, which simplifies encoding of audio
+ /// files finding appropriate audio encoder automatically (using list of registered
+ /// audio encoders). Instead of using required audio encoder directly, users may use this
+ /// class, which will find required encoder by file's extension.
+ ///
+ ///
+ /// By default the class will query all referenced assemblies for types that are marked
+ /// with the . If the user would like to implement
+ /// a new encoder, all that is necessary is to mark a new class with the
+ /// and make it implement the interface.
+ ///
+ ///
+ public class AudioEncoder
+ {
+ private static Dictionary encoderTypes = new Dictionary();
+ private static ThreadLocal> encoders =
+ new ThreadLocal>(() => new Dictionary());
+
+ ///
+ /// Encodes a signal from the specified file.
+ ///
+ ///
+ /// File name to save the signal to.
+ /// The audio signal that should be saved to disk.
+ ///
+ public static void EncodeToFile(string fileName, Signal signal)
+ {
+ string fileExtension = FormatHandlerAttribute.GetNormalizedExtension(fileName);
+
+ IAudioEncoder encoder = FormatEncoderAttribute.GetEncoder(fileExtension, encoderTypes, encoders.Value);
+
+ if (encoder != null)
+ {
+ // open stream
+ using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write))
+ {
+ // open decoder
+ encoder.Open(stream);
+
+ // write all audio frames
+ encoder.Encode(signal);
+
+ encoder.Close();
+ }
+
+ return;
+ }
+
+ throw new ArgumentException(String.Format("No suitable encoder has been found for the file format {0}. If ", fileExtension) +
+ "you are trying to encode .wav files, please add a reference to Accord.Audio.DirectSound.", "fileName");
+ }
+
+ }
+}
diff --git a/Sources/Accord.Audio/Generators/Base/BaseSignalGenerator.cs b/Sources/Accord.Audio/Generators/Base/BaseSignalGenerator.cs
new file mode 100644
index 0000000000..0c7c18b74
--- /dev/null
+++ b/Sources/Accord.Audio/Generators/Base/BaseSignalGenerator.cs
@@ -0,0 +1,76 @@
+// Accord Audio Library
+// The Accord.NET Framework
+// http://accord-framework.net
+//
+// Copyright © César Souza, 2009-2017
+// cesarsouza at gmail.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+namespace Accord.Audio.Generators
+{
+ using System;
+ using Accord.Audio.Generators;
+
+ ///
+ /// Base class for signal generators implementing the interface.
+ ///
+ ///
+ public abstract class BaseSignalGenerator
+ {
+ ///
+ /// Gets or sets the sampling rate used to create signals.
+ ///
+ ///
+ public int SamplingRate { get; set; }
+
+ ///
+ /// Gets or sets the number of channels of the created signals.
+ ///
+ ///
+ public int Channels { get; set; }
+
+ ///
+ /// Gets or sets the sample format for created signals.
+ ///
+ ///
+ public SampleFormat Format { get; set; }
+
+ ///
+ /// Generates a signal with the given number of samples.
+ ///
+ ///
+ /// The number of samples to generate.
+ ///
+ /// The generated signal
+ ///
+ public abstract Signal Generate(int samples);
+
+ ///
+ /// Generates a signal with the given duration.
+ ///
+ ///
+ /// The duration of the signal to generate.
+ ///
+ /// The generated signal
+ ///
+ public Signal Generate(TimeSpan duration)
+ {
+ return Generate(Signal.GetNumberOfSamples(duration, SamplingRate));
+ }
+
+ }
+}
diff --git a/Sources/Accord.Audio/Generators/ISignalGenerator.cs b/Sources/Accord.Audio/Generators/Base/ISignalGenerator.cs
similarity index 86%
rename from Sources/Accord.Audio/Generators/ISignalGenerator.cs
rename to Sources/Accord.Audio/Generators/Base/ISignalGenerator.cs
index 3ca593ded..df68081f5 100644
--- a/Sources/Accord.Audio/Generators/ISignalGenerator.cs
+++ b/Sources/Accord.Audio/Generators/Base/ISignalGenerator.cs
@@ -59,5 +59,15 @@ public interface ISignalGenerator
///
Signal Generate(int samples);
+ ///
+ /// Generates a signal with the given duration.
+ ///
+ ///
+ /// The duration of the signal to generate.
+ ///
+ /// The generated signal
+ ///
+ Signal Generate(TimeSpan duration);
+
}
}
diff --git a/Sources/Accord.Audio/Generators/CosineGenerator.cs b/Sources/Accord.Audio/Generators/CosineGenerator.cs
index 4d1985d65..9827e8d44 100644
--- a/Sources/Accord.Audio/Generators/CosineGenerator.cs
+++ b/Sources/Accord.Audio/Generators/CosineGenerator.cs
@@ -28,7 +28,7 @@ namespace Accord.Audio.Generators
/// Cosine signal generator.
///
///
- public class CosineGenerator : ISignalGenerator
+ public class CosineGenerator : BaseSignalGenerator, ISignalGenerator
{
private double theta;
@@ -45,24 +45,6 @@ public class CosineGenerator : ISignalGenerator
///
public double Amplitude { get; set; }
- ///
- /// Gets or sets the Sampling Rate of the generated signals.
- ///
- ///
- public int SamplingRate { get; set; }
-
- ///
- /// Gets or sets the number of channels for the generated signals.
- ///
- ///
- public int Channels { get; set; }
-
- ///
- /// Gets or sets the sample format for created signals.
- ///
- ///
- public SampleFormat Format { get; set; }
-
///
/// Constructs a new cosine Signal Generator.
///
@@ -96,7 +78,7 @@ private void init(double frequency, double amplitude, int samplingRate)
/// Generates a signal.
///
///
- public Signal Generate(int samples)
+ public override Signal Generate(int samples)
{
Signal signal = new Signal(Channels, samples, SamplingRate, Format);
@@ -105,15 +87,15 @@ public Signal Generate(int samples)
if (Format == SampleFormat.Format32BitIeeeFloat)
{
var dst = (float*)signal.Data.ToPointer();
- for (int i = 0; i < signal.Samples; i++)
- for (int c = 0; c < signal.Channels; c++, dst++)
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
*dst = (float)(Amplitude * Math.Cos(i * theta));
}
else if (Format == SampleFormat.Format64BitIeeeFloat)
{
var dst = (double*)signal.Data.ToPointer();
- for (int i = 0; i < signal.Samples; i++)
- for (int c = 0; c < signal.Channels; c++, dst++)
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
*dst = (Amplitude * Math.Cos(i * theta));
}
else
diff --git a/Sources/Accord.Audio/Generators/ImpulseGenerator.cs b/Sources/Accord.Audio/Generators/ImpulseGenerator.cs
index 278850ce6..15eecfd2f 100644
--- a/Sources/Accord.Audio/Generators/ImpulseGenerator.cs
+++ b/Sources/Accord.Audio/Generators/ImpulseGenerator.cs
@@ -30,38 +30,19 @@ namespace Accord.Audio.Generators
/// Impulse train signal generator.
///
///
- public class ImpulseGenerator : ISignalGenerator
+ public class ImpulseGenerator : BaseSignalGenerator, ISignalGenerator
{
private int interval;
private const float ampMax = 1f;
- ///
- /// Gets or sets the number of channels to generate.
- ///
- ///
- public int Channels { get; set; }
-
- ///
- /// Gets or sets the sampling rate of channels to generate.
- ///
- ///
- public int SamplingRate { get; set; }
-
///
/// Gets or sets the number of pulses to generate in the signal.
///
///
public int Pulses { get; set; }
- ///
- /// Gets or sets the sample format for created signals.
- ///
- ///
- public SampleFormat Format { get; set; }
-
-
///
/// Gets or sets the beats per minute for the pulses.
///
@@ -98,7 +79,7 @@ public ImpulseGenerator(int bpm, int pulses, int sampleRate, SampleFormat format
/// Generates the given number of samples.
///
///
- public Signal Generate(int samples)
+ public override Signal Generate(int samples)
{
Signal signal = new Signal(Channels, samples, SamplingRate, Format);
diff --git a/Sources/Accord.Audio/Generators/SignalGenerator.cs b/Sources/Accord.Audio/Generators/SignalGenerator.cs
index ef1d28d87..0efa9e1cb 100644
--- a/Sources/Accord.Audio/Generators/SignalGenerator.cs
+++ b/Sources/Accord.Audio/Generators/SignalGenerator.cs
@@ -28,7 +28,7 @@ namespace Accord.Audio.Generators
/// Custom function signal generator.
///
///
- public class SignalGenerator : ISignalGenerator
+ public class SignalGenerator : BaseSignalGenerator, ISignalGenerator
{
///
@@ -38,24 +38,6 @@ public class SignalGenerator : ISignalGenerator
///
public Func Function { get; set; }
- ///
- /// Gets or sets the Sampling Rate of the generated signals.
- ///
- ///
- public int SamplingRate { get; set; }
-
- ///
- /// Gets or sets the number of channels for the generated signals.
- ///
- ///
- public int Channels { get; set; }
-
- ///
- /// Gets or sets the sample format for created signals.
- ///
- ///
- public SampleFormat Format { get; set; }
-
///
/// Constructs a new signal generator.
///
@@ -72,7 +54,7 @@ public SignalGenerator(Func func)
/// Generates a signal.
///
///
- public Signal Generate(int samples)
+ public override Signal Generate(int samples)
{
Signal signal = new Signal(Channels, samples, SamplingRate, Format);
@@ -81,15 +63,15 @@ public Signal Generate(int samples)
if (Format == SampleFormat.Format32BitIeeeFloat)
{
var dst = (float*)signal.Data.ToPointer();
- for (int i = 0; i < signal.Samples; i++)
- for (int c = 0; c < signal.Channels; c++, dst++)
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
*dst = (float)(Function(i));
}
else if (Format == SampleFormat.Format64BitIeeeFloat)
{
var dst = (double*)signal.Data.ToPointer();
- for (int i = 0; i < signal.Samples; i++)
- for (int c = 0; c < signal.Channels; c++, dst++)
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
*dst = (double)(Function(i));
}
else
diff --git a/Sources/Accord.Audio/Generators/SineGenerator.cs b/Sources/Accord.Audio/Generators/SineGenerator.cs
index ddc5bd865..448664a49 100644
--- a/Sources/Accord.Audio/Generators/SineGenerator.cs
+++ b/Sources/Accord.Audio/Generators/SineGenerator.cs
@@ -1,129 +1,125 @@
-// Accord Audio Library
-// The Accord.NET Framework
-// http://accord-framework.net
-//
-// Copyright © César Souza, 2009-2017
-// cesarsouza at gmail.com
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-//
-
-namespace Accord.Audio.Generators
-{
- using System;
-
- ///
- /// Sine signal generator.
- ///
- ///
- public class SineGenerator : ISignalGenerator
- {
- private double theta;
-
-
- ///
- /// Gets or sets the Frequency of the sine signal.
- ///
- ///
- public double Frequency { get; set; }
-
- ///
- /// Gets or sets the Amplitude of the sine signal.
- ///
- ///
- public double Amplitude { get; set; }
-
- ///
- /// Gets or sets the Sampling Rate of the generated signals.
- ///
- ///
- public int SamplingRate { get; set; }
-
- ///
- /// Gets or sets the number of channels for the generated signals.
- ///
- ///
- public int Channels { get; set; }
-
- ///
- /// Gets or sets the sample format for created signals.
- ///
- ///
- public SampleFormat Format { get; set; }
-
- ///
- /// Constructs a new Cosine Signal Generator.
- ///
- ///
- public SineGenerator()
- {
- init(1.0 / (2.0 * Math.PI), 1, 1);
- }
-
- ///
- /// Constructs a new Cosine Signal Generator.
- ///
- ///
- public SineGenerator(double frequency, double amplitude, int samplingRate)
- {
- init(frequency, amplitude, samplingRate);
- }
-
- private void init(double frequency, double amplitude, int samplingRate)
- {
- this.Frequency = frequency;
- this.Amplitude = amplitude;
- this.Format = SampleFormat.Format32BitIeeeFloat;
- this.SamplingRate = samplingRate;
- this.Channels = 1;
-
- this.theta = 2.0 * Math.PI * frequency / samplingRate;
- }
-
- ///
- /// Generates a signal.
- ///
- ///
- public Signal Generate(int samples)
- {
- Signal signal = new Signal(Channels, samples, SamplingRate, Format);
-
- unsafe
- {
- if (Format == SampleFormat.Format32BitIeeeFloat)
- {
- var dst = (float*)signal.Data.ToPointer();
- for (int i = 0; i < signal.Samples; i++)
- for (int c = 0; c < signal.Channels; c++, dst++)
- *dst = (float)(Amplitude * Math.Sin(i * theta));
- }
- else if (Format == SampleFormat.Format64BitIeeeFloat)
- {
- var dst = (double*)signal.Data.ToPointer();
- for (int i = 0; i < signal.Samples; i++)
- for (int c = 0; c < signal.Channels; c++, dst++)
- *dst = (Amplitude * Math.Sin(i * theta));
- }
- else
- {
- throw new UnsupportedSampleFormatException("Sample format is not supported by the filter.");
- }
- }
-
- return signal;
- }
-
- }
-}
+// Accord Audio Library
+// The Accord.NET Framework
+// http://accord-framework.net
+//
+// Copyright © César Souza, 2009-2017
+// cesarsouza at gmail.com
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+//
+
+namespace Accord.Audio.Generators
+{
+ using System;
+
+ ///
+ /// Sine signal generator.
+ ///
+ ///
+ public class SineGenerator : BaseSignalGenerator, ISignalGenerator
+ {
+ private double theta;
+
+
+ ///
+ /// Gets or sets the Frequency of the sine signal.
+ ///
+ ///
+ public double Frequency { get; set; }
+
+ ///
+ /// Gets or sets the Amplitude of the sine signal.
+ ///
+ ///
+ public double Amplitude { get; set; }
+
+ ///
+ /// Constructs a new Cosine Signal Generator.
+ ///
+ ///
+ public SineGenerator()
+ {
+ init(1.0 / (2.0 * Math.PI), 1, 1);
+ }
+
+ ///
+ /// Constructs a new Cosine Signal Generator.
+ ///
+ ///
+ public SineGenerator(double frequency, double amplitude, int samplingRate)
+ {
+ init(frequency, amplitude, samplingRate);
+ }
+
+ private void init(double frequency, double amplitude, int samplingRate)
+ {
+ this.Frequency = frequency;
+ this.Amplitude = amplitude;
+ this.Format = SampleFormat.Format32BitIeeeFloat;
+ this.SamplingRate = samplingRate;
+ this.Channels = 1;
+
+ this.theta = 2.0 * Math.PI * frequency / samplingRate;
+ }
+
+ ///
+ /// Generates a signal.
+ ///
+ ///
+ public override Signal Generate(int samples)
+ {
+ Signal signal = new Signal(Channels, samples, SamplingRate, Format);
+
+ unsafe
+ {
+ if (Format == SampleFormat.Format32BitIeeeFloat)
+ {
+ var dst = (float*)signal.Data.ToPointer();
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
+ *dst = (float)(Amplitude * Math.Sin(i * theta));
+ }
+ else if (Format == SampleFormat.Format64BitIeeeFloat)
+ {
+ var dst = (double*)signal.Data.ToPointer();
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
+ *dst = (Amplitude * Math.Sin(i * theta));
+ }
+ else if (Format == SampleFormat.Format32Bit)
+ {
+ var dst = (Int32*)signal.Data.ToPointer();
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
+ *dst = (Int32)(Amplitude * Math.Sin(i * theta));
+ }
+ else if (Format == SampleFormat.Format16Bit)
+ {
+ var dst = (Int16*)signal.Data.ToPointer();
+ for (int i = 0; i < signal.NumberOfFrames; i++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
+ *dst = (Int16)(Amplitude * Math.Sin(i * theta));
+ }
+ else
+ {
+ throw new UnsupportedSampleFormatException("Sample format is not supported by the filter.");
+ }
+ }
+
+ return signal;
+ }
+
+ }
+}
diff --git a/Sources/Accord.Audio/Generators/SquareGenerator.cs b/Sources/Accord.Audio/Generators/SquareGenerator.cs
index b314c5270..abc85f3fe 100644
--- a/Sources/Accord.Audio/Generators/SquareGenerator.cs
+++ b/Sources/Accord.Audio/Generators/SquareGenerator.cs
@@ -27,7 +27,7 @@ namespace Accord.Audio.Generators
///
/// Square Signal Generator
///
- public class SquareGenerator : ISignalGenerator
+ public class SquareGenerator : BaseSignalGenerator, ISignalGenerator
{
///
@@ -42,24 +42,6 @@ public class SquareGenerator : ISignalGenerator
///
public double Amplitude { get; set; }
- ///
- /// Gets or sets the Sampling Rate of the generated signals.
- ///
- ///
- public int SamplingRate { get; set; }
-
- ///
- /// Gets or sets the number of channels for the generated signals.
- ///
- ///
- public int Channels { get; set; }
-
- ///
- /// Gets or sets the sample format for created signals.
- ///
- ///
- public SampleFormat Format { get; set; }
-
///
/// Creates a new Square Signal Generator.
///
@@ -74,7 +56,7 @@ public SquareGenerator()
/// Generates a signal.
///
///
- public Signal Generate(int samples)
+ public override Signal Generate(int samples)
{
Signal signal = new Signal(Channels, samples, SamplingRate, Format);
@@ -92,7 +74,7 @@ public Signal Generate(int samples)
float q = i * p;
float t = a * (q - (float)Math.Round(q));
- for (int c = 0; c < signal.Channels; c++, dst++)
+ for (int c = 0; c < signal.NumberOfChannels; c++, dst++)
*dst = t;
}
}
diff --git a/Sources/Accord.Audio/MFCC.cs b/Sources/Accord.Audio/MFCC.cs
index 386d143eb..237bb9ee6 100644
--- a/Sources/Accord.Audio/MFCC.cs
+++ b/Sources/Accord.Audio/MFCC.cs
@@ -250,7 +250,7 @@ public MelFrequencyCepstrumCoefficient(
///
protected override IList InnerTransform(Signal signal)
{
- if (signal.Channels > 1)
+ if (signal.NumberOfChannels > 1)
{
signal = new MonoFilter().Apply(signal);
}
diff --git a/Sources/Accord.Audio/SampleConverter.cs b/Sources/Accord.Audio/SampleConverter.cs
index f299c58b1..687dac93c 100644
--- a/Sources/Accord.Audio/SampleConverter.cs
+++ b/Sources/Accord.Audio/SampleConverter.cs
@@ -680,6 +680,50 @@ public static void Convert(Int32 from, out Int32 to)
}
#endregion
+ #region From Single (float) to Double (double)
+ ///
+ /// Converts a matrix of signed 32-bit integer samples
+ /// into a matrix of 32-bit floating point samples.
+ ///
+ ///
+ /// The original sample.
+ /// The resulting sample.
+ ///
+ public static void Convert(float[][] from, double[][] to)
+ {
+ for (int i = 0; i < from.Length; i++)
+ for (int j = 0; j < from[i].Length; j++)
+ to[i][j] = (double)from[i][j];
+ }
+
+ ///
+ /// Converts a array of signed 32-bit integer samples
+ /// into a array of 32-bit floating point samples.
+ ///
+ ///
+ /// The original sample.
+ /// The resulting sample.
+ ///
+ public static void Convert(float[] from, double[] to)
+ {
+ for (int i = 0; i < from.Length; i++)
+ to[i] = (double)from[i];
+ }
+
+ ///
+ /// Converts a signed 32-bit integer sample
+ /// into a 32-bit floating point sample.
+ ///
+ ///
+ /// The original sample.
+ /// The resulting sample.
+ ///
+ public static void Convert(float from, out double to)
+ {
+ to = (double)from;
+ }
+ #endregion
+
#endregion
}
diff --git a/Sources/Accord.Audio/Signals/ComplexSignal.cs b/Sources/Accord.Audio/Signals/ComplexSignal.cs
index 6838a0324..7703f1117 100644
--- a/Sources/Accord.Audio/Signals/ComplexSignal.cs
+++ b/Sources/Accord.Audio/Signals/ComplexSignal.cs
@@ -177,7 +177,7 @@ public ComplexSignal(int channels, int length, int sampleRate)
///
public Complex[,] ToArray()
{
- Complex[,] array = new Complex[Length, Channels];
+ Complex[,] array = new Complex[Length, NumberOfChannels];
GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
IntPtr pointer = handle.AddrOfPinnedObject();
@@ -205,7 +205,7 @@ public Complex[] ToArray(int channel)
public Complex[] GetChannel(int channel)
{
Complex[] array = new Complex[Length];
- int channels = Channels;
+ int channels = NumberOfChannels;
int length = Length;
unsafe
@@ -229,7 +229,7 @@ public Complex[] GetChannel(int channel)
///
private void SetChannel(int channel, Complex[] samples)
{
- int channels = Channels;
+ int channels = NumberOfChannels;
int length = Length;
unsafe
@@ -256,7 +256,7 @@ public void ForwardFourierTransform()
if (status == ComplexSignalStatus.Normal ||
status == ComplexSignalStatus.Analytic)
{
- for (int i = 0; i < Channels; i++)
+ for (int i = 0; i < NumberOfChannels; i++)
{
Complex[] channel = GetChannel(i);
FourierTransform.FFT(channel, FourierTransform.Direction.Forward);
@@ -274,7 +274,7 @@ public void BackwardFourierTransform()
{
if (status == ComplexSignalStatus.FourierTransformed)
{
- for (int i = 0; i < Channels; i++)
+ for (int i = 0; i < NumberOfChannels; i++)
{
Complex[] channel = GetChannel(i);
FourierTransform.FFT(channel, FourierTransform.Direction.Backward);
@@ -291,7 +291,7 @@ public void ForwardHilbertTransform()
{
if (status == ComplexSignalStatus.Normal)
{
- for (int c = 0; c < Channels; c++)
+ for (int c = 0; c < NumberOfChannels; c++)
{
Complex[] channel = GetChannel(c);
HilbertTransform.FHT(channel, FourierTransform.Direction.Forward);
@@ -308,7 +308,7 @@ public void BackwardHilbertTransform()
{
if (status == ComplexSignalStatus.Analytic)
{
- for (int c = 0; c < Channels; c++)
+ for (int c = 0; c < NumberOfChannels; c++)
{
Complex[] channel = GetChannel(c);
HilbertTransform.FHT(channel, FourierTransform.Direction.Backward);
@@ -334,17 +334,17 @@ public static ComplexSignal FromSignal(Signal signal)
{
if (signal.SampleFormat == SampleFormat.Format32BitIeeeFloat)
{
- float[] buffer = new float[signal.Samples];
+ float[] buffer = new float[signal.NumberOfSamples];
Marshal.Copy(signal.Data, buffer, 0, buffer.Length);
- float[,] data = new float[signal.Length, signal.Channels];
- Buffer.BlockCopy(buffer, 0, data, 0, signal.Samples * sizeof(float));
+ float[,] data = new float[signal.Length, signal.NumberOfChannels];
+ Buffer.BlockCopy(buffer, 0, data, 0, signal.NumberOfSamples * sizeof(float));
return FromArray(data, signal.SampleRate);
}
else if (signal.SampleFormat == SampleFormat.Format128BitComplex)
{
- return new ComplexSignal(signal.RawData, signal.Channels,
+ return new ComplexSignal(signal.RawData, signal.NumberOfChannels,
signal.Length, signal.SampleRate);
}
else
@@ -449,7 +449,7 @@ public static ComplexSignal Combine(params ComplexSignal[] signals)
{
// Compute common data
int length = 0;
- int nchannels = signals[0].Channels;
+ int nchannels = signals[0].NumberOfChannels;
int sampleRate = signals[0].SampleRate;
// Compute final length
diff --git a/Sources/Accord.Audio/Signals/Signal.cs b/Sources/Accord.Audio/Signals/Signal.cs
index 4c6e31da8..1a4e8ed91 100644
--- a/Sources/Accord.Audio/Signals/Signal.cs
+++ b/Sources/Accord.Audio/Signals/Signal.cs
@@ -22,6 +22,8 @@
namespace Accord.Audio
{
+ using Accord;
+ using Accord.Math;
using System;
using System.Runtime.InteropServices;
using Accord.Compat;
@@ -163,12 +165,12 @@ public SampleFormat SampleFormat
///
public TimeSpan Duration
{
- get { return DurationOfSamples(length, sampleRate); }
+ get { return GetDurationOfSamples(length, sampleRate); }
}
///
- /// Gets the number of samples in each channel of this signal,
- /// as known as the number of frames in the signal.
+ /// Gets the number of samples in each channel of this signal, as known
+ /// as the number of frames in the signal.
///
///
public int Length
@@ -177,10 +179,40 @@ public int Length
}
///
- /// Gets the total number of samples in this signal.
+ /// Obsolete. Please use instead.
///
///
+ [Obsolete("Please use NumberOfSamples instead.")]
public int Samples
+ {
+ get { return NumberOfSamples; }
+ }
+
+ ///
+ /// Gets the size of the samples in this image, in bytes. For
+ /// example, a 16-bit PCM signal would have sample size 2.
+ ///
+ ///
+ public int SampleSize
+ {
+ get { return GetSampleSize(this.format) / 8; }
+ }
+
+ ///
+ /// Gets the total number of audio samples in a single channel of this signal.
+ /// This property returns exactly the same value as .
+ ///
+ ///
+ public int NumberOfFrames
+ {
+ get { return length; }
+ }
+
+ ///
+ /// Gets the total number of audio samples in this signal (NumberOfFrames * NumberOfChannels).
+ ///
+ ///
+ public int NumberOfSamples
{
get { return length * channels; }
}
@@ -195,10 +227,20 @@ public int SampleRate
}
///
- /// Gets the number of channels of this signal.
+ /// Obsolete. Please use instead.
///
///
+ [Obsolete("Please use NumberOfChannels instead.")]
public int Channels
+ {
+ get { return NumberOfChannels; }
+ }
+
+ ///
+ /// Gets the number of channels of this signal.
+ ///
+ ///
+ public int NumberOfChannels
{
get { return channels; }
}
@@ -290,7 +332,7 @@ public double GetEnergy()
{
// Iterate over all samples and compute energy
float* src = (float*)this.ptrData.ToPointer();
- for (int i = 0; i < this.Samples; i++, src++)
+ for (int i = 0; i < this.NumberOfSamples; i++, src++)
{
v = (*src);
e += v * v;
@@ -300,7 +342,7 @@ public double GetEnergy()
{
// Iterate over all samples and compute energy
Complex* src = (Complex*)this.Data.ToPointer();
- for (int i = 0; i < this.Samples; i++, src++)
+ for (int i = 0; i < this.NumberOfSamples; i++, src++)
{
double m = (*src).Magnitude;
e += m * m;
@@ -323,24 +365,19 @@ public double GetEnergy()
///
public float GetSample(int channel, int position)
{
- float sample;
-
unsafe
{
void* ptr = ptrData.ToPointer();
- int pos = position * Channels + channel;
+ int pos = position * NumberOfChannels + channel;
switch (format)
{
case SampleFormat.Format32BitIeeeFloat:
- sample = ((float*)ptr)[pos];
- break;
- default:
- throw new NotSupportedException();
+ return ((float*)ptr)[pos];
}
}
- return sample;
+ throw new NotSupportedException();
}
///
@@ -358,18 +395,17 @@ public void SetSample(int channel, int position, float value)
unsafe
{
void* ptr = ptrData.ToPointer();
- int pos = position * Channels + channel;
+ int pos = position * NumberOfChannels + channel;
switch (format)
{
case SampleFormat.Format32BitIeeeFloat:
((float*)ptr)[pos] = value;
- break;
-
- default:
- throw new NotSupportedException();
+ return;
}
}
+
+ throw new NotSupportedException();
}
///
@@ -408,14 +444,13 @@ public static Signal FromArray(Array signal, int channels, int sampleRate,
/// Creates a new Signal from a float array.
///
///
- public static Signal FromArray(Array signal, int size, int channels, int sampleRate,
+ public static Signal FromArray(Array signal, int length, int channels, int sampleRate,
SampleFormat format = SampleFormat.Format32BitIeeeFloat)
{
- int sampleSize = GetSampleSize(format) / 8;
-
- byte[] buffer = new byte[size * sampleSize];
- Buffer.BlockCopy(signal, 0, buffer, 0, buffer.Length);
- int samples = size / channels;
+ int bytes = length * Marshal.SizeOf(signal.GetInnerMostType());
+ byte[] buffer = new byte[bytes];
+ Buffer.BlockCopy(signal, 0, buffer, 0, bytes);
+ int samples = length / channels;
return new Signal(buffer, channels, samples, sampleRate, format);
}
@@ -437,12 +472,14 @@ public void CopyTo(float[] array)
{
if (format == Audio.SampleFormat.Format32BitIeeeFloat)
{
+ if (array.Length * sizeof(float) != rawData.Length)
+ throw new Exception("The provided array is not large enough to contain than the signal.");
Buffer.BlockCopy(rawData, 0, array, 0, rawData.Length);
}
else if (format == Audio.SampleFormat.Format16Bit)
{
- short[] source = new short[Samples];
+ short[] source = new short[NumberOfSamples];
Buffer.BlockCopy(rawData, 0, source, 0, rawData.Length);
SampleConverter.Convert(source, array);
}
@@ -465,18 +502,16 @@ public void CopyTo(double[] array)
}
else if (format == Audio.SampleFormat.Format32BitIeeeFloat)
{
- float[] source = new float[Samples];
+ float[] source = new float[NumberOfSamples];
Buffer.BlockCopy(rawData, 0, source, 0, rawData.Length);
- for (int i = 0; i < source.Length; i++)
- array[i] = source[i];
+ SampleConverter.Convert(source, array);
}
else if (format == Audio.SampleFormat.Format16Bit)
{
- short[] source = new short[Samples];
+ short[] source = new short[NumberOfSamples];
Buffer.BlockCopy(rawData, 0, source, 0, rawData.Length);
SampleConverter.Convert(source, array);
}
-
else
{
throw new InvalidOperationException();
@@ -491,7 +526,7 @@ public void CopyTo(double[] array)
///
public float[] ToFloat()
{
- float[] array = new float[Samples];
+ float[] array = new float[NumberOfSamples];
CopyTo(array);
return array;
}
@@ -504,7 +539,7 @@ public float[] ToFloat()
///
public double[] ToDouble()
{
- double[] array = new double[Samples];
+ double[] array = new double[NumberOfSamples];
CopyTo(array);
return array;
}
@@ -516,16 +551,31 @@ public double[] ToDouble()
/// Gets the number of samples contained in a signal of given duration and sampling rate.
///
///
- public static int NumberOfSamples(long duration, int samplingRate)
+ /// The duration of the signal.
+ /// The sampling rate of the signal.
+ ///
+ public static int GetNumberOfSamples(TimeSpan duration, int samplingRate)
+ {
+ return GetNumberOfSamples(duration.TotalMilliseconds, samplingRate);
+ }
+
+ ///
+ /// Gets the number of samples contained in a signal of given duration and sampling rate.
+ ///
+ ///
+ /// The duration of the signal, in milliseconds.
+ /// The sampling rate of the signal.
+ ///
+ public static int GetNumberOfSamples(double duration, int samplingRate)
{
- return (int)((duration / 1000) * samplingRate);
+ return (int)((duration / 1000.0) * samplingRate);
}
///
/// Gets the duration of each sample in a signal with the given number of samples and sampling rate.
///
///
- public static TimeSpan DurationOfSamples(long samples, int samplingRate)
+ public static TimeSpan GetDurationOfSamples(long samples, int samplingRate)
{
return TimeSpan.FromMilliseconds(samples / (double)samplingRate * 1000.0);
}
@@ -625,6 +675,21 @@ public static Signal FromFile(string fileName)
return AudioDecoder.DecodeFromFile(fileName);
}
+
+ ///
+ /// Loads a signal from a file, such as a ".wav" file.
+ ///
+ ///
+ /// Name of the file to be read.
+ ///
+ /// The signal that has been read from the file.
+ ///
+ public void Save(string fileName)
+ {
+ AudioEncoder.EncodeToFile(fileName, this);
+ }
+
+
#endregion
diff --git a/Sources/Accord.Audio/Windows/RectangularWindow.cs b/Sources/Accord.Audio/Windows/RectangularWindow.cs
index 5f8ff1aa4..2c6ea1860 100644
--- a/Sources/Accord.Audio/Windows/RectangularWindow.cs
+++ b/Sources/Accord.Audio/Windows/RectangularWindow.cs
@@ -94,7 +94,7 @@ public RectangularWindow(int length, int sampleRate)
///
public Signal Apply(Signal signal, int sampleIndex)
{
- int channels = signal.Channels;
+ int channels = signal.NumberOfChannels;
int samples = signal.Length;
int minLength = System.Math.Min(samples - sampleIndex, Length);
@@ -131,15 +131,15 @@ public Signal Apply(Signal signal, int sampleIndex)
///
public ComplexSignal Apply(ComplexSignal complexSignal, int sampleIndex)
{
- Complex[,] resultData = new Complex[Length, complexSignal.Channels];
+ Complex[,] resultData = new Complex[Length, complexSignal.NumberOfChannels];
ComplexSignal result = ComplexSignal.FromArray(resultData, complexSignal.SampleRate);
- int channels = result.Channels;
+ int channels = result.NumberOfChannels;
int minLength = System.Math.Min(complexSignal.Length - sampleIndex, Length);
unsafe
{
- for (int c = 0; c < complexSignal.Channels; c++)
+ for (int c = 0; c < complexSignal.NumberOfChannels; c++)
{
Complex* dst = (Complex*)result.Data.ToPointer() + c;
Complex* src = (Complex*)complexSignal.Data.ToPointer() + c + channels * sampleIndex;
diff --git a/Sources/Accord.Audio/Windows/WindowBase.cs b/Sources/Accord.Audio/Windows/WindowBase.cs
index e205132d1..48bfea6c7 100644
--- a/Sources/Accord.Audio/Windows/WindowBase.cs
+++ b/Sources/Accord.Audio/Windows/WindowBase.cs
@@ -97,7 +97,7 @@ public float this[int index]
///
public virtual Signal Apply(Signal signal, int sampleIndex)
{
- int channels = signal.Channels;
+ int channels = signal.NumberOfChannels;
int minLength = System.Math.Min(signal.Length - sampleIndex, Length);
@@ -133,13 +133,13 @@ public virtual Signal Apply(Signal signal, int sampleIndex)
///
public virtual unsafe ComplexSignal Apply(ComplexSignal complexSignal, int sampleIndex)
{
- Complex[,] resultData = new Complex[Length, complexSignal.Channels];
+ Complex[,] resultData = new Complex[Length, complexSignal.NumberOfChannels];
ComplexSignal result = ComplexSignal.FromArray(resultData, complexSignal.SampleRate);
- int channels = result.Channels;
+ int channels = result.NumberOfChannels;
int minLength = System.Math.Min(complexSignal.Length - sampleIndex, Length);
- for (int c = 0; c < complexSignal.Channels; c++)
+ for (int c = 0; c < complexSignal.NumberOfChannels; c++)
{
Complex* dst = (Complex*)result.Data.ToPointer() + c;
Complex* src = (Complex*)complexSignal.Data.ToPointer() + c + channels * sampleIndex;
diff --git a/Sources/Accord.Controls.Audio/WavechartBox.cs b/Sources/Accord.Controls.Audio/WavechartBox.cs
index a8eaf11d3..8b332879d 100644
--- a/Sources/Accord.Controls.Audio/WavechartBox.cs
+++ b/Sources/Accord.Controls.Audio/WavechartBox.cs
@@ -182,7 +182,7 @@ private static WavechartBox show(String title, bool hold, params Tuple