/// <summary>
        /// Returns a HISTORGRAM OF THE DISTRIBUTION of SPECTRAL maxima.
        /// </summary>
        public static Tuple <int[], int[]> HistogramOfSpectralPeaks(double[,] spectrogram)
        {
            if (spectrogram == null)
            {
                throw new ArgumentNullException(nameof(spectrogram));
            }

            int frameCount   = spectrogram.GetLength(0);
            int freqBinCount = spectrogram.GetLength(1);

            int[] peakBins  = new int[frameCount];   // store bin id of peaks
            int[] histogram = new int[freqBinCount]; // histogram of peak locations

            // for all frames in dB array
            for (int r = 0; r < frameCount; r++)
            {
                double[] spectrum = DataTools.GetRow(spectrogram, r);

                //locate maximum peak
                int j = DataTools.GetMaxIndex(spectrum);

                //if (spectrogram[r, j] > peakThreshold)
                //{
                histogram[j]++;

                //store bin of peak
                peakBins[r] = j;

                //}
            }

            return(Tuple.Create(histogram, peakBins));
        }
        /// <summary>
        /// (2) LOWEST PERCENTILE FRAMES METHOD
        /// Assumes the passed matrix is a spectrogram and that all values in the data matrix are positive.
        /// Returns the noise profile over freq bins. i.e. one noise value per freq bin.
        /// First calculate the frame averages, sort in ascending order and accumulate the first N% of frames.
        /// WARNING: This method should NOT be used for short recordings i.e LT approx 10-15 seconds long.
        /// </summary>
        /// <param name="matrix">the spectrogram whose rows=frames, cols=freq bins.</param>
        /// <param name="lowPercentile">The percent of lowest energy frames to be included in calculation of the noise profile.</param>
        /// <returns>Returns a noise profile consisting of averaged values from the selected X% of low energy frames.</returns>
        public static double[] GetNoiseProfile_fromLowestPercentileFrames(double[,] matrix, int lowPercentile)
        {
            int rowCount = matrix.GetLength(0);
            int colCount = matrix.GetLength(1);
            int cutoff   = lowPercentile * rowCount / 100;

            if (cutoff == 0)
            {
                throw new Exception("Illegal zero value for cutoff in method NoiseRemoval_Briggs.GetNoiseProfile_LowestPercentile()");
            }

            double[] frameEnergyLevels = MatrixTools.GetRowAverages(matrix);
            var      sorted            = DataTools.SortArrayInAscendingOrder(frameEnergyLevels);

            int[] order = sorted.Item1;

            // sum the lowest percentile frames
            double[] noiseProfile = new double[colCount];
            for (int i = 0; i < cutoff; i++)
            {
                double[] row = DataTools.GetRow(matrix, order[i]);
                for (int c = 0; c < colCount; c++)
                {
                    noiseProfile[c] += row[c];
                }
            }

            // get average of the lowest percentile frames
            for (int c = 0; c < colCount; c++)
            {
                noiseProfile[c] /= cutoff;
            }

            return(noiseProfile);
        }
Beispiel #3
0
        /// <summary>
        /// THIS METHOD CALLED FROM ULTIMATELY UP LINE FROM AcousticIndicesCalculate class.
        /// returns an array showing which freq bin in each frame has the maximum amplitude
        /// </summary>
        /// <param name="spectrogram"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public static int[] GetSpectralMaxima(double[,] spectrogram, double threshold)
        {
            int rowCount     = spectrogram.GetLength(0);
            int colCount     = spectrogram.GetLength(1);
            var maxFreqArray = new int[rowCount]; //array (one element per frame) indicating which freq bin has max amplitude.

            //var hitsMatrix = new double[rowCount, colCount];

            for (int r = 0; r < rowCount; r++)
            {
                double[] spectrum = DataTools.GetRow(spectrogram, r);
                spectrum = DataTools.filterMovingAverage(spectrum, 3); // smoothing to remove noise

                //find local freq maxima and store in freqArray & hits matrix.
                int maxFreqbin = DataTools.GetMaxIndex(spectrum);
                if (spectrum[maxFreqbin] > threshold) //only record spectral peak if it is above threshold.
                {
                    maxFreqArray[r] = maxFreqbin;

                    //hitsMatrix[r + nh, maxFreqbin] = 1.0;
                }
            }

            return(maxFreqArray);
        } // GetSpectralMaxima()
