Пример #1
0
        private void ParseDwordEvent(Enums.Event eventId, BinaryReader reader)
        {
            var data = reader.ReadUInt32();

            OutputLine($"int: {data:X8}");

            switch (eventId)
            {
            case Enums.Event.DWordColor:
                if (_curChannel != null)
                {
                    _curChannel.Color = data;
                }
                break;

            case Enums.Event.DWordMiddleNote:
                if (_curChannel != null && _curChannel.Data is GeneratorData genData)
                {
                    genData.BaseNote = data + 9;
                }
                break;

            case Enums.Event.DWordInsertColor:
                _curInsert.Color = data;
                break;

            case Enums.Event.DWordFineTempo:
                project.Tempo = data / 1000.0;
                break;
            }
        }
Пример #2
0
        public void TriggerEvent(Enums.Event eventType)
        {
            Action thisEvent = null;

            if (eventDictionary.TryGetValue(eventType, out thisEvent))
            {
                thisEvent.Invoke();
            }
        }
Пример #3
0
        public void TriggerEvent(Enums.Event eventType, int[] eventData)
        {
            Action <int[]> thisEvent = null;

            if (intArrayEventDictionary.TryGetValue(eventType, out thisEvent))
            {
                thisEvent.Invoke(eventData);
            }
        }
Пример #4
0
        public void StopListening(Enums.Event eventType, Action <int[]> listener)
        {
            Action <int[]> thisEvent;

            if (intArrayEventDictionary.TryGetValue(eventType, out thisEvent))
            {
                thisEvent -= listener;
            }
        }
Пример #5
0
        private void _ParseDataEvent(Enums.Event eventId, BinaryReader reader)
        {
            var    dataLen   = GetBufferLen(reader);
            var    dataBytes = reader.ReadBytes(dataLen);
            string txt       = "";

            for (var i = 0; i < dataBytes.Length; i++)
            {
                txt = txt + "/" + dataBytes[i];
            }
            Console.Write(" = [" + txt + "]");
        }
Пример #6
0
        public void StartListening(Enums.Event eventType, Action <int[]> listener)
        {
            Action <int[]> thisEvent;

            if (intArrayEventDictionary.TryGetValue(eventType, out thisEvent))
            {
                thisEvent += listener;
            }
            else
            {
                thisEvent += listener;
                intArrayEventDictionary.Add(eventType, thisEvent);
            }
        }
Пример #7
0
        private void ParseByteEvent(Enums.Event eventId, BinaryReader reader)
        {
            var data = reader.ReadByte();

            if (_verbose)
            {
                OutputLine($"byte: {data:X2}");
            }

            //Console.Write(" = "+data);

            var genData = _curChannel?.Data as GeneratorData;

            switch (eventId)
            {
            case Enums.Event.ByteMainVol:
                _project.MainVolume = data;
                break;

            case Enums.Event.ByteUseLoopPoints:
                if (genData != null)
                {
                    genData.SampleUseLoopPoints = true;
                }
                break;

            case Enums.Event.ByteMixSliceNum:
                if (genData != null)
                {
                    genData.Insert = data;
                }
                break;

            case Enums.Event.BytePlayTruncatedNotes:
                _project.PlayTruncatedNotes = Convert.ToBoolean(data);
                break;
            }
        }
