@@ -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 ) ) ;
0 commit comments