예제 #1
0
        internal static void PrintOffAndName(string file)
        {
            var bytes = File.ReadAllBytes(file);
            var rc    = LSOFile.LSOFactory(bytes);
            var list  = new List <int>()
            {
                0x16, 0x1A, 0x1E, 0x22, 0x2E, 0x34, 0x7A, 0x11A, 0x134, 0x1D9, 0x1EC, 0x1FA, 0x19C
            };

            list.AddRange(Enumerable.Range(0x800, 0xB74).Where(x => x % 4 == 0).ToList());

            //for (int i = 0xC; i < 0xB74; i += 4)
            foreach (int i in list)
            {
                var off = rc.getRealOffset(i);

                if ((uint)off > bytes.Length)
                {
                    Console.WriteLine($"Offset: {i:X4} ({off:X4})");
                    continue;
                }

                var size = bytes[off];
                var name = Encoding.ASCII.GetString(bytes.Skip(off + 0x65).TakeWhile(b => !b.Equals(0)).ToArray());
                name = String.IsNullOrEmpty(name) ? Encoding.ASCII.GetString(bytes.Skip(off + 0x2D).TakeWhile(b => !b.Equals(0)).ToArray())
                    : name;

                Console.WriteLine($"Offset: {i:X4} ({off:X4}), Size: {size:X4}, Name: {name}");
            }
        }
