private static void CleanupAfterSegment <TSource>(
            SegmentSettings <TSource> settings,
            bool hasUniqueDirectoryPerSegment,
            bool shouldSaveAudioSegment)
        {
            Debug.Assert(
                settings.SegmentAudioFile.DirectoryName == settings.SegmentTempDirectory.FullName,
                "The used audio file should be saved in the segment temp directory (but wasn't).");

            int id = settings.InstanceId;

            // delete the prepared audio file segment or move it to output folder if we are keeping it
            if (shouldSaveAudioSegment)
            {
                Log.Debug(
                    $"Item {id} moved file {settings.SegmentAudioFile.FullName} to output because " +
                    $"saveIntermediateWavFiles was not set to {nameof(SaveBehavior.Never)}");

                var destination = Path.Combine(
                    settings.SegmentOutputDirectory.FullName,
                    settings.SegmentAudioFile.Name);
                settings.SegmentAudioFile.MoveTo(destination);
            }
            else
            {
                // failing is not fatal, but it does mean we'll be leaving a file behind.
                settings.SegmentAudioFile.TryDelete($"AnalysisSettings Item: {id}");
            }

            // if there's a unique directory per segment we just delete folder
            // however if it is shared we can only delete resources inside it (see above)
            // as all instances use the same directory!
            if (hasUniqueDirectoryPerSegment)
            {
                if (settings.SegmentOutputDirectory.FullName == settings.SegmentTempDirectory.FullName)
                {
                    Log.Debug(
                        "Not deleting segment temp directory because it is identical to segment output directory");
                }
                else
                {
                    // delete the directory created for this run
                    // Failing is not fatal, but it does mean we'll be leaving a dir behind.
                    settings.SegmentTempDirectory.TryDelete(recursive: true, message: $"AnalysisSettings Item: {id}");
                }
            }
        }
        private static void ValidateResult <T>(
            AnalysisSettings preAnalysisSettings,
            AnalysisResult2 result,
            SegmentSettings <T> segmentSettings,
            TimeSpan preparedFileDuration,
            bool parallelized)
        {
            Contract.Ensures(
                result.SettingsUsed != null,
                "The settings used in the analysis must be populated in the analysis result.");
            Contract.Ensures(
                result.SegmentStartOffset == segmentSettings.SegmentStartOffset,
                "The segment start offset of the result should match the start offset that it was instructed to analyze");
            Contract.Ensures(
                Math.Abs((result.SegmentAudioDuration - preparedFileDuration).TotalMilliseconds) < 1.0,
                "The duration analyzed (reported by the analysis result) should be withing a millisecond of the provided audio file");

            if (preAnalysisSettings.AnalysisImageSaveBehavior == SaveBehavior.Always ||
                preAnalysisSettings.AnalysisImageSaveBehavior == SaveBehavior.WhenEventsDetected &&
                result.Events.Length > 0)
            {
                Contract.Ensures(
                    segmentSettings.SegmentImageFile.RefreshInfo().Exists,
                    "If the analysis was instructed to produce an image file, then it should exist");
            }

            Contract.Ensures(
                result.Events != null,
                "The Events array should never be null. No events should be represented by a zero length Events array.");
            if (result.Events.Length != 0 && preAnalysisSettings.AnalysisDataSaveBehavior)
            {
                Contract.Ensures(
                    result.EventsFile.RefreshInfo().Exists,
                    "If events were produced and an events file was expected, then the events file should exist");
            }

            Contract.Ensures(
                result.SummaryIndices != null,
                "The SummaryIndices array should never be null. No SummaryIndices should be represented by a zero length SummaryIndices array.");
            if (result.SummaryIndices.Length != 0 && preAnalysisSettings.AnalysisDataSaveBehavior)
            {
                Contract.Ensures(
                    result.SummaryIndicesFile.RefreshInfo().Exists,
                    "If SummaryIndices were produced and an SummaryIndices file was expected, then the SummaryIndices file should exist");
            }

            Contract.Ensures(
                result.SpectralIndices != null,
                "The SpectralIndices array should never be null. No SpectralIndices should be represented by a zero length SpectralIndices array.");
            if (result.SpectralIndices.Length != 0 && preAnalysisSettings.AnalysisDataSaveBehavior)
            {
                foreach (var spectraIndicesFile in result.SpectraIndicesFiles)
                {
                    Contract.Ensures(
                        spectraIndicesFile.RefreshInfo().Exists,
                        "If SpectralIndices were produced and SpectralIndices files were expected, then the SpectralIndices files should exist");
                }
            }

            foreach (var eventBase in result.Events)
            {
                Contract.Ensures(
                    eventBase.ResultStartSeconds >= result.SegmentStartOffset.TotalSeconds,
                    "Every event should be found within the bounds of the current segment. This error occurs when segmentStartOffset is not set correctly.");

                // ReSharper disable CompareOfFloatsByEqualityOperator
                Contract.Ensures(
                    eventBase.EventStartSeconds == eventBase.ResultStartSeconds,
                    "The relative EventStartSeconds should equal the seconds component of StartOffset");

                // ReSharper restore CompareOfFloatsByEqualityOperator
                Contract.Ensures(
                    Math.Abs(eventBase.SegmentStartSeconds - result.SegmentStartOffset.TotalSeconds) < 0.0001,
                    "Segment start offsets must match");

                Contract.Ensures(
                    eventBase.SegmentDurationSeconds > 0.0,
                    "eventBase.SegmentDurationSeconds must be greater than 0.0");
            }

            foreach (var summaryIndexBase in result.SummaryIndices)
            {
                Contract.Ensures(
                    summaryIndexBase.ResultStartSeconds >= result.SegmentStartOffset.TotalSeconds,
                    "Every summary index generated by this analysis should be found within the bounds of the segment analyzed");
            }

            foreach (var spectralIndexBase in result.SpectralIndices)
            {
                Contract.Ensures(
                    spectralIndexBase.ResultStartSeconds >= result.SegmentStartOffset.TotalSeconds,
                    "Every spectral index generated by this analysis should be found within the bounds of the segment analyzed");
            }
        }
Exemple #3
0
 /// <inheritdoc/>
 public abstract AnalysisResult2 Analyze <T>(AnalysisSettings analysisSettings, SegmentSettings <T> segmentSettings);