示例#1
0
        public Project Load(string filename, int songIndex, int duration, int patternLength, int startFrame, bool removeIntroSilence)
        {
            nsf = NsfOpen(filename);

            if (nsf == null)
            {
                return(null);
            }

            var palSource = (NsfIsPal(nsf) & 1) == 1;
            var numFrames = duration * (palSource ? 50 : 60);

            project = new Project();

            project.Name      = Marshal.PtrToStringAnsi(NsfGetTitle(nsf));
            project.Author    = Marshal.PtrToStringAnsi(NsfGetArtist(nsf));
            project.Copyright = Marshal.PtrToStringAnsi(NsfGetCopyright(nsf));
            project.PalMode   = palSource;

            switch (NsfGetExpansion(nsf))
            {
            case EXTSOUND_VRC6: project.SetExpansionAudio(Project.ExpansionVrc6); break;

            case EXTSOUND_VRC7: project.SetExpansionAudio(Project.ExpansionVrc7); break;

            case EXTSOUND_FDS:  project.SetExpansionAudio(Project.ExpansionFds);  break;

            case EXTSOUND_MMC5: project.SetExpansionAudio(Project.ExpansionMmc5); break;

            case EXTSOUND_N163: project.SetExpansionAudio(Project.ExpansionN163, GetNumNamcoChannels(filename, songIndex, numFrames)); break;

            case EXTSOUND_S5B:  project.SetExpansionAudio(Project.ExpansionS5B);  break;

            case 0: break;

            default:
                NsfClose(nsf);     // Unsupported expansion combination.
                return(null);
            }

            var songName = Marshal.PtrToStringAnsi(NsfGetTrackName(nsf, songIndex));

            song          = project.CreateSong(string.IsNullOrEmpty(songName) ? $"Song {songIndex + 1}" : songName);
            channelStates = new ChannelState[song.Channels.Length];

            NsfSetTrack(nsf, songIndex);

            song.ResizeNotes(1, false);
            song.SetDefaultPatternLength(patternLength);

            for (int i = 0; i < song.Channels.Length; i++)
            {
                channelStates[i] = new ChannelState();
            }

            var foundFirstNote = !removeIntroSilence;

            var p = 0;
            var n = 0;
            var f = startFrame;

            for (int i = 0; i < numFrames; i++)
            {
                p = f / song.PatternLength;
                n = f % song.PatternLength;

                if (p >= Song.MaxLength - 1)
                {
                    break;
                }

                var playCalled = 0;
                do
                {
                    playCalled = NsfRunFrame(nsf);
                }while (playCalled == 0);

                for (int c = 0; c < song.Channels.Length; c++)
                {
                    foundFirstNote |= UpdateChannel(p, n, song.Channels[c], channelStates[c]);
                }

                if (foundFirstNote)
                {
                    f++;
                }
                else
                {
                    // Reset everything until we find our first note.
                    project.DeleteAllInstrument();
                    project.DeleteAllSamples();
                    for (int c = 0; c < song.Channels.Length; c++)
                    {
                        channelStates[c] = new ChannelState();
                    }
                }
            }

            song.SetLength(p + 1);

            NsfClose(nsf);

            var factors = Utils.GetFactors(song.PatternLength, Song.MaxNoteLength);

            if (factors.Length > 0 && factors[0] <= Song.MaxNoteLength)
            {
                song.ResizeNotes(factors[0], false);
            }
            else
            {
                song.ResizeNotes(1, false);
            }

            song.SetSensibleBarLength();
            song.DeleteEmptyPatterns();
            song.UpdatePatternStartNotes();
            project.DeleteUnusedInstruments();
            project.UpdateAllLastValidNotesAndVolume();

            return(project);
        }