/// <summary> /// Only call this method for short recordings. /// If accumulating data for long recordings then call the method for long recordings - i.e. /// double[] spectralIndex = GenerateOscillationDataAndImages(FileInfo audioSegment, Dictionary configDict, false, false). /// </summary> public static FreqVsOscillationsResult GetFreqVsOscillationsDataAndImage(BaseSonogram sonogram, string algorithmName) { double sensitivity = DefaultSensitivityThreshold; int sampleLength = DefaultSampleLength; var freqOscilMatrix = GetFrequencyByOscillationsMatrix(sonogram.Data, sensitivity, sampleLength, algorithmName); var image = GetFreqVsOscillationsImage(freqOscilMatrix, sonogram.FramesPerSecond, sonogram.FBinWidth, sampleLength, algorithmName); var sourceName = Path.GetFileNameWithoutExtension(sonogram.Configuration.SourceFName); // get the OSC spectral index // var spectralIndex = ConvertMatrix2SpectralIndexBySummingFreqColumns(freqOscilMatrix, skipNRows: 1); var spectralIndex = MatrixTools.GetMaximumColumnValues(freqOscilMatrix); if (spectralIndex == null) { throw new ArgumentNullException(nameof(spectralIndex)); } // DEBUGGING // Add spectralIndex into the matrix because want to add it to image. // This is for debugging only and can comment this line int rowCount = freqOscilMatrix.GetLength(0); MatrixTools.SetRow(freqOscilMatrix, rowCount - 2, spectralIndex); var result = new FreqVsOscillationsResult { SourceFileName = sourceName, FreqOscillationImage = image, FreqOscillationData = freqOscilMatrix, OscillationSpectralIndex = spectralIndex, }; return(result); }
/// <summary> /// Creates an image from the frequency/oscillations matrix. /// The y-axis scale = frequency bins as per normal spectrogram. /// The x-axis scale is oscillations per second. /// </summary> /// <param name="freqOscilMatrix">the input frequency/oscillations matrix</param> /// <param name="framesPerSecond">to give the time scale</param> /// <param name="freqBinWidth">to give the frequency scale</param> /// <param name="sampleLength">to allow calculation of the oscillations scale</param> /// <param name="algorithmName">the algorithm used to compute the oscillations.</param> /// <returns>bitmap image</returns> public static Image GetFreqVsOscillationsImage(double[,] freqOscilMatrix, double framesPerSecond, double freqBinWidth, int sampleLength, string algorithmName) { // remove the high cycles/sec end of the matrix because nothing really happens here. int maxRows = freqOscilMatrix.GetLength(0) / 2; freqOscilMatrix = MatrixTools.Submatrix(freqOscilMatrix, 0, 0, maxRows - 1, freqOscilMatrix.GetLength(1) - 1); // get the OSC spectral index var spectralIndex = MatrixTools.GetMaximumColumnValues(freqOscilMatrix); // Convert spectrum index to oscillations per second double oscillationBinWidth = framesPerSecond / sampleLength; //draw an image freqOscilMatrix = MatrixTools.MatrixRotate90Anticlockwise(freqOscilMatrix); // each value is to be drawn as a 5 pixel x 5 pixel square int xscale = 5; int yscale = 5; if (maxRows < 10) { xscale = 10; } //var image1 = ImageTools.DrawMatrixInColour(freqOscilMatrix, xPixelsPerCell: xscale, yPixelsPerCell: yscale); //var image2 = ImageTools.DrawVectorInColour(DataTools.reverseArray(spectralIndex), cellWidth: xscale); var image1 = ImageTools.DrawMatrixInGrayScale(freqOscilMatrix, xPixelsPerCell: xscale, yPixelsPerCell: yscale, reverse: true); spectralIndex = DataTools.NormaliseByScalingMaxValueToOne(spectralIndex); var image2 = ImageTools.DrawVectorInGrayScaleWithoutNormalisation(DataTools.reverseArray(spectralIndex), xscale, yscale, reverse: true); var image = ImageTools.CombineImagesInLine(new[] { image1, image2 }); // place a grid line every 5 cycles per second. double cycleInterval = 5.0; double xTicInterval = cycleInterval / oscillationBinWidth * xscale; // a tic every 1000 Hz. int herzInterval = 1000; double yTicInterval = herzInterval / freqBinWidth * yscale; int xOffset = xscale / 2; int yOffset = yscale / 2; image = ImageTools.DrawYaxisScale(image, 10, herzInterval, yTicInterval, yOffset); image = ImageTools.DrawXaxisScale(image, 15, cycleInterval, xTicInterval, 10, -xOffset); var titleBar = DrawTitleBarOfOscillationSpectrogram(algorithmName, image.Width); var imageList = new List <Image> { titleBar, image }; var compositeBmp = (Bitmap)ImageTools.CombineImagesVertically(imageList); return(compositeBmp); }
public static double[] GetSpectralIndex_Osc(AudioRecording recordingSegment, int frameLength, int sampleLength, double sensitivity) { var spgm = GetSpectrogramMatrix(recordingSegment, frameLength); // Sample length i.e. number of frames spanned to calculate oscillations per second int framecount = spgm.GetLength(0); // adjust sample length i.e. patch size for short recordings. sampleLength = AdjustSampleSize(framecount, sampleLength); var freqOscilMatrix = GetFrequencyByOscillationsMatrix(spgm, sensitivity, sampleLength, "autocorr-fft"); //NOTE: Generate an oscillations spectral index for making LDFC spectrograms by taking the max of each column var spectralIndex = MatrixTools.GetMaximumColumnValues(freqOscilMatrix); return(spectralIndex); }
public static Image GetFreqVsOscillationsImage(double[,] freqOscilMatrix, double framesPerSecond, double freqBinWidth, int sampleLength, string algorithmName) { // remove the high cycles/sec end of the matrix because nothing really happens here. freqOscilMatrix = MatrixTools.Submatrix(freqOscilMatrix, 0, 0, 30, freqOscilMatrix.GetLength(1) - 1); // get the OSC spectral index // double[] spectralIndex = ConvertMatrix2SpectralIndexBySummingFreqColumns(freqOscilMatrix, skipNrows: 0); var spectralIndex = MatrixTools.GetMaximumColumnValues(freqOscilMatrix); // Convert spectrum index to oscillations per second double oscillationBinWidth = framesPerSecond / sampleLength; //draw an image freqOscilMatrix = MatrixTools.MatrixRotate90Anticlockwise(freqOscilMatrix); int xscale = 5; int yscale = 5; var image1 = ImageTools.DrawMatrixInColour(freqOscilMatrix, xPixelsPerCell: xscale, yPixelsPerCell: yscale); var image2 = ImageTools.DrawVectorInColour(DataTools.reverseArray(spectralIndex), cellWidth: xscale); var image = ImageTools.CombineImagesInLine(new[] { image1, image2 }); // a tic every 5cpsec. double cycleInterval = 5.0; double xTicInterval = cycleInterval / oscillationBinWidth * xscale; // a tic every 1000 Hz. int herzInterval = 1000; double yTicInterval = herzInterval / freqBinWidth * yscale; int xOffset = xscale / 2; int yOffset = yscale / 2; image = ImageTools.DrawXandYaxes(image, 18, cycleInterval, xTicInterval, xOffset, herzInterval, yTicInterval, yOffset); var titleBar = DrawTitleBarOfOscillationSpectrogram(algorithmName, image.Width); var imageList = new List <Image> { titleBar, image }; var compositeBmp = (Bitmap)ImageTools.CombineImagesVertically(imageList); return(compositeBmp); }