Ejemplo n.º 1
0
Archivo: Mel.cs Proyecto: azret/mozart
        public static Matrix ShortTimeFourierTransform(Complex[] sig, Set filter, double vol = 0.01, int dbMin = -20, int dbMax = +20)
        {
            Console.Write($"\r\nBuilding a new Mel model...\r\n");
            double norm = 0.0,
                   cc   = 0;
            var Model   = new Matrix((int)Math.Ceiling(sig.Length / (double)2048));

            foreach (var STFT in Complex.ShortTimeFourierTransform(sig))
            {
                int i = Model.Count;
                if (i >= Model.Capacity)
                {
                    throw new OutOfMemoryException();
                }
                Vector it;
                Debug.Assert(Model[i] == null);
                Model[i] = it = MelFromFourier(STFT);
                for (var j = 0; j < it.Axis.Length; j++)
                {
                    norm += it.Axis[j].Re;
                    cc++;
                }
            }
            if (cc > 0)
            {
                norm = norm /= cc;
                if (norm > 0)
                {
                    norm = 1d / norm;
                }
            }
            for (int i = 0; i < Model.Count; i++)
            {
                var it = Model[i];
                if (it != null)
                {
                    for (var j = 0; j < it.Axis.Length; j++)
                    {
                        it.Axis[j].Re = Math.Round(norm

                                                   /* Note that this surface is really wierd... i.e. There are
                                                    *      positive and negative decibeles */
                                                   * it.Axis[j].Re / (it.Axis.Length * 0.1), 3);
                        it.Axis[j].Re = it.Axis[j].Re;
                        if (it.Axis[j].Re > 0)
                        {
                            RunSpeachFrequencyFilters(it, j, vol, dbMin, dbMax);
                        }
                        if (it.Axis[j].Re > 0 && filter != null)
                        {
                            /* Filter out the specified pitches */
                            var n = Envelopes.MIDI2NOTE(Envelopes.FREQ2MIDI(it.Axis[j].Im));
                            if (string.IsNullOrWhiteSpace(n) || filter.Has(n))
                            {
                                it.Axis[j].Re = 0;
                            }
                        }
                        double finalMag = Math.Round(it.Axis[j].Re, 2);
                        it.Axis[j].Re
                            = finalMag;
                    }
                    double dot = 0.0;
                    for (var j = 0; j < it.Axis.Length; j++)
                    {
                        dot += it.Axis[j].Re * 1;
                    }
                    it.Score.Im = Math.Round(
                        Tanh.f(dot), 2);
                }
            }
            return(Model);
        }