예제 #1
0
파일: Mel.cs 프로젝트: azret/mozart
        static void RunSpeachFrequencyFilters(Vector it, int j, double vol = 0.01, int dbMin = -20, int dbMax = +20)
        {
            bool IsAudible(double f)
            {
                if ((f >= 8.1 && f <= 16743.9))
                {
                    return(true);
                }
                return(false);
            }

            bool pass = true;

            if (!IsAudible(it.Axis[j].Im))
            {
                pass = false;
            }
            if (it.Axis[j].Re <= 0.01)
            {
                pass = false;
            }
            if (pass)
            {
                var n = Envelopes.MIDI2NOTE(Envelopes.FREQ2MIDI(it.Axis[j].Im));
                if (string.IsNullOrWhiteSpace(n))
                {
                    pass = false;
                }
                if (n == null || (!n.Contains("3") && !n.Contains("4") && !n.Contains("5") &&
                                  !n.Contains("6")))
                {
                    pass = false;
                }
                if (pass && it.Axis[j].Re > 0)
                {
                    var dB = Envelopes.dB(it.Axis[j].Re);
                    if (dB <= dbMin || dB >= dbMax)
                    {
                        pass = false;
                    }
                }
            }
            if (!pass)
            {
                it.Axis[j].Re = 0;
            }
        }
예제 #2
0
        static Vector CreateMidiVector(Complex[] fft)
        {
            int N = fft.Length * 2;

            Debug.Assert(N == 1024);
            double[] im       = new double[128];
            Vector   vec      = new Vector("𝅘𝅥𝅮", null, im);
            var      duration = Math.Round(
                (double)N / Wav._hz, 5);

            Debug.Assert((int)(duration * Wav._hz) == N);
            vec.Score.Re = duration;
            vec.Score.Im = N;
            for (int i = 0; i < fft.Length; i++)
            {
                double h   = Wav._hz / (double)N,
                       f   = i * h;
                double vol = fft[i].Abs();
                var    m   = Envelopes.FREQ2MIDI(f);
                if (m >= 0 && m < vec.Axis.Length && vol > 1E-3)
                {
                    vec.Axis[m].Re += vol;
                    vec.Axis[m].Im += 1;
                }
            }
            for (int m = 0; m < vec.Axis.Length; m++)
            {
                if (vec.Axis[m].Im == 0)
                {
                    vec.Axis[m].Re = 0;
                }
                else
                {
                    vec.Axis[m].Re /= vec.Axis[m].Im;
                }
                vec.Axis[m].Im = Envelopes.MIDI2FREQ(m);
                Debug.Assert(Envelopes.FREQ2MIDI(vec.Axis[m].Im) == m);
            }
            Debug.Assert(vec.Axis[69].Im == 440);
            return(vec);
        }
예제 #3
0
        static void RunSpeachFrequencyFilters(Vector vec, int j)
        {
            bool IsAudible(double f)
            {
                if ((f >= 8.1 && f <= 16743.9))
                {
                    return(true);
                }
                return(false);
            }

            if (!IsAudible(vec.Axis[j].Im))
            {
                vec.Axis[j].Re = 0;
            }
            var n = Envelopes.MIDI2NOTE(Envelopes.FREQ2MIDI(vec.Axis[j].Im));

            if (string.IsNullOrWhiteSpace(n)
                // || n.Contains("#")
                // || n.Contains("0")
                // || n.Contains("1")
                // || n.Contains("2")
                // || n.Contains("3")
                // || n.Contains("4")
                // || n.Contains("5")
                // || n == "C6"
                // || n == "E6"
                // || n == "D6"
                // || n == "A6"
                // || n == "F6"
                // || n == "G6"
                // || n == "B6"
                // || n.Contains("7")
                // || n.Contains("8")
                // || n.Contains("9")
                )
            {
                vec.Axis[j].Re = 0;
            }
        }
