Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MP2K] Add UI to batch export all songs as MIDI #98

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
66 changes: 58 additions & 8 deletions VG Music Studio/Core/GBA/MP2K/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
laqieer marked this conversation as resolved.
Show resolved Hide resolved
// 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
{
Expand Down Expand Up @@ -121,6 +125,7 @@ public void LoadSong(long index)
}
_tracks = null;
}

Events = null;
SongEntry entry = _config.Reader.ReadObject<SongEntry>(_config.SongTableOffsets[0] + (index * 8));
SongHeader header = _config.Reader.ReadObject<SongHeader>(entry.HeaderOffset - GBA.Utils.CartridgeOffset);
Expand Down Expand Up @@ -256,6 +261,8 @@ void EmulateNote(byte key, byte velocity, byte addedDuration)
{
if (!EventExists(offset))
{
Debug.WriteLine(trackIndex.ToString());
laqieer marked this conversation as resolved.
Show resolved Hide resolved
Debug.WriteLine("Loaded first voice command");
AddEvent(new VoiceCommand { Voice = cmd });
}
break;
Expand All @@ -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;
Expand Down Expand Up @@ -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
laqieer marked this conversation as resolved.
Show resolved Hide resolved
// 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:
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -675,6 +694,7 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args)
long startOfPatternTicks = 0, endOfPatternTicks = 0;
sbyte transpose = 0;
var playing = new List<NoteCommand>();

for (int i = 0; i < Events[trackIndex].Count; i++)
{
SongEvent e = Events[trackIndex][i];
Expand Down Expand Up @@ -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 + 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;
}
case VolumeCommand vol:
{
if (trackIndex == 8)
laqieer marked this conversation as resolved.
Show resolved Hide resolved
{
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)
Expand Down Expand Up @@ -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) {
laqieer marked this conversation as resolved.
Show resolved Hide resolved
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:
Expand Down
1 change: 1 addition & 0 deletions VG Music Studio/Core/GBA/MP2K/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
29 changes: 28 additions & 1 deletion VG Music Studio/Properties/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions VG Music Studio/Properties/Strings.es.resx
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,13 @@
<data name="SuccessSaveDLS" xml:space="preserve">
<value>DLS guardado en {0}.</value>
</data>
<data name="ErrorSaveMIDIBatch" xml:space="preserve">
<value>Error al Exportar MIDI {0}</value>
</data>
<data name="MenuSaveMIDIBatch" xml:space="preserve">
<value>Exportar todo Canción como MIDI</value>
</data>
<data name="SuccessSaveMIDIBatch" xml:space="preserve">
<value>MIDIs guardado en {0}.</value>
</data>
</root>
9 changes: 9 additions & 0 deletions VG Music Studio/Properties/Strings.it.resx
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,13 @@
<data name="SuccessSaveDLS" xml:space="preserve">
<value>VoiceTable salvata in {0}.</value>
</data>
<data name="ErrorSaveMIDIBatch" xml:space="preserve">
<value>Errore Durante L'Esportazione in MIDI {0}</value>
</data>
<data name="MenuSaveMIDIBatch" xml:space="preserve">
<value>Esporta tutto Brano in MIDI</value>
</data>
<data name="SuccessSaveMIDIBatch" xml:space="preserve">
<value>MIDIs salvato in {0}.</value>
</data>
</root>
11 changes: 11 additions & 0 deletions VG Music Studio/Properties/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,15 @@
<value>VoiceTable saved to {0}.</value>
<comment>{0} is the file name.</comment>
</data>
<data name="ErrorSaveMIDIBatch" xml:space="preserve">
<value>Error Exporting MIDI {0}</value>
<comment>{0} is the song number.</comment>
</data>
<data name="MenuSaveMIDIBatch" xml:space="preserve">
<value>Export All Songs as MIDI</value>
</data>
<data name="SuccessSaveMIDIBatch" xml:space="preserve">
<value>MIDIs saved to {0}.</value>
<comment>{0} is the folder name.</comment>
</data>
</root>
71 changes: 69 additions & 2 deletions VG Music Studio/UI/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 };
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -500,6 +507,66 @@ 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;
Stop();
var args = new Core.GBA.MP2K.Player.MIDISaveArgs
{
SaveCommandsBeforeTranspose = true,
ReverseVolume = true,
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(string.Format(Strings.SuccessSaveMIDIBatch, d.FileName), 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)
{
var d = new CommonSaveFileDialog
Expand Down