/// <summary> /// Get track info from the filename /// </summary> /// <param name = "mintracklen">Min track length</param> /// <param name = "maxtracklen">Max track length</param> /// <param name = "filename">Filename from which to extract the requested info</param> /// <param name = "proxy">Audio proxy to read tags</param> /// <returns>Track to be analyzed further / null if the track is not eligible</returns> public static Track GetTrackInfo(int mintracklen, int maxtracklen, string filename, BassProxy proxy) { TAG_INFO tags = proxy.GetTagInfoFromFile(filename); //get file tags string artist, title; double duration; if (tags == null) { /*The song does not contain any tags*/ artist = "Unknown"; title = "Unknown"; duration = 60; } else { /*The song contains related tags*/ artist = tags.artist; title = tags.title; duration = tags.duration; } if (String.IsNullOrEmpty(artist)) /*assign a name to music files that don't have tags*/ artist = "Unknown"; if (String.IsNullOrEmpty(title)) /*assign a title to music files that don't have tags*/ title = "Unknown"; if (duration < mintracklen || duration > maxtracklen) /*check the duration of a music file*/ return null; Track track = new Track { Artist = artist, Title = title, TrackLength = duration, Path = Path.GetFullPath(filename) }; return track; }
static void Process(Files.File file) { var audio = new Files.AudioFile { ID = file.ID, ContentType = file.ContentType, Name = file.Name, Size = file.Size, Url = file.Url, FullPath = file.FullPath }; audio.AlterPath = file.FullPath.ToLower().Replace("mp3", "wav"); var proxy = new BassProxy(); if (!File.Exists(audio.AlterPath)) proxy.RecodeTheFile(file.FullPath, audio.AlterPath, 5512); FingerprintManager manager = new FingerprintManager(); manager.FingerprintLength = Length; manager.TopWavelets = 150; manager.MaxFrequency = 2048; manager.MinFrequency = 512; //float[][] spec = manager.CreateSpectrogram(proxy, audio.AlterPath, 0, 0); var StaticStride = new StaticStride(0); audio.Finger = manager.CreateFingerprints(proxy, audio.AlterPath, StaticStride).ToArray(); FileProvider.Save(audio); }
/// <summary> /// Resample the song /// </summary> private void BtnResampleClick(object sender, EventArgs e) { if (String.IsNullOrEmpty(_tbPathToFile.Text)) { MessageBox.Show(Resources.SelectAPathToBeDrawn, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(Path.GetFullPath(_tbPathToFile.Text))) { MessageBox.Show(Resources.NoSuchFile, Resources.NoSuchFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } SaveFileDialog sfd = new SaveFileDialog { Filter = Resources.FileFilterWav, FileName = Path.GetFileNameWithoutExtension(_tbPathToFile.Text) + ".wav" }; if (sfd.ShowDialog() == DialogResult.OK) { Action action = () => { using (BassProxy bass = new BassProxy()) { string pathToRecoded = Path.GetFullPath(sfd.FileName); bass.RecodeTheFile(_tbPathToFile.Text, pathToRecoded, (int) _nudSampleRate.Value); } }; FadeControls(false); action.BeginInvoke( (result) => { action.EndInvoke(result); FadeControls(true); MessageBox.Show(Resources.FileConverted, Resources.FileConverted, MessageBoxButtons.OK, MessageBoxIcon.Information); return; }, null); } }
/// <summary> /// Draw the fingerprints of an audio file /// </summary> private void BtnDrawFingerprintsClick(object sender, EventArgs e) { if (String.IsNullOrEmpty(_tbPathToFile.Text)) { MessageBox.Show(Resources.SelectAPathToBeDrawn, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(Path.GetFullPath(_tbPathToFile.Text))) { MessageBox.Show(Resources.NoSuchFile, Resources.NoSuchFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (_lbImageTypes.SelectedIndex == 0) { string fileName = Path.GetFileNameWithoutExtension(_tbPathToFile.Text); SaveFileDialog sfd = new SaveFileDialog { FileName = fileName + "_fingerprints_" + ".jpg", Filter = Resources.FileFilterJPeg }; if (sfd.ShowDialog() == DialogResult.OK) { string path = Path.GetFullPath(sfd.FileName); FadeControls(false); Action action = () => { using (IAudio proxy = new BassProxy()) { FingerprintManager manager = new FingerprintManager(); StaticStride stride = new StaticStride((int) _nudStride.Value); int totalFingerprints = 0; List<bool[]> fingerprints = manager.CreateFingerprints(proxy, Path.GetFullPath(_tbPathToFile.Text), stride); int width = manager.FingerprintLength; int height = manager.LogBins; Bitmap image = Imaging.GetFingerprintsImage(fingerprints, width, height); image.Save(path); image.Dispose(); } }; action.BeginInvoke((result) => { FadeControls(true); MessageBox.Show(Resources.ImageIsDrawn, Resources.Finished, MessageBoxButtons.OK, MessageBoxIcon.Information); action.EndInvoke(result); }, action); } } else if (_lbImageTypes.SelectedIndex == 1) { FolderBrowserDialog fbd = new FolderBrowserDialog(); if (fbd.ShowDialog() == DialogResult.OK) { string path = fbd.SelectedPath; string fileName = Path.GetFileName(_tbPathToFile.Text); FadeControls(false); Action action = () => { using (IAudio proxy = new BassProxy()) { FingerprintManager manager = new FingerprintManager(); StaticStride stride = new StaticStride((int) _nudStride.Value); List<bool[]> result = manager.CreateFingerprints(proxy, Path.GetFullPath(_tbPathToFile.Text), stride); int i = -1; int width = manager.FingerprintLength; int height = manager.LogBins; foreach (bool[] item in result) { Image image = Imaging.GetFingerprintImage(item, width, height); image.Save(path + "\\" + fileName + i++ + ".jpg", ImageFormat.Jpeg); } } }; action.BeginInvoke((result) => { FadeControls(true); MessageBox.Show(Resources.ImageIsDrawn, Resources.Finished, MessageBoxButtons.OK, MessageBoxIcon.Information); action.EndInvoke(result); } , action); } } }
/// <summary> /// Draw wavelets /// </summary> private void BtnDrawWaveletsClick(object sender, EventArgs e) { if (String.IsNullOrEmpty(_tbPathToFile.Text)) { MessageBox.Show(Resources.SelectAPathToBeDrawn, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(Path.GetFullPath(_tbPathToFile.Text))) { MessageBox.Show(Resources.NoSuchFile, Resources.NoSuchFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } string fileName = Path.GetFileNameWithoutExtension(_tbPathToFile.Text); SaveFileDialog sfd = new SaveFileDialog { FileName = fileName + ".jpg", Filter = Resources.FileFilterJPeg }; if (sfd.ShowDialog() == DialogResult.OK) { string path = Path.GetFullPath(sfd.FileName); FadeControls(false); Action action = () => { using (IAudio proxy = new BassProxy()) { FingerprintManager manager = new FingerprintManager(); StaticStride stride = new StaticStride((int) _nudStride.Value); Image image = Imaging.GetWaveletSpectralImage(Path.GetFullPath(_tbPathToFile.Text), stride, proxy, manager); image.Save(path); image.Dispose(); } }; action.BeginInvoke((result) => { FadeControls(true); MessageBox.Show(Resources.ImageIsDrawn, Resources.Finished, MessageBoxButtons.OK, MessageBoxIcon.Information); action.EndInvoke(result); }, action); } }
/// <summary> /// Draw the spectrogram of the audio file /// </summary> private void BtnDrawSpectrumClick(object sender, EventArgs e) { if (String.IsNullOrEmpty(_tbPathToFile.Text)) { MessageBox.Show(Resources.SelectAPathToBeDrawn, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(Path.GetFullPath(_tbPathToFile.Text))) { MessageBox.Show(Resources.NoSuchFile, Resources.NoSuchFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } SaveFileDialog sfd = new SaveFileDialog { Filter = Resources.FileFilterJPeg, FileName = Path.GetFileNameWithoutExtension(_tbPathToFile.Text) + "_spectrum_" + ".jpg" }; if (sfd.ShowDialog() == DialogResult.OK) { FadeControls(false); Action action = () => { using (BassProxy proxy = new BassProxy()) { FingerprintManager manager = new FingerprintManager(); float[][] data = manager.CreateSpectrogram(proxy, Path.GetFullPath(_tbPathToFile.Text), 0, 0); double duration = proxy.GetTagInfoFromFile(Path.GetFullPath(_tbPathToFile.Text)).duration; Bitmap image = Imaging.GetSpectrogramImage(data, (int) _nudWidth.Value, (int) _nudHeight.Value); image.Save(sfd.FileName, ImageFormat.Jpeg); image.Dispose(); } }; action.BeginInvoke(((result) => { FadeControls(true); action.EndInvoke(result); MessageBox.Show(Resources.ImageIsDrawn, Resources.Finished, MessageBoxButtons.OK, MessageBoxIcon.Information); }), null); } }
/// <summary> /// Draw the signal of the audio file /// </summary> private void BtnDrawSignalClick(object sender, EventArgs e) { if (String.IsNullOrEmpty(_tbPathToFile.Text)) { MessageBox.Show(Resources.SelectAPathToBeDrawn, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(Path.GetFullPath(_tbPathToFile.Text))) { MessageBox.Show(Resources.NoSuchFile, Resources.NoSuchFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } SaveFileDialog sfd = new SaveFileDialog { Filter = Resources.FileFilterJPeg, FileName = Path.GetFileNameWithoutExtension(_tbPathToFile.Text) + "_signal_" + ".jpg" }; if (sfd.ShowDialog() == DialogResult.OK) { string fullpath = Path.GetFullPath(_tbPathToFile.Text); FadeControls(false); Action action = () => { #pragma warning disable 612,618 using (IAudio proxy = new BassProxy()) #pragma warning restore 612,618 { FingerprintManager manager = new FingerprintManager(); float[] data = proxy.ReadMonoFromFile(fullpath, manager.SampleRate, 0, 0); Bitmap image = Imaging.GetSignalImage(data, (int) _nudWidth.Value, (int) _nudHeight.Value); image.Save(sfd.FileName, ImageFormat.Jpeg); image.Dispose(); } }; action.BeginInvoke(((result) => { FadeControls(true); action.EndInvoke(result); MessageBox.Show(Resources.ImageIsDrawn, Resources.Finished, MessageBoxButtons.OK, MessageBoxIcon.Information); }), null); } }
/// <summary> /// Dump information into file /// </summary> private void BtnDumpInfoClick(object sender, EventArgs e) { if (String.IsNullOrEmpty(_tbPathToFile.Text)) { MessageBox.Show(Resources.ErrorNoFileToAnalyze, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (String.IsNullOrEmpty(_tbOutputPath.Text)) { MessageBox.Show(Resources.SelectPathToDump, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (!File.Exists(Path.GetFullPath(_tbPathToFile.Text))) { MessageBox.Show(Resources.NoSuchFile, Resources.NoSuchFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } if (_chbCompare.Checked) { if (String.IsNullOrEmpty(_tbSongToCompare.Text)) { MessageBox.Show(Resources.ErrorNoFileToAnalyze, Resources.SelectFile, MessageBoxButtons.OK, MessageBoxIcon.Information); return; } } Action action = () => { using (BassProxy proxy = new BassProxy()) { FadeControls(false); int minFreq = (int) _nudFreq.Value; int topWavelets = (int) _nudTopWavelets.Value; int stride = (int) _nudStride.Value; IStride objStride = (_chbStride.Checked) ? (IStride) new RandomStride(0, stride) : new StaticStride(stride); FingerprintManager manager = new FingerprintManager {MinFrequency = minFreq, TopWavelets = topWavelets}; DumpResults resultObj = new DumpResults(); string pathToInput = _tbPathToFile.Text; string pathToOutput = _tbOutputPath.Text; int hashTables = (int) _nudTables.Value; int hashKeys = (int) _nudKeys.Value; stride = (int) _nudQueryStride.Value; int numFingerprints = (int) _nudNumberOfSubsequent.Value; IStride queryStride = (_chbQueryStride.Checked) ? (IStride) new RandomStride(0, stride) : new StaticStride(stride); queryStride = new StaticStride(5115, 5115/2); GetFingerprintSimilarity(manager, objStride, queryStride, numFingerprints, proxy, pathToInput, resultObj); GetHashSimilarity(manager, objStride, queryStride, numFingerprints, hashTables, hashKeys, proxy, pathToInput, resultObj); if (_chbCompare.Checked) { string pathToDifferent = _tbSongToCompare.Text; GetFingerprintSimilarity(manager, objStride, proxy, pathToInput, pathToDifferent, resultObj); } resultObj.Info.MinFrequency = minFreq; resultObj.Info.TopWavelets = topWavelets; resultObj.Info.StrideSize = stride; resultObj.Info.RandomStride = _chbStride.Checked; resultObj.Info.Filename = pathToInput; resultObj.ComparisonDone = _chbCompare.Checked; XmlSerializer serializer = new XmlSerializer(typeof (DumpResults)); TextWriter writer = new StreamWriter(pathToOutput); serializer.Serialize(writer, resultObj); writer.Close(); } }; action.BeginInvoke( (result) => { action.EndInvoke(result); FadeControls(true); }, null); }
static void Process(string path) { Console.WriteLine(path); var proxy = new BassProxy(); proxy.RecodeTheFile(path + ".mp3", path + ".wav", 5512); var data = File.CreateText(path + ".txt"); FingerprintManager manager = new FingerprintManager(); manager.FingerprintLength = Length; manager.TopWavelets = 150; manager.MaxFrequency = 2048; manager.MinFrequency = 512; float[][] spec = manager.CreateSpectrogram(proxy, path + ".wav", 0, 0); var StaticStride = ( path == "7" ) ? new StaticStride(Milliseconds) : new StaticStride(0); var fingerprint = manager.CreateFingerprints(proxy, path + ".wav", StaticStride); if (path == "4") { sfinger = fingerprint; } foreach (var finger in fingerprint) { int[] bits = finger.Select(f => f ? 1 : 0).ToArray(); data.WriteLine(string.Join(";", bits)); } data.Close(); if(File.Exists( path + ".jpg") ) File.Delete(path + ".jpg"); if (spec.Length > 0) { Bitmap image = Imaging.GetSpectrogramImage(spec, 800, 600); image.Save(path + ".jpg", ImageFormat.Jpeg); } if (path == "7") { var hasMin = new MinHash(new LocalPermutations("2.txt", ";")); var result = File.CreateText("r.txt"); Dictionary<int, int> count = new Dictionary<int, int>(); foreach (var finger in sfinger) { //var t = fingerprint.Select(p => MinHash.CalculateSimilarity(finger, p)).OrderByDescending(p => p).ToArray(); //var t = fingerprint.Select(p => MinHash.CalculateHammingDistance (finger, p)).OrderByDescending(p => p).ToArray(); //var t = sfinger.Select(p => MinHash.CalculateSimilarity(finger, p)).OrderByDescending(p => p).ToArray(); for (int i = 0; i < fingerprint.Count; i++) { var similarity = MinHash.CalculateSimilarity(finger, fingerprint[i]); if (similarity > 0.5f) { if (!count.ContainsKey(i)) count.Add(i, 0); count[i]++; result.Write("{1}:{0};", similarity.ToString("#.000"), i, i * 11.6f * Block, (i + 1) * 11.6f * Block); } } result.WriteLine(); } foreach (var c in count.OrderByDescending(p => p.Value)) result.Write("{0}:{1};", c.Key, c.Value); result.WriteLine("-------------------"); foreach (var c in count.OrderBy(p => p.Key)) result.WriteLine("{0}:{1} Time: {2} ms;", c.Key, c.Value, c.Key * 11.6f * Block); result.Close(); } }
/// <summary> /// Actual synchronous insert in the database /// </summary> /// <param name = "start">Start index</param> /// <param name = "end">End index</param> private void InsertInDatabase(int start, int end) { BassProxy proxy = new BassProxy(); //Proxy used to read from file IStride stride = null; Invoke(new Action(() => { stride = WinUtils.GetStride((StrideType) _cmbStrideType.SelectedIndex, //Get stride according to the underlying combo box selection (int) _nudStride.Value, 0, _fingerManager.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; TAG_INFO tags = proxy.GetTagInfoFromFile(_fileList[i]); //Get Tags from file if (tags == null) { //TAGS are null _badFiles++; Invoke(actionAddItems, new Object[] {"TAGS ARE NULL", _fileList[i], 0, 0}, Color.Red); continue; } string artist = tags.artist; //Artist string title = tags.title; //Title double duration = tags.duration; //Duration if (duration < MIN_TRACK_LENGTH || duration > MAX_TRACK_LENGTH) //Check whether the duration is ok { //Duration too small _badFiles++; Invoke(actionAddItems, new Object[] {"BAD DURATION", _fileList[i], 0, 0}, Color.Red); continue; } if (String.IsNullOrEmpty(artist) || String.IsNullOrEmpty(title)) //Check whether the tags are properly defined { //Title or Artist tag is null _badFiles++; Invoke(actionAddItems, new Object[] {"TAGS MISSING", _fileList[i], 0, 0}, Color.Red); continue; } Album album = GetCoresspondingAlbum(tags); //Get Album (whether new or unknown or aborted) if (album == null) //Check whether the user aborted return; Track track = null; lock (this) { try { if (_dalManager.ReadTrackByArtistAndTitleName(artist, title) != null) // Check if this file is already in the database { _duplicates++; //There is such file in the database continue; } track = new Track(-1, artist, title, album.Id, (int) duration); //Create New Track _dalManager.InsertTrack(track); //Insert new Track in the database } catch (Exception e) { //catch any exception and abort the insertion MessageBox.Show(e.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } } int count = 0; try { List<bool[]> images = _fingerManager.CreateFingerprints(proxy, _fileList[i], stride); //Create Fingerprints and insert them in database List<Fingerprint> inserted = Fingerprint.AssociateFingerprintsToTrack(images, track.Id); _dalManager.InsertFingerprint(inserted); count = inserted.Count; switch (_hashAlgorithm) //Hash if there is a need in doing so { case HashAlgorithm.LSH: //LSH + Min Hash has been chosen HashFingerprintsUsingMinHash(inserted, track, _hashTables, _hashKeys); break; case HashAlgorithm.NeuralHasher: HashFingerprintsUsingNeuralHasher(inserted, track); break; case HashAlgorithm.None: break; } } catch (Exception e) { //catch any exception and abort the insertion MessageBox.Show(e.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Invoke(actionAddItems, new Object[] {artist, title, album.Name, duration, count}, Color.Empty); _left--; _processed++; Invoke(actionInterface); } }
private void ProcessFiles() { Action finishDel = delegate { buttonStop.Enabled = false; buttonPause.Enabled = false; buttonStartConversion.Enabled = true; _stopped = false; }; Process process = new Process { StartInfo = { FileName = "ffmpeg.exe", CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, RedirectStandardInput = true, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false } }; Action del = delegate { labelCurrentProcessed.Text = _currentProceesedFiles.ToString(); labelSkipped.Text = _skipped.ToString(); richTextBox1.AppendText(process.StandardError.ReadToEnd() + "\n"); richTextBox1.Focus(); richTextBox1.SelectionStart = richTextBox1.Text.Length; }; using (BassProxy proxy = new BassProxy()) { foreach (string f in _fileList) { if (_stopped) { Invoke(finishDel); Thread.CurrentThread.Abort(); } while (_pause) { if (_stopped) { Invoke(finishDel); Thread.CurrentThread.Abort(); } Thread.Sleep(1000); } TAG_INFO tags = null; try { //Read Tags from the file tags = proxy.GetTagInfoFromFile(f); } catch { _skipped++; _currentProceesedFiles++; Invoke(del); continue; } //Compose the output name of the wav file if (String.IsNullOrEmpty(tags.title) || tags.title.Length == 0) { //Skip file _skipped++; _currentProceesedFiles++; Invoke(del); continue; } string artist = ""; if (String.IsNullOrEmpty(tags.artist)) { if (tags.composer == null) { _skipped++; _currentProceesedFiles++; Invoke(del); continue; } artist = tags.composer; } else artist = tags.artist; string outfilename = tags.title + " + " + artist + ".wav"; string outfile = _outputPath + "\\" + outfilename; string arguments = "-i \"" + f + "\" -ac 1 -ar " + _samplingRate + " -ab " + _bitRate + " \"" + outfile + "\""; process.StartInfo.Arguments = arguments; process.Start(); process.StandardInput.Write("n"); _currentProceesedFiles++; Invoke(del); } } Invoke(finishDel); }