Пример #8
0
        private void ParseDataEvent(Enums.Event eventId, BinaryReader reader)
        {
            var dataLen   = GetBufferLen(reader);
            var dataStart = reader.BaseStream.Position;
            var dataEnd   = dataStart + dataLen;

            var genData  = _curChannel?.Data as GeneratorData;
            var autData  = _curChannel?.Data as AutomationData;
            var slotData = _curSlot;

            switch (eventId)
            {
            case Enums.Event.DataPluginParams:
                if (slotData != null)
                {
                    OutputLine($"Found plugin settings for insert (id {_curInsert.Id})");
                    _curSlot.PluginSettings = reader.ReadBytes(dataLen);
                    _curSlot.Plugin         = ParsePluginChunk(slotData.PluginSettings);
                }
                else
                {
                    if (genData == null)
                    {
                        break;
                    }
                    if (genData.PluginSettings != null)
                    {
                        throw new Exception("Attempted to overwrite plugin");
                    }

                    OutputLine($"Found plugin settings for {genData.GeneratorName} (id {_curChannel.Id})");
                    genData.PluginSettings = reader.ReadBytes(dataLen);
                    genData.Plugin         = ParsePluginChunk(genData.PluginSettings);
                }
                break;

            case Enums.Event.DataChanParams:
            {
                if (genData == null)
                {
                    break;
                }
                var unknown1 = reader.ReadBytes(40);
                genData.ArpDir   = (Enums.ArpDirection)reader.ReadInt32();
                genData.ArpRange = reader.ReadInt32();
                genData.ArpChord = reader.ReadInt32();
                genData.ArpTime  = reader.ReadInt32() + 1;
                genData.ArpGate  = reader.ReadInt32();
                genData.ArpSlide = reader.ReadBoolean();
                var unknown2 = reader.ReadBytes(31);
                genData.ArpRepeat = reader.ReadInt32();
                var unknown3 = reader.ReadBytes(29);
            }
            break;

            case Enums.Event.DataBasicChanParams:
                if (genData == null)
                {
                    break;
                }
                genData.Panning = reader.ReadInt32();
                genData.Volume  = reader.ReadInt32();
                break;

            case Enums.Event.DataPatternNotes:
                while (reader.BaseStream.Position < dataEnd)
                {
                    var pos       = reader.ReadInt32();
                    var unknown1  = reader.ReadInt16();
                    var ch        = reader.ReadByte();
                    var unknown2  = reader.ReadByte();
                    var length    = reader.ReadInt32();
                    var key       = reader.ReadByte();
                    var unknown3  = reader.ReadInt16();
                    var unknown4  = reader.ReadByte();
                    var finePitch = reader.ReadUInt16();
                    var release   = reader.ReadUInt16();
                    var pan       = reader.ReadByte();
                    var velocity  = reader.ReadByte();
                    var x1        = reader.ReadByte();
                    var x2        = reader.ReadByte();

                    var channel = project.Channels[ch];
                    if (!_curPattern.Notes.ContainsKey(channel))
                    {
                        _curPattern.Notes.Add(channel, new List <Note>());
                    }
                    _curPattern.Notes[channel].Add(new Note
                    {
                        Position  = pos,
                        Length    = length,
                        Key       = key,
                        FinePitch = finePitch,
                        Release   = release,
                        Pan       = pan,
                        Velocity  = velocity
                    });
                }
                break;

            case Enums.Event.DataInsertParams:
                while (reader.BaseStream.Position < dataEnd)
                {
                    var startPos    = reader.BaseStream.Position;
                    var unknown1    = reader.ReadInt32();
                    var messageId   = (Enums.InsertParam)reader.ReadByte();
                    var unknown2    = reader.ReadByte();
                    var channelData = reader.ReadUInt16();
                    var messageData = reader.ReadInt32();

                    var slotId     = channelData & 0x3F;
                    var insertId   = (channelData >> 6) & 0x7F;
                    var insertType = channelData >> 13;

                    var insert = project.Inserts[insertId];

                    switch (messageId)
                    {
                    case Enums.InsertParam.SlotState:
                        insert.Slots[slotId].State = messageData;
                        break;

                    case Enums.InsertParam.SlotVolume:
                        insert.Slots[slotId].Volume = messageData;
                        break;

                    case Enums.InsertParam.Volume:
                        insert.Volume = messageData;
                        break;

                    case Enums.InsertParam.Pan:
                        insert.Pan = messageData;
                        break;

                    case Enums.InsertParam.StereoSep:
                        insert.StereoSep = messageData;
                        break;

                    case Enums.InsertParam.LowLevel:
                        insert.LowLevel = messageData;
                        break;

                    case Enums.InsertParam.BandLevel:
                        insert.BandLevel = messageData;
                        break;

                    case Enums.InsertParam.HighLevel:
                        insert.HighLevel = messageData;
                        break;

                    case Enums.InsertParam.LowFreq:
                        insert.LowFreq = messageData;
                        break;

                    case Enums.InsertParam.BandFreq:
                        insert.BandFreq = messageData;
                        break;

                    case Enums.InsertParam.HighFreq:
                        insert.HighFreq = messageData;
                        break;

                    case Enums.InsertParam.LowWidth:
                        insert.LowWidth = messageData;
                        break;

                    case Enums.InsertParam.BandWidth:
                        insert.BandWidth = messageData;
                        break;

                    case Enums.InsertParam.HighWidth:
                        insert.HighWidth = messageData;
                        break;

                    default:
                        if ((int)messageId >= 64 && (int)messageId <= 64 + 104)          // any value 64 or above appears to be the desination insert
                        {
                            var insertDest = (int)messageId - 64;
                            insert.RouteVolumes[insertDest] = messageData;
                            OutputLine($"{startPos:X4} insert send from {insertId} to {insertDest} volume: {messageData:X8}");
                        }
                        else
                        {
                            OutputLine($"{startPos:X4} insert param: {messageId} {insertId}-{slotId}, data: {messageData:X8}");
                        }
                        break;
                    }
                }
                break;

            case Enums.Event.DataAutomationChannels:
                while (reader.BaseStream.Position < dataEnd)
                {
                    var unknown1          = reader.ReadUInt16();
                    var automationChannel = reader.ReadByte();
                    var unknown2          = reader.ReadUInt32();
                    var unknown3          = reader.ReadByte();
                    var param             = reader.ReadUInt16();
                    var paramDestination  = reader.ReadInt16();
                    var unknown4          = reader.ReadUInt64();

                    var channel = project.Channels[automationChannel];

                    if ((paramDestination & 0x2000) == 0)      // Automation on channel
                    {
                        channel.Data = new AutomationData
                        {
                            Channel      = project.Channels[paramDestination],
                            Parameter    = param & 0x7fff,
                            VstParameter = (param & 0x8000) > 0 ? true : false          // switch determines if automation is on channel or vst
                        };
                    }
                    else
                    {
                        channel.Data = new AutomationData     // automation on insert slot
                        {
                            Parameter = param & 0x7fff,
                            InsertId  = (paramDestination & 0x0FF0) >> 6,     // seems to be out by one
                            SlotId    = paramDestination & 0x003F
                        };
                    }
                }
                break;

            case Enums.Event.DataPlayListItems:
                while (reader.BaseStream.Position < dataEnd)
                {
                    var startTime   = reader.ReadInt32();
                    var patternBase = reader.ReadUInt16();
                    var patternId   = reader.ReadUInt16();
                    var length      = reader.ReadInt32();
                    var track       = reader.ReadInt32();
                    if (_versionMajor == 20)
                    {
                        track = 501 - track;
                    }
                    else
                    {
                        track = 198 - track;
                    }
                    var  unknown1  = reader.ReadUInt16();
                    var  itemFlags = reader.ReadUInt16();
                    var  unknown3  = reader.ReadUInt32();
                    bool muted     = (itemFlags & 0x2000) > 0 ? true : false;   // flag determines if item is muted

                    // id of 0-patternBase is samples or automation, after is pattern
                    if (patternId <= patternBase)
                    {
                        var startOffset = (int)(reader.ReadSingle() * (float)project.Ppq);
                        var endOffset   = (int)(reader.ReadSingle() * (float)project.Ppq);

                        project.Tracks[track].Items.Add(new ChannelPlaylistItem
                        {
                            Position    = startTime,
                            Length      = length,
                            StartOffset = startOffset,
                            EndOffset   = endOffset,
                            Channel     = project.Channels[patternId],
                            Muted       = muted
                        });
                    }
                    else
                    {
                        var startOffset = reader.ReadInt32();
                        var endOffset   = reader.ReadInt32();

                        project.Tracks[track].Items.Add(new PatternPlaylistItem
                        {
                            Position    = startTime,
                            Length      = length,
                            StartOffset = startOffset,
                            EndOffset   = endOffset,
                            Pattern     = project.Patterns[patternId - patternBase - 1],
                            Muted       = muted
                        });
                    }
                }
                break;

            case Enums.Event.DataAutomationData:
            {
                var unknown1 = reader.ReadUInt32();         // always 1?
                var unknown2 = reader.ReadUInt32();         // always 64?
                var unknown3 = reader.ReadByte();
                var unknown4 = reader.ReadUInt16();
                var unknown5 = reader.ReadUInt16();         // always 0?
                var unknown6 = reader.ReadUInt32();
                var keyCount = reader.ReadUInt32();

                if (autData == null)
                {
                    break;
                }
                autData.Keyframes = new AutomationKeyframe[keyCount];

                for (var i = 0; i < keyCount; i++)
                {
                    var startPos = reader.BaseStream.Position;

                    var keyPos     = reader.ReadDouble();
                    var keyVal     = reader.ReadDouble();
                    var keyTension = reader.ReadSingle();
                    var unknown7   = reader.ReadUInt32();       // seems linked to tension?

                    var endPos = reader.BaseStream.Position;
                    reader.BaseStream.Position = startPos;
                    var byteData = reader.ReadBytes((int)(endPos - startPos));
                    OutputLine($"Key {i} data: {string.Join(" ", byteData.Select(x => x.ToString("X2")))}");

                    autData.Keyframes[i] = new AutomationKeyframe
                    {
                        Position = (int)(keyPos * project.Ppq),
                        Tension  = keyTension,
                        Value    = keyVal
                    };
                }

                // remaining data is unknown
            }
            break;

            case Enums.Event.DataInsertRoutes:
                for (var i = 0; i < Project.MaxInsertCount; i++)
                {
                    _curInsert.Routes[i] = reader.ReadBoolean();
                }

                var newIndex = _curInsert.Id + 1;
                if (newIndex < project.Inserts.Length)
                {
                    _curInsert = project.Inserts[newIndex];
                }

                break;

            case Enums.Event.DataInsertFlags:
                reader.ReadUInt32();
                var flags = (Enums.InsertFlags)reader.ReadUInt32();
                _curInsert.Flags = flags;
                _curSlot         = new InsertSlot(); // New insert route, create new slot
                break;
            }

            // make sure cursor is at end of data
            reader.BaseStream.Position = dataEnd;
        }
