Skip to content

Commit 40ee0a2

Browse files
committed
More fixes, improve training, add new neural config
1 parent c00f2a8 commit 40ee0a2

File tree

14 files changed

+2995
-2771
lines changed

14 files changed

+2995
-2771
lines changed

LuteBot/Core/Midi/MidiPlayer.cs

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ public class MidiPlayer
3535
public MidiPlayer(TrackSelectionManager trackSelectionManager)
3636
{
3737
trackSelectionManager.Player = this;
38-
38+
3939
this.trackSelectionManager = trackSelectionManager;
40-
40+
4141
}
4242

4343
public Dictionary<int, MidiChannelItem> GetMidiChannels()
@@ -239,6 +239,7 @@ public async Task LoadFileAsync(string filename)
239239
var prog = (int)dryNote.Channel;
240240
if (programNumbers.TryGetValue(dryNote.Channel, out var pn))
241241
prog = pn.ProgramNumber;
242+
channel.midiInstrument = prog;
242243

243244
var absoluteTicks = (int)dryNote.TimeAs<MidiTimeSpan>(tempoMap).TimeSpan;
244245

@@ -262,15 +263,15 @@ public async Task LoadFileAsync(string filename)
262263
channels[dryNote.Channel].tickNotes[absoluteTicks].Add(note);
263264
tracks[trackNum].tickNotes[absoluteTicks].Add(note);
264265

265-
channel.totalNoteLength += note.timeLength;
266+
266267
if (dryNote.NoteNumber < channel.lowestNote)
267268
channel.lowestNote = dryNote.NoteNumber;
268269
if (dryNote.NoteNumber > channel.highestNote)
269270
channel.highestNote = dryNote.NoteNumber;
270271
channel.averageNote += dryNote.NoteNumber;
271272
channel.numNotes++;
272273

273-
track.totalNoteLength += note.timeLength;
274+
274275
if (dryNote.NoteNumber < track.lowestNote)
275276
track.lowestNote = dryNote.NoteNumber;
276277
if (dryNote.NoteNumber > track.highestNote)
@@ -297,24 +298,50 @@ public async Task LoadFileAsync(string filename)
297298

298299
trackNum++;
299300
}
300-
301+
var totalNumNotes = channels.Values.Sum(c => c.numNotes);
301302
foreach (var channel in channels.Values)
302303
{
303304
if (channel.numNotes > 0)
304305
{
305-
channel.avgNoteLength = channel.totalNoteLength / channel.numNotes;
306-
channel.averageNote = (int)((float)channel.averageNote / channel.numNotes);
307-
// avg Variation: iterate notes, find difference to last note, add up and divide
306+
// Total note length... Can't just sum durations
307+
TimeSpan lastTime = TimeSpan.Zero;
308+
TimeSpan lastDuration = TimeSpan.Zero;
308309
int lastNote = -1;
309310
int totalVariation = 0;
310-
foreach (var noteList in channel.tickNotes.Values)
311-
foreach (var note in noteList)
311+
foreach (var tickNote in channel.tickNotes)
312+
{
313+
if (tickNote.Value.Any())
312314
{
313-
if (lastNote > -1)
314-
totalVariation += Math.Abs(note.note - lastNote);
315-
lastNote = note.note;
315+
var tickDuration = TimeSpan.FromSeconds(tickNote.Value.Max(n => n.timeLength));
316+
var noteStartTime = tickNote.Value.First().startTime;
317+
if (noteStartTime > lastTime + lastDuration)
318+
{
319+
channel.totalNoteLength += (float)tickDuration.TotalSeconds;
320+
}
321+
else if (noteStartTime + tickDuration > lastTime + lastDuration)
322+
{
323+
channel.totalNoteLength += (float)((noteStartTime + tickDuration) - (lastTime + lastDuration)).TotalSeconds;
324+
}
325+
lastTime = noteStartTime;
326+
lastDuration = tickDuration;
327+
// avg Variation: iterate notes, find difference to last note, add up and divide
328+
foreach (var note in tickNote.Value)
329+
{
330+
if (lastNote > -1)
331+
totalVariation += Math.Abs(note.note - lastNote);
332+
lastNote = note.note;
333+
}
316334
}
335+
}
336+
337+
channel.avgNoteLength = channel.totalNoteLength / channel.numNotes;
338+
channel.averageNote = (int)((float)channel.averageNote / channel.numNotes);
317339
channel.avgVariation = totalVariation / channel.numNotes;
340+
if (currentTimeLength.TotalSeconds > 0)
341+
channel.percentTimePlaying = (float)(channel.totalNoteLength / currentTimeLength.TotalSeconds);
342+
else
343+
channel.percentTimePlaying = 0;
344+
channel.percentSongNotes = channel.numNotes / (float)totalNumNotes;
318345
}
319346
}
320347

