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
24 changes: 19 additions & 5 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 @@ -378,7 +383,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 @@ -675,6 +683,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 @@ -842,7 +851,7 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args)
}
case TuneCommand tune:
{
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:
Expand All @@ -852,6 +861,11 @@ public void SaveAsMIDI(string fileName, MIDISaveArgs args)
}
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,8 +1271,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:
{
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