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