Beispiel #4
0
        public static double[] GetAvSpectrum_HighestPercentile(double[,] matrix, int highPercentile)
        {
            double[] energyLevels = MatrixTools.GetRowAverages(matrix);
            var      sorted       = DataTools.SortArray(energyLevels); // sorts array in descending order

            int[] order = sorted.Item1;

            int colCount = matrix.GetLength(1);
            int cutoff   = (int)(highPercentile * matrix.GetLength(0) / 100D);

            double[] avSpectrum = new double[colCount];

            // sum the lowest percentile frames
            for (int i = 0; i < cutoff; i++)
            {
                double[] row = DataTools.GetRow(matrix, order[i]);
                for (int c = 0; c < colCount; c++)
                {
                    avSpectrum[c] += row[c];
                }
            }

            // get average of the lowest percentile frames
            for (int c = 0; c < colCount; c++)
            {
                avSpectrum[c] /= cutoff;
            }

            return(avSpectrum);
        }
        //********************************************************************************************************************
        //********************************************************************************************************************
        //********************************************************************************************************************
        //******************************* CEPTRA COEFFICIENTS USING DCT AND COSINES

        public static double[,] Cepstra(double[,] spectra, int coeffCount)
        {
            int frameCount = spectra.GetLength(0); //number of frames
            int binCount   = spectra.GetLength(1); //number of filters in filter bank

            //set up the cosine coefficients. Need one extra to compensate for DC coeff.
            double[,] cosines = Cosines(binCount, coeffCount + 1);

            //following two lines write matrix of cos values for checking.
            //string fPath = @"C:\SensorNetworks\Sonograms\cosines.txt";
            //FileTools.WriteMatrix2File_Formatted(cosines, fPath, "F3");

            //following two lines write bmp image of cos values for checking.
            //string fPath = @"C:\SensorNetworks\Sonograms\cosines.bmp";
            //ImageTools.DrawMatrix(cosines, fPath);

            double[,] op = new double[frameCount, coeffCount];
            for (int i = 0; i < frameCount; i++)
            {
                double[] spectrum = DataTools.GetRow(spectra, i); //transfer matrix row=i to vector
                double[] cepstrum = DCT(spectrum, cosines);

                for (int j = 0; j < coeffCount; j++)
                {
                    op[i, j] = cepstrum[j + 1]; //+1 in order to skip first DC value
                }
            } //end of all frames

            return(op);
        }
Beispiel #6
0
        public static byte[,] IdentifySpectralRidgesInFreqDirection(double[,] matrix, double threshold)
        {
            int rows = matrix.GetLength(0);
            int cols = matrix.GetLength(1);

            //A: CONVERT MATRIX to BINARY FORM INDICATING SPECTRAL RIDGES
            var binary = new byte[rows, cols];

            // row at a time, each row = one frame.
            for (int r = 0; r < rows; r++)
            {
                double[] row = DataTools.GetRow(matrix, r);
                row = DataTools.filterMovingAverage(row, 3); //## SMOOTH FREQ BIN - high value breaks up vertical tracks
                for (int c = 3; c < cols - 3; c++)
                {
                    double d1 = row[c] - row[c - 1];
                    double d2 = row[c] - row[c + 1];
                    double d3 = row[c] - row[c - 2];
                    double d4 = row[c] - row[c + 2];
                    double d5 = row[c] - row[c - 3];
                    double d6 = row[c] - row[c + 3];

                    //identify a peak
                    if (d1 > threshold && d2 > threshold && d3 > threshold && d4 > threshold && d5 > threshold && d6 > threshold)
                    {
                        binary[r, c] = 1;
                    }
                } //end for every col
            }     //end for every row

            return(binary);
        }