Пример #9
0
        private void ParseTextEvent(Enums.Event eventId, BinaryReader reader)
        {
            var dataLen   = GetBufferLen(reader);
            var dataBytes = reader.ReadBytes(dataLen);

            Decoder stringDecoder = null;

            bool isUTF16 = false;

            // check if it's a UTF16 string
            // dirty but works
            for (int i = 1; i < dataLen / 2; i++)
            {
                if (dataBytes[i] == dataBytes[i + 2] && dataBytes[i] == 0)
                {
                    isUTF16 = true;
                    break;
                }
            }

            if (isUTF16)
            {
                stringDecoder = _enc16.GetDecoder();
            }
            else
            {
                stringDecoder = _enc8.GetDecoder();
            }

            int nChars = stringDecoder.GetCharCount(dataBytes, 0, dataLen);

            char[] chars = new char[nChars];

            nChars = stringDecoder.GetChars(dataBytes, 0, dataLen, chars, 0);
            var unicodeString = new String(chars, 0, nChars);

            if (unicodeString.EndsWith("\0"))
            {
                unicodeString = unicodeString.Substring(0, unicodeString.Length - 1);
            }

            OutputLine($"text: {unicodeString}");

            var genData = _curChannel?.Data as GeneratorData;

            switch (eventId)
            {
            case Enums.Event.TextChanName:
                if (_curChannel != null)
                {
                    _curChannel.Name = unicodeString;
                }
                break;

            case Enums.Event.TextPatName:
                if (_curPattern != null)
                {
                    _curPattern.Name = unicodeString;
                }
                break;

            case Enums.Event.TextTitle:
                project.ProjectTitle = unicodeString;
                break;

            case Enums.Event.TextProjectPath:
                project.ProjectPath = unicodeString;
                break;

            case Enums.Event.TextAuthor:
                project.Author = unicodeString;
                break;

            case Enums.Event.TextComment:
                project.Comment = unicodeString;
                break;

            case Enums.Event.TextGenre:
                project.Genre = unicodeString;
                break;

            case Enums.Event.TextSampleFileName:
                if (genData == null)
                {
                    break;
                }
                genData.SampleFileName = unicodeString;
                genData.GeneratorName  = "Sampler";
                break;

            case Enums.Event.TextVersion:
                project.VersionString = Encoding.UTF8.GetString(dataBytes);
                if (project.VersionString.EndsWith("\0"))
                {
                    project.VersionString = project.VersionString.Substring(0, project.VersionString.Length - 1);
                }
                var numbers = project.VersionString.Split('.');
                _versionMajor   = int.Parse(numbers[0]);
                project.Version = (int.Parse(numbers[0]) << 8) +
                                  (int.Parse(numbers[1]) << 4) +
                                  (int.Parse(numbers[2]) << 0);
                break;

            case Enums.Event.GeneratorName:
                if (genData != null)
                {
                    genData.GeneratorName = unicodeString;
                }
                break;

            case Enums.Event.TextInsertName:
                _curInsert.Name = unicodeString;
                break;
            }
        }
