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"); } }
/// <inheritdoc/> public abstract AnalysisResult2 Analyze <T>(AnalysisSettings analysisSettings, SegmentSettings <T> segmentSettings);