@@ -443,7 +470,7 @@ public string GetChannelName(int id)
443470
{
444471
chunkNumber++; return t.GetNotes(new NoteDetectionSettings { NoteSearchContext = NoteSearchContext.AllEventsCollections, NoteStartDetectionPolicy = NoteStartDetectionPolicy.LastNoteOn }).Where(n => (!trackSelectionManager.MidiTracks.ContainsKey(chunkNumber) || trackSelectionManager.MidiTracks[chunkNumber].Active) && (!trackId.HasValue || trackId.Value == chunkNumber)
445472
&& (!trackSelectionManager.MidiChannels.ContainsKey(n.Channel) || trackSelectionManager.MidiChannels[n.Channel].Active) && n.Velocity > 0 && n.Channel != 9)
446-
.Select(n => new LuteMod.Sequencing.Note() { duration = Math.Min((float)n.LengthAs<MetricTimeSpan>(tempoMap).TotalSeconds - (0.0171f*2), 1), Tick = n.Time, Tone = n.NoteNumber + trackSelectionManager.MidiChannels[n.Channel].offset + trackSelectionManager.NoteOffset, Type = LuteMod.Sequencing.NoteType.On });
473+
.Select(n => new LuteMod.Sequencing.Note() { duration = Math.Min((float)n.LengthAs<MetricTimeSpan>(tempoMap).TotalSeconds - (0.0171f * 2), 1), Tick = n.Time, Tone = n.NoteNumber + trackSelectionManager.MidiChannels[n.Channel].offset + trackSelectionManager.NoteOffset, Type = LuteMod.Sequencing.NoteType.On });
447474
}).ToList();
448475
// Always add the tempo at 0 time
449476
var startTempo = tempoMap.GetTempoAtTime(new MetricTimeSpan(0));

LuteBot/Extensions.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static bool IsEmptyLocate(byte[] array, byte[] candidate)
6363
|| candidate.Length > array.Length;
6464
}
6565

66-
public static int numParamsPerChannel = 8;
66+
public static int numParamsPerChannel = 10;
6767

6868
public static float[][] GetRecurrentInput(this MidiChannelItem channel, int noteParams, float maxTickNumber)
6969
{
@@ -129,7 +129,7 @@ public static float[] GetNeuralInput(this MidiChannelItem[] song)
129129
}
130130

131131

