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; } }
public void TriggerEvent(Enums.Event eventType) { Action thisEvent = null; if (eventDictionary.TryGetValue(eventType, out thisEvent)) { thisEvent.Invoke(); } }
public void TriggerEvent(Enums.Event eventType, int[] eventData) { Action <int[]> thisEvent = null; if (intArrayEventDictionary.TryGetValue(eventType, out thisEvent)) { thisEvent.Invoke(eventData); } }
public void StopListening(Enums.Event eventType, Action <int[]> listener) { Action <int[]> thisEvent; if (intArrayEventDictionary.TryGetValue(eventType, out thisEvent)) { thisEvent -= listener; } }
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 + "]"); }
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); } }
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; } }
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; }
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; } }
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; } }
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; } }
//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; } }