Beispiel #7
0
 /// <summary>
 /// Given a DataTools object where the query is set to grab the appropriate keys,
 /// put the ContextSpecific keys into ConfigKeys
 /// </summary>
 /// <param name="db"></param>
 protected void InitConfigKeys(DataTools db)
 {
     if (ConfigKeys != null)
     {
         while (!db.EOF)
         {
             var row = db.GetRow();
             var nm  = row["value"];
             ConfigKeys.Add(new KeyValuePair <string, string>("endpoint", nm.ToString()));
             db.NextRow();
         }
     }
 }
        /// <summary>
        /// First convert spectrogram to Binary using threshold. An amplitude threshold of 0.03 = -30 dB.   An amplitude threhold of 0.05 = -26dB.
        /// </summary>
        public static TrainingDataInfo GetTrainingDataForClustering(double[,] spectrogram, ClusteringParameters cp)
        {
            int frameCount   = spectrogram.GetLength(0);
            int freqBinCount = spectrogram.GetLength(1);
            var trainingData = new List <double[]>(); // training data that will be used for clustering

            double[,] trainingDataAsSpectrogram = new double[frameCount, freqBinCount];

            // training data represented in spectrogram
            bool[] selectedFrames = new bool[frameCount];

            for (int r = 0; r < frameCount; r++)
            {
                double[] spectrum = DataTools.GetRow(spectrogram, r);
                spectrum = DataTools.VectorReduceLength(spectrum, cp.ReductionFactor);

                // reduce length of the vector by factor of N and convert to binary
                for (int i = 0; i < spectrum.Length; i++)
                {
                    if (spectrum[i] >= cp.IntensityThreshold)
                    {
                        spectrum[i] = 1.0;
                    }
                    else
                    {
                        spectrum[i] = 0.0;
                    }
                }

                // remove isolated peaks.
                //for (int i = 1; i < spectrum.Length - 1; i++)
                //{
                //    if ((spectrum[i] == 1.0) && (spectrum[i - 1] == 0.0) && (spectrum[i + 1] == 0.0))
                //    {
                //        spectrum[i] = 0.0;
                //    }
                //}

                // only include frames where activity exceeds threshold
                if (spectrum.Sum() > cp.RowSumThreshold)
                {
                    trainingData.Add(spectrum);
                    IncludeSpectrumInSpectrogram(trainingDataAsSpectrogram, r, spectrum, cp.ReductionFactor);
                    selectedFrames[r] = true;
                }
            }

            return(new TrainingDataInfo(trainingDataAsSpectrogram, trainingData, selectedFrames, cp.LowBinBound, cp.UpperBinBound, cp.IntensityThreshold));
        }
        /// <summary>
        /// use this version when want to make matrix of Cosines only one time.
        /// </summary>
        public static double[,] Cepstra(double[,] spectra, int coeffCount, double[,] cosines)
        {
            int frameCount = spectra.GetLength(0);  //number of frames

            double[,] op = new double[frameCount, coeffCount];
            for (int i = 0; i < frameCount; i++)
            {
                double[] spectrum = DataTools.GetRow(spectra, i); //transfer matrix row=i to vector
                double[] cepstrum = DCT(spectrum, cosines);

                for (int j = 0; j < coeffCount; j++)
                {
                    op[i, j] = cepstrum[j + 1]; //+1 in order to skip first DC value
                }
            } //end of all frames

            return(op);
        }
Beispiel #10
0
        public static double[,] MakeAcousticVectors(SonogramConfig config, double[,] matrix, double[] decibels, int sampleRate)
        {
            int  ccCount            = config.mfccConfig.CcCount;
            bool includeDelta       = config.mfccConfig.IncludeDelta;
            bool includeDoubleDelta = config.mfccConfig.IncludeDoubleDelta;
            int  deltaT             = config.DeltaT;

            Log.WriteIfVerbose(" MakeAcousticVectors(matrix, decibels, includeDelta=" + includeDelta + ", includeDoubleDelta=" + includeDoubleDelta + ", deltaT=" + deltaT + ")");
            var tuple = MakeCepstrogram(config, matrix, decibels, sampleRate);

            double[,] m = tuple.Item1;

            //this.SnrData.ModalNoiseProfile = tuple.Item2; //store the full bandwidth modal noise profile

            //initialise feature vector for template - will contain three acoustic vectors - for T-dT, T and T+dT
            int frameCount = m.GetLength(0);
            int cepstralL  = m.GetLength(1);                         // length of cepstral vector
            int featurevL  = 3 * cepstralL;                          // to accomodate cepstra for T-2, T and T+2

            double[,] acousticM = new double[frameCount, featurevL]; //init the matrix of acoustic vectors
            for (int i = deltaT; i < frameCount - deltaT; i++)
            {
                double[] rowTm2 = DataTools.GetRow(m, i - deltaT);
                double[] rowT   = DataTools.GetRow(m, i);
                double[] rowTp2 = DataTools.GetRow(m, i + deltaT);

                for (int j = 0; j < cepstralL; j++)
                {
                    acousticM[i, j] = rowTm2[j];
                }

                for (int j = 0; j < cepstralL; j++)
                {
                    acousticM[i, cepstralL + j] = rowT[j];
                }

                for (int j = 0; j < cepstralL; j++)
                {
                    acousticM[i, cepstralL + cepstralL + j] = rowTp2[j];
                }
            }

            return(acousticM);
        }
