private void RefineTrackDefinitionsByScanning(TrackList tracks) { long scanSelectionLength = _vinylRipOptions.ScanWindowLengthInSamples(_file); long trackStartWindowLength = _file.SecondsToPosition(0.05); //TODO: make configurable - was 0.05 long trackEndWindowLength = _file.SecondsToPosition(0.2); //TODO: make configurable - was 0.2 //long trackEndWindowOverlap = 0; long trackEndWindowOverlap = trackEndWindowLength - (long)Math.Round(trackEndWindowLength / 4.0f); // was 0 for (int i = 0; i < tracks.Count; i++) { TrackDefinition track = tracks[i]; List <ScanResult> refineStartResults = DoStatisticsScan(trackStartWindowLength, track.StartPosition, track.StartPosition + scanSelectionLength); foreach (ScanResult scanResult in refineStartResults) { if (!scanResult.RmsLevelExceeds(_vinylRipOptions.GapNoisefloorThresholdInDecibels)) { Output.ToScriptWindow(" ..Track {0} looking for better START: {1} -> {2}", track.Number, OutputHelper.FormatToTimeSpan(_file.PositionToSeconds(scanResult.SelectionStart)), OutputHelper.FormatToTimeSpan(_file.PositionToSeconds(scanResult.SelectionEnd)) ); continue; } track.StartPosition = scanResult.SelectionStart; Output.ToScriptWindow("Track {0} - Moving START to {1}", track.Number, OutputHelper.FormatToTimeSpan(_file.PositionToSeconds(track.StartPosition))); break; } //TODO: use longer, overlapping windows (but with short intervals between) to find track ends?? long trackEndScanPosition = track.EndPosition + trackEndWindowLength; if (trackEndScanPosition > tracks.FileLength) { trackEndScanPosition = tracks.FileLength; } else if (!track.IsLast && trackEndScanPosition > tracks[i + 1].StartPosition) { trackEndScanPosition = tracks[i + 1].StartPosition - 1; } List <ScanResult> refineEndResults = DoStatisticsScan(trackEndWindowLength, track.EndPosition - scanSelectionLength, trackEndScanPosition, trackEndWindowOverlap); for (int j = 0; j < refineEndResults.Count; j++) { ScanResult scanResult = refineEndResults[j]; if (scanResult.RmsLevelExceeds(_vinylRipOptions.GapNoisefloorThresholdInDecibels)) { Output.ToScriptWindow(" ..Track {0} looking for better END: {1} -> {2}", track.Number, OutputHelper.FormatToTimeSpan(_file.PositionToSeconds(scanResult.SelectionStart)), OutputHelper.FormatToTimeSpan(_file.PositionToSeconds(scanResult.SelectionEnd)) ); continue; } track.EndPosition = scanResult.SelectionStart - 1; Output.ToScriptWindow("Track {0} - Moving END to {1}", track.Number, OutputHelper.FormatToTimeSpan(_file.PositionToSeconds(track.EndPosition))); break; } } }
public SfAudioSelection EnforceNoisePrintSelection(IScriptableApp app, double noiseprintLength) { if (!IsCurrentSelectionGreaterThan(app, noiseprintLength)) { throw new ScriptAbortedException("A noise selection of {0} seconds or more must be made before running this script.", noiseprintLength); } ISfDataWnd window = _file.Window; WindowTasks.SelectBothChannels(window); long noiseprintSampleLength = _file.SecondsToPosition(noiseprintLength); SfAudioSelection selection = new SfAudioSelection(window.Selection.Start, noiseprintSampleLength, 0); return(selection); }
//TODO: clear console //TODO: come up with a way of saving settings between script runs, and between the 2 scripts (save options to json?) protected override void Execute() { _file = App.CurrentFile; _fileTasks = new FileTasks(_file); _fileTasks.EnforceStereoFileOpen(); _fileTasks.ZoomOutFull(); //TODO: retain marker positions in script and undo NOT working! //_file.UndosAreEnabled = true; //int undoId = _file.BeginUndo("PrepareAudio"); //_file.EndUndo(undoId, true); _vinylRipOptions = new VinylRipOptions(); _noiseprintSelection = _fileTasks.EnforceNoisePrintSelection(App, _vinylRipOptions.NoiseprintLengthSeconds); _file.Markers.Add(new SfAudioMarker(_noiseprintSelection)); CleanVinylRecording(AggressiveCleaningPreset, 3, _noiseprintSelection); //TODO: configure number of noise reduction passes? _vinylRipOptions.StartScanFilePositionInSamples = _file.SecondsToPosition(_vinylRipOptions.NoiseprintLengthSeconds); _trackList = FindTracks(App, _file); App.DoMenuAndWait("Edit.UndoAll", false); FileMarkersWrapper markers = new FileMarkersWrapper(_file); TrackMarkerFactory regionFactory = new TrackMarkerFactory(markers, Output, new TrackMarkerNameBuilder()); foreach (TrackDefinition track in _trackList) { regionFactory.CreateRegion(track.Number, track.StartPosition, track.Length); } }
public SplitTrackDefinition InsertTrackBefore() { var newTrackLength = TrackRegion.Start - _originalFile.SecondsToPosition(_options.DefaultTrackFadeOutLengthInSeconds) - PreceedingInsertionLimitPoint; var newTrackNumber = Number; var newRegion = _regionFactory.CreateRegion(newTrackNumber, PreceedingInsertionLimitPoint, newTrackLength); _splitTrackList.Insert(Number - 1, null); return(CreateTrackInList(newTrackNumber, newRegion)); }
public bool CanAddNextTrack(long nextTrackStartPosition) { if (LastAdded == null) { return(true); } // would track gap be too short ? long minimumAllowableStartPosition = LastAdded.EndPosition + _file.SecondsToPosition(_vinylRipOptions.MinimumTrackGapInSeconds); return(minimumAllowableStartPosition <= nextTrackStartPosition); }
public SplitTrackDefinition AddNew(SfAudioMarker trackRegionMarker, int trackNumber, VinylRipOptions options) { SplitTrackDefinition track = new SplitTrackDefinition(this, _file, options, _markerFactory, _regionFactory, _output); this[trackNumber - 1] = track; track.Number = trackNumber; track.TrackRegion = trackRegionMarker; track.FadeInEndMarker = GetTrackFadeInEndMarker(track.Number, options.DefaultTrackFadeInLengthInSamples); var fadeOutLengthInSamples = _file.SecondsToPosition(options.DefaultTrackFadeOutLengthInSeconds); track.FadeOutEndMarker = GetTrackFadeOutEndMarker(track.Number, fadeOutLengthInSamples); return(track); }
public long ScanWindowLengthInSamples(ISfFileHost file) { return(file.SecondsToPosition(ScanWindowLengthInSeconds)); }
private void runFadeEffectProcess() { if (isRunning) { return; } try { if (fadeInPresetComboBox.Items.Count <= 0) { MessageBox.Show("Fade in Preset is empty.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); fadeInPresetComboBox.Focus(); return; } if (fadeOutPresetComboBox.Items.Count <= 0) { MessageBox.Show("Fade in Preset is empty.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); fadeOutPresetComboBox.Focus(); return; } isRunning = true; List <string> files = new List <string>(); foreach (DataGridViewRow row in fileList.Rows) { files.Add(Path.Combine((string)row.Cells[1].Value, (string)row.Cells[0].Value)); } if (files.Count <= 0) { return; } progressBar.Maximum = files.Count; int count = 0; foreach (string file in files) { fileList.Rows[count].ErrorText = string.Empty; if (cancelRequest) { break; } ISfFileHost filehost = null; int undo = 0; try { filehost = forgeApp.FindFile(file); if (filehost == null) { filehost = forgeApp.OpenFile(file, false, false); } if (filehost.WaitForDoneOrCancel() == SfStatus.Fail) { fileList.Rows[count].ErrorText = string.Format("{0} can not be opened.", file); continue; } undo = filehost.BeginUndo("Fade In and Out"); SfStatus status = SfStatus.NotAvailable; Int64 fadetime = filehost.SecondsToPosition((double)fadeInTimeNumericUpDown.Value); if (fadetime <= filehost.Length) { filehost.DoEffect(EffectName, fadeInPresetComboBox.Text, new SfAudioSelection(0, fadetime), EffectOptions.EffectOnly); status = filehost.WaitForDoneOrCancel(); if (status == SfStatus.Success) { fadetime = filehost.SecondsToPosition((double)fadeOutTimeNumericUpDown.Value); if (fadetime <= filehost.Length) { filehost.DoEffect(EffectName, fadeOutPresetComboBox.Text, new SfAudioSelection(filehost.Length - fadetime, fadetime), EffectOptions.EffectOnly); status = filehost.WaitForDoneOrCancel(); } else { fileList.Rows[count].ErrorText = string.Format("The fade out time({0}) is longer than total time({1}).", fadetime, filehost.Length); status = SfStatus.Fail; } } } else { fileList.Rows[count].ErrorText = string.Format("The fade in time({0}) is longer than total time({1}).", fadetime, filehost.Length); status = SfStatus.Fail; } filehost.WaitForDoneOrCancel(); if (status != SfStatus.Success) { if (fileList.Rows[count].ErrorText == string.Empty) { fileList.Rows[count].ErrorText = string.Format("error code({0}).", status); } } filehost.EndUndo(undo, (status != SfStatus.Success)); filehost.WaitForDoneOrCancel(); filehost.Save(SaveOptions.WaitForDoneOrCancel); filehost.WaitForDoneOrCancel(); filehost.Close(CloseOptions.SaveChanges); filehost.WaitForDoneOrCancel(); } catch (Exception e) { forgeApp.SetStatusText(e.ToString()); filehost.EndUndo(undo, true); filehost.Close(CloseOptions.DiscardChanges); fileList.Rows[count].ErrorText = e.ToString(); } finally { count++; progressBar.Value++; progressBar.Refresh(); } } } finally { isRunning = false; cancelRequest = false; } }