예제 #1
0
        /// <summary>
        /// Amplitude envelope builder
        /// Save maximum values
        /// </summary>
        public Samples Build(Samples source, int newBitrate = 20, bool differentiate = false)
        {
            float koeff = 1f * newBitrate /source.Bitrate;
            var values = source.Values;
            var resValues = new float[(int)(values.Length * koeff)+1];

            for (var i = values.Length - 2; i >= 0; i--)
            {
                var newIndex = (int) (i*koeff);
                var prevValue = resValues[newIndex];
                var value = values[i];
                if (differentiate)
                {
                    value = values[i + 1] - value;
                }
                value = Math.Abs(value);

                if (prevValue < value)
                {
                    resValues[newIndex] = value;
                }
            }

            return new Samples()
            {
                Bitrate = newBitrate, Values = resValues
            };
        }
예제 #2
0
        public void DrawOneSide(Samples samples, Graphics gr, Rectangle bounds, bool normalize = false)
        {
            var kx = bounds.Width / samples.Values.Length;
            var ky = bounds.Height;
            var cy = bounds.Bottom;
            var cx = bounds.Left;

            var values = samples.Values;
            if (normalize)
            {
                var s = samples.Clone();
                s.Normalize();
                values = s.Values;
            }

            using (var pen = new Pen(ForeColor))
            for (int i = 0; i < values.Length; i++)
            {
                var x = i * kx;
                var y = values[i];
                if (y > 1) y = 1;
                if (y < -1) continue;
                y = y * ky;
                gr.DrawLine(pen, cx + x, cy, cx + x, cy - y);
            }
        }
예제 #3
0
        public Samples Clone()
        {
            var result = new Samples();
            result.Bitrate = Bitrate;
            result.Values = new float[Values.Length];
            Array.Copy(Values, result.Values, Values.Length);

            return result;
        }
예제 #4
0
        public void Process(Audio item, AudioInfo info)
        {
            var tempogram = new Tempogram();
            //get maximum values
            Samples samples = new EnvelopeProcessor(factory).Build(info.Samples, 32, false);
            var newSamples = new Samples()
            {
                Values = new float[samples.Values.Length], Bitrate = samples.Bitrate
            };

            var intensity = 0;

            for (int i = 0; i < samples.Values.Length - 1; i++)
            {
                var diff = samples.Values[i + 1] - samples.Values[i];
                samples.Values[i] = diff > 0 ? diff : 0; //разница между всеми амплитудами
                newSamples.Values[i] = diff;
                if (diff > minAmplitudeChangeForIntensityRate)
                {
                    intensity++;
                }
            }
            samples.Values[samples.Values.Length - 1] = 0;
            newSamples.Values[samples.Values.Length - 1] = 0;

            var durationOfTrack = samples.Values.Length / samples.Bitrate;//time of sound

            var maxShift = (int)(samples.Values.Length * (maxRithmDuration / durationOfTrack));

            var autoCorr1 = AutoCorr(samples.Values, maxShift, 5);
            var autoCorr2 = AutoCorr(newSamples.Values, maxShift, 2);
            var lengthCorr1 = (float)autoCorr1.Length;
            var log2 = Math.Log(2);
            var list1 = new List<KeyValuePair<float, float>>();
            var list2 = new List<KeyValuePair<float, float>>();
            for (int i = 0; i < lengthCorr1; i++)
            {
                var j = i / (float)lengthCorr1;
                j = (float)(Math.Log(j + 1) / log2);
                list1.Add(new KeyValuePair<float, float>(j, autoCorr1[i]));

                var v = autoCorr2[i];
                list2.Add(new KeyValuePair<float, float>(j, v > 0 ? v : 0));
            }
            tempogram.LongTempogram.Build(list1);
            tempogram.ShortTempogram.Build(list2);

            tempogram.Intensity = (float)intensity / durationOfTrack;

            CalcTempo(tempogram);

            //save to audio item
            item.Data.Add(tempogram);
        }
예제 #5
0
 public Envelope(Samples samples)
 {
     var values = samples.Values;
     //pack
     packedValues = new byte[values.Length / 2];
     for (int i = 0; i < values.Length; i += 2)
     {
         var v1 = (int)(16 * values[i]);
         var v2 = (int)(16 * values[i + 1]);
         if (v1 > 15) v1 = 15;
         if (v2 > 15) v2 = 15;
         packedValues[i / 2] = (byte)((v1 << 4) + v2);
     }
 }