private void btnOK_Click(object sender, EventArgs e) { try { // Update settings from controls TrackCount = txtTracks.Text.ToInt(2, "Track count"); float m = 0; if(!txtMinTrackLength.Text.TimeSpanToSeconds(ref m)) throw new ApplicationException("Invalid min track length"); Properties.Settings.Default.MinTrackLength = m; Properties.Settings.Default.SilenceFilterCentre = txtCentre.Text.ToFloat("Centre Frequency"); Properties.Settings.Default.SilenceFilterQ = txtQ.Text.ToFloat("Filter width (Q)"); Properties.Settings.Default.StartSilenceThreshold = txtStartSilence.Text.ToFloat("Start silence threshold"); Properties.Settings.Default.EndSilenceThreshold = txtEndSilence.Text.ToFloat("Start Music threshold"); Properties.Settings.Default.Save(); btnOK.Enabled = false; // Disable OK until finished m_Task.Run(delegate(TaskRunner.Task t) { Progress("Finding silences between tracks", 0); // Get list of potential gaps float length = m_Reader.WaveFormat.BytesToSeconds(m_Reader.Length); // Length of file in secs List<GapInfo> gaps = new List<GapInfo>(); // Found silences GapFinder f = new GapFinder(m_Reader); float start = 0; // Start of track Program.Trace("Album length {0}", length.ToTimeSpanString()); while (!t.Stop && f.FindMusic(start, -1)) { // Found some music - add info about the gap gaps.Add(new GapInfo() { Start = start, End = f.Position, AverageVolume = f.AverageVolume }); string status = "Track " + gaps.Count + " at " + f.Position.ToTimeSpanString(); Program.Trace(status); Progress(status, (int)(100 * f.Position / length)); if (f.FindSilence(f.Position, -1)) { // Found a silence while (!t.Stop && f.Position - start < Properties.Settings.Default.MinTrackLength) { // Track is too small - find music, then another silence Progress(status, (int)(100 * f.Position / length)); if (!f.FindMusic(f.Position, -1)) break; Progress(status, (int)(100 * f.Position / length)); if (!f.FindSilence(f.Position, -1)) break; } Program.Trace("Track " + gaps.Count + " ends at " + f.Position.ToTimeSpanString()); start = f.Position; } else { Program.Trace("Album ends at " + f.Position.ToTimeSpanString()); break; } Progress("Track " + gaps.Count + " ends at " + f.Position.ToTimeSpanString(), (int)(100 * f.Position / length)); } // And the gap at the end gaps.Add(new GapInfo() { Start = start, End = length, AverageVolume = f.AverageVolume }); if (!t.Stop) { if (gaps.Count < TrackCount + 1) { Despatch(delegate() { lblStatus.Text = "Only " + (gaps.Count - 1) + " Tracks found"; Refresh(); }); } else { // Eliminate loudest gaps (but not first or last) while (gaps.Count > TrackCount + 1) { float vol = float.MinValue; int loudest = 0; for (int i = 1; i < gaps.Count - 2; i++) { if (gaps[i].AverageVolume > vol) { vol = gaps[i].AverageVolume; loudest = i; } } gaps.RemoveAt(loudest); } } } if (!t.Stop) { // Now create/update track information Tracks = new List<Track>(); for (int i = 1; i < gaps.Count; i++) { GapInfo last = gaps[i - 1]; // Copy existing track, or create new one Track trk = Program.Album != null && i <= Program.Album.Tracks.Count ? new Track(Program.Album.Tracks[i - 1]) : new Track(); trk.Gap = last.End - last.Start; trk.LengthSeconds = gaps[i].Start - last.End; Tracks.Add(trk); } } if (!t.Stop) { // Have finished = close dialog with OK Despatch(delegate() { btnOK.Enabled = true; DialogResult = System.Windows.Forms.DialogResult.OK; Close(); }); } }); } catch(Exception ex) { lblStatus.Text = ex.Message; } }
/// <summary> /// Adjust track starts to coincide with actual start of music. /// Can call from any thread. /// </summary> private void autoGap() { Status("Checking track gaps"); GapFinder f = new GapFinder(m_Reader); float end = 0; // Silence at end of previous track (or start of recording, at first) foreach (Track t in Program.Album.Tracks) { float start; if (f.FindMusic(end, 60)) { // Set track start to start of music start = f.Position; // Set track gap to length of silence t.Gap = start - end; } else { // No music found in first 60 secs - just default to gap provided start = end + t.Gap; } end = start + t.LengthSeconds; // Where track end should be, according to Program.Album.Tracks // Is there silence shortly after the end of the track? if(f.FindSilence(end, 60) // If not, go back 30 seconds (or less, subject to MinTrackLength), and look again || f.FindSilence(Math.Max(start + Properties.Settings.Default.MinTrackLength, end - 30), 30)) { // Found silence - set correct track end, and length end = f.Position; t.LengthSeconds = end - start; } } }