예제 #4
0
파일: Mel.cs 프로젝트: azret/mozart
        static Vector MelFromFourier(Complex[] STFT)
        {
            int Fs = STFT.Length * 2;

            Debug.Assert(Fs == 1024 * 2);
            double[] re = new double[CBOW.DIMS],
            im = new double[CBOW.DIMS],
            cc = new double[CBOW.DIMS];
            for (int i = 0; i < STFT.Length; i++)
            {
                double h = Wav._hz / (double)Fs,
                       f = i * h;
                var m    = Envelopes.FREQ2MIDI(f);
                Debug.Assert(m == Envelopes.FREQ2MIDI(Envelopes.MIDI2FREQ(m)));
                if (m >= 0 && m < CBOW.DIMS)
                {
                    re[m] += STFT[i].Abs();
                    cc[m] += +1;
                }
            }
            for (int m = 0; m < CBOW.DIMS; m++)
            {
                // Normalize
                if (cc[m] > 0)
                {
                    re[m] /= cc[m];
                }
                im[m] = Envelopes.MIDI2FREQ(m);
            }
            Vector it       = new Vector("𝆕", re, im);
            var    duration = Math.Round((double)Fs / Wav._hz, 5);

            Debug.Assert((int)(duration * Wav._hz) == Fs);
            double scale = 1.6;

            it.Score.Re = scale * duration;
            return(it);
        }
예제 #5
0
    static void ParseNotes(Matrix Model, string sl, int dims)
    {
        int i = 0, wordStart = i;

        while (i < sl.Length && (sl[i] == '\t' || sl[i] == ' ' ||
                                 sl[i] == '•' || sl[i] == '|' || sl[i] == '⁞'))
        {
            i++;
        }
        Vector vec;
        int    t = Model.Count;

        if (t >= Model.Capacity)
        {
            throw new OutOfMemoryException();
        }
        vec = new Vector("𝆕");
        if (vec.Axis == null)
        {
            vec.Axis = new Complex[dims];
        }
        Model[t] = vec;
        for (; ;)
        {
            wordStart = i;
            while (i < sl.Length && (sl[i] == '±' || sl[i] == '-' || sl[i] == '+' || sl[i] == 'E' ||
                                     sl[i] == 'A' || sl[i] == 'B' || sl[i] == 'C' ||
                                     sl[i] == 'D' || sl[i] == 'F' || sl[i] == 'G' ||
                                     sl[i] == '#' ||
                                     sl[i] == '.' || char.IsDigit(sl[i])))
            {
                i++;
            }
            var ImSign = +1;
            int len    = (i - wordStart) - 1;
            while (wordStart + len > 0 && wordStart + len < sl.Length &&
                   (sl[wordStart + len] == '-' || sl[wordStart + len] == '+' || sl[wordStart + len] == '±'))
            {
                if (sl[wordStart + len] == '-')
                {
                    ImSign = -1;
                }
                len--;
            }
            string Re = sl.Substring(wordStart, len + 1);
            string Im = null;
            if (i < sl.Length && (sl[i] == 'i'))
            {
                i++;
                wordStart = i;
                while (i < sl.Length && (sl[i] == '-' || sl[i] == '+' || sl[i] == 'E' ||
                                         sl[i] == 'A' || sl[i] == 'B' || sl[i] == 'C' ||
                                         sl[i] == 'D' || sl[i] == 'F' || sl[i] == 'G' ||
                                         sl[i] == '#' ||
                                         sl[i] == '.' || char.IsDigit(sl[i])))
                {
                    i++;
                }
                Im = sl.Substring(wordStart, i - wordStart);
            }
            if (!string.IsNullOrWhiteSpace(Re))
            {
                var f = Envelopes.NOTE2FREQ(Re);
                int m = Envelopes.FREQ2MIDI(f);
                if (m >= 0 && m < vec.Axis.Length)
                {
                    vec.Axis[m].Im = f;
                    vec.Axis[m].Re = 1;
                    if (!string.IsNullOrWhiteSpace(Im))
                    {
                        vec.Axis[m].Re = Envelopes.Amplitude((int)(ImSign * double.Parse(Im)));
                    }
                }
                while (i < sl.Length && (sl[i] == '\t' || sl[i] == ' ' || sl[i] == '•' || sl[i] == '|' || sl[i] == '⁞'))
                {
                    i++;
                }
            }
            else   /* End of Line */
            {
                break;
            }
        }
    }
예제 #6
0
파일: Mel.cs 프로젝트: 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);
        }