132-
public static float[] GetNeuralInputs(this MidiChannelItem c, float maxAvgNoteLength, float maxNumNotes, float maxTotalNoteLength)
132+
public static float[] GetNeuralInputs(this MidiChannelItem c)
133133
{
134134
// We'll try not normalizing
135135

@@ -141,18 +141,20 @@ public static float[] GetNeuralInputs(this MidiChannelItem c, float maxAvgNoteLe
141141

142142
//inputs[j * 6] = (maxAvgNoteLength > 0 ? channel.avgNoteLength / maxAvgNoteLength : 0);
143143
int i = 0;
144-
inputs[i++] = (maxAvgNoteLength > 0 ? channel.avgNoteLength / maxAvgNoteLength : 0);
144+
inputs[i++] = channel.avgNoteLength;
145145
inputs[i++] = channel.maxChordSize;
146-
inputs[i++] = (maxTotalNoteLength > 0 ? channel.totalNoteLength / maxTotalNoteLength : 0);
146+
inputs[i++] = channel.percentTimePlaying;
147147
//inputi++lNoteLength;
148148
inputs[i++] = channel.highestNote / 128f;
149149
inputs[i++] = channel.lowestNote / 128f;
150-
inputs[i++] = (maxNumNotes > 0 ? channel.numNotes / maxNumNotes : 0);
151-
//inputi++ 6] = channel.Id / 16f;
150+
151+
inputs[i++] = channel.percentSongNotes;
152+
152153
inputs[i++] = channel.midiInstrument / 128f;
153-
inputs[i++] = channel.avgVariation;
154+
inputs[i++] = channel.avgVariation / 64f; // Doubt this ever gets above 64, which this handles
154155
//inputs[j * 6 + 5] = channel.numNotes;
155-
156+
inputs[i++] = channel.averageNote / 128f;
157+
inputs[i++] = channel.Id / 16f;
156158

157159
return inputs;
158160
}

LuteBot/IO/Files/SaveManager.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,9 @@ public static SoundBoard LoadLastSoundBoard(string path)
288288
return LoadNoDialog<SoundBoard>(path);
289289
}
290290

291-
public static void SaveTrackSelectionData(Dictionary<int, SimpleTrackSelectionData> data, string fileName, string targetPath = null)
291+
public static async Task SaveTrackSelectionData(Dictionary<int, SimpleTrackSelectionData> data, string fileName, string targetPath = null)
292292
{
293-
SaveNoDialog(data, fileName, targetPath);
293+
await SaveNoDialog(data, fileName, targetPath).ConfigureAwait(false);
294294
}
295295

296296
public static Dictionary<int, SimpleTrackSelectionData> LoadTrackSelectionData(string fileName)
@@ -483,7 +483,7 @@ private static T LoadNoDialog<T>(string path)
483483
return result;
484484
}
485485

486-
private static void SaveNoDialog<T>(T target, string path, string targetPath = null)
486+
private static async Task SaveNoDialog<T>(T target, string path, string targetPath = null)
487487
{
488488
if (targetPath == null)
489489
targetPath = path;
@@ -526,7 +526,12 @@ private static void SaveNoDialog<T>(T target, string path, string targetPath = n
526526

527527
midiDataBytes = midiDataBytes.Concat(Encoding.ASCII.GetBytes(json)).ToArray();
528528

529-
File.WriteAllBytes(targetPath, midiDataBytes);
529+
using (var fs = new FileStream(targetPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, true))
530+
using (var ms = new MemoryStream(midiDataBytes))
531+
{
532+
await ms.CopyToAsync(fs).ConfigureAwait(false);
533+
await fs.FlushAsync().ConfigureAwait(false);
534+
}
530535

531536
// First read in the existing data
532537
//byte[] midiData;

LuteBot/LuteBot.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@
304304
<None Include="app.config" />
305305
<None Include="app.manifest" />
306306
<None Include="channelNeural">
307-
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
307+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
308308
</None>
309309
<None Include="LuteMod\AutoLoaderWindowsClient.pak">
310310
<CopyToOutputDirectory>Always</CopyToOutputDirectory>

LuteBot/LuteMod/FLuteMod_2.61.pak

183 Bytes
Binary file not shown.

LuteBot/PartitionsForm.cs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ private async Task<bool> SavePartition(string name, bool overwrite = false)
443443
{
444444
try
445445
{
446+
string midiFileName = null;
446447
await LuteBotForm.luteBotForm.InvokeAsync(() =>
447448
{
448449

@@ -581,17 +582,18 @@ await LuteBotForm.luteBotForm.InvokeAsync(() =>
581582
// Lastly, save the settings in a midi file with the same name, in the same folder, for ease of sharing...
582583
// TODO: Consider storing these in appdata, and providing a button to access them. Both might get complicated if I make partition playlists
583584
// Actually... I think I will store them in appdata.
584-
var midFileName = Path.Combine(partitionMidiPath, name + ".mid");
585-
Directory.CreateDirectory(partitionMidiPath);
586-
Task.Run(() => tsm.SaveTrackManager(midFileName)); // Lutebot doesn't need this anytime soon - and shouldn't offer the option to load it until it exists anyway
587-
585+
588586
//Invoke((MethodInvoker)delegate {
589587
PopulateIndexList();
590588
//});
591589
}
592590
}
593591
}
594592
}).ConfigureAwait(false);
593+
midiFileName = Path.Combine(partitionMidiPath, name + ".mid");
594+
Directory.CreateDirectory(partitionMidiPath);
595+
await tsm.SaveTrackManager(midiFileName).ConfigureAwait(false); // Lutebot doesn't need this anytime soon - and shouldn't offer the option to load it until it exists anyway
596+
595597
}
596598
catch (Exception ex)
597599
{
@@ -643,7 +645,7 @@ public async void saveMultipleSongsToolStripMenuItem_Click(object sender, EventA
643645
foreach (var f in filenames.Reverse()) // So the first ones are first again
644646
{
645647
await LuteBotForm.luteBotForm.LoadFile(f, true).ConfigureAwait(false);
646-
await SavePartition(Regex.Replace(Path.GetFileName(f).Replace(".mid", ""), "[^a-zA-Z0-9]", "")).ConfigureAwait(false);
648+
await SavePartition(Regex.Replace(Path.GetFileName(f).Replace(".mid", ""), "[^a-zA-Z0-9 ]", "")).ConfigureAwait(false);
647649
}
648650
}
649651
}
@@ -753,17 +755,24 @@ private void ExportMidis(IEnumerable<string> partitionNames)
753755
});
754756
}
755757

