public static float[] Decode(string fileIn, int srate, int secondsToAnalyze) { DbgTimer t = new DbgTimer(); t.Start(); float[] floatBuffer = null; // check if file exists if (fileIn != null && fileIn != "") { FileInfo fi = new FileInfo(fileIn); if (!fi.Exists) { Console.Out.WriteLine("No file found {0}!", fileIn); return(null); } } // Try to use Un4Seen Bass BassProxy bass = BassProxy.Instance; double duration = bass.GetDurationInSeconds(fileIn); if (duration > 0) { Dbg.WriteLine("Using BASS to decode the file ..."); // duration in seconds if (duration > secondsToAnalyze) { // find segment to extract double startSeconds = (duration / 2 - (secondsToAnalyze / 2)); if (startSeconds < 0) { startSeconds = 0; } floatBuffer = bass.ReadMonoFromFile(fileIn, srate, secondsToAnalyze * 1000, (int)(startSeconds * 1000)); // if this failes, the duration read from the tags was wrong or it is something wrong with the audio file if (floatBuffer == null) { IOUtils.LogMessageToFile(Mir.WARNING_FILES_LOG, fileIn); } } else { // return whole file floatBuffer = bass.ReadMonoFromFile(fileIn, srate, 0, 0); // if this failes, the duration read from the tags was wrong or it is something wrong with the audio file if (floatBuffer == null) { IOUtils.LogMessageToFile(Mir.WARNING_FILES_LOG, fileIn); } } } // Bass failed reading or never even tried, so use another alternative if (floatBuffer == null) { Dbg.WriteLine("Using MPlayer and SOX to decode the file ..."); fileIn = Regex.Replace(fileIn, "%20", " "); floatBuffer = DecodeUsingMplayerAndSox(fileIn, srate, secondsToAnalyze); } return(floatBuffer); }
/// <summary> /// Scan a directory recursively and add all the audio files found to the database /// </summary> /// <param name="path">Path to directory</param> /// <param name="db">MandelEllis or Scms Database Instance</param> /// <param name="repository">Soundfingerprinting Repository</param> /// <param name="skipDurationAboveSeconds">Skip files with duration longer than this number of seconds (0 or less disables this)</param> /// <param name="silent">true if silent mode (reduced console output)</param> public static void ScanDirectory(string path, Db db, Repository repository, double skipDurationAboveSeconds, bool silent=false) { Stopwatch stopWatch = Stopwatch.StartNew(); FAILED_FILES_LOG.Delete(); WARNING_FILES_LOG.Delete(); // scan directory for audio files try { // By some reason the IOUtils.GetFiles returns a higher count than what seams correct?! IEnumerable<string> filesAll = Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories) .Where(f => extensions.Contains(Path.GetExtension(f).ToLower())); Console.Out.WriteLine("Found {0} files in scan directory.", filesAll.Count()); // Get all already processed files stored in the database and store in memory // It seems to work well with huge volumes of files (200k) IList<string> filesAlreadyProcessed = repository.DatabaseService.ReadTrackFilenames(); Console.Out.WriteLine("Database contains {0} already processed files.", filesAlreadyProcessed.Count); // find the files that has not already been added to the database List<string> filesRemaining = filesAll.Except(filesAlreadyProcessed).ToList(); Console.Out.WriteLine("Found {0} files remaining in scan directory to be processed.", filesRemaining.Count); int filesCounter = 1; int filesAllCounter = filesAlreadyProcessed.Count + 1; #if !DEBUG Console.Out.WriteLine("Running in multi-threaded mode!"); Parallel.ForEach(filesRemaining, file => { #else Console.Out.WriteLine("Running in single-threaded mode!"); foreach (string file in filesRemaining) { #endif FileInfo fileInfo = new FileInfo(file); // Try to use Un4Seen Bass to check duration BassProxy bass = BassProxy.Instance; double duration = bass.GetDurationInSeconds(fileInfo.FullName); // check if we should skip files longer than x seconds if ( (skipDurationAboveSeconds > 0 && duration > 0 && duration < skipDurationAboveSeconds) || skipDurationAboveSeconds <= 0 || duration < 0) { if(!Analyzer.AnalyzeAndAddComplete(fileInfo, db, repository)) { //if(!Analyzer.AnalyzeAndAddSoundfingerprinting(fileInfo, repository)) { //if(!Analyzer.AnalyzeAndAddScms(fileInfo, db)) { Console.Out.WriteLine("Failed! Could not generate audio fingerprint for {0}!", fileInfo.Name); IOUtils.LogMessageToFile(FAILED_FILES_LOG, fileInfo.FullName); } else { Console.Out.WriteLine("[{1}/{2} - {3}/{4}] Succesfully added {0} to database. (Thread: {5})", fileInfo.Name, filesCounter, filesRemaining.Count, filesAllCounter, filesAll.Count(), Thread.CurrentThread.ManagedThreadId); // Threadsafe increment (TODO: doesn't always seem to work?) //filesCounter++; //filesAllCounter++; Interlocked.Increment(ref filesCounter); Interlocked.Increment(ref filesAllCounter); } } else { if (!silent) Console.Out.WriteLine("Skipping {0} since duration exceeds limit ({1:0.00} > {2:0.00} sec.)", fileInfo.Name, duration, skipDurationAboveSeconds); } fileInfo = null; } #if !DEBUG ); #endif int filesActuallyProcessed = filesCounter -1; Console.WriteLine("Added {0} out of a total remaining set of {1} files. (Of {2} files found).", filesActuallyProcessed, filesRemaining.Count(), filesAll.Count()); } catch (UnauthorizedAccessException UAEx) { Console.WriteLine(UAEx.Message); } catch (PathTooLongException PathEx) { Console.WriteLine(PathEx.Message); } catch (System.NullReferenceException NullEx) { Console.WriteLine(NullEx.Message); } Console.WriteLine("Time used: {0}", stopWatch.Elapsed); }