Beispiel #11
0
        /// <summary>
        /// Simply get a user from the localDb
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public Dictionary <string, string> GetUser(string username)
        {
            Dictionary <string, string> retVal = new Dictionary <string, string>();
            //$$$ Centalize this - without locking up a connection
            DataTools dt = new DataTools();

            dt.Provider         = provider;
            dt.ConnectionString = connectionString;
            dt.OpenConnection();
            string[] parameter = { UsernameCol, username };
            //!!! What is wrong with parameterized query?
            //dt.GetResultSet(findUserQuery, parameter);
            dt.GetResultSet(string.Format(findUserQueryTok, username));

            while (!dt.EOF)
            {
                var row = dt.GetRow();
                var nm  = row[UsernameCol];
                retVal.Add(UsernameCol, nm.ToString());
                dt.NextRow();
            }
            return(retVal);
        }
        /// <summary>
        /// find spectral peaks per frame by subtracting the average energy of top and bottom band from the syllable band energy.
        /// then if it is higher than a dB threshold, the index of the peak bin will be returned.
        /// </summary>
        public static Tuple <int[][], int[][]> FindLocalSpectralPeaks(double[,] matrix, int[] peakBinsIndex, int widthMidBand,
                                                                      int topBufferSize, int bottomBufferSize, double threshold)
        {
            int frameCount = matrix.GetLength(0);

            // save the target peak bins index [frameCount, freqBinCount]
            List <int[]> targetPeakBinsIndex = new List <int[]>();

            // save the bands' boundaries in each frame
            List <int[]> bandIndex = new List <int[]>();

            // for all frames of the input spectrogram
            for (int r = 0; r < frameCount; r++)
            {
                // retrieve each frame
                double[] spectrum = DataTools.GetRow(matrix, r);

                // smoothing to remove noise
                //spectrum = DataTools.filterMovingAverage(spectrum, 3);

                //find the boundaries of middle frequency band: the min bin index and the max bin index
                int minMid = peakBinsIndex[r] - (widthMidBand / 2);
                int maxMid = peakBinsIndex[r] + (widthMidBand / 2);

                // find the average energy
                double midBandAvgEnergy = CalculateAverageEnergy(spectrum, minMid, maxMid);

                //find the boundaries of top frequency band: the min bin index and the max bin index
                int minTop = maxMid + 1; //maxMid + 2; //
                int maxTop = minTop + topBufferSize;

                // find the average energy
                double topBandAvgEnergy = CalculateAverageEnergy(spectrum, minTop, maxTop);

                //find the boundaries of top frequency band: the min bin index and the max bin index
                int maxBottom = minMid - 1; //minMid - 2; //
                int minBottom = maxBottom - bottomBufferSize;

                // find the average energy
                double bottomBandAvgEnergy = CalculateAverageEnergy(spectrum, minBottom, maxBottom);

                // peak energy in each spectrum
                //double peakEnergy = midBandAvgEnergy - ((topBandAvgEnergy + bottomBandAvgEnergy) / 2);
                double peakEnergyInDb = 10 * Math.Log10(midBandAvgEnergy / ((topBandAvgEnergy + bottomBandAvgEnergy) / 2));

                int[] ind     = new int[2];
                int[] bandInd = new int[5];

                // convert avg energy to decibel values
                //var peakEnergyInDb = 10 * Math.Log10(peakEnergy);

                // record the peak if the peak energy is higher than a threshold
                if (peakEnergyInDb > threshold)
                {
                    ind[0] = r;
                    ind[1] = peakBinsIndex[r];
                    targetPeakBinsIndex.Add(ind);
                }

                // saving the index of top, mid, and bottom band boundaries
                bandInd[0] = r;
                bandInd[1] = minBottom;
                bandInd[2] = minMid;
                bandInd[3] = maxMid;
                bandInd[4] = maxTop;
                bandIndex.Add(bandInd);
            }

            return(Tuple.Create(targetPeakBinsIndex.ToArray(), bandIndex.ToArray()));
        }