758+
public async Task reloadAll(bool reorderTracks)
759+
{
760+
var filenames = listBoxPartitions.Items.Cast<string>().Reverse().ToArray();
761+
762+
await AutoSaveFiles(filenames, true, reorderTracks).ConfigureAwait(false);
763+
}
764+
756765
private async void reloadSelectedButton_Click(object sender, EventArgs e)
757766
{
758767
if (listBoxPartitions.SelectedItems.Count > 0)
759768
{
760-
var filenames = listBoxPartitions.SelectedItems.Cast<string>().Reverse();
769+
var filenames = listBoxPartitions.SelectedItems.Cast<string>().Reverse().ToArray();
761770

762-
await AutoSaveFiles(filenames).ConfigureAwait(false);
771+
await AutoSaveFiles(filenames, true).ConfigureAwait(false);
763772
}
764773
}
765774

766-
public async Task AutoSaveFiles(IEnumerable<string> filenames)
775+
public async Task AutoSaveFiles(IEnumerable<string> filenames, bool overwrite = false, bool reorderTracks = false)
767776
{
768777
string warnings = "";
769778
await LuteBotForm.luteBotForm.InvokeAsync(() =>
@@ -785,9 +794,9 @@ await LuteBotForm.luteBotForm.InvokeAsync(() =>
785794
}
786795
try
787796
{
788-
await LuteBotForm.luteBotForm.LoadFile(filePath, true).ConfigureAwait(false);
797+
await LuteBotForm.luteBotForm.LoadFile(filePath, true, reorderTracks).ConfigureAwait(false);
789798
if (player.dryWetFile != null)
790-
await SavePartition(Regex.Replace(Path.GetFileName(filePath).Replace(".mid", ""), "[^a-zA-Z0-9]", ""), false).ConfigureAwait(false);
799+
await SavePartition(Regex.Replace(Path.GetFileName(filePath).Replace(".mid", ""), "[^a-zA-Z0-9 ]", ""), overwrite).ConfigureAwait(false);
791800

792801
}
793802
catch (Exception ex)

LuteBot/TrackSelection/MidiChannelItem.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ public class MidiChannelItem
191191
public Dictionary<int, List<MidiNote>> tickNotes { get; internal set; } = new Dictionary<int, List<MidiNote>>(); // For setup and filtering, as well as disabling/enabling specific notes
192192
public int midiInstrument { get; set; }
193193
public float avgVariation { get; set; }
194+
public float percentTimePlaying { get; set; }
195+
public float percentSongNotes { get; set; }
194196

195197
public MidiChannelItem() { }
196198

0 commit comments

Comments
 (0)