Example #1
0
        public void GetSamples_Request123SamplesFrom1ChannelAudio_ReturnsSamplesFor1Channel()
        {
            var samples = _helper.GetSamples(123);

            Assert.AreEqual(123, samples.GetLength(0));
            Assert.AreEqual(1, samples.GetLength(1));
        }
Example #2
0
        /// ------------------------------------------------------------------------------------
        public IEnumerable <TimeSpan> GetNaturalBreaks()
        {
            uint requestedSamples = (uint)StreamReader.TotalTime.TotalMilliseconds;

            //(StreamReader.SampleCount > uint.MaxValue) ? uint.MaxValue : (uint)StreamReader.SampleCount;
            if (requestedSamples > 0)
            {
                var  samples          = AudioFileHelper.GetSamples(StreamReader, requestedSamples);
                uint remainingSamples = (uint)samples.GetLength(0);

                if (remainingSamples > 0)
                {
                    uint lastBreak             = 0;
                    var  millisecondsPerSample = StreamReader.TotalTime.TotalMilliseconds / remainingSamples;
                    _adjacentSamplesToFactorIntoAdjustedScore = (uint)(_settings.AutoSegmenterPreferrerdPauseLengthInMilliseconds / millisecondsPerSample);
                    var minSamplesPerSegment = (uint)(_settings.AutoSegmenterMinimumSegmentLengthInMilliseconds / millisecondsPerSample);
                    var maxSamplesPerSegment = (uint)(_settings.AutoSegmenterMaximumSegmentLengthInMilliseconds / millisecondsPerSample);

                    uint idealSegmentLengthInSamples = (uint)Math.Ceiling((minSamplesPerSegment + maxSamplesPerSegment) / 2.0);

                    while (remainingSamples >= maxSamplesPerSegment)
                    {
                        if (remainingSamples < idealSegmentLengthInSamples * 2)
                        {
                            idealSegmentLengthInSamples = remainingSamples / 2;
                        }
                        uint     samplesOnEitherSideOfTarget = idealSegmentLengthInSamples + _adjacentSamplesToFactorIntoAdjustedScore - minSamplesPerSegment;
                        uint     targetBreak    = lastBreak + idealSegmentLengthInSamples;
                        uint     bestBreak      = targetBreak;
                        double[] rawScores      = new double[idealSegmentLengthInSamples * 2 + 1];
                        double[] adjustedScores = new double[idealSegmentLengthInSamples * 2 + 1];
                        rawScores[idealSegmentLengthInSamples] = ComputeRawScore(samples, targetBreak);
                        double bestScore    = double.MaxValue;
                        double averageScore = 0;
                        for (uint i = 1; i < samplesOnEitherSideOfTarget; i++)
                        {
                            if (i < idealSegmentLengthInSamples)
                            {
                                rawScores[idealSegmentLengthInSamples + i] = ComputeRawScore(samples, targetBreak + i);
                                rawScores[idealSegmentLengthInSamples - i] = ComputeRawScore(samples, targetBreak - i);
                            }
                            if (i >= _adjacentSamplesToFactorIntoAdjustedScore)
                            {
                                // DEBUG code if ((targetBreak - i) * millisecondsPerSample < 138939 && lastBreak > 138939 - maxSamplesPerSegment)
                                //{
                                //    System.Diagnostics.Debug.WriteLine("Position = " + (lastBreak + idealSegmentLengthInSamples + i) + "; Raw score = " + rawScores[idealSegmentLengthInSamples + i]);
                                //    System.Diagnostics.Debug.WriteLine("Position = " + (lastBreak + idealSegmentLengthInSamples - i) + "; Raw score = " + rawScores[idealSegmentLengthInSamples - i]);
                                //}
                                double distanceFactor         = Math.Pow(i * _settings.AutoSegmenterOptimumLengthClampingFactor + 1, 2);
                                uint   iAdjust                = idealSegmentLengthInSamples + i - _adjacentSamplesToFactorIntoAdjustedScore;
                                double totalNewAdjustedScores = adjustedScores[iAdjust] = ComputeAdjustedScore(rawScores, iAdjust, distanceFactor);
                                if (adjustedScores[iAdjust] < bestScore)
                                {
                                    bestScore = adjustedScores[iAdjust];
                                    bestBreak = lastBreak + iAdjust;
                                }
                                iAdjust = idealSegmentLengthInSamples - i + _adjacentSamplesToFactorIntoAdjustedScore;
                                adjustedScores[iAdjust] = ComputeAdjustedScore(rawScores, iAdjust, distanceFactor);
                                totalNewAdjustedScores += adjustedScores[iAdjust];
                                if (adjustedScores[iAdjust] < bestScore)
                                {
                                    bestScore = adjustedScores[iAdjust];
                                    bestBreak = lastBreak + iAdjust;
                                }
                                uint samplesInPrevAvg = (1 + 2 * (i - _adjacentSamplesToFactorIntoAdjustedScore - 1));
                                averageScore = (averageScore * samplesInPrevAvg + totalNewAdjustedScores) / (samplesInPrevAvg + 2);
                                if (bestScore < averageScore / 2 && i < idealSegmentLengthInSamples &&
                                    rawScores[idealSegmentLengthInSamples + i] < rawScores[idealSegmentLengthInSamples + i + 1] &&
                                    rawScores[idealSegmentLengthInSamples - i] < rawScores[idealSegmentLengthInSamples - i - 1])
                                {
                                    break;
                                }
                            }
                        }
                        remainingSamples -= (bestBreak - lastBreak);
                        lastBreak         = bestBreak;
                        yield return(TimeSpan.FromMilliseconds(millisecondsPerSample * bestBreak));
                    }
                    if (remainingSamples > 0)
                    {
                        yield return(StreamReader.TotalTime);
                    }
                }
            }
        }