Пример #10
0
        private void ParseWordEvent(Enums.Event eventId, BinaryReader reader)
        {
            var data = reader.ReadUInt16();

            OutputLine($"word: {data:X4}");

            var genData = _curChannel?.Data as GeneratorData;

            switch (eventId)
            {
            case Enums.Event.WordNewChan:
                _curChannel = project.Channels[data];
                break;

            case Enums.Event.WordNewPat:
                while (project.Patterns.Count < data)
                {
                    project.Patterns.Add(new Pattern {
                        Id = project.Patterns.Count
                    });
                }
                _curPattern = project.Patterns[data - 1];
                break;

            case Enums.Event.WordTempo:
                project.Tempo = data;
                break;

            case Enums.Event.WordFadeStereo:
                if (genData == null)
                {
                    break;
                }
                if ((data & 0x02) != 0)
                {
                    genData.SampleReversed = true;
                }
                else if ((data & 0x100) != 0)
                {
                    genData.SampleReverseStereo = true;
                }
                break;

            case Enums.Event.WordPreAmp:
                if (genData == null)
                {
                    break;
                }
                genData.SampleAmp = data;
                break;

            case Enums.Event.WordMainPitch:
                project.MainPitch = data;
                break;

            case Enums.Event.WordInsertIcon:
                _curInsert.Icon = data;
                break;

            case Enums.Event.WordCurrentSlotNum:
                if (_curSlot != null)     // Current slot after plugin event, now re-arranged.
                {
                    _curInsert.Slots[data] = _curSlot;
                    _curSlot = new InsertSlot();
                }
                _curChannel = null;
                break;
            }
        }
