Exemple #1
0
        private static bool ReadMusHeader(Stream Input, musheader Header)
        {
            Input.Read(Header.id, 0, 4);
            Header.scorelength       = GetShort(Input);
            Header.scorestart        = GetShort(Input);
            Header.primarychannels   = GetShort(Input);
            Header.secondarychannels = GetShort(Input);
            Header.instrumentcount   = GetShort(Input);

            //TODO: Convert to little endian? GetShort is prepared!

            return(true);
        }
Exemple #2
0
        public static bool Convert(Stream In, Stream Out)
        {
            Init();
            // Header for the MUS file
            musheader Header = new musheader();
            // Descriptor for the current MUS event
            byte eventdescriptor;
            // Channel number
            byte channel;
            // Current Event
            musevent Event;

            // Bunch of vars read from MUS lump
            byte key;
            byte controllernumber = 0;
            byte controllervalue  = 0;

            // Flag for when the score end marker is hit.
            bool hitscoreend = false;

            // Temp working byte
            byte working;
            // Used in building up time delays
            uint timedelay;

            for (channel = 0; channel < NUM_CHANNELS; ++channel)
            {
                channel_map[channel] = -1;
            }

            // Grab the header
            if (!ReadMusHeader(In, Header))
            {
                return(true);
            }


            // Check MUS header
            if (Header.id[0] != 'M' ||
                Header.id[1] != 'U' ||
                Header.id[2] != 'S' ||
                Header.id[3] != 0x1A)
            {
                return(true);
            }

            In.Seek(Header.scorestart, SeekOrigin.Begin);

            // So, we can assume the MUS file is faintly legit. Let's start
            // writing MIDI data...

            Out.Write(midiheader, 0, midiheader.Length);

            tracksize = 0;

            // Now, process the MUS file:
            while (!hitscoreend)
            {
                // Handle a block of events:
                while (!hitscoreend)
                {
                    // Fetch channel number and event code:
                    eventdescriptor = (byte)In.ReadByte();
                    channel         = GetMIDIChannel(eventdescriptor & 0x0F);
                    Event           = (musevent)(eventdescriptor & 0x70);
                    switch (Event)
                    {
                    case musevent.mus_releasekey:
                        key = (byte)In.ReadByte();
                        if (WriteReleaseKey(channel, key, Out))
                        {
                            return(true);
                        }
                        break;

                    case musevent.mus_presskey:
                        key = (byte)In.ReadByte();
                        if (key > 0x7F)
                        {
                            channelvelocities[channel]  = (byte)In.ReadByte();
                            channelvelocities[channel] &= 0x7F;
                        }

                        if (WritePressKey(channel, key, channelvelocities[channel], Out))
                        {
                            return(true);
                        }

                        break;

                    case musevent.mus_pitchwheel:
                        key = (byte)In.ReadByte();
                        if (WritePitchWheel(channel, (short)(key * 64), Out))
                        {
                            return(true);
                        }
                        break;

                    case musevent.mus_systemevent:
                        controllernumber = (byte)In.ReadByte();
                        if (controllernumber < 10 || controllernumber > 14)
                        {
                            return(true);
                        }

                        if (WriteChangeController_Valueless(channel, controller_map[controllernumber], Out))
                        {
                            return(true);
                        }
                        break;

                    case musevent.mus_changecontroller:
                        controllernumber = (byte)In.ReadByte();
                        controllervalue  = (byte)In.ReadByte();
                        if (controllernumber == 0)
                        {
                            if (WriteChangePatch(channel, controllervalue, Out))
                            {
                                return(true);
                            }
                        }
                        else
                        {
                            if (controllernumber < 1 || controllernumber > 9)
                            {
                                return(true);
                            }

                            if (WriteChangeController_Valued(channel, controller_map[controllernumber], controllervalue, Out))
                            {
                                return(true);
                            }
                        }

                        break;

                    case musevent.mus_scoreend:
                        hitscoreend = true;
                        break;

                    default:
                        return(true);
                    }

                    if (eventdescriptor > 0x7F)
                    {
                        break;
                    }
                } //INNER
                // Now we need to read the time code:
                if (!hitscoreend)
                {
                    timedelay = 0;
                    while (true)
                    {
                        working   = (byte)In.ReadByte();
                        timedelay = timedelay * 128 + (uint)(working & 0x7F);
                        if (working < 0x80)
                        {
                            break;
                        }
                    }
                    queuedtime += timedelay;
                }
            } //OUTER

            // End of track
            if (WriteEndTrack(Out))
            {
                return(true);
            }
            Out.Seek(18, SeekOrigin.Begin);

            Out.Write(new byte[]
            {
                (byte)((tracksize >> 24) & 0xFF),
                (byte)((tracksize >> 16) & 0xFF),
                (byte)((tracksize >> 8) & 0xFF),
                (byte)(tracksize & 0xFF)
            }, 0, 4);
            Out.Flush();
            return(false);
        }