Example #1
0
        public override bool Load(int curious)
        {
            INSTRUMENT d;
            SAMPLE     q;
            int        t, u;
            bool       dummypat = false;

            char[] tracker = new char[21];
            //char[] modtype = new char[60];

            /* try to read module header */
            mh.id          = m_Reader.Read_String(17);
            mh.songname    = m_Reader.Read_String(21);
            mh.trackername = m_Reader.Read_String(20);

            mh.version = m_Reader.Read_Intel_ushort();
            if ((mh.version < 0x102) || (mh.version > 0x104))
            {
                m_LoadError = MMERR_NOT_A_MODULE;
                return(false);
            }
            mh.headersize = m_Reader.Read_Intel_uint();
            mh.songlength = m_Reader.Read_Intel_ushort();
            mh.restart    = m_Reader.Read_Intel_ushort();
            mh.numchn     = m_Reader.Read_Intel_ushort();
            mh.numpat     = m_Reader.Read_Intel_ushort();
            mh.numins     = m_Reader.Read_Intel_ushort();
            mh.flags      = m_Reader.Read_Intel_ushort();
            mh.tempo      = m_Reader.Read_Intel_ushort();
            mh.bpm        = m_Reader.Read_Intel_ushort();

            if (mh.bpm == 0 || mh.songlength > 256)
            {
                m_LoadError = MMERR_NOT_A_MODULE;
                return(false);
            }

            m_Reader.Read_bytes(mh.orders, mh.songlength);
            if (!m_Reader.Seek((int)(mh.headersize + 60), SeekOrigin.Begin) || m_Reader.isEOF())
            {
                m_LoadError = MMERR_LOADING_HEADER;
                return(false);
            }

            /* set module variables */
            m_Module.initspeed = (byte)mh.tempo;
            m_Module.inittempo = mh.bpm;

            tracker = mh.trackername.ToCharArray();
            for (t = tracker.Length - 1; (t >= 0) && (tracker[t] <= ' '); t--)
            {
                tracker[t] = (char)0;
            }

            /* some modules have the tracker name empty */
            if (tracker[0] == 0)
            {
                tracker = "Unknown tracker".ToCharArray();
            }

            String modType = String.Format("{0} (XM format {1}.{2})", tracker, mh.version >> 8, mh.version & 0xff);

            m_Module.modtype  = modType;
            m_Module.numchn   = (byte)mh.numchn;
            m_Module.numpat   = mh.numpat;
            m_Module.numtrk   = (ushort)(m_Module.numpat * m_Module.numchn); /* get number of channels */
            m_Module.songname = mh.songname;
            m_Module.numpos   = mh.songlength;                               /* copy the songlength */
            m_Module.reppos   = (ushort)(mh.restart < mh.songlength ? mh.restart : 0);
            m_Module.numins   = mh.numins;
            m_Module.flags   |= SharpMikCommon.UF_XMPERIODS | SharpMikCommon.UF_INST | SharpMikCommon.UF_NOWRAP | SharpMikCommon.UF_FT2QUIRKS | SharpMikCommon.UF_PANNING;
            if ((mh.flags & 1) != 0)
            {
                m_Module.flags |= SharpMikCommon.UF_LINEAR;
            }

            m_Module.bpmlimit = 32;

            m_Module.chanvol.Memset(64, m_Module.numchn);           /* store channel volumes */

            m_Module.positions = new ushort[m_Module.numpos + 1];
            for (t = 0; t < m_Module.numpos; t++)
            {
                m_Module.positions[t] = mh.orders[t];
            }

            /* We have to check for any pattern numbers in the order list greater than
             *             the number of patterns total. If one or more is found, we set it equal to
             *             the pattern total and make a dummy pattern to workaround the problem */
            for (t = 0; t < m_Module.numpos; t++)
            {
                if (m_Module.positions[t] >= m_Module.numpat)
                {
                    m_Module.positions[t] = m_Module.numpat;
                    dummypat = true;
                }
            }
            if (dummypat)
            {
                m_Module.numpat++; m_Module.numtrk += m_Module.numchn;
            }

            if (mh.version < 0x0104)
            {
                if (!LoadInstruments())
                {
                    return(false);
                }
                if (!LoadPatterns(dummypat))
                {
                    return(false);
                }
                for (t = 0; t < m_Module.numsmp; t++)
                {
                    nextwav[t] += (uint)m_Reader.Tell();
                }
            }
            else
            {
                if (!LoadPatterns(dummypat))
                {
                    return(false);
                }
                if (!LoadInstruments())
                {
                    return(false);
                }
            }

            m_Module.AllocSamples();

            sampHeader = 0;
            for (u = 0; u < m_Module.numsmp; u++)
            {
                q = m_Module.samples[u];
                XMWAVHEADER s = wh[sampHeader++];

                q.samplename = s.samplename;
                q.length     = s.length;
                q.loopstart  = s.loopstart;
                q.loopend    = (uint)(s.loopstart + s.looplength);
                q.volume     = s.volume;
                q.speed      = (uint)s.finetune + 128;
                q.panning    = s.panning;
                q.seekpos    = nextwav[u];
                q.vibtype    = s.vibtype;
                q.vibsweep   = s.vibsweep;
                q.vibdepth   = s.vibdepth;
                q.vibrate    = s.vibrate;

                if ((s.type & 0x10) != 0)
                {
                    q.length    >>= 1;
                    q.loopstart >>= 1;
                    q.loopend   >>= 1;
                }

                q.flags |= SharpMikCommon.SF_OWNPAN | SharpMikCommon.SF_DELTA | SharpMikCommon.SF_SIGNED;
                if ((s.type & 0x3) != 0)
                {
                    q.flags |= SharpMikCommon.SF_LOOP;
                }
                if ((s.type & 0x2) != 0)
                {
                    q.flags |= SharpMikCommon.SF_BIDI;
                }
                if ((s.type & 0x10) != 0)
                {
                    q.flags |= SharpMikCommon.SF_16BITS;
                }
            }


            sampHeader = 0;
            for (u = 0; u < m_Module.numins; u++)
            {
                d = m_Module.instruments[u];
                for (t = 0; t < XMNOTECNT; t++)
                {
                    if (d.samplenumber[t] >= m_Module.numsmp)
                    {
                        d.samplenote[t] = 255;
                    }
                    else
                    {
                        int note = t + wh[d.samplenumber[t]].relnote;
                        d.samplenote[t] = (byte)((note < 0) ? 0 : note);
                    }
                }
            }

            wh      = null;
            nextwav = null;
            return(true);
        }