Пример #11
0
        private void ParseTextEvent(Enums.Event eventId, BinaryReader reader)
        {
            var dataLen       = GetBufferLen(reader);
            var dataBytes     = reader.ReadBytes(dataLen);
            var unicodeString = Encoding.Unicode.GetString(dataBytes);

            if (unicodeString.EndsWith("\0"))
            {
                unicodeString = unicodeString.Substring(0, unicodeString.Length - 1);
            }

            OutputLine($"text: {unicodeString}");

            var genData = _curChannel?.Data as GeneratorData;

            switch (eventId)
            {
            case Enums.Event.TextChanName:
                if (_curChannel != null)
                {
                    _curChannel.Name = unicodeString;
                }
                break;

            case Enums.Event.TextPatName:
                if (_curPattern != null)
                {
                    _curPattern.Name = unicodeString;
                }
                break;

            case Enums.Event.TextTitle:
                _project.ProjectTitle = unicodeString;
                break;

            case Enums.Event.TextSampleFileName:
                if (genData == null)
                {
                    break;
                }
                genData.SampleFileName = unicodeString;
                genData.GeneratorName  = "Sampler";
                break;

            case Enums.Event.TextVersion:
                _project.VersionString = Encoding.UTF8.GetString(dataBytes);
                if (_project.VersionString.EndsWith("\0"))
                {
                    _project.VersionString = _project.VersionString.Substring(0, _project.VersionString.Length - 1);
                }
                var numbers = _project.VersionString.Split('.');
                _versionMajor    = int.Parse(numbers[0]);
                _project.Version = (int.Parse(numbers[0]) << 8) +
                                   (int.Parse(numbers[1]) << 4) +
                                   (int.Parse(numbers[2]) << 0);
                break;

            case Enums.Event.GeneratorName:
                if (genData != null)
                {
                    genData.GeneratorName = unicodeString;
                }
                break;

            case Enums.Event.TextInsertName:
                _curInsert.Name = unicodeString;
                break;
            }
        }
