diff --git a/OpenUtau.Core/PlaybackManager.cs b/OpenUtau.Core/PlaybackManager.cs index cac0826bc..4b533ada8 100644 --- a/OpenUtau.Core/PlaybackManager.cs +++ b/OpenUtau.Core/PlaybackManager.cs @@ -145,50 +145,62 @@ public static float DecibelToVolume(double db) { return (db <= -24) ? 0 : (float)MusicMath.DecibelToLinear((db < -16) ? db * 2 + 16 : db); } - public void RenderMixdown(UProject project, string exportPath) { - Task.Run(() => { - var task = Task.Run(() => { + public async Task RenderMixdown(UProject project, string exportPath) { + await Task.Run(() => { + try { RenderEngine engine = new RenderEngine(project); - var projectMix = engine.RenderMixdown(0,DocManager.Inst.MainScheduler, ref renderCancellation,wait:true).Item1; + var projectMix = engine.RenderMixdown(0, DocManager.Inst.MainScheduler, ref renderCancellation, wait: true).Item1; DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Exporting to {exportPath}.")); + + CheckFileWritable(exportPath); WaveFileWriter.CreateWaveFile16(exportPath, new ExportAdapter(projectMix).ToMono(1, 0)); DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Exported to {exportPath}.")); - }); - try { - task.Wait(); - } catch (AggregateException ae) { - foreach (var e in ae.Flatten().InnerExceptions) { - Log.Error(e, "Failed to render."); - } + } catch (IOException ioe) { + DocManager.Inst.ExecuteCmd(new ErrorMessageNotification($"Failed to export {exportPath}.", ioe)); + DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Failed to export {exportPath}.")); + } catch (Exception e) { + DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("Failed to render.", e)); + DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Failed to render.")); } }); } - public void RenderToFiles(UProject project, string exportPath) { - Task.Run(() => { - var task = Task.Run(() => { + public async Task RenderToFiles(UProject project, string exportPath) { + await Task.Run(() => { + string file = ""; + try { RenderEngine engine = new RenderEngine(project); var trackMixes = engine.RenderTracks(DocManager.Inst.MainScheduler, ref renderCancellation); for (int i = 0; i < trackMixes.Count; ++i) { if (trackMixes[i] == null || i >= project.tracks.Count || project.tracks[i].Muted) { continue; } - var file = PathManager.Inst.GetExportPath(exportPath, project.tracks[i]); + file = PathManager.Inst.GetExportPath(exportPath, project.tracks[i]); DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Exporting to {file}.")); + + CheckFileWritable(file); WaveFileWriter.CreateWaveFile16(file, new ExportAdapter(trackMixes[i]).ToMono(1, 0)); DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Exported to {file}.")); } - }); - try { - task.Wait(); - } catch (AggregateException ae) { - foreach (var e in ae.Flatten().InnerExceptions) { - Log.Error(e, "Failed to render."); - } + } catch (IOException ioe) { + DocManager.Inst.ExecuteCmd(new ErrorMessageNotification($"Failed to export {file}.", ioe)); + DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Failed to export {file}.")); + } catch (Exception e) { + DocManager.Inst.ExecuteCmd(new ErrorMessageNotification("Failed to render.", e)); + DocManager.Inst.ExecuteCmd(new ProgressBarNotification(0, $"Failed to render.")); } }); } + private void CheckFileWritable(string filePath) { + if (!File.Exists(filePath)) { + return; + } + using (FileStream fp = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) { + return; + } + } + void SchedulePreRender() { Log.Information("SchedulePreRender"); var engine = new RenderEngine(DocManager.Inst.Project); diff --git a/OpenUtau/Views/MainWindow.axaml.cs b/OpenUtau/Views/MainWindow.axaml.cs index a76d4c080..4c0edc842 100644 --- a/OpenUtau/Views/MainWindow.axaml.cs +++ b/OpenUtau/Views/MainWindow.axaml.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.IO; using System.Linq; using System.Reactive; using System.Threading; @@ -219,7 +220,7 @@ void OnMenuOpenProjectLocation(object sender, RoutedEventArgs args) { MessageBox.MessageBoxButtons.Ok); } try { - var dir = System.IO.Path.GetDirectoryName(project.FilePath); + var dir = Path.GetDirectoryName(project.FilePath); if (dir != null) { OS.OpenFolder(dir); } else { @@ -261,9 +262,9 @@ void OnMenuSaveTemplate(object sender, RoutedEventArgs args) { if (string.IsNullOrEmpty(file)) { return; } - file = System.IO.Path.GetFileNameWithoutExtension(file); + file = Path.GetFileNameWithoutExtension(file); file = $"{file}.ustx"; - file = System.IO.Path.Combine(PathManager.Inst.TemplatesPath, file); + file = Path.Combine(PathManager.Inst.TemplatesPath, file); Ustx.Save(file, project.CloneAsTemplate()); }; dialog.ShowDialog(this); @@ -330,17 +331,17 @@ async void OnMenuExportMixdown(object sender, RoutedEventArgs args) { var file = await FilePicker.SaveFile( this, "menu.file.exportmixdown", FilePicker.WAV); if (!string.IsNullOrEmpty(file)) { - PlaybackManager.Inst.RenderMixdown(project, file); + await PlaybackManager.Inst.RenderMixdown(project, file); } } async void OnMenuExportWav(object sender, RoutedEventArgs args) { var project = DocManager.Inst.Project; if (await WarnToSave(project)) { - var name = System.IO.Path.GetFileNameWithoutExtension(project.FilePath); - var path = System.IO.Path.GetDirectoryName(project.FilePath); - path = System.IO.Path.Combine(path!, "Export", $"{name}.wav"); - PlaybackManager.Inst.RenderToFiles(project, path); + var name = Path.GetFileNameWithoutExtension(project.FilePath); + var path = Path.GetDirectoryName(project.FilePath); + path = Path.Combine(path!, "Export", $"{name}.wav"); + await PlaybackManager.Inst.RenderToFiles(project, path); } } @@ -349,7 +350,7 @@ async void OnMenuExportWavTo(object sender, RoutedEventArgs args) { var file = await FilePicker.SaveFile( this, "menu.file.exportwavto", FilePicker.WAV); if (!string.IsNullOrEmpty(file)) { - PlaybackManager.Inst.RenderToFiles(project, file); + await PlaybackManager.Inst.RenderToFiles(project, file); } } @@ -404,9 +405,9 @@ async void OnMenuExportDsV2WithoutPitchTo(object sender, RoutedEventArgs e) { async void OnMenuExportUst(object sender, RoutedEventArgs e) { var project = DocManager.Inst.Project; if (await WarnToSave(project)) { - var name = System.IO.Path.GetFileNameWithoutExtension(project.FilePath); - var path = System.IO.Path.GetDirectoryName(project.FilePath); - path = System.IO.Path.Combine(path!, "Export", $"{name}.ust"); + var name = Path.GetFileNameWithoutExtension(project.FilePath); + var path = Path.GetDirectoryName(project.FilePath); + path = Path.Combine(path!, "Export", $"{name}.ust"); for (var i = 0; i < project.parts.Count; i++) { var part = project.parts[i]; if (part is UVoicePart voicePart) { @@ -719,7 +720,7 @@ async void OnDrop(object? sender, DragEventArgs args) { return; } string file = storageItem.Path.LocalPath; - var ext = System.IO.Path.GetExtension(file); + var ext = Path.GetExtension(file); if (ext == ".ustx" || ext == ".ust" || ext == ".vsqx" || ext==".ufdata") { if (!DocManager.Inst.ChangesSaved && !await AskIfSaveAndContinue()) { return;