public RealtimeAudioSamplesAggregator(IStride stride, int minSize) { Stride = stride; MinSize = minSize; buffer = new float[minSize]; }
private void RunTest(string[] parameters) { string action = parameters[0]; switch (action) { case "Insert": string folderWithSongs = parameters[1]; var stride = utils.ToStride(parameters[2], parameters[3], parameters[4]); DeleteAll(); var sb = TestRunnerWriter.StartInsert(); Insert(folderWithSongs, stride, sb); TestRunnerWriter.SaveInsertDataToFolder(sb, pathToResultsFolder, stride); lastInsertStride = stride; break; case "Run": string folderWithPositives = parameters[1]; string folderWithNegatives = parameters[2]; var queryStride = utils.ToStride(parameters[3], parameters[4], parameters[5]); int seconds = int.Parse(parameters[6]); var startAts = ToStartAts(parameters[7]); RunTestScenario(folderWithPositives, folderWithNegatives, queryStride, seconds, startAts); break; } }
/// <summary> /// Create fingerprints out of down sampled samples /// </summary> /// <param name = "samples">Down sampled to 5512 samples </param> /// <param name = "track">Track</param> /// <param name = "stride">Stride</param> /// <param name = "hashTables">Number of hash tables</param> /// <param name = "hashKeys">Number of hash keys</param> public void CreateInsertFingerprints( float[] samples, Track track, IStride stride, int hashTables, int hashKeys) { if (track == null) { return; /*track is not eligible*/ } /*Create fingerprints that will be used as initial fingerprints to be queried*/ List<bool[]> fingerprints = workUnitBuilder.BuildWorkUnit() .On(samples) .WithCustomConfiguration(config => config.Stride = stride) .GetFingerprintsUsingService(service) .Result; storage.InsertTrack(track); /*Insert track into the storage*/ /*Get signature's hash signature, and associate it to a specific track*/ List<HashSignature> creationalsignatures = GetSignatures(fingerprints, track, hashTables, hashKeys); foreach (HashSignature hash in creationalsignatures) { storage.InsertHash(hash, HashType.Creational); /*Set this hashes as also the query hashes*/ storage.InsertHash(hash, HashType.Query); } }
private void Insert(string folderWithSongs, IStride stride, StringBuilder sb) { var allFiles = AllFiles(folderWithSongs); int inserted = 0; var stopWatch = new Stopwatch(); stopWatch.Start(); Parallel.ForEach( allFiles, file => { OnTestRunnerEvent( OngoingActionEvent, new TestRunnerOngoingEventArgs { Message = string.Format( "Inserting tracks {0} out of {1}. Track {2}", Interlocked.Increment(ref inserted), allFiles.Count, System.IO.Path.GetFileNameWithoutExtension(file)) }); var track = InsertTrack(file); var hashes = fcb.BuildFingerprintCommand() .From(file) .WithFingerprintConfig(config => { config.Stride = stride; }) .UsingServices(audioService) .Hash() .Result; modelService.InsertHashDataForTrack(hashes, track); }); stopWatch.Stop(); sb.AppendLine(string.Format("{0},{1}", inserted, stopWatch.ElapsedMilliseconds / 1000)); }
public List<bool[]> CreateFingerprintsFromLogSpectrum( double[][] logarithmizedSpectrum, IStride stride, int fingerprintLength, int overlap, int topWavelets) { DbgTimer t = new DbgTimer(); t.Start (); // Cut the logaritmic spectrogram into smaller spectrograms with one stride between each List<double[][]> spectralImages = SpectrumService.CutLogarithmizedSpectrum(logarithmizedSpectrum, stride, fingerprintLength, overlap); // Then apply the wavelet transform on them to later reduce the resolution // do this in place WaveletService.ApplyWaveletTransformInPlace(spectralImages); // Then for each of the wavelet reduce the resolution by only keeping the top wavelets // and ignore the magnitude of the top wavelets. // Instead, we can simply keep the sign of it (+/-). // This information is enough to keep the extract perceptual characteristics of a song. List<bool[]> fingerprints = new List<bool[]>(); foreach (var spectralImage in spectralImages) { bool[] image = FingerprintDescriptor.ExtractTopWavelets(spectralImage, topWavelets); fingerprints.Add(image); } Dbg.WriteLine ("Created {1} Fingerprints from Log Spectrum - Execution Time: {0} ms", t.Stop().TotalMilliseconds, fingerprints.Count); return fingerprints; }
/// <summary> /// Create fingerprints according to the Google's researchers algorithm /// </summary> /// <param name = "spectrum">Spectrogram of the song</param> /// <param name = "stride">Stride between 2 consecutive fingerprints</param> /// <returns>Fingerprint signatures</returns> public List <bool[]> CreateFingerprints(float[][] spectrum, IStride stride) { int fingerprintLength = FingerprintLength; int overlap = Overlap; int logbins = LogBins; int start = stride.GetFirstStride() / overlap; List <bool[]> fingerprints = new List <bool[]>(); int width = spectrum.GetLength(0); while (start + fingerprintLength < width) { float[][] frames = new float[fingerprintLength][]; for (int i = 0; i < fingerprintLength; i++) { frames[i] = new float[logbins]; Array.Copy(spectrum[start + i], frames[i], logbins); } start += fingerprintLength + stride.GetStride() / overlap; WaveletDecomposition.DecomposeImageInPlace(frames); /*Compute wavelets*/ bool[] image = ExtractTopWavelets(frames); fingerprints.Add(image); } return(fingerprints); }
private Task <QueryResult> BuildQuery(IStride queryStride, int seconds, string positive, int startAt) { return(qcb.BuildQueryCommand() .From(positive, seconds, startAt) .WithFingerprintConfig(fingerprintConfig => { fingerprintConfig.Stride = queryStride; }) .UsingServices(modelService, audioService) .Query()); }
public RepositoryGateway() { _storage = new RamStorage(NUMBER_OF_HASH_TABLES); /*Number of LSH Tables, used for storage purposes*/ _permutations = new LocalPermutations(PATH_TO_PERMUTATIONS, SEPARATOR); /*Permutations*/ _repository = new Repository(_storage, _permutations); _proxy = new BassProxy(); /*audio proxy used in reading the file*/ _createStride = new IncrementalStaticStride(STRIDE_SIZE_INCREMENTAL, SAMPLES_IN_FINGERPRINT); _queryStride = new IncrementalRandomStride(STRIDE_SIZE_INCREMENTAL, SAMPLES_IN_FINGERPRINT, SAMPLES_IN_FINGERPRINT); }
public Image GetWaveletsImages( double[][] spectrum, IStride strideBetweenConsecutiveImages, int fingerprintLength, int overlap, int imagesPerRow) { List <double[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum( spectrum, strideBetweenConsecutiveImages, fingerprintLength, overlap); waveletService.ApplyWaveletTransformInPlace(spectralImages); int width = spectralImages[0].GetLength(0); int height = spectralImages[0][0].Length; int fingersCount = spectralImages.Count; int rowCount = (int)Math.Ceiling((float)fingersCount / imagesPerRow); int imageWidth = (rowCount == 1 ? width + 2 * SpaceBetweenImages : ((imagesPerRow * (width + SpaceBetweenImages)) + SpaceBetweenImages)); int imageHeight = (rowCount * (height + SpaceBetweenImages)) + SpaceBetweenImages; Bitmap image = new Bitmap(imageWidth, imageHeight, PixelFormat.Format16bppRgb565); SetBackground(image, Color.White); int verticalOffset = SpaceBetweenImages; int horizontalOffset = SpaceBetweenImages; int count = 0; foreach (double[][] spectralImage in spectralImages) { double average = spectralImage.Average(col => col.Average(v => Math.Abs(v))); for (int i = 0; i < width /*128*/; i++) { for (int j = 0; j < height /*32*/; j++) { Color color = ValueToBlackWhiteColor(spectralImage[i][j], average); image.SetPixel(i + horizontalOffset, j + verticalOffset, color); } } count++; if (count % imagesPerRow == 0) { verticalOffset += height + SpaceBetweenImages; horizontalOffset = SpaceBetweenImages; } else { horizontalOffset += width + SpaceBetweenImages; } } return(image); }
public static Dictionary<Int32, QueryStats> QueryOneSongMinHashFast( string pathToSong, IStride queryStride, IAudioService proxy, DaoGateway dalManager, int seconds, int lshHashTables, int lshGroupsPerKey, int thresholdTables, int topWavelets, ref long queryTime) { ///*Fingerprint service*/ //fingerprintService service = new fingerprintService {TopWavelets = topWavelets}; //Stopwatch stopWatch = new Stopwatch(); //stopWatch.Start(); //int startIndex = -1; //Dictionary<Int32, QueryStats> stats = new Dictionary<Int32, QueryStats>(); //int lenOfQuery = service.SampleRate*seconds; //double[] samples = service.GetSamplesFromSong(proxy, pathToSong); //int startOfQuery = Random.Next(0, samples.Length - lenOfQuery); //double[] querySamples = new double[lenOfQuery]; //Array.Copy(samples, startOfQuery, querySamples, 0, lenOfQuery); //startIndex = startOfQuery/service.SampleRate; //MinHash minHash = new MinHash(dalManager); //IStride stride = queryStride; //int index = stride.FirstStrideSize(); //while (index + service.SamplesPerFingerprint < querySamples.Length) //{ // Fingerprint f = service.CreateFingerprintFromSamplesArray(querySamples, index); // if (f == null) continue; // index += service.SamplesPerFingerprint + stride.StrideSize(); // int[] bin = minHash.ComputeMinHashSignature(f); /*Compute Min Hash on randomly selected fingerprints*/ // Dictionary<int, long> hashes = minHash.GroupMinHashToLSHBuckets(bin, lshHashTables, lshGroupsPerKey); /*Find all candidates by querying the database*/ // long[] hashbuckets = hashes.Values.ToArray(); // var candidates = dalManager.ReadFingerprintsByHashBucketLSH(hashbuckets, thresholdTables); // if (candidates != null && candidates.Count > 0) // { // var query = (from candidate in candidates // select candidate.Value.Item1).Distinct(); // foreach (var item in query) // { // stats.Add(item, new QueryStats(0, 0, 0, startIndex, startIndex + seconds, 0)); // } // break; // } //} //stopWatch.Stop(); //queryTime = stopWatch.ElapsedMilliseconds; /*Set the query Time parameter*/ return null; }
public ResultEntry Validate( ResultEntry result, IStride validationStride, string pathToAudioFile, IModelService modelService, IAudioService audioService, int topWavelets, int thresholdVotes) { double startAt = result.TrackStartsAt, length = result.QueryLength - result.TrackStartsAt; if (startAt + result.Track.Length < result.QueryLength) { length = result.Track.Length; } var newResult = queryCommandBuilder.BuildQueryCommand() .From(pathToAudioFile, length, startAt).WithConfigs( config => { config.Stride = validationStride; config.TopWavelets = topWavelets; }, queryConfig => { queryConfig.ThresholdVotes = thresholdVotes; }) .UsingServices(modelService, audioService) .Query() .Result; if (!newResult.ContainsMatches) { return(result); } var newEntry = newResult.BestMatch; if (newEntry.Confidence > result.Confidence) { return(new ResultEntry( newEntry.Track, newEntry.QueryMatchStartsAt, newEntry.QueryMatchLength, newEntry.TrackMatchStartsAt, newEntry.TrackStartsAt + result.TrackStartsAt, newEntry.Confidence, newEntry.HammingSimilaritySum, newEntry.QueryLength, newEntry.BestMatch)); } return(result); }
public Image GetLogSpectralImages( double[][] spectrum, IStride strideBetweenConsecutiveImages, int fingerprintLength, int overlap, int imagesPerRow) { List <double[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum( spectrum, strideBetweenConsecutiveImages, fingerprintLength, overlap); return(GetLogSpectralImages(spectralImages, imagesPerRow)); }
public Image GetLogSpectralImages( float[][] spectrum, IStride strideBetweenConsecutiveImages, int fingerprintLength, int overlap, int imagesPerRow) { List<float[][]> spetralImages = spectrumService.CutLogarithmizedSpectrum( spectrum, strideBetweenConsecutiveImages, fingerprintLength, overlap); int width = spetralImages[0].GetLength(0); int height = spetralImages[0][0].Length; int fingersCount = spetralImages.Count; int rowCount = (int)Math.Ceiling((float)fingersCount / imagesPerRow); int imageWidth = (imagesPerRow * (width + SpaceBetweenImages)) + SpaceBetweenImages; int imageHeight = (rowCount * (height + SpaceBetweenImages)) + SpaceBetweenImages; Bitmap image = new Bitmap(imageWidth, imageHeight, PixelFormat.Format16bppRgb565); SetBackground(image, Color.White); int verticalOffset = SpaceBetweenImages; int horizontalOffset = SpaceBetweenImages; int count = 0; foreach (float[][] spectralImage in spetralImages) { double average = spectralImage.Average(col => col.Average(v => Math.Abs(v))); for (int i = 0; i < width /*128*/; i++) { for (int j = 0; j < height /*32*/; j++) { Color color = ValueToBlackWhiteColor(spectralImage[i][j], average); image.SetPixel(i + horizontalOffset, j + verticalOffset, color); } } count++; if (count % imagesPerRow == 0) { verticalOffset += height + SpaceBetweenImages; horizontalOffset = SpaceBetweenImages; } else { horizontalOffset += width + SpaceBetweenImages; } } return image; }
private List<bool[]> CreateFingerprintsFromLogSpectrum(float[][] logarithmizedSpectrum, IStride stride, int fingerprintLength, int overlap, int topWavelets) { List<float[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum(logarithmizedSpectrum, stride, fingerprintLength, overlap); waveletService.ApplyWaveletTransformInPlace(spectralImages); List<bool[]> fingerprints = new List<bool[]>(); foreach (var spectralImage in spectralImages) { bool[] image = fingerprintDescriptor.ExtractTopWavelets(spectralImage, topWavelets); fingerprints.Add(image); } return fingerprints; }
private List<bool[]> CreateFingerprintsFromLogSpectrum(float[][] logarithmizedSpectrum, IStride stride, int fingerprintLength, int overlap, int topWavelets) { List<float[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum(logarithmizedSpectrum, stride, fingerprintLength, overlap); waveletDecomposition.DecomposeImagesInPlace(spectralImages); var fingerprints = new List<bool[]>(); foreach (var spectralImage in spectralImages) { bool[] image = fingerprintDescriptor.ExtractTopWavelets(spectralImage, topWavelets); if (!IsSilence(image)) { fingerprints.Add(image); } } return fingerprints; }
public void ExtractCandidatesUsingSamples(float[] samples) { int recognized = 0, verified = 0; IStride samplesToSkip = queryStride; queryCommandBuilder.BuildQueryCommand() .From(samples) .WithConfigs( fingerprintConfig => { fingerprintConfig.Stride = samplesToSkip; fingerprintConfig.NumberOfLSHTables = hashTables; fingerprintConfig.NumberOfMinHashesPerTable = hashKeys; }, queryConfig => { queryConfig.ThresholdVotes = threshold; }) .UsingServices(modelService, audioService) .Query() .ContinueWith( t => { var queryResult = t.Result; if (!queryResult.IsSuccessful) { AddGridLine(new object[] { string.Empty, "No candidates!", false, -1, -1 }, Color.Red); return; } TrackData recognizedTrack = queryResult.BestMatch.Track; recognized++; verified++; AddGridLine( new object[] { "Uknown Song", recognizedTrack.Title + "-" + recognizedTrack.Artist, true, -1, -1 }, Color.Empty); _tbResults.Text = ((float)recognized / verified).ToString(CultureInfo.InvariantCulture); }, TaskScheduler.FromCurrentSynchronizationContext()); }
public ResultEntry Validate( ResultEntry result, IStride validationStride, string pathToAudioFile, IModelService modelService, IAudioService audioService) { double startAt = result.TrackStartsAt, length = result.QueryLength - result.TrackStartsAt; if (startAt + result.Track.Length < result.QueryLength) { length = result.Track.Length; } var newResult = queryCommandBuilder.BuildQueryCommand() .From(pathToAudioFile, length, startAt) .WithFingerprintConfig(config => config.Stride = validationStride) .UsingServices(modelService, audioService) .Query() .Result; if (!newResult.ContainsMatches) { return result; } var newEntry = newResult.BestMatch; if (newEntry.Confidence > result.Confidence) { return new ResultEntry( newEntry.Track, newEntry.QueryMatchStartsAt, newEntry.QueryMatchLength, newEntry.TrackMatchStartsAt, newEntry.TrackStartsAt + result.TrackStartsAt, newEntry.Confidence, newEntry.HammingSimilaritySum, newEntry.QueryLength, newEntry.BestMatch); } return result; }
public WinQueryResults( int secondsToAnalyze, int startSecond, int hashTables, int hashKeys, int threshold, IStride queryStride, ITagService tagService, IModelService modelService, IAudioService audioService, IQueryCommandBuilder queryCommandBuilder) { InitializeComponent(); Icon = Resources.Sound; this.secondsToAnalyze = secondsToAnalyze; this.startSecond = startSecond; this.queryStride = queryStride; this.hashTables = hashTables; this.hashKeys = hashKeys; this.threshold = threshold; this.tagService = tagService; this.modelService = modelService; this.audioService = audioService; this.queryCommandBuilder = queryCommandBuilder; // ReSharper disable PossibleNullReferenceException _dgvResults.Columns.Add(ColSongName, "Initial Song"); _dgvResults.Columns[ColSongName].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColResultName, "Result Song"); _dgvResults.Columns[ColResultName].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColResult, "ISRC Match"); _dgvResults.Columns[ColResult].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColHammingAvg, "Hamming Distance"); _dgvResults.Columns[ColHammingAvg].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColNumberOfCandidates, "Number of candidates"); _dgvResults.Columns[ColNumberOfCandidates].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColISRC, "Result ISRC"); _dgvResults.Columns[ColISRC].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; // ReSharper restore PossibleNullReferenceException _btnExport.Enabled = false; }
/// <summary> /// Create fingerprints out of down sampled samples /// </summary> /// <param name = "samples">Down sampled to 5512 samples </param> /// <param name = "track">Track</param> /// <param name = "stride">Stride</param> /// <param name = "hashTables">Number of hash tables</param> /// <param name = "hashKeys">Number of hash keys</param> public void CreateInsertFingerprints(float[] samples, Track track, IStride stride, int hashTables, int hashKeys) { if (track == null) return; /*track is not eligible*/ /*Create fingerprints that will be used as initial fingerprints to be queried*/ List<bool[]> dbFingers = _manager.CreateFingerprints(samples, stride); _storage.InsertTrack(track); /*Insert track into the storage*/ /*Get fingerprint's hash signature, and associate it to a specific track*/ List<HashSignature> creationalsignatures = GetSignatures(dbFingers, track, hashTables, hashKeys); foreach (HashSignature hash in creationalsignatures) { _storage.InsertHash(hash, HashType.Creational); /*Set this hashes as also the query hashes*/ _storage.InsertHash(hash, HashType.Query); } return; }
private TestRunnerEventArgs GetTestRunnerEventArgsForFinishedTestIteration(IStride queryStride, int seconds, List <int> startAts, FScore fscore, HammingDistanceResultStatistics statistics, int iteration, Stopwatch stopwatch, int verified) { return(new TestRunnerEventArgs { FScore = fscore, RowWithDetails = new object[] { GetInsertMetadata(), queryStride.ToString(), seconds, startAts[iteration], fscore.Precision, fscore.Recall, fscore.F1, statistics.TruePositiveInfo, statistics.TruePositivePercentileInfo, statistics.FalseNegativesInfo, statistics.FalseNegativesPercentileInfo, statistics.FalsePositivesInfo, statistics.FalsePositivesPercentileInfo, (double)stopwatch.ElapsedMilliseconds / 1000 }, Verified = verified }); }
/// <summary> /// Create fingerprints out of down sampled samples /// </summary> /// <param name = "samples">Down sampled to 5512 samples</param> /// <param name = "track">Track</param> /// <param name = "stride">Stride</param> /// <param name = "hashTables">Number of hash tables</param> /// <param name = "hashKeys">Number of hash keys</param> public void CreateInsertFingerprints(float[] samples, Track track, IStride stride, int hashTables, int hashKeys) { if (track == null) { return; /*track is not eligible*/ } /*Create fingerprints that will be used as initial fingerprints to be queried*/ List<bool[]> fingerprints = fingerprintUnitBuilder.BuildFingerprints() .On(samples) .WithCustomConfiguration(config => config.Stride = stride) .RunAlgorithm() .Result; storage.InsertTrack(track); /*Insert track into the storage*/ /*Get signature's hash signature, and associate it to a specific track*/ IEnumerable<HashSignature> creationalsignatures = GetSignatures(fingerprints, track, hashTables, hashKeys); foreach (HashSignature hash in creationalsignatures) { storage.InsertHash(hash); } }
public List<float[][]> CutLogarithmizedSpectrum(float[][] logarithmizedSpectrum, IStride strideBetweenConsecutiveImages, int fingerprintImageLength, int overlap) { int start = strideBetweenConsecutiveImages.FirstStrideSize / overlap; int logarithmicBins = logarithmizedSpectrum[0].Length; List<float[][]> spectralImages = new List<float[][]>(); int width = logarithmizedSpectrum.GetLength(0); while (start + fingerprintImageLength < width) { float[][] spectralImage = AllocateMemoryForFingerprintImage(fingerprintImageLength, logarithmicBins); for (int i = 0; i < fingerprintImageLength; i++) { Array.Copy(logarithmizedSpectrum[start + i], spectralImage[i], logarithmicBins); } start += fingerprintImageLength + (strideBetweenConsecutiveImages.StrideSize / overlap); spectralImages.Add(spectralImage); } return spectralImages; }
/// <summary> /// Cut logarithmized spetrum to spectral images /// </summary> /// <param name="logarithmizedSpectrum">Logarithmized spectrum of the initial signal</param> /// <param name="strideBetweenConsecutiveImages">Stride between consecutive images (static 928ms db, random 46ms query)</param> /// <param name="fingerprintImageLength">Length of 1 fingerprint image (w parameter equal to 128, which alogside overlap leads to 128*64 = 8192 = 1.48s)</param> /// <param name="overlap">Overlap between consecutive spectral images, taken previously (64 ~ 11.6ms)</param> /// <returns>List of logarithmic images</returns> public List <double[][]> CutLogarithmizedSpectrum( double[][] logarithmizedSpectrum, IStride strideBetweenConsecutiveImages, int fingerprintImageLength, int overlap) { int start = strideBetweenConsecutiveImages.FirstStrideSize / overlap; int logarithmicBins = logarithmizedSpectrum[0].Length; List <double[][]> spectralImages = new List <double[][]>(); int width = logarithmizedSpectrum.GetLength(0); while (start + fingerprintImageLength < width) { double[][] spectralImage = this.AllocateMemoryForFingerprintImage(fingerprintImageLength, logarithmicBins); for (int i = 0; i < fingerprintImageLength; i++) { Array.Copy(logarithmizedSpectrum[start + i], spectralImage[i], logarithmicBins); } start += fingerprintImageLength + (strideBetweenConsecutiveImages.StrideSize / overlap); spectralImages.Add(spectralImage); } // Make sure at least the input spectrum is a part of the output list if (spectralImages.Count == 0) { double[][] spectralImage = this.AllocateMemoryForFingerprintImage(fingerprintImageLength, logarithmicBins); int rowCount = logarithmizedSpectrum.Length; int columnCount = logarithmizedSpectrum[0].Length; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { spectralImage[i][j] = logarithmizedSpectrum[i][j]; } } spectralImages.Add(spectralImage); } return(spectralImages); }
public RealtimeQueryConfiguration(int thresholdVotes, IRealtimeResultEntryFilter resultEntryFilter, Action <ResultEntry> successCallback, Action <ResultEntry> didNotPassFilterCallback, Action <Hashes> queryFingerprintsCallback, Action <Exception, Hashes> errorCallback, Action restoredAfterErrorCallback, IEnumerable <Hashes> downtimeHashes, IStride stride, double permittedGap, double downtimeCapturePeriod, int millisecondsDelay, IDictionary <string, string> metaFieldFilters) { QueryConfiguration = new DefaultQueryConfiguration { ThresholdVotes = thresholdVotes, FingerprintConfiguration = new DefaultFingerprintConfiguration { SpectrogramConfig = new DefaultSpectrogramConfig { Stride = stride } }, YesMetaFieldsFilters = metaFieldFilters, PermittedGap = permittedGap }; ResultEntryFilter = resultEntryFilter; SuccessCallback = successCallback; DidNotPassFilterCallback = didNotPassFilterCallback; QueryFingerprintsCallback = queryFingerprintsCallback; ErrorCallback = errorCallback; RestoredAfterErrorCallback = restoredAfterErrorCallback; DowntimeHashes = downtimeHashes; DowntimeCapturePeriod = downtimeCapturePeriod; MillisecondsDelay = millisecondsDelay; }
public QueryResults( int secondsToAnalyze, int startSecond, int hashTables, int hashKeys, int threshold, IStride queryStride, ITagService tagService, IModelService modelService, IAudioService audioService, IQueryCommandBuilder queryCommandBuilder) { this.secondsToAnalyze = secondsToAnalyze; this.startSecond = startSecond; this.queryStride = queryStride; this.hashTables = hashTables; this.hashKeys = hashKeys; this.threshold = threshold; this.tagService = tagService; this.modelService = modelService; this.audioService = audioService; this.queryCommandBuilder = queryCommandBuilder; }
public WinQueryResults( int secondsToAnalyze, int startSecond, int hashTables, int hashKeys, int threshold, IStride queryStride, ITagService tagService, IModelService modelService, IFingerprintQueryBuilder fingerprintQueryBuilder) { InitializeComponent(); Icon = Resources.Sound; this.secondsToAnalyze = secondsToAnalyze; this.startSecond = startSecond; this.queryStride = queryStride; this.hashTables = hashTables; this.hashKeys = hashKeys; this.threshold = threshold; this.tagService = tagService; this.modelService = modelService; this.fingerprintQueryBuilder = fingerprintQueryBuilder; // ReSharper disable PossibleNullReferenceException _dgvResults.Columns.Add(ColSongName, "Initial Song"); _dgvResults.Columns[ColSongName].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColResultName, "Result Song"); _dgvResults.Columns[ColResultName].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColResult, "Result"); _dgvResults.Columns[ColResult].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColHammingAvg, "Hamming Distance"); _dgvResults.Columns[ColHammingAvg].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(ColElapsedTime, "Elapsed Time"); _dgvResults.Columns[ColElapsedTime].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; // ReSharper restore PossibleNullReferenceException _btnExport.Enabled = false; }
private void Insert(string folderWithSongs, IStride stride, StringBuilder sb) { var allFiles = AllFiles(folderWithSongs); int inserted = 0; var stopWatch = new Stopwatch(); stopWatch.Start(); Parallel.ForEach( allFiles, file => { OnTestRunnerEvent( OngoingActionEvent, new TestRunnerOngoingEventArgs { Message = $"Inserting tracks {Interlocked.Increment(ref inserted)} out of {allFiles.Count}. Track {System.IO.Path.GetFileNameWithoutExtension(file)}" }); var track = GetTrack(file); var hashes = fcb.BuildFingerprintCommand() .From(file) .WithFingerprintConfig( config => { config.Stride = stride; return(config); }) .UsingServices(audioService) .Hash() .Result; modelService.Insert(track, hashes); }); stopWatch.Stop(); sb.AppendLine($"{inserted},{stopWatch.ElapsedMilliseconds / 1000}"); }
/// <summary> /// Cut logarithmized spetrum to spectral images /// </summary> /// <param name="logarithmizedSpectrum">Logarithmized spectrum of the initial signal</param> /// <param name="strideBetweenConsecutiveImages">Stride between consecutive images (static 928ms db, random 46ms query)</param> /// <param name="fingerprintImageLength">Length of 1 fingerprint image (w parameter equal to 128, which alogside overlap leads to 128*64 = 8192 = 1.48s)</param> /// <param name="overlap">Overlap between consecutive spectral images, taken previously (64 ~ 11.6ms)</param> /// <returns>List of logarithmic images</returns> public List<double[][]> CutLogarithmizedSpectrum( double[][] logarithmizedSpectrum, IStride strideBetweenConsecutiveImages, int fingerprintImageLength, int overlap) { int start = strideBetweenConsecutiveImages.FirstStrideSize / overlap; int logarithmicBins = logarithmizedSpectrum[0].Length; List<double[][]> spectralImages = new List<double[][]>(); int width = logarithmizedSpectrum.GetLength(0); while (start + fingerprintImageLength < width) { double[][] spectralImage = this.AllocateMemoryForFingerprintImage(fingerprintImageLength, logarithmicBins); for (int i = 0; i < fingerprintImageLength; i++) { Array.Copy(logarithmizedSpectrum[start + i], spectralImage[i], logarithmicBins); } start += fingerprintImageLength + (strideBetweenConsecutiveImages.StrideSize / overlap); spectralImages.Add(spectralImage); } // Make sure at least the input spectrum is a part of the output list if (spectralImages.Count == 0) { double[][] spectralImage = this.AllocateMemoryForFingerprintImage(fingerprintImageLength, logarithmicBins); int rowCount = logarithmizedSpectrum.Length; int columnCount = logarithmizedSpectrum[0].Length; for (int i = 0; i < rowCount; i++) { for (int j = 0; j < columnCount; j++) { spectralImage[i][j] = logarithmizedSpectrum[i][j]; } } spectralImages.Add(spectralImage); } return spectralImages; }
/// <summary> /// Public constructor for NN algorithm /// </summary> /// <param name = "connectionString">Connection string</param> /// <param name = "secondsToAnalyze">Number of fingerprints to analyze</param> /// <param name = "startSeconds">Starting seconds</param> /// <param name = "stride">Query stride</param> /// <param name = "topWavelets">Number of top wavelets</param> /// <param name = "fileList">File list to analyze</param> /// <param name = "pathToEnsemble">Path to ensemble</param> public WinQueryResults(string connectionString, int secondsToAnalyze, int startSeconds, IStride stride, int topWavelets, List<string> fileList, string pathToEnsemble) : this(connectionString, secondsToAnalyze, startSeconds, stride, topWavelets, fileList) { _ensemble = NNEnsemble.Load(pathToEnsemble); _dgvResults.Columns.Add(COL_HIT, "Number of hits"); _dgvResults.Columns[COL_HIT].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; Action action = ExtractCandidatesWithNeuralHasher; action.BeginInvoke((result) => action.EndInvoke(result), action); }
private void RunTestScenario(string folderWithPositives, string folderWithNegatives, IStride queryStride, int seconds, List <int> startAts) { int iterations = startAts.Count; var positives = AllFiles(folderWithPositives); var negatives = AllFiles(folderWithNegatives); for (int iteration = 0; iteration < iterations; ++iteration) { OnTestRunnerEvent(OngoingActionEvent, new TestRunnerOngoingEventArgs { Message = $"Iteration {iteration + 1} out of {iterations} with {queryStride}, query seconds {seconds}" }); var stopwatch = new Stopwatch(); stopwatch.Start(); int trueNegatives = 0, truePositives = 0, falseNegatives = 0, falsePositives = 0, verified = 0; var truePositiveHammingDistance = new ConcurrentBag <int>(); var falseNegativesHammingDistance = new ConcurrentBag <int>(); var falsePositivesHammingDistance = new ConcurrentBag <int>(); var sb = TestRunnerWriter.StartTestIteration(); int currentIteration = iteration; int startAt = startAts[currentIteration]; Parallel.ForEach( positives, positive => { Interlocked.Increment(ref verified); var tags = GetTagsFromFile(positive); var actualTrack = GetActualTrack(tags); var queryResult = BuildQuery(queryStride, seconds, positive, startAt).Result; if (!queryResult.ContainsMatches) { Interlocked.Increment(ref falseNegatives); var notFoundLine = GetNotFoundLine(tags); AppendLine(sb, notFoundLine); OnTestRunnerEvent( PositiveNotFoundEvent, GetTestRunnerEventArgs( truePositives, trueNegatives, falsePositives, falseNegatives, notFoundLine, verified)); return; } var recognizedTrack = queryResult.BestMatch.Track; bool isSuccessful = recognizedTrack.Id.Equals(actualTrack.Id); if (isSuccessful) { Interlocked.Increment(ref truePositives); truePositiveHammingDistance.Add((int)queryResult.BestMatch.Score); } else { Interlocked.Increment(ref falsePositives); falseNegativesHammingDistance.Add((int)queryResult.BestMatch.Score); } var foundLine = GetFoundLine(ToTrackString(actualTrack.Artist, actualTrack.Title), recognizedTrack, isSuccessful, queryResult); AppendLine(sb, foundLine); OnTestRunnerEvent(PositiveFoundEvent, GetTestRunnerEventArgs(truePositives, trueNegatives, falsePositives, falseNegatives, foundLine, verified)); }); Parallel.ForEach( negatives, negative => { Interlocked.Increment(ref verified); var tags = GetTagsFromFile(negative); var queryResult = BuildQuery(queryStride, seconds, negative, startAt).Result; if (!queryResult.ContainsMatches) { Interlocked.Increment(ref trueNegatives); var notFoundLine = GetNotFoundLine(tags); AppendLine(sb, notFoundLine); OnTestRunnerEvent( NegativeNotFoundEvent, GetTestRunnerEventArgs( truePositives, trueNegatives, falsePositives, falseNegatives, notFoundLine, verified)); return; } var recognizedTrack = queryResult.BestMatch.Track; falsePositivesHammingDistance.Add((int)queryResult.BestMatch.Score); Interlocked.Increment(ref falsePositives); var foundLine = GetFoundLine(ToTrackString(tags), recognizedTrack, false, queryResult); AppendLine(sb, foundLine); OnTestRunnerEvent( NegativeFoundEvent, GetTestRunnerEventArgs(truePositives, trueNegatives, falsePositives, falseNegatives, foundLine, verified)); }); stopwatch.Stop(); var fscore = new FScore(truePositives, trueNegatives, falsePositives, falseNegatives); var stats = HammingDistanceResultStatistics.From( truePositiveHammingDistance, falseNegativesHammingDistance, falsePositivesHammingDistance, testRunnerConfig.Percentiles); TestRunnerWriter.FinishTestIteration(sb, fscore, stats, stopwatch.ElapsedMilliseconds); TestRunnerWriter.SaveTestIterationToFolder(sb, pathToResultsFolder, queryStride, GetInsertMetadata(), seconds, startAt); var finishedTestIteration = GetTestRunnerEventArgsForFinishedTestIteration(queryStride, seconds, startAts, fscore, stats, iteration, stopwatch, verified); OnTestRunnerEvent(TestIterationFinishedEvent, finishedTestIteration); TestRunnerWriter.AppendLine(suite, finishedTestIteration.RowWithDetails); } }
public Image GetLogSpectralImages( double[][] spectrum, IStride strideBetweenConsecutiveImages, int fingerprintLength, int overlap, int imagesPerRow) { List<double[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum( spectrum, strideBetweenConsecutiveImages, fingerprintLength, overlap); return GetLogSpectralImages(spectralImages, imagesPerRow); }
/// <summary> /// Public constructor for LSH + Min Hash algorithm /// </summary> /// <param name = "connectionString">Connection string</param> /// <param name = "secondsToAnalyze">Number of fingerprints to analyze</param> /// <param name = "stride">Stride</param> /// <param name = "fileList">File list</param> /// <param name = "hashTables">Min hash hash tables</param> /// <param name = "hashKeys">Min hash hash keys</param> /// <param name = "startSecond">Starting second of analysis</param> /// <param name = "thresholdTables">Number of threshold tables</param> /// <param name = "topWavelets">Number of top wavelets to consider</param> public WinQueryResults(string connectionString, int secondsToAnalyze, int startSecond, IStride stride, List<string> fileList, int hashTables, int hashKeys, int thresholdTables, int topWavelets) : this(connectionString, secondsToAnalyze, startSecond, stride, topWavelets, fileList) { _hashTables = hashTables; _hashKeys = hashKeys; _threshold = thresholdTables; _dgvResults.Columns.Add(COL_HAMMING_AVG_BY_TRACK, "Hamming Avg. By Track"); // ReSharper disable PossibleNullReferenceException _dgvResults.Columns[COL_HAMMING_AVG_BY_TRACK].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_MIN_HAMMING, "Min. Hamming"); _dgvResults.Columns[COL_MIN_HAMMING].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_SORT_VALUE, "Sort Value"); _dgvResults.Columns[COL_SORT_VALUE].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_TOTAL_TABLES, "Total Table Votes"); _dgvResults.Columns[COL_TOTAL_TABLES].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_TOTAL_TRACK_VOTES, "Total Track Votes"); _dgvResults.Columns[COL_TOTAL_TRACK_VOTES].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_START_QUERY_INDEX, "Query Index Start"); _dgvResults.Columns[COL_START_QUERY_INDEX].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_TOTAL_FINGERPRINTS, "Total Fingerprints"); _dgvResults.Columns[COL_TOTAL_FINGERPRINTS].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_SIMILARITY, "Min Similarity"); _dgvResults.Columns[COL_SIMILARITY].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_ELAPSED_TIME, "Elapsed Time"); _dgvResults.Columns[COL_ELAPSED_TIME].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; // ReSharper restore PossibleNullReferenceException _btnExport.Enabled = false; _nudTotal.Value = _fileList.Count; Action action = ExtractCandidatesWithMinHashAlgorithm; /*Extract candidates using MinHash + LSH algorithm*/ action.BeginInvoke( (result) => { try { action.EndInvoke(result); } catch (ThreadAbortException) { /*Recognition aborted*/ return; } catch (Exception e) { MessageBox.Show(Resources.RecognitionEndedWithAnError + e.Message + Resources.LineFeed + e.StackTrace, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } MessageBox.Show(Resources.RecognitionEnded, Resources.RecognitionEnded, MessageBoxButtons.OK, MessageBoxIcon.Information); Invoke(new Action( () => { _btnStop.Enabled = true; _btnExport.Enabled = true; })); }, action); }
private void RunTestScenario(string folderWithPositives, string folderWithNegatives, IStride queryStride, int seconds, List<int> startAts) { int iterations = startAts.Count; var positives = AllFiles(folderWithPositives); var negatives = AllFiles(folderWithNegatives); for (int iteration = 0; iteration < iterations; ++iteration) { OnTestRunnerEvent( OngoingActionEvent, new TestRunnerOngoingEventArgs { Message = string.Format( "Iteration {0} out of {1} with {2}, query seconds {3}", iteration + 1, iterations, queryStride, seconds) }); var stopwatch = new Stopwatch(); stopwatch.Start(); int trueNegatives = 0, truePositives = 0, falseNegatives = 0, falsePositives = 0, verified = 0; var truePositiveHammingDistance = new ConcurrentBag<int>(); var falseNegativesHammingDistance = new ConcurrentBag<int>(); var falsePositivesHammingDistance = new ConcurrentBag<int>(); var sb = TestRunnerWriter.StartTestIteration(); int currentIteration = iteration; int startAt = startAts[currentIteration]; Parallel.ForEach( positives, positive => { Interlocked.Increment(ref verified); var tags = GetTagsFromFile(positive); var actualTrack = GetActualTrack(tags); var queryResult = BuildQuery(queryStride, seconds, positive, startAt).Result; if (!queryResult.ContainsMatches) { Interlocked.Increment(ref falseNegatives); var notFoundLine = GetNotFoundLine(tags); AppendLine(sb, notFoundLine); OnTestRunnerEvent( PositiveNotFoundEvent, GetTestRunnerEventArgs( truePositives, trueNegatives, falsePositives, falseNegatives, notFoundLine, verified)); return; } var recognizedTrack = queryResult.BestMatch.Track; bool isSuccessful = recognizedTrack.TrackReference.Equals(actualTrack.TrackReference); if (isSuccessful) { Interlocked.Increment(ref truePositives); truePositiveHammingDistance.Add(queryResult.BestMatch.HammingSimilaritySum); } else { Interlocked.Increment(ref falsePositives); falseNegativesHammingDistance.Add(queryResult.BestMatch.HammingSimilaritySum); } var foundLine = GetFoundLine(ToTrackString(actualTrack), recognizedTrack, isSuccessful, queryResult); AppendLine(sb, foundLine); OnTestRunnerEvent(PositiveFoundEvent, GetTestRunnerEventArgs(truePositives, trueNegatives, falsePositives, falseNegatives, foundLine, verified)); }); Parallel.ForEach( negatives, negative => { Interlocked.Increment(ref verified); var tags = GetTagsFromFile(negative); var queryResult = BuildQuery(queryStride, seconds, negative, startAt).Result; if (!queryResult.ContainsMatches) { Interlocked.Increment(ref trueNegatives); var notFoundLine = GetNotFoundLine(tags); AppendLine(sb, notFoundLine); OnTestRunnerEvent( NegativeNotFoundEvent, GetTestRunnerEventArgs( truePositives, trueNegatives, falsePositives, falseNegatives, notFoundLine, verified)); return; } var recognizedTrack = queryResult.BestMatch.Track; falsePositivesHammingDistance.Add(queryResult.BestMatch.HammingSimilaritySum); Interlocked.Increment(ref falsePositives); var foundLine = GetFoundLine(ToTrackString(tags), recognizedTrack, false, queryResult); AppendLine(sb, foundLine); OnTestRunnerEvent( NegativeFoundEvent, GetTestRunnerEventArgs(truePositives, trueNegatives, falsePositives, falseNegatives, foundLine, verified)); }); stopwatch.Stop(); var fscore = new FScore(truePositives, trueNegatives, falsePositives, falseNegatives); var stats = HammingDistanceResultStatistics.From( truePositiveHammingDistance, falseNegativesHammingDistance, falsePositivesHammingDistance, testRunnerConfig.Percentiles); TestRunnerWriter.FinishTestIteration(sb, fscore, stats, stopwatch.ElapsedMilliseconds); TestRunnerWriter.SaveTestIterationToFolder(sb, pathToResultsFolder, queryStride, GetInsertMetadata(), seconds, startAt); var finishedTestIteration = GetTestRunnerEventArgsForFinishedTestIteration(queryStride, seconds, startAts, fscore, stats, iteration, stopwatch, verified); OnTestRunnerEvent(TestIterationFinishedEvent, finishedTestIteration); TestRunnerWriter.AppendLine(suite, finishedTestIteration.RowWithDetails); } }
/// <summary> /// Create fingerprints/min-hash signatures/LSH buckets and insert them in underlying storage /// </summary> /// <param name = "files">Files to be processed</param> /// <param name = "audioProxy">Audio proxy used in processing</param> /// <param name = "queryStride">Stride between 2 consecutive fingerprints on query</param> /// <param name = "creationalStride">Stride between 2 consecutive fingerprints on creation</param> /// <param name = "mintracklen">Minimum track length</param> /// <param name = "maxtracklen">Maximum track length</param> /// <param name = "milliSecondsToProcess">Number of milliseconds to process</param> /// <param name = "startMillisecond">Start processing at a specific millisecond</param> /// <param name = "hashTables">Number of hash-tables used in LSH decomposition</param> /// <param name = "hashKeys">Number of Min Hash keys per LSH table</param> /// <param name = "trackProcessed">Invoked once the track is processed</param> /// <returns>List of processed tracks</returns> public List <Track> ProcessTracks(List <string> files, BassProxy audioProxy, IStride queryStride, IStride creationalStride, int mintracklen, int maxtracklen, int milliSecondsToProcess, int startMillisecond, int hashTables, int hashKeys, Action <Track> trackProcessed) { List <Track> tracks = new List <Track>(); _threadCounts++; foreach (string file in files) //filter files that can be processed { if (_aborted) { break; } Track track = GetTrack(mintracklen, maxtracklen, file, audioProxy); if (track == null) { continue; /*track is not eligible because of min/max parameters*/ } //create spectrogram of the file float[][] logSpectrum = null; try { //try creating the spectrum from a file logSpectrum = _manager.CreateLogSpectrogram(audioProxy, track.Path, milliSecondsToProcess, startMillisecond); } catch (Exception ex) { if (ex is ThreadAbortException) { throw; } /*the file might be corrupted or missing*/ continue; /*Continue processing even if creation of the spectrogram failed*/ } _storage.InsertTrack(track); /*Insert track into the storage*/ /*Create fingerprints that will be used as initial fingerprints to be queried*/ List <bool[]> dbFingers = _manager.CreateFingerprints(logSpectrum, creationalStride); /*Get fingerprint's hash signature, and associate it to a specific track*/ List <HashSignature> creationalsignatures = GetSignatures(dbFingers, track, hashTables, hashKeys); foreach (HashSignature hash in creationalsignatures) { _storage.InsertHash(hash, HashType.Creational); /*Set this hashes as also the query hashes*/ _storage.InsertHash(hash, HashType.Query); } /*Create fingerprints for query*/ List <bool[]> queryFingers = _manager.CreateFingerprints(logSpectrum, queryStride); /*Create fingerprints*/ List <HashSignature> querysignatures = GetSignatures(queryFingers, track, hashTables, hashKeys); // ***** PIN TODO: CHANGE THIS object[][] arr = new object[querysignatures.Count][]; int count = 0; foreach (HashSignature hash in querysignatures) { _storage.InsertHash(hash, HashType.Query); /*Insert hash-buckets into hash-tables*/ String signatureText = "{"; for (int s = 0; s < hash.Signature.Length; s++) { signatureText += hash.Signature[s]; signatureText += " "; } signatureText += "}"; arr[count++] = new object[5] { hash.Id, hash.Track.Title, hash.Track.Artist, hash.Track.TrackLength, signatureText }; } String filenameToSave = String.Format("C:\\{0}-hash-buckets.txt", System.IO.Path.GetFileNameWithoutExtension(file)); CSVWriter csv = new CSVWriter(filenameToSave); csv.Write(arr); // ***** end PIN if (trackProcessed != null) { trackProcessed.Invoke(track); } tracks.Add(track); } _threadCounts--; return(tracks); }
private Task<QueryResult> BuildQuery(IStride queryStride, int seconds, string positive, int startAt) { return qcb.BuildQueryCommand() .From(positive, seconds, startAt) .WithFingerprintConfig(fingerprintConfig => { fingerprintConfig.Stride = queryStride; }) .UsingServices(modelService, audioService) .Query(); }
/// <summary> /// Get fingerprint similarity of one song /// </summary> /// <param name = "manager">Fingerprint manager used in file decomposition</param> /// <param name = "dbstride">Database creation stride</param> /// <param name = "queryStride">Query stride</param> /// <param name = "numberOfItemsToCompare">Number of subsequent elements to compare with</param> /// <param name = "proxy">Proxy</param> /// <param name = "path">Path to first file</param> /// <param name = "results">Results object to be filled with the corresponding data</param> private static void GetFingerprintSimilarity(FingerprintManager manager, IStride dbstride, IStride queryStride, int numberOfItemsToCompare, IAudio proxy, string path, DumpResults results) { int startindex = 0; int count = 0; double sum = 0; List<bool[]> list = manager.CreateFingerprints(proxy, path, dbstride); List<bool[]> listToCompare = manager.CreateFingerprints(proxy, path, queryStride); count = list.Count; int toCompare = listToCompare.Count; double max = double.MinValue; for (int i = 0; i < count; i++) { for (int j = 0; j < toCompare; j++) { double value = MinHash.CalculateSimilarity(list[i], listToCompare[j]); if (value > max) max = value; sum += value; } } results.Results.SumJaqFingerprintsSimilarity = sum; results.Results.AverageJaqFingerprintSimilarity = sum/(count*toCompare); results.Results.MaxJaqFingerprintSimilarity = max; }
public static void SaveTestIterationToFolder(StringBuilder sb, string resultsFolder, IStride queryStride, string insertMetadata, int queryLength, int startAt) { string filename = string.Format("results_{0}_{1}_q{2}s_at{3}s.csv", insertMetadata, queryStride, queryLength, startAt); string absolutePath = Path.Combine(resultsFolder, filename); Write(sb, absolutePath); }
public Image GetLogSpectralImages( double[][] spectrum, IStride strideBetweenConsecutiveImages, int fingerprintLength, int overlap, int imagesPerRow) { List<double[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum( spectrum, strideBetweenConsecutiveImages, fingerprintLength, overlap); int blockSizeX = 4; int blockSizeY = 4; int width = spectralImages[0].GetLength(0); int height = spectralImages[0][0].Length; int fingersCount = spectralImages.Count; int rowCount = (int)Math.Ceiling((float)fingersCount / imagesPerRow); int imageWidth = (blockSizeX * imagesPerRow * (width + SpaceBetweenImages)) + SpaceBetweenImages; int imageHeight = (blockSizeY * rowCount * (height + SpaceBetweenImages)) + SpaceBetweenImages; //Bitmap image = new Bitmap(imageWidth, imageHeight, PixelFormat.Format16bppRgb565); Bitmap image = new Bitmap(imageWidth, imageHeight); Graphics graphics = Graphics.FromImage(image); SetBackground(image, Color.White); int verticalOffset = SpaceBetweenImages; int horizontalOffset = SpaceBetweenImages; int count = 0; foreach (double[][] spectralImage in spectralImages) { double maxValue = spectralImage.Max((b) => b.Max((v) => Math.Abs(v))); maxValue = 20 * Math.Log10(maxValue); //double average = spectralImage.Average(col => col.Average(v => Math.Abs(v))); for (int i = 0; i < width /*128*/; i++) { for (int j = 0; j < height /*32*/; j++) { //Color color = ValueToBlackWhiteColor(spectralImage[i][j], average); //image.SetPixel(i + horizontalOffset, j + verticalOffset, color); double val = 20 * Math.Log10(spectralImage[i][j]); Color color = Color.White; if (!double.IsNaN(val) && !double.IsInfinity(val)) { color = ValueToBlackWhiteColor(val, maxValue); } Brush brush = new SolidBrush(color); //graphics.FillRectangle(brush, i + horizontalOffset, j + verticalOffset, (int)deltaX + 1, 1); //image.SetPixel(i + horizontalOffset, j + verticalOffset, color); graphics.FillRectangle(brush, (i + horizontalOffset)*blockSizeX, (height - j + verticalOffset + 1)*blockSizeY, blockSizeX, blockSizeY); } } count++; if (count % imagesPerRow == 0) { verticalOffset += height + SpaceBetweenImages; horizontalOffset = SpaceBetweenImages; } else { horizontalOffset += width + SpaceBetweenImages; } } image = ColorUtils.Colorize(image, 255, ColorUtils.ColorPaletteType.MATLAB); return image; }
/// <summary> /// Get hash similarity of one song /// </summary> /// <param name = "manager">Fingerprint manager</param> /// <param name = "dbstride">Database stride between fingerprints</param> /// <param name = "queryStride">Query stride between fingerprints</param> /// <param name = "numberOfFingerprintsToAnalyze">Number of fingerprints to analyze</param> /// <param name = "hashTables">Number of hash tables in the LSH transformation</param> /// <param name = "hashKeys">Number of hash keys per table in the LSH transformation</param> /// <param name = "proxy">Audio proxy</param> /// <param name = "path">Path to analyzed file</param> /// <param name = "results">Results object to be filled with the appropriate data</param> private static void GetHashSimilarity(FingerprintManager manager, IStride dbstride, IStride queryStride, int numberOfFingerprintsToAnalyze, int hashTables, int hashKeys, IAudio proxy, string path, DumpResults results) { double sum = 0; int hashesCount = 0; int startindex = 0; List<bool[]> listDb = manager.CreateFingerprints(proxy, path, dbstride); List<bool[]> listQuery = manager.CreateFingerprints(proxy, path, queryStride); IPermutations perms = new DbPermutations(ConfigurationManager.ConnectionStrings["FingerprintConnectionString"].ConnectionString); MinHash minHash = new MinHash(perms); List<int[]> minHashDb = listDb.Select(minHash.ComputeMinHashSignature).ToList(); List<int[]> minHashQuery = listQuery.Select(minHash.ComputeMinHashSignature).ToList(); /*Calculate Min Hash signature similarity by comparing 2 consecutive signatures*/ int countDb = minHashDb.Count; int countQuery = minHashQuery.Count; int minHashSignatureLen = minHashDb[0].Length; int similarMinHashValues = 0; for (int i = 0; i < countDb; i++) { for (int j = 0; j < countQuery; j++) { for (int k = 0; k < minHashSignatureLen; k++) if (minHashDb[i][k] == minHashQuery[j][k]) similarMinHashValues++; } } results.Results.SumIdenticalMinHash = similarMinHashValues; results.Results.AverageIdenticalMinHash = (double) similarMinHashValues/(countDb*countQuery*minHashSignatureLen); /*Group min hash signatures into LSH Buckets*/ List<Dictionary<int, long>> lshBucketsDb = minHashDb.Select(item => minHash.GroupMinHashToLSHBuckets(item, hashTables, hashKeys)).ToList(); List<Dictionary<int, long>> lshBucketsQuery = minHashQuery.Select(item => minHash.GroupMinHashToLSHBuckets(item, hashTables, hashKeys)).ToList(); int countSignatures = lshBucketsDb.Count; sum = 0; foreach (Dictionary<int, long> a in lshBucketsDb) { Dictionary<int, long>.ValueCollection aValues = a.Values; foreach (Dictionary<int, long> b in lshBucketsQuery) { Dictionary<int, long>.ValueCollection bValues = b.Values; hashesCount += aValues.Intersect(bValues).Count(); } } results.Results.SumJaqLSHBucketSimilarity = -1; results.Results.AverageJaqLSHBucketSimilarity = -1; results.Results.TotalIdenticalLSHBuckets = hashesCount; }
public void ExtractCandidatesWithMinHashAlgorithm(List <string> fileList) { int recognized = 0, verified = 0; IStride samplesToSkip = queryStride; Action <object[], Color> actionInterface = AddGridLine; ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = 4, CancellationToken = cancellationTokenSource.Token }; Task.Factory.StartNew(() => { Parallel.For( 0, fileList.Count, parallelOptions, (index, loopState) => { if (stopQuerying) { cancellationTokenSource.Cancel(); loopState.Stop(); } string pathToFile = fileList[index]; /*Path to song to recognize*/ TagInfo tags = tagService.GetTagInfo(pathToFile); // Get Tags from file if (tags == null || tags.IsEmpty) { Invoke(actionInterface, new object[] { string.Empty, pathToFile }, Color.Red); return; } string artist = string.IsNullOrEmpty(tags.Artist) ? Path.GetFileNameWithoutExtension(pathToFile) : tags.Artist; // Artist string title = string.IsNullOrEmpty(tags.Title) ? Path.GetFileNameWithoutExtension(pathToFile) : tags.Title; // Title string isrc = tags.ISRC; double duration = tags.Duration; // Duration // Check whether the duration is ok if (duration < MinTrackLength || duration > MaxTrackLength || secondsToAnalyze > duration) { // Duration too small Invoke(actionInterface, new object[] { "BAD DURATION", pathToFile }, Color.Red); return; } TrackData actualTrack = null; if (!string.IsNullOrEmpty(isrc)) { actualTrack = modelService.ReadTrackByISRC(isrc); } else if (!string.IsNullOrEmpty(tags.Artist) && !string.IsNullOrEmpty(tags.Title)) { actualTrack = modelService.ReadTrackByArtistAndTitleName(tags.Artist, tags.Title).FirstOrDefault(); } var queryResult = queryCommandBuilder.BuildQueryCommand() .From(pathToFile, secondsToAnalyze, startSecond) .WithConfigs( fingerprintConfig => { fingerprintConfig.Stride = samplesToSkip; fingerprintConfig.NumberOfLSHTables = hashTables; fingerprintConfig.NumberOfMinHashesPerTable = hashKeys; }, queryConfig => { queryConfig.ThresholdVotes = threshold; }) .UsingServices(modelService, audioService) .Query() .Result; if (cancellationTokenSource.IsCancellationRequested) { return; } if (!queryResult.IsSuccessful) { Invoke( actionInterface, new object[] { title + "-" + artist, "No match found!", false, -1, -1, "No match found!" }, Color.Red); if (actualTrack != null) { verified++; } return; } verified++; TrackData recognizedTrack = queryResult.BestMatch.Track; bool isSuccessful = actualTrack == null || recognizedTrack.TrackReference.Equals(actualTrack.TrackReference); if (isSuccessful) { recognized++; } Invoke( actionInterface, new object[] { title + "-" + artist, recognizedTrack.Title + "-" + recognizedTrack.Artist, isSuccessful, queryResult.BestMatch.Similarity, queryResult.AnalyzedCandidatesCount, recognizedTrack.ISRC }, Color.Empty); Invoke(new Action( () => { _tbResults.Text = ((float)recognized / verified).ToString(CultureInfo.InvariantCulture); })); }); }).ContinueWith(task => { MessageBox.Show("Finished!", "Finished query!"); }); }
private List <bool[]> CreateFingerprintsFromLogSpectrum(float[][] logarithmizedSpectrum, IStride stride, int fingerprintLength, int overlap, int topWavelets) { List <float[][]> spectralImages = spectrumService.CutLogarithmizedSpectrum(logarithmizedSpectrum, stride, fingerprintLength, overlap); waveletDecomposition.DecomposeImagesInPlace(spectralImages); var fingerprints = new List <bool[]>(); foreach (var spectralImage in spectralImages) { bool[] image = fingerprintDescriptor.ExtractTopWavelets(spectralImage, topWavelets); if (!IsSilence(image)) { fingerprints.Add(image); } } return(fingerprints); }
/// <summary> /// Get fingerprint similarity between 2 different songs. /// </summary> /// <param name = "manager">Fingerprint manager used in file decomposition</param> /// <param name = "stride">Stride object parameter</param> /// <param name = "proxy">Proxy to the audio object</param> /// <param name = "path">Path to first file</param> /// <param name = "differentPath">Path to different file</param> /// <param name = "results">Results object to be filled with the corresponding data</param> private static void GetFingerprintSimilarity(FingerprintManager manager, IStride stride, IAudio proxy, string path, string differentPath, DumpResults results) { int startindex = 0; int count = 0; double sum = 0; List<bool[]> imglista = manager.CreateFingerprints(proxy, path, stride); List<bool[]> imglistb = manager.CreateFingerprints(proxy, differentPath, stride); count = imglista.Count > imglistb.Count ? imglistb.Count : imglista.Count; double max = double.MinValue; for (int i = 0; i < count; i++) { int j = i; double value = MinHash.CalculateSimilarity(imglista[i], imglistb[j]); if (value > max) max = value; sum += value; } results.SumJaqFingerprintSimilarityBetweenDiffertSongs = sum; results.AverageJaqFingerprintsSimilarityBetweenDifferentSongs = sum/count; results.MaxJaqFingerprintsSimilarityBetweenDifferentSongs = max; }
private TestRunnerEventArgs GetTestRunnerEventArgsForFinishedTestIteration(IStride queryStride, int seconds, List<int> startAts, FScore fscore, HammingDistanceResultStatistics statistics, int iteration, Stopwatch stopwatch, int verified) { return new TestRunnerEventArgs { FScore = fscore, RowWithDetails = new object[] { this.GetInsertMetadata(), queryStride.ToString(), seconds, startAts[iteration], fscore.Precision, fscore.Recall, fscore.F1, statistics.TruePositiveInfo, statistics.TruePositivePercentileInfo, statistics.FalseNegativesInfo, statistics.FalseNegativesPercentileInfo, statistics.FalsePositivesInfo, statistics.FalsePositivesPercentileInfo, (double)stopwatch.ElapsedMilliseconds / 1000 }, Verified = verified }; }
public static void SaveInsertDataToFolder(StringBuilder sb, string resultsFolder, IStride insertStride) { string filename = string.Format("insert_{0}.csv", insertStride); string absolutePath = Path.Combine(resultsFolder, filename); Write(sb, absolutePath); }
public List <float[][]> CutLogarithmizedSpectrum(float[][] logarithmizedSpectrum, IStride strideBetweenConsecutiveImages, int fingerprintImageLength, int overlap) { int index = (int)((float)strideBetweenConsecutiveImages.FirstStride / overlap); int numberOfLogBins = logarithmizedSpectrum[0].Length; var spectralImages = new List <float[][]>(); int width = logarithmizedSpectrum.GetLength(0); while (index + fingerprintImageLength <= width) { float[][] spectralImage = AllocateMemoryForFingerprintImage(fingerprintImageLength, numberOfLogBins); for (int i = 0; i < fingerprintImageLength; i++) { Array.Copy(logarithmizedSpectrum[index + i], spectralImage[i], numberOfLogBins); } index += fingerprintImageLength + (int)((float)strideBetweenConsecutiveImages.GetNextStride() / overlap); spectralImages.Add(spectralImage); } return(spectralImages); }
/// <summary> /// Create fingerprints gathered from one specific song /// </summary> /// <param name = "proxy">Proxy used in reading the audio file</param> /// <param name = "filename">Filename</param> /// <param name = "stride">Stride used in fingerprint creation</param> /// <returns>List of fingerprint signatures</returns> public List <bool[]> CreateFingerprints(IWaveformPlayer proxy, string filename, IStride stride) { return(CreateFingerprints(proxy, filename, stride, 0, 0)); }
/// <summary> /// Protected constructor of WinQueryResults class /// </summary> /// <param name = "connectionString">Connection string used for the underlying data source</param> /// <param name = "secondsToAnalyze">Number of consequent fingerprints to analyze</param> /// <param name = "startSecond">Starting seconds</param> /// <param name = "stride">Stride used in the query</param> /// <param name = "topWavelets">Number of top wavelets to analyze</param> /// <param name = "fileList">List of all files to be recognized</param> protected WinQueryResults(string connectionString, int secondsToAnalyze, int startSecond, IStride stride, int topWavelets, List<string> fileList) { InitializeComponent(); /*Initialize Designer Components*/ Icon = Resources.Sound; _connectionString = connectionString; _topWavelets = topWavelets; _dalManager = new DaoGateway(ConfigurationManager.ConnectionStrings["FingerprintConnectionString"].ConnectionString); _permStorage = new DbPermutations(ConfigurationManager.ConnectionStrings["FingerprintConnectionString"].ConnectionString); _manager = new FingerprintManager {TopWavelets = topWavelets}; _dalManager.SetConnectionString(_connectionString); /*Set connection string for DAL manager*/ _secondsToAnalyze = secondsToAnalyze; /*Number of fingerprints to analyze from each song*/ _startSecond = startSecond; _fileList = fileList; /*List of files to analyze*/ _dgvResults.Columns.Add(COL_SONG_NAME, "Initial Song"); _dgvResults.Columns[COL_SONG_NAME].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_RESULT_NAME, "Result Song"); _dgvResults.Columns[COL_RESULT_NAME].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_POSITION, "Position"); _dgvResults.Columns[COL_POSITION].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_RESULT, "Result"); _dgvResults.Columns[COL_RESULT].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _dgvResults.Columns.Add(COL_HAMMING_AVG, "Hamming Avg."); _dgvResults.Columns[COL_HAMMING_AVG].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; _queryStride = stride; }
private void InsertInDatabase(int start, int end) { int topWavelets = (int)_nudTopWav.Value; IStride stride = null; Invoke( new Action( () => { stride = WinUtils.GetStride( (StrideType)_cmbStrideType.SelectedIndex, (int)_nudStride.Value, 0, new DefaultFingerprintConfiguration().SamplesPerFingerprint); }), null); Action actionInterface = () => { _pbTotalSongs.PerformStep(); _nudProcessed.Value = processed; _nudLeft.Value = left; _nudBadFiles.Value = badFiles; _nudDetectedDuplicates.Value = duplicates; }; Action <object[], Color> actionAddItems = (parameters, color) => { int index = _dgvFillDatabase.Rows.Add(parameters); _dgvFillDatabase.FirstDisplayedScrollingRowIndex = index; if (color != Color.Empty) { _dgvFillDatabase.Rows[index].DefaultCellStyle.BackColor = color; } }; for (int i = start; i < end; i++) { // Process the corresponding files if (stopFlag) { return; } TagInfo tags = tagService.GetTagInfo(fileList[i]); // Get Tags from file if (tags == null || tags.IsEmpty) { badFiles++; processed++; left--; Invoke(actionAddItems, new object[] { "TAGS ARE NULL", fileList[i], 0, 0 }, Color.Red); Invoke(actionInterface); continue; } string isrc = tags.ISRC; string artist = tags.Artist; // Artist string title = tags.Title; // Title int releaseYear = tags.Year; string album = tags.Album; double duration = tags.Duration; // Duration // Check whether the duration is OK if (duration < MinTrackLength || duration > MaxTrackLength) { // Duration too small badFiles++; processed++; left--; Invoke(actionAddItems, new object[] { "Bad duration", fileList[i], 0, 0 }, Color.Red); Invoke(actionInterface); continue; } // Check whether the tags are properly defined if (string.IsNullOrEmpty(isrc) && (string.IsNullOrEmpty(artist) || string.IsNullOrEmpty(title))) { badFiles++; processed++; left--; Invoke( actionAddItems, new object[] { "ISRC Tag is missing. Skipping file...", fileList[i], 0, 0 }, Color.Red); Invoke(actionInterface); continue; } IModelReference trackReference; try { lock (this) { // Check if this file is already in the database if (IsDuplicateFile(isrc, artist, title)) { duplicates++; // There is such file in the database processed++; left--; Invoke(actionInterface); continue; } var track = new TrackData(isrc, artist, title, album, releaseYear, (int)duration); trackReference = modelService.InsertTrack(track); // Insert new Track in the database } } catch (Exception e) { // catch any exception and abort the insertion processed++; left--; badFiles++; MessageBox.Show(e.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); Invoke(actionInterface); return; } int count; try { var hashDatas = fingerprintCommandBuilder .BuildFingerprintCommand() .From(fileList[i]) .WithFingerprintConfig( config => { config.TopWavelets = topWavelets; config.Stride = stride; }) .UsingServices(audioService) .Hash() .Result; // Create SubFingerprints modelService.InsertHashDataForTrack(hashDatas, trackReference); count = hashDatas.Count; } catch (Exception e) { // catch any exception and abort the insertion MessageBox.Show(e.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); badFiles++; processed++; left--; Invoke(actionInterface); return; } Invoke(actionAddItems, new object[] { artist, title, isrc, duration, count }, Color.Empty); left--; processed++; Invoke(actionInterface); } }