private void GetInstruments() { instruments = new List <RnsIns>(); int insId = 0; foreach (var instrument in project.Instruments.Instrument) { var rnsins = new RnsIns(); rnsins.Name = instrument.Name; rnsins.InstrumentId = insId; AudioPluginDevice plug = null; if (instrument.PluginGenerator != null) { plug = instrument.PluginGenerator.PluginDevice; } else if (instrument.PluginProperties != null) { plug = instrument.PluginProperties.PluginDevice; } if (plug != null) { //var plug = instrument.PluginGenerator.PluginDevice; Song.Device device = null; Song.DeviceId deviceId; if (Enum.TryParse <Song.DeviceId>(plug.PluginIdentifier, out deviceId)) { device = new Song.Device(); device.Id = deviceId; device.Chunk = Convert.FromBase64String(FixBase64(plug.ParameterChunk)); rnsins.Device = device; } if (device == null) { logger.WriteLine(string.Format("WARNING: Instrument {0}[{2}] skipped (unsupported plugin): {1}", instrument.Name, plug.PluginIdentifier, insId)); } } else { logger.WriteLine(string.Format("WARNING: Instrument {0}[{1}] skipped (not a vst plugin)", instrument.Name, insId)); } instruments.Add(rnsins); insId++; } }
private Song.Track ConvertTrack(int trackId) { Song.Track songTrack = null; var trackObject = project.Tracks.Items[trackId]; string trackName = GetProp("Name", trackObject).ToString(); object[] trackDevices = ((TrackFilterDeviceChain)GetProp("FilterDevices", trackObject)).Devices.Items; var songPatterns = new List <Pattern>(); var allLines = new List <RsnPatternLineNode>(); // copy all patterns out to full song foreach (var seq in project.PatternSequence.SequenceEntries.SequenceEntry) { songPatterns.Add(project.PatternPool.Patterns.Pattern[seq.Pattern]); } // loop each pattern to create complete picture of notes and automations... int lineIndex = 0; foreach (var pattern in songPatterns) { var track = pattern.Tracks.Items[trackId]; // grab current lines on pattern var currentLines = (PatternLineNode[])GetProp("Lines", track); if (currentLines != null) { foreach (PatternLineNode line in currentLines) { var newLine = new RsnPatternLineNode(); newLine.NoteColumns = line.NoteColumns; newLine.EffectColumns = line.EffectColumns; newLine.OrigianlIndex = line.index; // keep original index for groooooove newLine.index = line.index += lineIndex; newLine.type = line.type; allLines.Add(newLine); } } lineIndex += pattern.NumberOfLines; } // convert tracker notes to midi events var allNotes = allLines.SelectMany(n => n.NoteColumns.NoteColumn); var allIns = allNotes.Select(n => n.Instrument).Where(i => i != null && i != "..").Distinct().ToList(); if (allIns.Count() > 1) { logger.WriteLine(string.Format( "WARNING: Track {0} has {1} instruments used, defaulting to instrument {2}", trackName, allIns.Count(), allIns.First())); } // automations.... int autoIndex = 0; var allAuto = new List <Song.Automation>(); var autoGroup = new List <PatternTrackAutomation>(); foreach (var pattern in songPatterns) { var track = pattern.Tracks.Items[trackId]; var automations = (PatternTrackAutomation)GetProp("Automations", track); if (automations != null) { autoGroup.Add(automations); } } // generate distinct list of device id's and params used on this track var pita = new List <PatternTrackEnvelope>(); if (autoGroup.Count > 0) { var allEnv = autoGroup.Select(g => g.Envelopes); if (allEnv != null) { foreach (var temp in allEnv) { pita.AddRange(temp.Envelope); } } } var distinct = pita.Select(a => new { DeviceIndex = a.DeviceIndex, ParamId = a.ParameterIndex }).Distinct().ToList(); // now populate each distinct device and param foreach (var thisAuto in distinct) { var thisAutoList = new List <RnsAuto>(); int deviceIndex = thisAuto.DeviceIndex; int paramId = thisAuto.ParamId; autoIndex = 0; foreach (var pattern in songPatterns) { var track = pattern.Tracks.Items[trackId]; var automations = (PatternTrackAutomation)GetProp("Automations", track); if (automations == null) { // pattern has no autos, add start / end from last auto value if (thisAutoList.Count > 0) { var newAuto = new RnsAuto(); newAuto.TimePoint = 0; // <--- start of pattern newAuto.Value = thisAutoList.Last().Value; newAuto.AutoLength = pattern.NumberOfLines * 256; newAuto.Offset = autoIndex; thisAutoList.Add(newAuto); newAuto = new RnsAuto(); newAuto.TimePoint = (pattern.NumberOfLines * 256) - 1; // <--- end of pattern newAuto.Value = thisAutoList.Last().Value; newAuto.AutoLength = pattern.NumberOfLines * 256; newAuto.Offset = autoIndex; thisAutoList.Add(newAuto); } } else { var myAutos = automations.Envelopes.Envelope.Where(a => a.DeviceIndex == deviceIndex && a.ParameterIndex == paramId); if (myAutos.ToList().Count == 0) { // this pattern has no autos, add start / end from last auto value if (thisAutoList.Count > 0) { var newAuto = new RnsAuto(); newAuto.TimePoint = 0; // <--- start of pattern newAuto.Value = thisAutoList.Last().Value; newAuto.AutoLength = pattern.NumberOfLines * 256; newAuto.Offset = autoIndex; thisAutoList.Add(newAuto); newAuto = new RnsAuto(); newAuto.TimePoint = (pattern.NumberOfLines * 256) - 1; // <--- end of pattern newAuto.Value = thisAutoList.Last().Value; newAuto.AutoLength = pattern.NumberOfLines * 256; newAuto.Offset = autoIndex; thisAutoList.Add(newAuto); } } else { // this pattern has automations.. so process foreach (var a in myAutos) { var autoTemp = new List <RnsAuto>(); foreach (string point in a.Envelope.Points) // add all current points { var timePoint = Convert.ToInt32(point.Split(',')[0]); var value = (float)Convert.ToDouble(point.Split(',')[1]); var newAuto = new RnsAuto(); newAuto.TimePoint = timePoint; newAuto.Value = value; newAuto.AutoLength = a.Envelope.Length; newAuto.Offset = autoIndex; autoTemp.Add(newAuto); } // create auto point for the start of this pattern if (autoTemp.First().TimePoint != 0) { var newAuto = new RnsAuto(); newAuto.TimePoint = 0; // <--- start of pattern newAuto.Value = autoTemp.First().Value; newAuto.AutoLength = autoTemp.First().AutoLength; newAuto.Offset = autoIndex; autoTemp.Insert(0, newAuto); } // create auto point for the end of this pattern if (autoTemp.Last().TimePoint != autoTemp.Last().AutoLength - 1) { var newAuto = new RnsAuto(); newAuto.TimePoint = autoTemp.Last().AutoLength - 1; // <--- end of pattern newAuto.Value = autoTemp.Last().Value; newAuto.AutoLength = autoTemp.Last().AutoLength; newAuto.Offset = autoIndex; autoTemp.Add(newAuto); } thisAutoList.AddRange(autoTemp); } } } // next position autoIndex += pattern.NumberOfLines * 256; } // double check we have starting point for this auto in case of a blank pattern if (thisAutoList.First().TimePoint != 0) { var newAuto = new RnsAuto(); newAuto.TimePoint = 0; // <--- start of pattern newAuto.Value = thisAutoList.First().Value; newAuto.AutoLength = thisAutoList.First().AutoLength; newAuto.Offset = autoIndex; thisAutoList.ToList().Insert(0, newAuto); } // all automation points for this device / param collated, now convert to our automations thisAutoList.ForEach(a => a.TimePoint += a.Offset); var finalAuto = new Song.Automation(); finalAuto.DeviceIndex = deviceIndex; finalAuto.ParamId = paramId - 1; // renoise param index is out by one due to automation on active flag foreach (var p in thisAutoList) { var point = new Song.Point(); point.Value = p.Value; point.TimeStamp = SecondsToSamples(p.TimePoint / 256.00 * (double)secondsPerIndex, sampleRate); finalAuto.Points.Add(point); } allAuto.Add(finalAuto); } RnsIns instrument = null; int instrumentId = -1; if (allIns.Count > 0) { instrumentId = Convert.ToInt32(allIns.First()); instrument = instruments.Where(i => i.InstrumentId == instrumentId).First(); } songTrack = new Song.Track(); songTrack.Name = trackName; songTrack.Volume = GetTrackVolume(trackDevices[0]); var devices = new List <RnsDevice>(); if (instrument != null) { devices.Add(new RnsDevice() { DeviceIndex = 0, Device = instrument.Device }); } devices.AddRange(GetDevices(trackDevices, trackName, instrumentId)); // add track devices foreach (var device in devices) { if (device.Device is Song.Device) { songTrack.Devices.Add((Song.Device)device.Device); } } // remap automations to correct devices foreach (var auto in allAuto) { if (devices.Find(a => a.DeviceIndex == auto.DeviceIndex).Device is InstrumentAutomationDevice) { auto.DeviceIndex = 0; // 0 is always instrument } else { auto.DeviceIndex = devices.IndexOf( devices.Find(a => a.DeviceIndex == auto.DeviceIndex && a.Device is Song.Device)); } } if (allAuto.RemoveAll(auto => auto.DeviceIndex == -1) > 0) { logger.WriteLine(string.Format("WARNING: Some automations skipped on track {0}", trackName)); } songTrack.Automations.AddRange(allAuto); songTrack.Events = NotesToEvents(allLines); return(songTrack); }