diff --git a/LanguageMaster.xml b/LanguageMaster.xml index 962c37e59..c693a3078 100644 --- a/LanguageMaster.xml +++ b/LanguageMaster.xml @@ -133,6 +133,7 @@ Command line: {1} {2} Note: Do check free disk space. LOW DISK SPACE! {0} free + No audio tracks found! Generate empty waveform? Batch generate waveform data diff --git a/libse/Language.cs b/libse/Language.cs index 61b8b8d68..0c02a03d2 100644 --- a/libse/Language.cs +++ b/libse/Language.cs @@ -261,6 +261,7 @@ namespace Nikse.SubtitleEdit.Core "Note: Do check free disk space.", LowDiskSpace = "LOW DISK SPACE!", FreeDiskSpace = "{0} free", + NoAudioTracksFoundGenerateEmptyWaveform = "No audio tracks found! Generate empty waveform?", }; AddWaveformBatch = new LanguageStructure.AddWaveformBatch diff --git a/libse/LanguageDeserializer.cs b/libse/LanguageDeserializer.cs index d0fb1efe1..7dc262c2d 100644 --- a/libse/LanguageDeserializer.cs +++ b/libse/LanguageDeserializer.cs @@ -376,6 +376,9 @@ namespace Nikse.SubtitleEdit.Core case "AddWaveform/FreeDiskSpace": language.AddWaveform.FreeDiskSpace = reader.Value; break; + case "AddWaveform/NoAudioTracksFoundGenerateEmptyWaveform": + language.AddWaveform.NoAudioTracksFoundGenerateEmptyWaveform = reader.Value; + break; case "AddWaveformBatch/Title": language.AddWaveformBatch.Title = reader.Value; break; diff --git a/libse/LanguageStructure.cs b/libse/LanguageStructure.cs index 6db8f3b8f..0229b3f60 100644 --- a/libse/LanguageStructure.cs +++ b/libse/LanguageStructure.cs @@ -131,6 +131,7 @@ public string WaveFileMalformed { get; set; } public string LowDiskSpace { get; set; } public string FreeDiskSpace { get; set; } + public string NoAudioTracksFoundGenerateEmptyWaveform { get; set; } } public class AddWaveformBatch diff --git a/libse/WaveToVisualizer.cs b/libse/WaveToVisualizer.cs index dd29b51af..1b087d01f 100644 --- a/libse/WaveToVisualizer.cs +++ b/libse/WaveToVisualizer.cs @@ -401,13 +401,7 @@ namespace Nikse.SubtitleEdit.Core /// /// Returns true if the current wave file can be processed. Compressed wave files are not supported. /// - public bool IsSupported - { - get - { - return _header.AudioFormat == WaveHeader.AudioFormatPcm && _header.Format == "WAVE"; - } - } + public bool IsSupported => _header.AudioFormat == WaveHeader.AudioFormatPcm && _header.Format == "WAVE"; /// /// Generates peaks and saves them to disk. @@ -501,6 +495,34 @@ namespace Nikse.SubtitleEdit.Core return new WavePeakData(peaksPerSecond, peaks); } + public static WavePeakData GenerateEmptyPeaks(string peakFileName, int totalSeconds) + { + int peaksPerSecond = Configuration.Settings.VideoControls.WaveformMinimumSampleRate; + var peaks = new List(); + peaks.Add(new WavePeak(1000, -1000)); + var totalPeaks = peaksPerSecond * totalSeconds; + for (int i = 0; i < totalPeaks; i++) + { + peaks.Add(new WavePeak(1, -1)); + } + peaks.Add(new WavePeak(1000, -1000)); + + // save results to file + using (var stream = File.Create(peakFileName)) + { + WaveHeader.WriteHeader(stream, peaksPerSecond, 2, 16, peaks.Count); + byte[] buffer = new byte[4]; + foreach (var peak in peaks) + { + WriteValue16Bit(buffer, 0, peak.Max); + WriteValue16Bit(buffer, 2, peak.Min); + stream.Write(buffer, 0, 4); + } + } + + return new WavePeakData(peaksPerSecond, peaks); + } + private static WavePeak CalculatePeak(float[] chunk, int count) { if (count == 0) diff --git a/src/Forms/AddWaveform.cs b/src/Forms/AddWaveform.cs index 39061d80f..4a8ccd8e3 100644 --- a/src/Forms/AddWaveform.cs +++ b/src/Forms/AddWaveform.cs @@ -25,6 +25,7 @@ namespace Nikse.SubtitleEdit.Forms private const string RetryEncodeParameters = "acodec=s16l"; private int _audioTrackNumber = -1; private int _delayInMilliseconds; + private int _numberOfAudioTracks; public AddWaveform() { @@ -231,6 +232,13 @@ namespace Nikse.SubtitleEdit.Forms return; } + if (_numberOfAudioTracks == 0 && MessageBox.Show(Configuration.Settings.Language.AddWaveform.NoAudioTracksFoundGenerateEmptyWaveform, Configuration.Settings.Language.General.Title, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) + { + MakeEmptyWaveFile(); + DialogResult = DialogResult.OK; + return; + } + MessageBox.Show(string.Format(Configuration.Settings.Language.AddWaveform.WaveFileNotFound, IntPtr.Size * 8, process.StartInfo.FileName, process.StartInfo.Arguments)); labelPleaseWait.Visible = false; @@ -241,6 +249,13 @@ namespace Nikse.SubtitleEdit.Forms if (targetFileInfo.Length <= 200) { + if (_numberOfAudioTracks == 0 && MessageBox.Show(Configuration.Settings.Language.AddWaveform.NoAudioTracksFoundGenerateEmptyWaveform, Configuration.Settings.Language.General.Title, MessageBoxButtons.YesNoCancel) == DialogResult.Yes) + { + MakeEmptyWaveFile(); + DialogResult = DialogResult.OK; + return; + } + MessageBox.Show(string.Format(Configuration.Settings.Language.AddWaveform.WaveFileMalformed, encoderName, process.StartInfo.FileName, process.StartInfo.Arguments)); labelPleaseWait.Visible = false; @@ -275,12 +290,21 @@ namespace Nikse.SubtitleEdit.Forms labelPleaseWait.Visible = false; } + private void MakeEmptyWaveFile() + { + labelProgress.Text = Configuration.Settings.Language.AddWaveform.GeneratingPeakFile; + Refresh(); + var videoInfo = UiUtil.GetVideoInfo(SourceVideoFileName); + Peaks = WavePeakGenerator.GenerateEmptyPeaks(_peakWaveFileName, (int)videoInfo.TotalMilliseconds / 1000); + labelPleaseWait.Visible = false; + } + private void AddWaveform_Shown(object sender, EventArgs e) { Refresh(); + _numberOfAudioTracks = 0; var audioTrackNames = new List(); var mkvAudioTrackNumbers = new Dictionary(); - int numberOfAudioTracks = 0; if (labelVideoFileName.Text.Length > 1 && File.Exists(labelVideoFileName.Text)) { if (labelVideoFileName.Text.EndsWith(".mkv", StringComparison.OrdinalIgnoreCase)) @@ -295,7 +319,7 @@ namespace Nikse.SubtitleEdit.Forms { if (track.IsAudio) { - numberOfAudioTracks++; + _numberOfAudioTracks++; if (track.CodecId != null && track.Language != null) { audioTrackNames.Add("#" + track.TrackNumber + ": " + track.CodecId.Replace("\0", string.Empty) + " - " + track.Language.Replace("\0", string.Empty)); @@ -338,7 +362,7 @@ namespace Nikse.SubtitleEdit.Forms audioTrackNames.Add(i.ToString(CultureInfo.InvariantCulture)); } } - numberOfAudioTracks = tracks.Count; + _numberOfAudioTracks = tracks.Count; } catch { @@ -347,7 +371,7 @@ namespace Nikse.SubtitleEdit.Forms } // Choose audio track - if (numberOfAudioTracks > 1) + if (_numberOfAudioTracks > 1) { using (var form = new ChooseAudioTrack(audioTrackNames, _audioTrackNumber)) {