public override void SerializeImpl(SerializerObject s) { if (Rows == null) { List <GAX2_PatternRow> rows = new List <GAX2_PatternRow>(); bool isEndOfTrack = false; int curDuration = 0; while (!isEndOfTrack) { GAX2_PatternRow row = s.SerializeObject <GAX2_PatternRow>(default, name: $"{nameof(Rows)}[{rows.Count}]");
private Track CreateTrack(GAX2_Song song, int trackNum) { Track t = new Track(); TempoChangeBuilder b = new TempoChangeBuilder(); b.Tempo = 500000; b.Build(); t.Insert(0, b.Result); ChannelMessageBuilder builder = new ChannelMessageBuilder(); int?lastNoteOn = null; int currentTime = 0; int timeScale = 5; t.EndOfTrackOffset = (song.Patterns[trackNum].Length * song.NumRowsPerPattern) * timeScale; for (int trackPiece = 0; trackPiece < song.Patterns[trackNum].Length; trackPiece++) { GAX2_Pattern gaxTrack = song.Patterns[trackNum][trackPiece]; int baseTime = trackPiece * song.NumRowsPerPattern; currentTime = baseTime; for (int i = 0; i < gaxTrack.Rows.Length; i++) { GAX2_PatternRow cmd = gaxTrack.Rows[i]; switch (cmd.Command) { case GAX2_PatternRow.Cmd.Note: if (cmd.Instrument == 250) { continue; } if (exportSingleSoundfont) { if (song.InstrumentSet[cmd.Instrument]?.Value == null || song.InstrumentSet[cmd.Instrument].Value.Sample >= 128) { continue; } } else { if (song.InstrumentSet[cmd.Instrument]?.Value == null || Array.IndexOf(song.InstrumentIndices, cmd.Instrument) >= 128) { continue; } } // Note off if (lastNoteOn.HasValue) { builder.Command = ChannelCommand.NoteOff; builder.MidiChannel = 0; builder.Data1 = lastNoteOn.Value; builder.Data2 = 127; builder.Build(); t.Insert(currentTime * timeScale, builder.Result); lastNoteOn = null; } // Program change { int instrument = 0; if (exportSingleSoundfont) { instrument = song.InstrumentSet[cmd.Instrument].Value.Sample; } else { instrument = Array.IndexOf(song.InstrumentIndices, cmd.Instrument); } builder.MidiChannel = 0; builder.Command = ChannelCommand.ProgramChange; builder.Data1 = instrument; builder.Build(); t.Insert(currentTime * timeScale, builder.Result); } // Note on { builder.Command = ChannelCommand.NoteOn; int freq = cmd.Note; int vel = cmd.Velocity; builder.Data1 = freq; //GetMidiPitch(GetFrequency(freq)); float velf = (vel / 255f); // hack int veli = Mathf.RoundToInt(velf * 127f); builder.Data2 = veli; lastNoteOn = builder.Data1; builder.Build(); t.Insert(currentTime * timeScale, builder.Result); } break; } currentTime += cmd.Duration; } } if (lastNoteOn.HasValue) { builder.Command = ChannelCommand.NoteOff; builder.MidiChannel = 0; builder.Data1 = lastNoteOn.Value; builder.Data2 = 127; builder.Build(); t.Insert(currentTime * timeScale, builder.Result); lastNoteOn = null; } return(t); }