Пример #12
0
        //int trackCounter=0;
        private void ParseTextEvent(Enums.Event eventId, BinaryReader reader)
        {
            var dataLen              = GetBufferLen(reader);
            var dataBytes            = reader.ReadBytes(dataLen);
            var unicodeString        = Encoding.Unicode.GetString(dataBytes);
            var defaultEncodedString = System.Text.Encoding.Default.GetString(dataBytes);

            //var unicodeString = System.Text.Encoding.Default.GetString(dataBytes);
            if (unicodeString.EndsWith("\0"))
            {
                unicodeString = unicodeString.Substring(0, unicodeString.Length - 1);
            }
            unicodeString = unicodeString.Replace('\n', ' ').Replace('\r', ' ').Replace('\'', '"');
            //unicodeString = unicodeString + "/" + dataBytes.Length;
            OutputLine($"text: {unicodeString}");

            //Console.Write(" = '" + unicodeString + "'");

            var genData = _curChannel?.Data as GeneratorData;

            //if(eventId== Enums.Event.TextPluginName)			Console.Error.WriteLine("eventId " + eventId+" = "+ unicodeString);
            switch (eventId)
            {
            case Enums.Event.TextPluginName:
                //Console.Error.WriteLine("eventId " + eventId + " = " + unicodeString+": "+ trackCounter+"."+_curChannel+"/"+ _project.Channels.Count);
                //_project.Tracks[trackCounter].Name= ""+ trackCounter+"."+unicodeString;
                //_project.Channels[trackCounter].ChannelName= unicodeString;
                //trackCounter++;
                if (_curChannel != null)
                {
                    _curChannel.ChannelName = unicodeString;
                }
                break;

            case Enums.Event.TextChanName:

                //Console.Error.WriteLine("TextChanName " + unicodeString);
                if (_curChannel != null)
                {
                    _curChannel.ChannelName = unicodeString;
                }
                //else {Console.Error.WriteLine("empty channel for "+ unicodeString); }
                break;

            case Enums.Event.TextPatName:
                if (_curPattern != null)
                {
                    _curPattern.Name = unicodeString;
                }
                break;

            case Enums.Event.TextTitle:
                _project.ProjectTitle = unicodeString;
                break;

            case Enums.Event.TextAuthor:
                _project.Author = unicodeString;
                //_project.Author = defaultEncodedString;
                break;

            case Enums.Event.TextComment:
                _project.Comment = unicodeString;
                break;

            case Enums.Event.TextGenre:
                _project.Genre = unicodeString;
                break;

            case Enums.Event.TextSampleFileName:
                if (genData == null)
                {
                    break;
                }
                genData.SampleFileName = unicodeString;
                genData.GeneratorName  = "Sampler";
                break;

            case Enums.Event.TextVersion:
                _project.VersionString = Encoding.UTF8.GetString(dataBytes);
                if (_project.VersionString.EndsWith("\0"))
                {
                    _project.VersionString = _project.VersionString.Substring(0, _project.VersionString.Length - 1);
                }
                var numbers = (_project.VersionString + ".0.0").Split('.');
                _versionMajor    = int.Parse(numbers[0]);
                _project.Version = (int.Parse(numbers[0]) << 8) +
                                   (int.Parse(numbers[1]) << 4) +
                                   (int.Parse(numbers[2]) << 0);
                break;

            case Enums.Event.GeneratorName:
                if (genData != null)
                {
                    genData.GeneratorName = unicodeString;
                }
                break;

            case Enums.Event.TextInsertName:
                _curInsert.Name = unicodeString;
                break;

            default:
                //Console.Error.WriteLine("unknown eventId "+ eventId+" for " + unicodeString);
                break;
            }
        }