Example #2
0
        bool LoadInstruments()
        {
            int        t, u, ck;
            INSTRUMENT d;
            uint       next   = 0;
            ushort     wavcnt = 0;

            if (!m_Module.AllocInstruments())
            {
                m_LoadError = MMERR_NOT_A_MODULE;
                return(false);
            }

            for (t = 0; t < m_Module.numins; t++)
            {
                d = m_Module.instruments[t];
                XMINSTHEADER ih = new XMINSTHEADER();
                long         headend;
                d.samplenumber.Memset(0xff, SharpMikCommon.INSTNOTES);

                /* read instrument header */
                headend  = m_Reader.Tell();
                ih.size  = m_Reader.Read_Intel_uint();
                headend += ih.size;
                ck       = m_Reader.Tell();
                m_Reader.Seek(0, SeekOrigin.End);

                if ((headend < 0) || (m_Reader.Tell() < headend) || (headend < ck))
                {
                    m_Reader.Seek(ck, SeekOrigin.Begin);
                    break;
                }
                m_Reader.Seek(ck, SeekOrigin.Begin);

                ih.name   = m_Reader.Read_String(22);
                ih.type   = m_Reader.Read_byte();
                ih.numsmp = m_Reader.Read_Intel_ushort();

                d.insname = ih.name;

                if ((short)ih.size > 29)
                {
                    ih.ssize = m_Reader.Read_Intel_uint();
                    if (((short)ih.numsmp > 0) && (ih.numsmp <= XMNOTECNT))
                    {
                        XMPATCHHEADER pth = new XMPATCHHEADER();
                        m_Reader.Read_bytes(pth.what, XMNOTECNT);
                        m_Reader.Read_Intel_ushorts(pth.volenv, XMENVCNT);
                        m_Reader.Read_Intel_ushorts(pth.panenv, XMENVCNT);
                        pth.volpts   = m_Reader.Read_byte();
                        pth.panpts   = m_Reader.Read_byte();
                        pth.volsus   = m_Reader.Read_byte();
                        pth.volbeg   = m_Reader.Read_byte();
                        pth.volend   = m_Reader.Read_byte();
                        pth.pansus   = m_Reader.Read_byte();
                        pth.panbeg   = m_Reader.Read_byte();
                        pth.panend   = m_Reader.Read_byte();
                        pth.volflg   = m_Reader.Read_byte();
                        pth.panflg   = m_Reader.Read_byte();
                        pth.vibflg   = m_Reader.Read_byte();
                        pth.vibsweep = m_Reader.Read_byte();
                        pth.vibdepth = m_Reader.Read_byte();
                        pth.vibrate  = m_Reader.Read_byte();
                        pth.volfade  = m_Reader.Read_Intel_ushort();

                        /* read the remainder of the header
                         *                         (2 bytes for 1.03, 22 for 1.04) */
                        if (headend >= m_Reader.Tell())
                        {
                            for (u = (int)(headend - m_Reader.Tell()); u != 0; u--)
                            {
                                m_Reader.Read_byte();
                            }
                        }

                        /* we can't trust the envelope point count here, as some
                         *                         modules have incorrect values (K_OSPACE.XM reports 32 volume
                         *                         points, for example). */
                        if (pth.volpts > XMENVCNT / 2)
                        {
                            pth.volpts = (byte)(XMENVCNT / 2);
                        }
                        if (pth.panpts > XMENVCNT / 2)
                        {
                            pth.panpts = (byte)(XMENVCNT / 2);
                        }

                        if ((m_Reader.isEOF()) || (pth.volpts > XMENVCNT / 2) || (pth.panpts > XMENVCNT / 2))
                        {
                            if (nextwav != null)
                            {
                                nextwav = null;
                            }
                            if (wh != null)
                            {
                                wh = null;
                            }
                            m_LoadError = MMERR_LOADING_SAMPLEINFO;
                            return(false);
                        }

                        for (u = 0; u < XMNOTECNT; u++)
                        {
                            d.samplenumber[u] = (ushort)(pth.what[u] + m_Module.numsmp);
                        }
                        d.volfade = pth.volfade;


                        XM_ProcessEnvelopeVolume(ref d, pth);
                        XM_ProcessEnvelopePan(ref d, pth);


                        if ((d.volflg & SharpMikCommon.EF_ON) != 0)
                        {
                            FixEnvelope(d.volenv, d.volpts);
                        }
                        if ((d.panflg & SharpMikCommon.EF_ON) != 0)
                        {
                            FixEnvelope(d.panenv, d.panpts);
                        }

                        /* Samples are stored outside the instrument struct now, so we
                         *                         have to load them all into a temp area, count the m_Module.numsmp
                         *                         along the way and then do an AllocSamples() and move
                         *                         everything over */
                        if (mh.version > 0x0103)
                        {
                            next = 0;
                        }

                        for (u = 0; u < ih.numsmp; u++)
                        {
                            XMWAVHEADER s = null;
                            if (wh != null && sampHeader < wh.Length)
                            {
                                s = wh[sampHeader];
                            }

                            /* Allocate more room for sample information if necessary */
                            if (m_Module.numsmp + u == wavcnt)
                            {
                                ushort lastSize = wavcnt;
                                wavcnt += (ushort)XM_SMPINCR;

                                if (nextwav == null)
                                {
                                    nextwav = new uint[wavcnt];
                                }
                                else
                                {
                                    Array.Resize(ref nextwav, wavcnt);
                                }

                                if (wh == null)
                                {
                                    wh = new XMWAVHEADER[wavcnt];
                                }
                                else
                                {
                                    Array.Resize(ref wh, wavcnt);
                                }

                                for (ushort i = lastSize; i < wavcnt; i++)
                                {
                                    wh[i] = new XMWAVHEADER();
                                }


                                //sampHeader=(wavcnt-XM_SMPINCR);
                                s = wh[sampHeader];
                            }

                            s.length     = m_Reader.Read_Intel_uint();
                            s.loopstart  = m_Reader.Read_Intel_uint();
                            s.looplength = m_Reader.Read_Intel_uint();
                            s.volume     = m_Reader.Read_byte();
                            s.finetune   = m_Reader.Read_sbyte();
                            s.type       = m_Reader.Read_byte();
                            s.panning    = m_Reader.Read_byte();
                            s.relnote    = m_Reader.Read_sbyte();
                            s.vibtype    = pth.vibflg;
                            s.vibsweep   = pth.vibsweep;
                            s.vibdepth   = (byte)(pth.vibdepth * 4);
                            s.vibrate    = pth.vibrate;
                            s.reserved   = m_Reader.Read_byte();
                            s.samplename = m_Reader.Read_String(22);

                            nextwav[m_Module.numsmp + u] = next;
                            next += s.length;

                            if (m_Reader.isEOF())
                            {
                                nextwav     = null;
                                wh          = null;
                                m_LoadError = MMERR_LOADING_SAMPLEINFO;
                                return(false);
                            }

                            sampHeader++;
                        }

                        if (mh.version > 0x0103)
                        {
                            for (u = 0; u < ih.numsmp; u++)
                            {
                                nextwav[m_Module.numsmp++] += (uint)m_Reader.Tell();
                            }
                            m_Reader.Seek((int)next, SeekOrigin.Current);
                        }
                        else
                        {
                            m_Module.numsmp += ih.numsmp;
                        }
                    }
                    else
                    {
                        /* read the remainder of the header */
                        ck = m_Reader.Tell();
                        m_Reader.Seek(0, SeekOrigin.End);

                        if ((headend < 0) || (m_Reader.Tell() < headend) || (headend < ck))
                        {
                            m_Reader.Seek(ck, SeekOrigin.Begin);
                            break;
                        }
                        m_Reader.Seek(ck, SeekOrigin.Begin);

                        u = (int)(headend - m_Reader.Tell());
                        for (; u != 0; u--)
                        {
                            m_Reader.Read_byte();
                        }

                        if (m_Reader.isEOF())
                        {
                            nextwav     = null;
                            wh          = null;
                            m_LoadError = MMERR_LOADING_SAMPLEINFO;
                            return(false);
                        }
                    }
                }
            }

            /* sanity check */
            if (m_Module.numsmp == 0)
            {
                nextwav     = null;
                wh          = null;
                m_LoadError = MMERR_LOADING_SAMPLEINFO;
                return(false);
            }

            return(true);
        }