From b10514e49f4ca53407d5f492c0e9cec87a2e2f26 Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 27 Apr 2022 18:38:57 +0800 Subject: [PATCH 01/10] [MP2K] Add UI to batch export all songs as MIDI --- .../Properties/Strings.Designer.cs | 29 ++++++++- VG Music Studio/Properties/Strings.es.resx | 9 +++ VG Music Studio/Properties/Strings.it.resx | 9 +++ VG Music Studio/Properties/Strings.resx | 10 +++ VG Music Studio/UI/MainForm.cs | 61 ++++++++++++++++++- 5 files changed, 115 insertions(+), 3 deletions(-) diff --git a/VG Music Studio/Properties/Strings.Designer.cs b/VG Music Studio/Properties/Strings.Designer.cs index 7153b371..edd5b9d9 100644 --- a/VG Music Studio/Properties/Strings.Designer.cs +++ b/VG Music Studio/Properties/Strings.Designer.cs @@ -19,7 +19,7 @@ namespace Kermalis.VGMusicStudio.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Strings { @@ -321,6 +321,15 @@ internal static string ErrorSaveMIDI { } } + /// + /// Looks up a localized string similar to Error Exporting MIDI {0}. + /// + internal static string ErrorSaveMIDIBatch { + get { + return ResourceManager.GetString("ErrorSaveMIDIBatch", resourceCulture); + } + } + /// /// Looks up a localized string similar to Error Exporting SF2. /// @@ -510,6 +519,15 @@ internal static string MenuSaveMIDI { } } + /// + /// Looks up a localized string similar to Export All Songs as MIDI. + /// + internal static string MenuSaveMIDIBatch { + get { + return ResourceManager.GetString("MenuSaveMIDIBatch", resourceCulture); + } + } + /// /// Looks up a localized string similar to Export VoiceTable as SF2. /// @@ -672,6 +690,15 @@ internal static string SuccessSaveMIDI { } } + /// + /// Looks up a localized string similar to MIDI all saved.. + /// + internal static string SuccessSaveMIDIBatch { + get { + return ResourceManager.GetString("SuccessSaveMIDIBatch", resourceCulture); + } + } + /// /// Looks up a localized string similar to VoiceTable saved to {0}.. /// diff --git a/VG Music Studio/Properties/Strings.es.resx b/VG Music Studio/Properties/Strings.es.resx index d98bb266..34bc4a6c 100644 --- a/VG Music Studio/Properties/Strings.es.resx +++ b/VG Music Studio/Properties/Strings.es.resx @@ -345,4 +345,13 @@ DLS guardado en {0}. + + Error al Exportar MIDI {0} + + + Exportar todo Canción como MIDI + + + MIDI todo guardado. + \ No newline at end of file diff --git a/VG Music Studio/Properties/Strings.it.resx b/VG Music Studio/Properties/Strings.it.resx index 935f17e8..72cf3810 100644 --- a/VG Music Studio/Properties/Strings.it.resx +++ b/VG Music Studio/Properties/Strings.it.resx @@ -345,4 +345,13 @@ VoiceTable salvata in {0}. + + Errore Durante L'Esportazione in MIDI {0} + + + Esporta tutto Brano in MIDI + + + MIDI tutto salvato. + \ No newline at end of file diff --git a/VG Music Studio/Properties/Strings.resx b/VG Music Studio/Properties/Strings.resx index 8e4ae4a1..7d206841 100644 --- a/VG Music Studio/Properties/Strings.resx +++ b/VG Music Studio/Properties/Strings.resx @@ -373,4 +373,14 @@ VoiceTable saved to {0}. {0} is the file name. + + Error Exporting MIDI {0} + {0} is the song number. + + + Export All Songs as MIDI + + + MIDI all saved. + \ No newline at end of file diff --git a/VG Music Studio/UI/MainForm.cs b/VG Music Studio/UI/MainForm.cs index 761394fa..aa1cfd22 100644 --- a/VG Music Studio/UI/MainForm.cs +++ b/VG Music Studio/UI/MainForm.cs @@ -35,7 +35,7 @@ internal class MainForm : ThemedForm private readonly MenuStrip _mainMenu; private readonly ToolStripMenuItem _fileItem, _openDSEItem, _openAlphaDreamItem, _openMP2KItem, _openSDATItem, - _dataItem, _trackViewerItem, _exportDLSItem, _exportMIDIItem, _exportSF2Item, _exportWAVItem, + _dataItem, _trackViewerItem, _exportDLSItem, _exportMIDIItem, _exportMIDIBatchItem, _exportSF2Item, _exportWAVItem, _playlistItem, _endPlaylistItem; private readonly Timer _timer; private readonly ThemedNumeric _songNumerical; @@ -83,12 +83,14 @@ private MainForm() _exportDLSItem.Click += ExportDLS; _exportMIDIItem = new ToolStripMenuItem { Enabled = false, Text = Strings.MenuSaveMIDI }; _exportMIDIItem.Click += ExportMIDI; + _exportMIDIBatchItem = new ToolStripMenuItem { Enabled = false, Text = Strings.MenuSaveMIDIBatch }; + _exportMIDIBatchItem.Click += ExportMIDIBatch; _exportSF2Item = new ToolStripMenuItem { Enabled = false, Text = Strings.MenuSaveSF2 }; _exportSF2Item.Click += ExportSF2; _exportWAVItem = new ToolStripMenuItem { Enabled = false, Text = Strings.MenuSaveWAV }; _exportWAVItem.Click += ExportWAV; _dataItem = new ToolStripMenuItem { Text = Strings.MenuData }; - _dataItem.DropDownItems.AddRange(new ToolStripItem[] { _trackViewerItem, _exportDLSItem, _exportMIDIItem, _exportSF2Item, _exportWAVItem }); + _dataItem.DropDownItems.AddRange(new ToolStripItem[] { _trackViewerItem, _exportDLSItem, _exportMIDIItem, _exportMIDIBatchItem, _exportSF2Item, _exportWAVItem }); // Playlist Menu _endPlaylistItem = new ToolStripMenuItem { Enabled = false, Text = Strings.MenuEndPlaylist }; @@ -241,6 +243,7 @@ private void SongNumerical_ValueChanged(object sender, EventArgs e) int numTracks = (Engine.Instance.Player.Events?.Length).GetValueOrDefault(); _positionBar.Enabled = _exportWAVItem.Enabled = success && numTracks > 0; _exportMIDIItem.Enabled = success && Engine.Instance.Type == Engine.EngineType.GBA_MP2K && numTracks > 0; + _exportMIDIBatchItem.Enabled = success && Engine.Instance.Type == Engine.EngineType.GBA_MP2K; _exportDLSItem.Enabled = _exportSF2Item.Enabled = success && Engine.Instance.Type == Engine.EngineType.GBA_AlphaDream; _autoplay = true; @@ -343,6 +346,7 @@ private void OpenDSE(object sender, EventArgs e) _songNumerical.Visible = false; _exportDLSItem.Visible = false; _exportMIDIItem.Visible = false; + _exportMIDIBatchItem.Visible = false; _exportSF2Item.Visible = false; } } @@ -375,6 +379,7 @@ private void OpenAlphaDream(object sender, EventArgs e) _songNumerical.Visible = true; _exportDLSItem.Visible = true; _exportMIDIItem.Visible = false; + _exportMIDIBatchItem.Visible = false; _exportSF2Item.Visible = true; } } @@ -407,6 +412,7 @@ private void OpenMP2K(object sender, EventArgs e) _songNumerical.Visible = true; _exportDLSItem.Visible = false; _exportMIDIItem.Visible = true; + _exportMIDIBatchItem.Visible = true; _exportSF2Item.Visible = false; } } @@ -439,6 +445,7 @@ private void OpenSDAT(object sender, EventArgs e) _songNumerical.Visible = true; _exportDLSItem.Visible = false; _exportMIDIItem.Visible = false; + _exportMIDIBatchItem.Visible = false; _exportSF2Item.Visible = false; } } @@ -500,6 +507,56 @@ private void ExportMIDI(object sender, EventArgs e) } } } + private void ExportMIDIBatch(object sender, EventArgs e) + { + var d = new CommonOpenFileDialog + { + Title = Strings.MenuSaveMIDIBatch, + AllowNonFileSystemItems = true, + IsFolderPicker = true, + EnsurePathExists = true, + Multiselect = false, + ShowPlacesList = true + }; + if (d.ShowDialog() == CommonFileDialogResult.Ok) + { + var p = (Core.GBA.MP2K.Player)Engine.Instance.Player; + var args = new Core.GBA.MP2K.Player.MIDISaveArgs + { + SaveCommandsBeforeTranspose = true, + ReverseVolume = false, + TimeSignatures = new List<(int AbsoluteTick, (byte Numerator, byte Denominator))> + { + (0, (4, 4)) + } + }; + for (long i = 0; i <= _songNumerical.Maximum; i++) + { + try + { + p.LoadSong(i); + } + catch (Exception ex) + { + FlexibleMessageBox.Show(ex, string.Format(Strings.ErrorLoadSong, i)); + continue; + } + if (p.MaxTicks <= 0) + { + continue; + } + try + { + p.SaveAsMIDI(d.FileName + "/" + i.ToString() + ".mid", args); + } + catch (Exception ex) + { + FlexibleMessageBox.Show(ex, string.Format(Strings.ErrorSaveMIDIBatch, i)); + } + } + FlexibleMessageBox.Show(Strings.SuccessSaveMIDIBatch, Text); + } + } private void ExportSF2(object sender, EventArgs e) { var d = new CommonSaveFileDialog From 7fbb126335448a54c4df70277ca0b1d38180a9a2 Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 27 Apr 2022 19:27:05 +0800 Subject: [PATCH 02/10] [MP2K] Fix program crash caused by batch export during song playing 1. Auto stop playing before batch export 2. Reload current song after batch export --- VG Music Studio/UI/MainForm.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/VG Music Studio/UI/MainForm.cs b/VG Music Studio/UI/MainForm.cs index aa1cfd22..3768c669 100644 --- a/VG Music Studio/UI/MainForm.cs +++ b/VG Music Studio/UI/MainForm.cs @@ -521,6 +521,7 @@ private void ExportMIDIBatch(object sender, EventArgs e) if (d.ShowDialog() == CommonFileDialogResult.Ok) { var p = (Core.GBA.MP2K.Player)Engine.Instance.Player; + Stop(); var args = new Core.GBA.MP2K.Player.MIDISaveArgs { SaveCommandsBeforeTranspose = true, @@ -555,6 +556,15 @@ private void ExportMIDIBatch(object sender, EventArgs e) } } FlexibleMessageBox.Show(Strings.SuccessSaveMIDIBatch, Text); + long oldIndex = (long)_songNumerical.Value; + try + { + Engine.Instance.Player.LoadSong(oldIndex); + } + catch (Exception ex) + { + FlexibleMessageBox.Show(ex, string.Format(Strings.ErrorLoadSong, Engine.Instance.Config.GetSongName(oldIndex))); + } } } private void ExportSF2(object sender, EventArgs e) From 6e3dd94a334941b9b2ddc0e68fef84eee438bdfd Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 27 Apr 2022 20:32:06 +0800 Subject: [PATCH 03/10] [MP2K] Add folder name (output path) to success message --- VG Music Studio/Properties/Strings.Designer.cs | 2 +- VG Music Studio/Properties/Strings.es.resx | 2 +- VG Music Studio/Properties/Strings.it.resx | 2 +- VG Music Studio/Properties/Strings.resx | 3 ++- VG Music Studio/UI/MainForm.cs | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) diff --git a/VG Music Studio/Properties/Strings.Designer.cs b/VG Music Studio/Properties/Strings.Designer.cs index edd5b9d9..e9c370c9 100644 --- a/VG Music Studio/Properties/Strings.Designer.cs +++ b/VG Music Studio/Properties/Strings.Designer.cs @@ -691,7 +691,7 @@ internal static string SuccessSaveMIDI { } /// - /// Looks up a localized string similar to MIDI all saved.. + /// Looks up a localized string similar to MIDIs saved to {0}.. /// internal static string SuccessSaveMIDIBatch { get { diff --git a/VG Music Studio/Properties/Strings.es.resx b/VG Music Studio/Properties/Strings.es.resx index 34bc4a6c..eb3153e8 100644 --- a/VG Music Studio/Properties/Strings.es.resx +++ b/VG Music Studio/Properties/Strings.es.resx @@ -352,6 +352,6 @@ Exportar todo Canción como MIDI - MIDI todo guardado. + MIDIs guardado en {0}. \ No newline at end of file diff --git a/VG Music Studio/Properties/Strings.it.resx b/VG Music Studio/Properties/Strings.it.resx index 72cf3810..49147751 100644 --- a/VG Music Studio/Properties/Strings.it.resx +++ b/VG Music Studio/Properties/Strings.it.resx @@ -352,6 +352,6 @@ Esporta tutto Brano in MIDI - MIDI tutto salvato. + MIDIs salvato in {0}. \ No newline at end of file diff --git a/VG Music Studio/Properties/Strings.resx b/VG Music Studio/Properties/Strings.resx index 7d206841..359db2ed 100644 --- a/VG Music Studio/Properties/Strings.resx +++ b/VG Music Studio/Properties/Strings.resx @@ -381,6 +381,7 @@ Export All Songs as MIDI - MIDI all saved. + MIDIs saved to {0}. + {0} is the folder name. \ No newline at end of file diff --git a/VG Music Studio/UI/MainForm.cs b/VG Music Studio/UI/MainForm.cs index 3768c669..92a19959 100644 --- a/VG Music Studio/UI/MainForm.cs +++ b/VG Music Studio/UI/MainForm.cs @@ -555,7 +555,7 @@ private void ExportMIDIBatch(object sender, EventArgs e) FlexibleMessageBox.Show(ex, string.Format(Strings.ErrorSaveMIDIBatch, i)); } } - FlexibleMessageBox.Show(Strings.SuccessSaveMIDIBatch, Text); + FlexibleMessageBox.Show(string.Format(Strings.SuccessSaveMIDIBatch, d.FileName), Text); long oldIndex = (long)_songNumerical.Value; try { From 997a4f734d4c4740ec29847d31ac6cc79a07cb56 Mon Sep 17 00:00:00 2001 From: laqieer Date: Thu, 28 Apr 2022 22:33:58 +0800 Subject: [PATCH 04/10] add hacks to assist in gba midi extraction --- VG Music Studio/Core/GBA/MP2K/Player.cs | 66 ++++++++++++++++++++++--- VG Music Studio/Core/GBA/MP2K/Track.cs | 1 + 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/VG Music Studio/Core/GBA/MP2K/Player.cs b/VG Music Studio/Core/GBA/MP2K/Player.cs index e00bd21a..4052a8e1 100644 --- a/VG Music Studio/Core/GBA/MP2K/Player.cs +++ b/VG Music Studio/Core/GBA/MP2K/Player.cs @@ -86,7 +86,11 @@ private void SetTicks() SongEvent e = evs.Single(ev => ev.Offset == track.DataOffset); if (track.CallStackDepth == 0 && e.Ticks.Count > 0) { - break; + // HACK: this check ensure that we can't get into an infinite jump + // loop. We now ensure we can't jump backwards, so we don't need + // this break anymore, but there may be some things we could improve on here + + // break; } else { @@ -121,6 +125,7 @@ public void LoadSong(long index) } _tracks = null; } + Events = null; SongEntry entry = _config.Reader.ReadObject(_config.SongTableOffsets[0] + (index * 8)); SongHeader header = _config.Reader.ReadObject(entry.HeaderOffset - GBA.Utils.CartridgeOffset); @@ -256,6 +261,8 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) { if (!EventExists(offset)) { + Debug.WriteLine(trackIndex.ToString()); + Debug.WriteLine("Loaded first voice command"); AddEvent(new VoiceCommand { Voice = cmd }); } break; @@ -264,6 +271,9 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) { if (!EventExists(offset)) { + Debug.WriteLine(trackIndex.ToString()); + Debug.WriteLine("Loaded first volume command"); + AddEvent(new VolumeCommand { Volume = cmd }); } break; @@ -378,7 +388,10 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) AddEvents(jumpOffset); } } - cont = false; + // HACK: It was previously assumed that a jump means there is no reasons to continue + // however there is some midis in GBA games which have instructions after the jump + // so don't breakout so we can continue to read those + // cont = false; break; } case 0xB3: @@ -458,7 +471,9 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) sbyte transpose = _config.Reader.ReadSByte(); if (!EventExists(offset)) { - AddEvent(new TransposeCommand { Transpose = transpose }); + Debug.WriteLine(trackIndex.ToString()); + Debug.WriteLine("Loaded transpose command"); + AddEvent(new TransposeCommand { Transpose = transpose }); } break; } @@ -468,7 +483,9 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) byte voice = _config.Reader.ReadByte(); if (!EventExists(offset)) { - AddEvent(new VoiceCommand { Voice = voice }); + Debug.WriteLine(trackIndex.ToString()); + Debug.WriteLine("Loaded second voice command"); + AddEvent(new VoiceCommand { Voice = voice }); } break; } @@ -477,7 +494,9 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) byte volume = _config.Reader.ReadByte(); if (!EventExists(offset)) { - AddEvent(new VolumeCommand { Volume = volume }); + Debug.WriteLine(trackIndex.ToString()); + Debug.WriteLine("Loaded second volume command"); + AddEvent(new VolumeCommand { Volume = volume }); } break; } @@ -675,6 +694,7 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args) long startOfPatternTicks = 0, endOfPatternTicks = 0; sbyte transpose = 0; var playing = new List(); + for (int i = 0; i < Events[trackIndex].Count; i++) { SongEvent e = Events[trackIndex][i]; @@ -837,21 +857,38 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args) } case TransposeCommand keysh: { - transpose = keysh.Transpose; + Debug.WriteLine("Some transpose command"); + Debug.WriteLine(ticks); + transpose = keysh.Transpose; break; } case TuneCommand tune: { - track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, trackIndex, 24, tune.Tune)); + if (trackIndex == 8) + { + Debug.WriteLine("Write tune command"); + Debug.WriteLine(ticks); + } + track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, trackIndex, 24, tune.Tune)); break; } case VoiceCommand voice: { + if (trackIndex == 8) + { + Debug.WriteLine("Write voice command"); + Debug.WriteLine(ticks); + } track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, trackIndex, voice.Voice)); break; } case VolumeCommand vol: { + if (trackIndex == 8) + { + Debug.WriteLine("Write volume command"); + Debug.WriteLine(ticks); + } double d = baseVolume / (double)0x7F; int volume = (int)(vol.Volume / d); // If there are rounding errors, fix them (happens if baseVolume is not 127 and baseVolume is not vol.Volume) @@ -1257,7 +1294,20 @@ private void ExecuteNext(Track track, ref bool update) } case 0xB2: { - track.DataOffset = (_config.ROM[track.DataOffset++] | (_config.ROM[track.DataOffset++] << 8) | (_config.ROM[track.DataOffset++] << 16) | (_config.ROM[track.DataOffset++] << 24)) - GBA.Utils.CartridgeOffset; + int jumpOffset = (_config.ROM[track.DataOffset++] | (_config.ROM[track.DataOffset++] << 8) | (_config.ROM[track.DataOffset++] << 16) | (_config.ROM[track.DataOffset++] << 24)) - GBA.Utils.CartridgeOffset; + // HACK: only do jumps if we are jumping forwards + // means we can't get into an infinite jump routine + if (jumpOffset > track.DataOffset) { + track.LastJumped = jumpOffset; + track.DataOffset = jumpOffset; + } + // HACK TODO: potentially use the Last Jumped value to allow us to jump backwards + // but ensure that we don't end up in an infinite loop + if (jumpOffset != track.LastJumped) + { + //track.LastJumped = jumpOffset; + //track.DataOffset = jumpOffset; + } break; } case 0xB3: diff --git a/VG Music Studio/Core/GBA/MP2K/Track.cs b/VG Music Studio/Core/GBA/MP2K/Track.cs index 1288008a..70eac55e 100644 --- a/VG Music Studio/Core/GBA/MP2K/Track.cs +++ b/VG Music Studio/Core/GBA/MP2K/Track.cs @@ -25,6 +25,7 @@ internal class Track public bool Stopped; public int DataOffset; public int[] CallStack = new int[3]; + public int LastJumped; public byte CallStackDepth; public byte RunCmd; public byte PrevKey; From 41323d6f21d5b433f62e44d34bbb3ece74bd9577 Mon Sep 17 00:00:00 2001 From: laqieer Date: Sun, 1 May 2022 01:24:33 +0800 Subject: [PATCH 05/10] [MP2k] Reverse volume when batch saving to Midi --- VG Music Studio/UI/MainForm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VG Music Studio/UI/MainForm.cs b/VG Music Studio/UI/MainForm.cs index 92a19959..bd7d9a62 100644 --- a/VG Music Studio/UI/MainForm.cs +++ b/VG Music Studio/UI/MainForm.cs @@ -525,7 +525,7 @@ private void ExportMIDIBatch(object sender, EventArgs e) var args = new Core.GBA.MP2K.Player.MIDISaveArgs { SaveCommandsBeforeTranspose = true, - ReverseVolume = false, + ReverseVolume = true, TimeSignatures = new List<(int AbsoluteTick, (byte Numerator, byte Denominator))> { (0, (4, 4)) From 5a85cda7b5896639f38691b2ea7e52046e8daddc Mon Sep 17 00:00:00 2001 From: laqieer Date: Tue, 3 May 2022 02:20:40 +0800 Subject: [PATCH 06/10] [MP2K] Fix tune in saved MIDI --- VG Music Studio/Core/GBA/MP2K/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VG Music Studio/Core/GBA/MP2K/Player.cs b/VG Music Studio/Core/GBA/MP2K/Player.cs index 4052a8e1..1a7332c7 100644 --- a/VG Music Studio/Core/GBA/MP2K/Player.cs +++ b/VG Music Studio/Core/GBA/MP2K/Player.cs @@ -869,7 +869,7 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args) Debug.WriteLine("Write tune command"); Debug.WriteLine(ticks); } - track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, trackIndex, 24, tune.Tune)); + track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, trackIndex, 24, tune.Tune + 0x40)); break; } case VoiceCommand voice: From c9a7473640048227e7bc5d3865d457f9da80d5e8 Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 4 May 2022 18:23:25 +0800 Subject: [PATCH 07/10] remove useless debug lines --- VG Music Studio/Core/GBA/MP2K/Player.cs | 33 ++++--------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/VG Music Studio/Core/GBA/MP2K/Player.cs b/VG Music Studio/Core/GBA/MP2K/Player.cs index 1a7332c7..3eb65a48 100644 --- a/VG Music Studio/Core/GBA/MP2K/Player.cs +++ b/VG Music Studio/Core/GBA/MP2K/Player.cs @@ -261,8 +261,6 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) { if (!EventExists(offset)) { - Debug.WriteLine(trackIndex.ToString()); - Debug.WriteLine("Loaded first voice command"); AddEvent(new VoiceCommand { Voice = cmd }); } break; @@ -271,9 +269,6 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) { if (!EventExists(offset)) { - Debug.WriteLine(trackIndex.ToString()); - Debug.WriteLine("Loaded first volume command"); - AddEvent(new VolumeCommand { Volume = cmd }); } break; @@ -471,9 +466,7 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) sbyte transpose = _config.Reader.ReadSByte(); if (!EventExists(offset)) { - Debug.WriteLine(trackIndex.ToString()); - Debug.WriteLine("Loaded transpose command"); - AddEvent(new TransposeCommand { Transpose = transpose }); + AddEvent(new TransposeCommand { Transpose = transpose }); } break; } @@ -483,9 +476,7 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) byte voice = _config.Reader.ReadByte(); if (!EventExists(offset)) { - Debug.WriteLine(trackIndex.ToString()); - Debug.WriteLine("Loaded second voice command"); - AddEvent(new VoiceCommand { Voice = voice }); + AddEvent(new VoiceCommand { Voice = voice }); } break; } @@ -494,9 +485,7 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) byte volume = _config.Reader.ReadByte(); if (!EventExists(offset)) { - Debug.WriteLine(trackIndex.ToString()); - Debug.WriteLine("Loaded second volume command"); - AddEvent(new VolumeCommand { Volume = volume }); + AddEvent(new VolumeCommand { Volume = volume }); } break; } @@ -857,28 +846,16 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args) } case TransposeCommand keysh: { - Debug.WriteLine("Some transpose command"); - Debug.WriteLine(ticks); - transpose = keysh.Transpose; + transpose = keysh.Transpose; break; } case TuneCommand tune: { - if (trackIndex == 8) - { - Debug.WriteLine("Write tune command"); - Debug.WriteLine(ticks); - } - track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, trackIndex, 24, tune.Tune + 0x40)); + track.Insert(ticks, new ChannelMessage(ChannelCommand.Controller, trackIndex, 24, tune.Tune + 0x40)); break; } case VoiceCommand voice: { - if (trackIndex == 8) - { - Debug.WriteLine("Write voice command"); - Debug.WriteLine(ticks); - } track.Insert(ticks, new ChannelMessage(ChannelCommand.ProgramChange, trackIndex, voice.Voice)); break; } From bc6f289ac8e815853bc957121e30b02261b30659 Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 4 May 2022 18:33:04 +0800 Subject: [PATCH 08/10] remove jump forward only logic which only works for some games without complex jump routines --- VG Music Studio/Core/GBA/MP2K/Player.cs | 17 ++--------------- VG Music Studio/Core/GBA/MP2K/Track.cs | 1 - 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/VG Music Studio/Core/GBA/MP2K/Player.cs b/VG Music Studio/Core/GBA/MP2K/Player.cs index 3eb65a48..241b374c 100644 --- a/VG Music Studio/Core/GBA/MP2K/Player.cs +++ b/VG Music Studio/Core/GBA/MP2K/Player.cs @@ -1271,21 +1271,8 @@ private void ExecuteNext(Track track, ref bool update) } case 0xB2: { - int jumpOffset = (_config.ROM[track.DataOffset++] | (_config.ROM[track.DataOffset++] << 8) | (_config.ROM[track.DataOffset++] << 16) | (_config.ROM[track.DataOffset++] << 24)) - GBA.Utils.CartridgeOffset; - // HACK: only do jumps if we are jumping forwards - // means we can't get into an infinite jump routine - if (jumpOffset > track.DataOffset) { - track.LastJumped = jumpOffset; - track.DataOffset = jumpOffset; - } - // HACK TODO: potentially use the Last Jumped value to allow us to jump backwards - // but ensure that we don't end up in an infinite loop - if (jumpOffset != track.LastJumped) - { - //track.LastJumped = jumpOffset; - //track.DataOffset = jumpOffset; - } - break; + track.DataOffset = (_config.ROM[track.DataOffset++] | (_config.ROM[track.DataOffset++] << 8) | (_config.ROM[track.DataOffset++] << 16) | (_config.ROM[track.DataOffset++] << 24)) - GBA.Utils.CartridgeOffset; + break; } case 0xB3: { diff --git a/VG Music Studio/Core/GBA/MP2K/Track.cs b/VG Music Studio/Core/GBA/MP2K/Track.cs index 70eac55e..1288008a 100644 --- a/VG Music Studio/Core/GBA/MP2K/Track.cs +++ b/VG Music Studio/Core/GBA/MP2K/Track.cs @@ -25,7 +25,6 @@ internal class Track public bool Stopped; public int DataOffset; public int[] CallStack = new int[3]; - public int LastJumped; public byte CallStackDepth; public byte RunCmd; public byte PrevKey; From af8a81736310ff2f7fc2e50afbe8d819c06a999c Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 4 May 2022 18:43:47 +0800 Subject: [PATCH 09/10] fix misses and format --- VG Music Studio/Core/GBA/MP2K/Player.cs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/VG Music Studio/Core/GBA/MP2K/Player.cs b/VG Music Studio/Core/GBA/MP2K/Player.cs index 241b374c..56921e22 100644 --- a/VG Music Studio/Core/GBA/MP2K/Player.cs +++ b/VG Music Studio/Core/GBA/MP2K/Player.cs @@ -86,11 +86,7 @@ private void SetTicks() SongEvent e = evs.Single(ev => ev.Offset == track.DataOffset); if (track.CallStackDepth == 0 && e.Ticks.Count > 0) { - // HACK: this check ensure that we can't get into an infinite jump - // loop. We now ensure we can't jump backwards, so we don't need - // this break anymore, but there may be some things we could improve on here - - // break; + break; } else { @@ -125,7 +121,6 @@ public void LoadSong(long index) } _tracks = null; } - Events = null; SongEntry entry = _config.Reader.ReadObject(_config.SongTableOffsets[0] + (index * 8)); SongHeader header = _config.Reader.ReadObject(entry.HeaderOffset - GBA.Utils.CartridgeOffset); @@ -683,7 +678,6 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args) long startOfPatternTicks = 0, endOfPatternTicks = 0; sbyte transpose = 0; var playing = new List(); - for (int i = 0; i < Events[trackIndex].Count; i++) { SongEvent e = Events[trackIndex][i]; @@ -861,11 +855,6 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args) } case VolumeCommand vol: { - if (trackIndex == 8) - { - Debug.WriteLine("Write volume command"); - Debug.WriteLine(ticks); - } double d = baseVolume / (double)0x7F; int volume = (int)(vol.Volume / d); // If there are rounding errors, fix them (happens if baseVolume is not 127 and baseVolume is not vol.Volume) @@ -1271,8 +1260,8 @@ private void ExecuteNext(Track track, ref bool update) } case 0xB2: { - track.DataOffset = (_config.ROM[track.DataOffset++] | (_config.ROM[track.DataOffset++] << 8) | (_config.ROM[track.DataOffset++] << 16) | (_config.ROM[track.DataOffset++] << 24)) - GBA.Utils.CartridgeOffset; - break; + track.DataOffset = (_config.ROM[track.DataOffset++] | (_config.ROM[track.DataOffset++] << 8) | (_config.ROM[track.DataOffset++] << 16) | (_config.ROM[track.DataOffset++] << 24)) - GBA.Utils.CartridgeOffset; + break; } case 0xB3: { From 71249717eeb1f0fdadf7443f5e63145dcece3586 Mon Sep 17 00:00:00 2001 From: laqieer Date: Wed, 4 May 2022 18:47:37 +0800 Subject: [PATCH 10/10] skip intructions after jump command --- VG Music Studio/Core/GBA/MP2K/Player.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/VG Music Studio/Core/GBA/MP2K/Player.cs b/VG Music Studio/Core/GBA/MP2K/Player.cs index 56921e22..b0708425 100644 --- a/VG Music Studio/Core/GBA/MP2K/Player.cs +++ b/VG Music Studio/Core/GBA/MP2K/Player.cs @@ -378,10 +378,7 @@ void EmulateNote(byte key, byte velocity, byte addedDuration) AddEvents(jumpOffset); } } - // HACK: It was previously assumed that a jump means there is no reasons to continue - // however there is some midis in GBA games which have instructions after the jump - // so don't breakout so we can continue to read those - // cont = false; + cont = false; break; } case 0xB3: