Esempio n. 1
0
        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++;
            }
        }
Esempio n. 2
0
        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);
        }