Esempio n. 1
0
        /// <summary>
        /// One iteration of reconstruction
        /// </summary>
        /// <param name="signal">Signal reconstructed at previous iteration</param>
        /// <returns>Reconstructed signal</returns>
        public float[] Iterate(float[] signal = null)
        {
            var magPhase = new MagnitudePhaseList()
            {
                Magnitudes = _magnitudes
            };

            if (signal == null)
            {
                var spectrumSize = _magnitudes[0].Length;

                var r            = new Random();
                var randomPhases = new List <float[]>();

                for (var i = 0; i < _magnitudes.Count; i++)
                {
                    randomPhases.Add(Enumerable.Range(0, spectrumSize)
                                     .Select(s => (float)(2 * Math.PI * r.NextDouble()))
                                     .ToArray());
                }

                magPhase.Phases = randomPhases;
            }
            else
            {
                magPhase.Phases = _stft.MagnitudePhaseSpectrogram(signal).Phases;
            }

            return(_stft.ReconstructMagnitudePhase(magPhase));
        }
Esempio n. 2
0
        /// <summary>
        /// Evaluate harmonic and percussive mag-phase spectrograms from given signal.
        /// Both spectrogram objects share the same phase array.
        /// </summary>
        /// <param name="signal"></param>
        /// <returns></returns>
        public (MagnitudePhaseList, MagnitudePhaseList) EvaluateSpectrograms(DiscreteSignal signal)
        {
            // spectrogram memory will be reused for harmonic magnitudes

            var harmonicSpectrogram = _stft.MagnitudePhaseSpectrogram(signal);
            var harmonicMagnitudes  = harmonicSpectrogram.Magnitudes;

            // median filtering along frequency axis:

            var percussiveMagnitudes = new List <float[]>(harmonicMagnitudes.Count);

            for (var i = 0; i < harmonicMagnitudes.Count; i++)
            {
                var mag = new DiscreteSignal(1, harmonicMagnitudes[i]);
                percussiveMagnitudes.Add(_medianPercussive.ApplyTo(mag).Samples);
                _medianPercussive.Reset();
            }

            // median filtering along time axis:

            for (var j = 0; j <= _stft.Size / 2; j++)
            {
                int i = 0, k = 0;

                for (; k < _medianHarmonic.Size / 2; k++)    // feed first Size/2 samples
                {
                    _medianHarmonic.Process(harmonicMagnitudes[k][j]);
                }

                for (; i < harmonicMagnitudes.Count - _medianHarmonic.Size / 2; i++, k++)
                {
                    var h = _medianHarmonic.Process(harmonicMagnitudes[k][j]);

                    harmonicMagnitudes[i][j]   *= _mask(h, percussiveMagnitudes[k][j]);
                    percussiveMagnitudes[i][j] *= _mask(percussiveMagnitudes[k][j], h);
                }

                for (k = 0; k < _medianHarmonic.Size / 2; i++, k++)     // don't forget last samples
                {
                    var h = _medianHarmonic.Process(0);

                    harmonicMagnitudes[i][j]   *= _mask(h, percussiveMagnitudes[i][j]);
                    percussiveMagnitudes[i][j] *= _mask(percussiveMagnitudes[i][j], h);
                }

                _medianHarmonic.Reset();
            }

            var percussiveSpectrogram = new MagnitudePhaseList
            {
                Magnitudes = percussiveMagnitudes,
                Phases     = harmonicSpectrogram.Phases
            };

            return(harmonicSpectrogram, percussiveSpectrogram);
        }