public void GetFileNameTestStartAndEndOffsets() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, 72.Seconds(), 600.Seconds(), true); Assert.AreEqual("original_1.2-10min.wav", actual); }
public void GetFileNameTestStartAndEndOffsetsRealFractionCappedAtSixPlaces() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, 73.123.Seconds(), 127.Seconds(), true); Assert.AreEqual("original_1.218717-2.116667min.wav", actual); }
public void GetFileNameTestNonRoundedOffset() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, 90.Seconds(), null, true); Assert.AreEqual("original_1.5min.wav", actual); }
public void GetFileNameTestRealFractionRoundedOffsetCappedAtSixPlaces() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, 67.Seconds(), null, true); Assert.AreEqual("original_1.116667min.wav", actual); }
public void GetFileNameTestStartOffset() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, 3660.Seconds(), null, true); Assert.AreEqual("original_61min.wav", actual); }
public void GetFileNameTestNullOffsets() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, null, null, true); Assert.AreEqual("original_0min.wav", actual); }
public void GetFileNameTestStartAndEndOffsetsRealFractionCappedAtThreePlacesNew() { var actual = AudioFilePreparer.GetFileName("original.mp3", MediaTypes.MediaTypeWav, 73.12399.Seconds(), 127.33333333.Seconds()); Assert.AreEqual("original_73.124-127.333.wav", actual); }
/// <summary> /// This entrypoint should be used for testing short files (less than 2 minutes). /// </summary> public static void Execute(Arguments arguments) { MainEntry.WarnIfDeveloperEntryUsed("EventRecognizer entry does not do any audio maniuplation."); Log.Info("Running event recognizer"); var sourceAudio = arguments.Source; var configFile = arguments.Config.ToFileInfo(); var outputDirectory = arguments.Output; if (configFile == null) { throw new FileNotFoundException("No config file argument provided"); } else if (!configFile.Exists) { Log.Warn($"Config file {configFile.FullName} not found... attempting to resolve config file"); configFile = ConfigFile.Resolve(configFile.Name, Directory.GetCurrentDirectory().ToDirectoryInfo()); } LoggedConsole.WriteLine("# Recording file: " + sourceAudio.FullName); LoggedConsole.WriteLine("# Configuration file: " + configFile); LoggedConsole.WriteLine("# Output folder: " + outputDirectory); // find an appropriate event IAnalyzer IAnalyser2 recognizer = AnalyseLongRecording.FindAndCheckAnalyzer <IEventRecognizer>( arguments.AnalysisIdentifier, configFile.Name); Log.Info("Attempting to run recognizer: " + recognizer.Identifier); Log.Info("Reading configuration file"); Config configuration = ConfigFile.Deserialize <RecognizerBase.RecognizerConfig>(configFile); // get default settings AnalysisSettings analysisSettings = recognizer.DefaultSettings; // convert arguments to analysis settings analysisSettings = arguments.ToAnalysisSettings( analysisSettings, outputIntermediate: true, resultSubDirectory: recognizer.Identifier, configuration: configuration); // Enable this if you want the Config file ResampleRate parameter to work. // Generally however the ResampleRate should remain at 22050Hz for all recognizers. //analysisSettings.AnalysisTargetSampleRate = (int) configuration[AnalysisKeys.ResampleRate]; // get transform input audio file - if needed Log.Info("Querying source audio file"); var audioUtilityRequest = new AudioUtilityRequest() { TargetSampleRate = analysisSettings.AnalysisTargetSampleRate, }; var preparedFile = AudioFilePreparer.PrepareFile( outputDirectory, sourceAudio, MediaTypes.MediaTypeWav, audioUtilityRequest, outputDirectory); var source = preparedFile.SourceInfo.ToSegment(); var prepared = preparedFile.TargetInfo.ToSegment(FileSegment.FileDateBehavior.None); var segmentSettings = new SegmentSettings <FileInfo>( analysisSettings, source, (analysisSettings.AnalysisOutputDirectory, analysisSettings.AnalysisTempDirectory), prepared); if (preparedFile.TargetInfo.SampleRate.Value != analysisSettings.AnalysisTargetSampleRate) { Log.Warn("Input audio sample rate does not match target sample rate"); } // Execute a pre analyzer hook recognizer.BeforeAnalyze(analysisSettings); // execute actual analysis - output data will be written Log.Info("Running recognizer: " + recognizer.Identifier); AnalysisResult2 results = recognizer.Analyze(analysisSettings, segmentSettings); // run summarize code - output data can be written Log.Info("Running recognizer summary: " + recognizer.Identifier); recognizer.SummariseResults( analysisSettings, source, results.Events, results.SummaryIndices, results.SpectralIndices, new[] { results }); //Log.Info("Recognizer run, saving extra results"); // TODO: Michael, output anything else as you wish. Log.Debug("Clean up temporary files"); if (source.Source.FullName != prepared.Source.FullName) { prepared.Source.Delete(); } int eventCount = results?.Events?.Length ?? 0; Log.Info($"Number of detected events: {eventCount}"); Log.Success(recognizer.Identifier + " recognizer has completed"); }
/// <summary> /// Calculate the file segments for analysis. /// </summary> /// <param name="fileSegments"> /// The file segments. /// </param> /// <param name="settings"> /// The settings. /// </param> /// <returns> /// Enumerable of sub-segments. /// </returns> public IEnumerable <ISegment <TSource> > CalculateSegments <TSource>( IEnumerable <ISegment <TSource> > fileSegments, AnalysisSettings settings) { foreach (var segment in fileSegments) { if (!(segment is FileSegment)) { throw new NotImplementedException("Anthony was too lazy to fix this properly. " + "Adding support proper support for ISegment is difficult " + "at this stage."); } var fileSegment = (FileSegment)segment; var startOffset = fileSegment.StartOffsetSeconds.Seconds(); var endOffset = fileSegment.EndOffsetSeconds.Seconds(); // process time alignment var startDelta = TimeSpan.Zero; var endDelta = TimeSpan.Zero; if (fileSegment.Alignment != TimeAlignment.None) { // FileSegment should have already verified a date will be present // ReSharper disable once PossibleInvalidOperationException var startDate = fileSegment.TargetFileStartDate.Value.ToUniversalTime(); // if there's a zero second to the time if (startDate.TimeOfDay.Seconds == 0 && startDate.TimeOfDay.Milliseconds == 0) { // then do nothing Log.Debug("TimeAlignment ignored because start date is already aligned"); } else { // calculate the delta to the next minute // 1:23:45, startOffset = 15 // 1:38:45 - start date with offset // 1:39:00 - next minute var dateWithStartOffset = startDate.Add(startOffset); var nextMinute = dateWithStartOffset.Ceiling(TimeSpan.FromMinutes(1)); startDelta = nextMinute - dateWithStartOffset; var dateWithEndOffset = startDate.Add(endOffset); var lastMinute = dateWithEndOffset.Floor(TimeSpan.FromMinutes(1)); endDelta = dateWithEndOffset - lastMinute; } } // the rest of the duration (excluding the start and end fractions from the time alignment) var fileSegmentDuration = (endOffset - startOffset - startDelta - endDelta).TotalMilliseconds; var analysisSegmentMaxDuration = settings.AnalysisMaxSegmentDuration?.TotalMilliseconds ?? fileSegmentDuration; var analysisSegmentMinDuration = this.filterShortSegments ? settings.AnalysisMinSegmentDuration : (TimeSpan?)null; Log.Debug($"{nameof(LocalSourcePreparer)}.{nameof(this.CalculateSegments)}: Calculating segments for duration {fileSegmentDuration}, each {analysisSegmentMaxDuration} long"); // segment into exact chunks - all but the last chunk will be equal to the max duration var segments = AudioFilePreparer.DivideExactLeaveLeftoversAtEnd( Convert.ToInt64(fileSegmentDuration), Convert.ToInt64(analysisSegmentMaxDuration)); var overlap = settings.SegmentOverlapDuration; long aggregate = 0; // include fractional segment cut from time alignment if ((fileSegment.Alignment == TimeAlignment.TrimEnd || fileSegment.Alignment == TimeAlignment.TrimNeither) && startDelta > TimeSpan.Zero) { Log.Debug($"Generated fractional segment for time alignment ({startOffset} - {startOffset + startDelta})"); var startAlignDelta = Convert.ToInt64(startDelta.TotalMilliseconds); if (TryCreateSegment( ref aggregate, startAlignDelta, fileSegment, startOffset, endOffset, overlap, analysisSegmentMinDuration, out var validFileSegment)) { yield return((ISegment <TSource>)validFileSegment); } } else { // advance the counter but don't produce the first segment aggregate += Convert.ToInt64(startDelta.TotalMilliseconds); } // yield each normal segment foreach (long offset in segments) { if (TryCreateSegment( ref aggregate, offset, fileSegment, startOffset, endOffset, overlap, analysisSegmentMinDuration, out var validFileSegment)) { yield return((ISegment <TSource>)validFileSegment); } } // include fractional segment cut from time alignment if ((fileSegment.Alignment == TimeAlignment.TrimStart || fileSegment.Alignment == TimeAlignment.TrimNeither) && startDelta > TimeSpan.Zero) { Log.Debug($"Generated fractional segment for time alignment ({endOffset - endDelta} - {endOffset})"); var endAlignDelta = Convert.ToInt64(endDelta.TotalMilliseconds); if (TryCreateSegment( ref aggregate, endAlignDelta, fileSegment, startOffset, endOffset, overlap, analysisSegmentMinDuration, out var validFileSegment)) { yield return((ISegment <TSource>)validFileSegment); } } } }