using QuikDawEditor.EditingClasses; using QuikDawEditor.MiscClasses; using QuikDawEditor.VST; using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Windows; using System.Windows.Media.Imaging; using System.Windows.Threading; using static QuikDawEditor.EDITING.StaticProperties; namespace QuikDawEditor; partial class EditorWindow { BackgroundWorker loadAudioBW; bool LoadingProject = false; public void LoadProject(string filePath) { if (!File.Exists(filePath)) { MessageBox.Show("File does not exist."); return; } string readString = File.ReadAllText(filePath); int firstLinePoint = readString.IndexOf(Environment.NewLine); BeatsPerMinute = Double.Parse(readString.Substring(0, firstLinePoint)); oldBPMvalue = BeatsPerMinute; editingProject = (Project)JsonSerializer.Deserialize(readString.Substring(firstLinePoint), typeof(Project)); editingProject.OpenedOriginalFilePath = filePath; editingProject.ProjectName =Path.GetFileNameWithoutExtension(filePath); LoadProject(editingProject); } public void LoadProject(Project editingProject) { ShowProcessingMessage("Loading project:\n" + editingProject.ProjectName); EnsureProjectDirectories(); LoadingProject = true; waveBitmapSources.Clear(); FileStream fstream = null; List UnusedWaveFormImages = new List(); foreach (string d in Directory.GetDirectories(ProjectWaveformImagesDirectory)) { bool waveFormImageUsed = editingProject.GetAllClips.Where(c => c.UniqueWaveFormImageDirectory == Path.GetFileName(d)).Count() > 0; if (waveFormImageUsed) { try { WaveBitmapSource newWBMS = new WaveBitmapSource() { sourceFileDirName = Path.GetFileName(d) }; waveBitmapSources.Add(newWBMS); foreach (string f in Directory.GetFiles(d)) { fstream = new FileStream(f, FileMode.Open); PngBitmapDecoder decoder = new PngBitmapDecoder(fstream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); newWBMS.waveBmSources.Add(decoder.Frames[0]); fstream.Close(); newWBMS.waveBmSources[newWBMS.waveBmSources.Count - 1].Freeze(); } } catch (Exception ex) {// MessageBox.Show(ex.Message + "\n" + ex.HResult.ToString()); if (ex.HResult == -2146233067) { fstream?.Close(); Directory.Delete(d, true); MessageBox.Show("Wave image file in directory:\n" + Path.GetFileName(d) + "\nwas corrupt, and has been deleted. Please reopen this project to recreate image file"); } } } else UnusedWaveFormImages.Add(d); } foreach (string wvi in UnusedWaveFormImages) Directory.Delete(wvi, true); ShowLocalMessage("waveBitmapSources count=" + waveBitmapSources.Count.ToString() + ", deleted: " + UnusedWaveFormImages.Count.ToString()); this.Title = "QuikDaw - Loading tracks and clips ... "; editingProject.UpdateAllClips(editingProject.Tracks); //Create the SampleProviders for tracks and clips try { projPlayer = new ProjectPlayer(); projPlayer.SendProcessMessage += ProjPlayer_SendProcessMessage; projPlayer.UpdateProjectEndPoint += ProjectPlayer_UpdateProjectEndPoint; projPlayer.ScaleGridToggled += ProjPlayer_ScaleGridToggled; projPlayer.ScrollTracksContentSVForward += ProjPlayer_ScrollTracksContentSVForward; projPlayer.CreateTimer(); AudioNotAvailableBanner.DataContext = projPlayer; ShowLocalMessage("Creating clips. . ."); //Check clip/vst source files and create clipsampleproviders loadAudioBW = new BackgroundWorker() { WorkerReportsProgress = true }; loadAudioBW.DoWork += LoadAudioBW_DoWork; loadAudioBW.ProgressChanged += LoadAudioBW_ProgressChanged; loadAudioBW.RunWorkerCompleted += LoadAudioBW_RunWorkerCompleted; loadAudioBW.RunWorkerAsync(); } catch (Exception ex) { MessageBox.Show("\n**Error trying to open the project!**\n" + ex.Message); } } private void ProjPlayer_ScaleGridToggled() { MainEditor.playGridHeader.UpdateGridVisual(); } private bool CloseProject(bool forceClose = false) { undoActions.Clear(); projPlayer.IsProjectPlaying = false; if (!forceClose) { if (editingProject.NeedsSaving) { switch (MessageBox.Show("Changes have not been saved. Save changes?", "Changes have been made", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel, MessageBoxOptions.DefaultDesktopOnly)) { case MessageBoxResult.Yes: editingProject.Save(); break; case MessageBoxResult.No: break; case MessageBoxResult.Cancel: return false; } } CloseAudioResources(); //Delete new project if it was never saved to file if (!Directory.Exists(EditingProjectPath) || Directory.GetFiles(EditingProjectPath).Where(f => Path.GetExtension(f) == ".qdd").Count() == 0) { MessageBoxResult result = MessageBox.Show("This project hasn't been saved to disk yet. Really discard?", "Project file doesn't exist yet", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.Yes, MessageBoxOptions.DefaultDesktopOnly); switch (result) { case MessageBoxResult.Yes: try { Directory.Delete(editingProject.ProjectDirectory, true); } catch (Exception ex) { MessageBox.Show("Created directory seems to have been changed. Will exit.\n" + ex.Message); } break; case MessageBoxResult.No: return true; } } } if (Properties.Settings.Default.AutoDeleteBackup) { if (Directory.Exists(ProjectBackupsDirectory)) { string[] backupFiles = Directory.GetFiles(ProjectBackupsDirectory); List olderThanOneMonthFiles = backupFiles.Where(bf => DateTime.Now.Subtract(new FileInfo(bf).LastWriteTime).Days > 30).ToList(); List toDeleteFiles = new List(); if (olderThanOneMonthFiles.Count > 0) { olderThanOneMonthFiles.Sort((omf1, omf2) => new FileInfo(omf1).LastWriteTime.CompareTo(new FileInfo(omf2).LastWriteTime)); string earliestFile = olderThanOneMonthFiles.FirstOrDefault(); int backYear = new FileInfo(earliestFile).LastWriteTime.Year; int backMonth = new FileInfo(earliestFile).LastWriteTime.Month; string currentFirstMonthFile = earliestFile; foreach (string file in olderThanOneMonthFiles) { if (file != currentFirstMonthFile && new FileInfo(currentFirstMonthFile).LastWriteTime.Year == new FileInfo(file).LastWriteTime.Year && new FileInfo(currentFirstMonthFile).LastWriteTime.Month == new FileInfo(file).LastWriteTime.Month) toDeleteFiles.Add(file); else currentFirstMonthFile = file; } foreach (string todelfile in toDeleteFiles) File.Delete(todelfile); } } } return true; } private void ProjPlayer_ScrollTracksContentSVForward(double scrollPix) { MainEditor.dontUpdateScroll = true; MainEditor.TracksContentSV.ScrollToHorizontalOffset(scrollPix); MainEditor.dontUpdateScroll = false; } private void ProjPlayer_SendProcessMessage(string message) { ShowLocalMessage(message); } private void LoadAudioBW_DoWork(object sender, DoWorkEventArgs e) { //Check MasterTrack fx vsts foreach (VstPluginReference vstref in editingProject.MasterTrack.MasterTrackEffectVsts) vstref.ReturnedWithoutError = File.Exists(vstref.VstDllFileFullPath); ShowLocalMessage("Checking vsts..."); editingProject.MasterTrack.InitializeVsts(); foreach (AutomationLane autoclip in editingProject.MasterTrack.AutomationLanes) autoclip.IsMasterTrackAutoClip = true; //Check track fx/inst vsts InitializeAudioForTracks(); } private void InitializeAudioForTracks() { foreach (Track t in editingProject.GetAllTracksInProject) t.InitializeTrackAudio(); } private void LoadAudioBW_ProgressChanged(object sender, ProgressChangedEventArgs e) { int cIndex = e.ProgressPercentage % 1000; int tIndex = (e.ProgressPercentage - cIndex) / 1000; //int percDone = (int)((double)cIndex / (double)editingProject.Tracks[tIndex].Clips.Count * 100); //CoverMessageTB.Text = "Loading audio track #" + tIndex.ToString().PadLeft(2, ' ') + " of " + editingProject.Tracks.Count.ToString().PadLeft(2, ' ') + "\n" + percDone.ToString().PadLeft(2, ' ') + "%"; } private void LoadAudioBW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MainEditor.UpdateTracksAreaMinWidth(); Debug.WriteLine("Finished preparing sample providers, will now open any VST editors"); OpenVSTEditors(); CoverMessageHide(); BindUIToProject(); splashWindow.Hide(); //Hide if it was opened editingProject.NeedsSaving = false; // start false because opening various windows may trigger true initially } private void OpenVSTEditors() { //THIS DONE AT END OF LOADING PROJECT foreach (Track t in editingProject.GetAllTracksInProject) { foreach (ActiveVstPlugin vplugin in t.TrackEffectVsts.Where(vp => vp.ReturnedWithoutError)) { Application.Current.Dispatcher.Invoke(() => { //must be invoke or else doesn't affect the plugin context if (vplugin.IsEditorOpen) vplugin.OpenEditor((EditorWindow)App.Current.MainWindow); }, DispatcherPriority.Normal); } foreach (ActiveVstPlugin vplugin in t.TrackInstrumentVsts.Where(vp => vp.ReturnedWithoutError)) { Application.Current.Dispatcher.Invoke(() => { //must be invoke or else doesn't affect the plugin context if (vplugin.IsEditorOpen) vplugin.OpenEditor((EditorWindow)App.Current.MainWindow); }, DispatcherPriority.Normal); } } } public void BindUIToProject() { MainEditor.PlayLine.DataContext = projPlayer; PlayControlDP.DataContext = projPlayer; TotalTimeCodeTB.DataContext = projPlayer; MenuDP.DataContext = projPlayer; MixdownsMI.DataContext = projPlayer; SnapToCB.SelectedIndex = editingProject.CurrentSnapTo == 2 ? 0 : (int)Math.Log2(1D / (double)editingProject.CurrentSnapTo) + 1; LoadingProject = false; AudioNotAvailableBanner.IsEnabled = true; MainEditor.ResetVisual(); MainEditor.Visibility = Visibility.Visible; Task.Run(() => { foreach (Track t in editingProject.GetAllTracksInProject) if (t.IsTrackCollapsed) editingProject.hiddenTracks.Add(t); Application.Current.Dispatcher.Invoke(() => { MainEditor.DataContext = editingProject; ControlPanelDP.DataContext = editingProject; projPlayer.UpdateEndPoint(); }, DispatcherPriority.Background); Application.Current.Dispatcher.Invoke(() => { MainEditor.TrackContentControlsIC.Focus(); MainEditor.TracksContentSV.ScrollToHorizontalOffset(projPlayer.CurrentPlayPosPixels * editingProject.ViewXZoomFac - 350); try { if (projPlayer.AudioDeviceOK) projPlayer.StartAudio(); } catch (Exception ex) { MessageBox.Show("Could not start audio\n" + ex.Message); } if (playAsioOut != null) { //editingProject.RecordInputs = new ObservableCollection(); editingProject.RecordInputs.Clear(); for (int chno = 0; chno < playAsioOut.DriverInputChannelCount; chno++) editingProject.RecordInputs.Add(new RecordInput() { RecordInputName = playAsioOut.AsioInputChannelName(chno), IsActiveInput = (Properties.Settings.Default.RecordInIndex == chno), RecordDeviceName = playAsioOut.DriverName }); this.Title = "QuikDaw Ready"; } else this.Title = "QuikDaw -- AUDIO NOT AVAILABLE"; this.IsEnabled = true; //Ready to operate ControlsDP.IsEnabled = true; MainEditor.HorizontalZoomMainTracks(1); MainEditor.TrackContentControlsIC.Focus(); MainEditor.TracksContentSV.ScrollToHorizontalOffset(projPlayer.CurrentPlayPosPixels * editingProject.ViewXZoomFac - 350); MainEditor.TracksContentSV.ScrollToVerticalOffset(0); ISPROJECTLOADED = true; ShowLocalMessage("Ready"); HideProcessingMessage(); MainEditor.UpdateTracksAreaMinWidth(); MainEditor.playGridHeader.UpdateGridVisual(); editingProject.UpdateProjectGridLines(); projPlayer.mmsp.ResetAllClips(0); //editingProject.ViewXZoomFac = 1; }, DispatcherPriority.Normal); }); } }