/// <summary> /// Create a spectrogram from a segment of the <paramref name="source"/> audio file. /// <paramref name="output"/> image file will be created. /// </summary> /// <param name="source"> /// The source audio file. /// </param> /// <param name="sourceMimeType"> /// The source Mime Type. /// </param> /// <param name="output"> /// The output image file. Ensure the file does not exist. /// </param> /// <param name="outputMimeType"> /// The output Mime Type. /// </param> /// <param name="request"> /// The spectrogram request. /// </param> public void Create(FileInfo source, string sourceMimeType, FileInfo output, string outputMimeType, SpectrogramRequest request) { this.ValidateMimeTypeExtension(source, sourceMimeType, output, outputMimeType); var tempFile = TempFileHelper.NewTempFile(this.TemporaryFilesDirectory, MediaTypes.ExtWav); var audioUtilRequest = new AudioUtilityRequest { MixDownToMono = true, OffsetStart = request.Start, OffsetEnd = request.End, TargetSampleRate = 22050, }; this.audioUtility.Modify(source, sourceMimeType, tempFile, MediaTypes.MediaTypeWav, audioUtilRequest); Image sourceImage; if (this.Log.IsDebugEnabled) { var stopwatch = new Stopwatch(); stopwatch.Start(); sourceImage = Spectrogram(File.ReadAllBytes(tempFile.FullName)); stopwatch.Stop(); this.Log.DebugFormat( "Generated spectrogram for {0}. Took {1} ({2}ms).", source.Name, stopwatch.Elapsed.Humanise(), stopwatch.Elapsed.TotalMilliseconds); this.Log.Debug("Source " + this.BuildFileDebuggingOutput(source)); } else { sourceImage = Spectrogram(File.ReadAllBytes(tempFile.FullName)); } // modify image to match request using (sourceImage) { // remove 1px from bottom (DC value) var sourceRectangle = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height - 1); using var requestedImage = new Image <Rgb24>( request.IsCalculatedWidthAvailable ? request.CalculatedWidth : sourceRectangle.Width, request.Height ?? sourceRectangle.Height); var destRectangle = new Rectangle(0, 0, requestedImage.Width, requestedImage.Height); requestedImage.DrawImage(sourceImage, destRectangle, sourceRectangle); var format = MediaTypes.GetImageFormat(MediaTypes.GetExtension(outputMimeType)); var encoder = requestedImage.GetConfiguration().ImageFormatsManager.FindEncoder(format); if (this.Log.IsDebugEnabled) { var stopwatch = new Stopwatch(); stopwatch.Start(); requestedImage.Save(output.FullName, encoder); stopwatch.Stop(); this.Log.DebugFormat( "Saved spectrogram for {0} to {1}. Took {2} ({3}ms).", source.Name, output.Name, stopwatch.Elapsed.Humanise(), stopwatch.Elapsed.TotalMilliseconds); this.Log.Debug("Output " + this.BuildFileDebuggingOutput(output)); } else { requestedImage.Save(output.FullName, encoder); } } tempFile.Delete(); }
/// <summary> /// Create a spectrogram from a segment of the <paramref name="source"/> audio file. /// <paramref name="output"/> image file will be created. /// </summary> /// <param name="source"> /// The source audio file. /// </param> /// <param name="sourceMimeType"> /// The source Mime Type. /// </param> /// <param name="output"> /// The output image file. Ensure the file does not exist. /// </param> /// <param name="outputMimeType"> /// The output Mime Type. /// </param> /// <param name="request"> /// The spectrogram request. /// </param> public void Create(FileInfo source, string sourceMimeType, FileInfo output, string outputMimeType, SpectrogramRequest request) { this.ValidateMimeTypeExtension(source, sourceMimeType, output, outputMimeType); this.CanProcess(output, new[] { MediaTypes.MediaTypePng, MediaTypes.MediaTypeJpeg }, null); // to get a proper image from sox, need to remove DC value, plus 1px from top and left. var wavFile = TempFileHelper.NewTempFile(this.TemporaryFilesDirectory, MediaTypes.ExtWav); var originalSoxFile = TempFileHelper.NewTempFile(this.TemporaryFilesDirectory, MediaTypes.ExtPng); var audioUtilRequest = new AudioUtilityRequest { OffsetStart = request.Start, OffsetEnd = request.End, MixDownToMono = true, TargetSampleRate = 22050 }; this.audioUtility.Modify(source, sourceMimeType, wavFile, MediaTypes.MediaTypeWav, audioUtilRequest); // generate spectrogram using sox. if (this.Log.IsDebugEnabled) { var stopwatch = new Stopwatch(); stopwatch.Start(); this.Spectrogram(wavFile, originalSoxFile); stopwatch.Stop(); this.Log.DebugFormat( "Generated and saved spectrogram for {0}. Took {1} ({2}ms).", source.Name, stopwatch.Elapsed.Humanise(), stopwatch.Elapsed.TotalMilliseconds); this.Log.Debug("Source " + this.BuildFileDebuggingOutput(source)); this.Log.Debug("Output " + this.BuildFileDebuggingOutput(output)); } else { this.Spectrogram(wavFile, originalSoxFile); } wavFile.Delete(); // modify the original image to match the request using (var sourceImage = Image.Load(originalSoxFile.FullName)) { // remove 1px from top, bottom (DC value) and left var sourceRectangle = new Rectangle(1, 1, sourceImage.Width - 1, sourceImage.Height - 2); var width = request.IsCalculatedWidthAvailable ? request.CalculatedWidth : sourceRectangle.Width; using var requestedImage = new Image <Rgb24>( width, request.Height ?? sourceRectangle.Height); var destRectangle = new Rectangle(0, 0, requestedImage.Width, requestedImage.Height); requestedImage.DrawImage(sourceImage, destRectangle, sourceRectangle); var format = MediaTypes.GetImageFormat(MediaTypes.GetExtension(outputMimeType)); var encoder = requestedImage.GetConfiguration().ImageFormatsManager.FindEncoder(format); if (this.Log.IsDebugEnabled) { var stopwatch = new Stopwatch(); stopwatch.Start(); requestedImage.Save(output.FullName, encoder); stopwatch.Stop(); this.Log.DebugFormat( "Saved spectrogram for {0} to {1}. Took {2} ({3}ms).", source.Name, output.Name, stopwatch.Elapsed.Humanise(), stopwatch.Elapsed.TotalMilliseconds); this.Log.Debug("Output " + this.BuildFileDebuggingOutput(output)); } else { requestedImage.Save(output.FullName, encoder); } } originalSoxFile.Delete(); }