예제 #2
0
        public static void ParseTracks(string f, string outFile)
        {
            var lso = LSOFile.LSOFactory(f);

            lso.ParseFile();
            MIDIFile mf = new MIDIFile(lso.BPM);


            foreach (var tempo in lso.GlobalTempo)
            {
                mf.TrackChunks[0].MTrkEvents.Add(new MTrkEvent((uint)(tempo.Timing / 2))
                {
                    Event = new SetTempoMetaEvent((double)((double)tempo.Tempo / (double)10000))
                });
            }

            foreach (var channel in lso.Channels)
            {
                var tracksInChannel = channel.Value.OrderBy(x => x.TrackPosition).ToList();

                foreach (var track in tracksInChannel)
                {
                    var Sequencer = new List <Sequence>();

                    MIDITrackChunk midiTrack = null;

                    midiTrack = new MIDITrackChunk(track.Channel, track.TrackName);
                    midiTrack.MTrkEvents.Add(new MTrkEvent(0)
                    {
                        Event = new ProgramChangeEvent(track.Channel, track.InitialInstrument)
                    });
                    int lastTime = 0;

                    // Check for track loop and duplicate until next track
                    if (track.IsLoopTrack && track.MIDIEvents.Count() > 0)
                    {
                        var trackIndex     = tracksInChannel.IndexOf(track);
                        var isTrackLastOne = trackIndex == tracksInChannel.Count() - 1;

                        var stopLoopPosition = isTrackLastOne ? lso.SongLength : tracksInChannel[trackIndex + 1].TrackPosition;

                        // replicate track data until stop

                        var currentEvents    = track.MIDIEvents.ToList();
                        var currentTime      = track.TrackLength;
                        var currentMIDIEvent = currentEvents.First();

                        var totalMidiInCurrentEvents = currentEvents.Count() - 1;
                        var multiplier = 1;

                        for (int midiEventIndex = 0; currentTime < stopLoopPosition; midiEventIndex++)
                        {
                            currentMIDIEvent = currentEvents[midiEventIndex].Clone();
                            var eventNewTime = currentMIDIEvent.Position + (track.TrackLength * multiplier);

                            if (eventNewTime >= stopLoopPosition)
                            {
                                break;
                            }

                            currentMIDIEvent.Position = eventNewTime;
                            track.MIDIEvents.Add(currentMIDIEvent);

                            if (midiEventIndex == totalMidiInCurrentEvents)
                            {
                                multiplier++;
                                midiEventIndex = -1;
                            }

                            currentTime = eventNewTime;
                        }
                    }

                    foreach (var lme in track.MIDIEvents)
                    {
                        var del = track.TrackPosition + lme.Position;

                        if (lme.MIDIFirstByte == 0xB0)
                        {
                            // Instrument Change
                            Sequencer.Add(new Sequence()
                            {
                                eType   = EvType.ControllerEvent,
                                MLE     = lme,
                                Time    = del,
                                Channel = (byte)track.Channel,
                                Note    = lme.MIDISecondByte
                            });
                            continue;
                        }

                        if (lme.MIDIFirstByte == 0xC0)
                        {
                            // Instrument Change
                            Sequencer.Add(new Sequence()
                            {
                                eType   = EvType.ProgramChangeEvent,
                                MLE     = lme,
                                Time    = del,
                                Channel = (byte)track.Channel,
                                Note    = lme.MIDIThirdByte
                            });
                            continue;
                        }

                        if (lme.MIDIFirstByte == 0xE0)
                        {
                            // Pitch Bend
                            Sequencer.Add(new Sequence()
                            {
                                eType     = EvType.PitchBend,
                                MLE       = lme,
                                Time      = del,
                                Channel   = (byte)track.Channel,
                                Note      = lme.MIDISecondByte,
                                ThirdByte = lme.MIDIThirdByte
                            });
                            continue;
                        }

                        // Note On
                        Sequencer.Add(new Sequence()
                        {
                            eType   = EvType.NoteOn,
                            MLE     = lme,
                            Time    = del,
                            Channel = (byte)track.Channel,
                            Note    = lme.MIDISecondByte
                        });

                        // Note Off
                        Sequencer.Add(new Sequence()
                        {
                            eType   = EvType.NoteOff,
                            MLE     = lme,
                            Time    = del + lme.MIDILength,
                            Channel = (byte)track.Channel,
                            Note    = lme.MIDISecondByte
                        });
                    }

                    Sequencer = Sequencer.OrderBy(x => x.Time).ToList();

                    // Add MIDI Events
                    foreach (var seq in Sequencer)
                    {
                        var delta = ((uint)(seq.Time - lastTime)) / 2;

                        MTrkEvent midiMtrkEvent = null;

                        switch (seq.eType)
                        {
                        case EvType.NoteOn:
                            midiMtrkEvent       = new MTrkEvent(delta);
                            midiMtrkEvent.Event = new MIDIEventNoteOn(seq.Channel, seq.MLE.MIDISecondByte, seq.MLE.MIDIThirdByte);
                            midiTrack.MTrkEvents.Add(midiMtrkEvent);
                            break;

                        case EvType.NoteOff:
                            midiMtrkEvent       = new MTrkEvent(delta);
                            midiMtrkEvent.Event = new MIDIEventNoteOn(seq.Channel, seq.MLE.MIDISecondByte, 0);
                            midiTrack.MTrkEvents.Add(midiMtrkEvent);
                            break;

                        case EvType.ProgramChangeEvent:
                            midiMtrkEvent       = new MTrkEvent(delta);
                            midiMtrkEvent.Event = new ProgramChangeEvent(seq.Channel, seq.MLE.MIDIThirdByte);
                            midiTrack.MTrkEvents.Add(midiMtrkEvent);
                            break;

                        case EvType.PitchBend:
                            midiMtrkEvent       = new MTrkEvent(delta);
                            midiMtrkEvent.Event = new PitchBendEvent(seq.Channel, seq.MLE.MIDIFirstByte, seq.MLE.MIDIThirdByte);
                            midiTrack.MTrkEvents.Add(midiMtrkEvent);
                            break;

                        case EvType.ControllerEvent:
                            midiMtrkEvent       = new MTrkEvent(delta);
                            midiMtrkEvent.Event = new ControllerEvent(seq.Channel, seq.MLE.MIDISecondByte, seq.MLE.MIDIThirdByte);
                            midiTrack.MTrkEvents.Add(midiMtrkEvent);
                            break;
                        }

                        lastTime = seq.Time;
                    }
                    mf.TrackChunks.Add(midiTrack);
                }
            }

            var midiFile = mf.ToBytes();

            File.WriteAllBytes(outFile, midiFile);
        }