Ejemplo n.º 1
0
        private RenderItem BuildRenderItem(UPhoneme phoneme, UVoicePart part, UProject project)
        {
            USinger singer  = project.Tracks[part.TrackNo].Singer;
            string  rawfile = Lib.EncodingUtil.ConvertEncoding(singer.FileEncoding, singer.PathEncoding, phoneme.Oto.File);

            rawfile = Path.Combine(singer.Path, rawfile);

            double strechRatio      = Math.Pow(2, 1.0 - (double)(int)phoneme.Parent.Expressions["velocity"].Data / 100);
            double length           = phoneme.Oto.Preutter * strechRatio + phoneme.Envelope.Points[4].X;
            double requiredLength   = Math.Ceiling(length / 50 + 1) * 50;
            double lengthAdjustment = phoneme.TailIntrude == 0 ? phoneme.Preutter : phoneme.Preutter - phoneme.TailIntrude + phoneme.TailOverlap;

            RenderItem item = new RenderItem()
            {
                // For resampler
                RawFile        = rawfile,
                NoteNum        = phoneme.Parent.NoteNum,
                Velocity       = (int)phoneme.Parent.Expressions["velocity"].Data,
                Volume         = (int)phoneme.Parent.Expressions["volume"].Data,
                StrFlags       = phoneme.Parent.GetResamplerFlags(),
                PitchData      = BuildPitchData(phoneme, part, project),
                RequiredLength = (int)requiredLength,
                Oto            = phoneme.Oto,
                Tempo          = project.BPM,

                // For connector
                SkipOver = phoneme.Oto.Preutter * strechRatio - phoneme.Preutter,
                PosMs    = project.TickToMillisecond(part.PosTick + phoneme.Parent.PosTick + phoneme.PosTick) - phoneme.Preutter,
                DurMs    = project.TickToMillisecond(phoneme.DurTick) + lengthAdjustment,
                Envelope = phoneme.Envelope.Points
            };

            return(item);
        }
Ejemplo n.º 2
0
        public RenderItem(UPhoneme phoneme, UVoicePart part, UProject project)
        {
            var singer = project.Tracks[part.TrackNo].Singer;

            SourceFile = phoneme.Oto.File;
            SourceFile = Path.Combine(PathManager.Inst.InstalledSingersPath, SourceFile);

            var strechRatio      = Math.Pow(2, 1.0 - (double)(int)phoneme.Parent.Expressions["velocity"].Data / 100);
            var length           = phoneme.Oto.Preutter * strechRatio + phoneme.Envelope.Points[4].X;
            var requiredLength   = Math.Ceiling(length / 50 + 1) * 50;
            var lengthAdjustment = phoneme.TailIntrude == 0 ? phoneme.Preutter : phoneme.Preutter - phoneme.TailIntrude + phoneme.TailOverlap;

            NoteNum        = phoneme.Parent.NoteNum;
            Velocity       = (int)phoneme.Parent.Expressions["velocity"].Data;
            Volume         = (int)phoneme.Parent.Expressions["volume"].Data;
            StrFlags       = phoneme.Parent.GetResamplerFlags();
            PitchData      = BuildPitchData(phoneme, part, project);
            RequiredLength = (int)requiredLength;
            Oto            = phoneme.Oto;
            Tempo          = project.BPM;

            SkipOver = phoneme.Oto.Preutter * strechRatio - phoneme.Preutter;
            PosMs    = project.TickToMillisecond(part.PosTick + phoneme.Parent.PosTick + phoneme.PosTick) - phoneme.Preutter;
            DurMs    = project.TickToMillisecond(phoneme.DurTick) + lengthAdjustment;
            Envelope = phoneme.Envelope.Points;

            phonemeName = phoneme.Phoneme;
        }
Ejemplo n.º 3
0
        public Tuple <MasterAdapter, List <Fader>, CancellationTokenSource, Task> RenderProject(int startTick)
        {
            var source = new CancellationTokenSource();
            var items  = new List <RenderItem>();
            var faders = new List <Fader>();

            foreach (var track in project.tracks)
            {
                var trackItems = PrepareTrack(track, project, startTick).ToArray();
                var sources    = trackItems.Select(item => {
                    var waveSource  = new WaveSource(item.PosMs, item.DurMs, item.Envelope, item.SkipOver);
                    item.OnComplete = data => waveSource.SetWaveData(data);
                    return(waveSource);
                }).ToList();
                sources.AddRange(project.parts
                                 .Where(part => part is UWavePart && part.trackNo == track.TrackNo)
                                 .Select(part => part as UWavePart)
                                 .Select(part => {
                    var waveSource = new WaveSource(
                        project.TickToMillisecond(part.position),
                        project.TickToMillisecond(part.Duration),
                        null,
                        part.skipMs);
                    if (part.Samples != null)
                    {
                        waveSource.SetSamples(part.Samples);
                    }
                    return(waveSource);
                }));
                var trackMix = new WaveMix(sources);
                items.AddRange(trackItems);
                var fader = new Fader(trackMix);
                fader.Scale = PlaybackManager.DecibelToVolume(track.Volume);
                faders.Add(fader);
            }
            items = items.OrderBy(item => item.PosMs).ToList();
            int threads  = Util.Preferences.Default.PrerenderThreads;
            var progress = new Progress(items.Count);
            var task     = Task.Run(() => {
                var progress = new Progress(items.Count);
                Parallel.ForEach(source: items, parallelOptions: new ParallelOptions()
                {
                    MaxDegreeOfParallelism = threads
                }, body: item => {
                    if (source.Token.IsCancellationRequested)
                    {
                        return;
                    }
                    item.progress = progress;
                    Resample(item);
                });
                ReleaseSourceTemp();
                progress.Clear();
            });
            var master = new MasterAdapter(new WaveMix(faders));

            master.SetPosition((int)(project.TickToMillisecond(startTick) * 44100 / 1000));
            return(Tuple.Create(master, faders, source, task));
        }
Ejemplo n.º 4
0
        private void Render(UProject project, int tick)
        {
            IResamplerDriver driver = GetPreviewDriver();

            if (driver == null)
            {
                return;
            }
            StopPreRender();
            var scheduler = TaskScheduler.FromCurrentSynchronizationContext();

            Task.Run(() => {
                RenderEngine engine = new RenderEngine(project, driver, cache, tick);
                var result          = engine.RenderProject(tick);
                faders     = result.Item2;
                var source = result.Item3;
                source     = Interlocked.Exchange(ref playbakCancellationTokenSource, source);
                if (source != null)
                {
                    source.Cancel();
                    Log.Information("Cancelling previous render");
                }
                StartPlayback(project.TickToMillisecond(tick), result.Item1);
            }).ContinueWith((task) => {
                if (task.IsFaulted)
                {
                    Log.Information($"{task.Exception}");
                    DocManager.Inst.ExecuteCmd(new UserMessageNotification(task.Exception.ToString()));
                    throw task.Exception;
                }
            }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, scheduler);
        }
Ejemplo n.º 5
0
        public RenderItem(UPhoneme phoneme, UVoicePart part, UTrack track, UProject project, string resamplerName)
        {
            SourceFile    = phoneme.oto.File;
            SourceFile    = Path.Combine(PathManager.Inst.InstalledSingersPath, SourceFile);
            ResamplerName = resamplerName;
            if (project.expressions.TryGetValue("eng", out var descriptor))
            {
                int    index     = (int)phoneme.GetExpression(project, "eng").Item1;
                string resampler = descriptor.options[index];
                if (!string.IsNullOrEmpty(resampler))
                {
                    ResamplerName = resampler;
                }
            }
            string ext = Path.GetExtension(SourceFile);

            SourceTemp = Path.Combine(PathManager.Inst.GetCachePath(null),
                                      $"{HashHex(track.Singer.Id)}-{HashHex(phoneme.oto.Set)}-{HashHex(SourceFile)}{ext}");

            Velocity   = (int)phoneme.GetExpression(project, "vel").Item1;
            Volume     = (int)phoneme.GetExpression(project, "vol").Item1;
            Modulation = (int)phoneme.GetExpression(project, "mod").Item1;
            var strechRatio      = Math.Pow(2, 1.0 - Velocity / 100.0);
            var length           = phoneme.oto.Preutter * strechRatio + phoneme.envelope.data[4].X;
            var requiredLength   = Math.Ceiling(length / 50 + 1) * 50;
            var lengthAdjustment = phoneme.tailIntrude == 0 ? phoneme.preutter : phoneme.preutter - phoneme.tailIntrude + phoneme.tailOverlap;

            NoteNum        = phoneme.Parent.tone;
            StrFlags       = phoneme.GetResamplerFlags(project);
            PitchData      = BuildPitchData(phoneme, part, project);
            RequiredLength = (int)requiredLength;
            Oto            = phoneme.oto;
            Tempo          = project.bpm;

            SkipOver = phoneme.oto.Preutter * strechRatio - phoneme.preutter;
            PosMs    = project.TickToMillisecond(part.position + phoneme.Parent.position + phoneme.position) - phoneme.preutter;
            DurMs    = project.TickToMillisecond(phoneme.Duration) + lengthAdjustment;
            Envelope = phoneme.envelope.data;

            phonemeName = phoneme.phoneme;
        }
Ejemplo n.º 6
0
        public async Task <List <TrackSampleProvider> > RenderAsync()
        {
            List <TrackSampleProvider> trackSampleProviders = project.Tracks.Select(
                track => new TrackSampleProvider()
            {
                Volume = PlaybackManager.DecibelToVolume(track.Volume)
            }).ToList();
            var cacheDir = PathManager.Inst.GetCachePath(project.FilePath);

            foreach (UPart part in project.Parts)
            {
                UVoicePart voicePart = part as UVoicePart;
                if (voicePart != null)
                {
                    SequencingSampleProvider sampleProvider = await RenderPartAsync(voicePart, project, cacheDir);

                    if (sampleProvider != null)
                    {
                        trackSampleProviders[voicePart.TrackNo].AddSource(
                            sampleProvider,
                            TimeSpan.FromMilliseconds(project.TickToMillisecond(voicePart.PosTick)));
                    }
                }
                UWavePart wavePart = part as UWavePart;
                if (wavePart != null)
                {
                    try {
                        var stream = new AudioFileReader(wavePart.FilePath);
                        trackSampleProviders[wavePart.TrackNo].AddSource(
                            new WaveToSampleProvider(stream),
                            TimeSpan.FromMilliseconds(project.TickToMillisecond(wavePart.PosTick)));
                    } catch (Exception e) {
                        Log.Error(e, "Failed to open audio file");
                    }
                }
            }
            return(trackSampleProviders);
        }
Ejemplo n.º 7
0
        private void BuildVoicePartDone(SequencingSampleProvider source, UPart part, UProject project)
        {
            lock (lockObject)
            {
                trackSources[part.TrackNo].AddSource(
                    source,
                    TimeSpan.FromMilliseconds(project.TickToMillisecond(part.PosTick)));
                pendingParts--;
            }

            if (pendingParts == 0)
            {
                StartPlayback();
            }
        }
Ejemplo n.º 8
0
        private void BuildAudio(UProject project)
        {
            trackSources = new List <TrackSampleProvider>();
            foreach (UTrack track in project.Tracks)
            {
                trackSources.Add(new TrackSampleProvider()
                {
                    Volume = DecibelToVolume(track.Volume), Pan = track.Pan
                });
            }
            pendingParts = project.Parts.Count;
            foreach (UPart part in project.Parts)
            {
                if (part is UWavePart)
                {
                    lock (lockObject)
                    {
                        trackSources[part.TrackNo].AddSource(
                            BuildWavePartAudio(part as UWavePart, project),
                            TimeSpan.FromMilliseconds(project.TickToMillisecond(part.PosTick))
                            );
                        pendingParts--;
                    }
                }
                else
                {
                    var singer = project.Tracks[part.TrackNo].Singer;
                    if (singer != null && singer.Loaded)
                    {
                        FileInfo         ResamplerFile = new FileInfo(PathManager.Inst.GetPreviewEnginePath());
                        IResamplerDriver engine        = ResamplerDriver.ResamplerDriver.LoadEngine(ResamplerFile.FullName);
                        BuildVoicePartAudio(part as UVoicePart, project, engine);
                    }
                    else
                    {
                        lock (lockObject) { pendingParts--; }
                    }
                }
            }

            if (pendingParts == 0)
            {
                StartPlayback();
            }
        }
Ejemplo n.º 9
0
        static public UProject Load(string file)
        {
            XmlDocument vsqx = new XmlDocument();

            try
            {
                vsqx.Load(file);
            }
            catch (Exception e)
            {
                System.Windows.MessageBox.Show(e.GetType().ToString() + "\n" + e.Message);
                return(null);
            }

            XmlNamespaceManager nsmanager = new XmlNamespaceManager(vsqx.NameTable);

            nsmanager.AddNamespace("v3", vsq3NameSpace);
            nsmanager.AddNamespace("v4", vsq4NameSpace);

            XmlNode root;
            string  nsPrefix;

            // Detect vsqx version
            root = vsqx.SelectSingleNode("v3:vsq3", nsmanager);

            if (root != null)
            {
                nsPrefix = "v3:";
            }
            else
            {
                root = vsqx.SelectSingleNode("v4:vsq4", nsmanager);

                if (root != null)
                {
                    nsPrefix = "v4:";
                }
                else
                {
                    System.Windows.MessageBox.Show("Unrecognizable VSQx file format.");
                    return(null);
                }
            }

            UProject uproject = new UProject();

            uproject.RegisterExpression(new IntExpression(null, "velocity", "VEL")
            {
                Data = 64, Min = 0, Max = 127
            });
            uproject.RegisterExpression(new IntExpression(null, "volume", "VOL")
            {
                Data = 100, Min = 0, Max = 200
            });
            uproject.RegisterExpression(new IntExpression(null, "opening", "OPE")
            {
                Data = 127, Min = 0, Max = 127
            });
            uproject.RegisterExpression(new IntExpression(null, "accent", "ACC")
            {
                Data = 50, Min = 0, Max = 100
            });
            uproject.RegisterExpression(new IntExpression(null, "decay", "DEC")
            {
                Data = 50, Min = 0, Max = 100
            });

            string bpmPath            = string.Format("{0}masterTrack/{0}tempo/{0}{1}", nsPrefix, nsPrefix == "v3:" ? "bpm" : "v");
            string beatperbarPath     = string.Format("{0}masterTrack/{0}timeSig/{0}{1}", nsPrefix, nsPrefix == "v3:" ? "nume" : "nu");
            string beatunitPath       = string.Format("{0}masterTrack/{0}timeSig/{0}{1}", nsPrefix, nsPrefix == "v3:" ? "denomi" : "de");
            string premeasurePath     = string.Format("{0}masterTrack/{0}preMeasure", nsPrefix);
            string resolutionPath     = string.Format("{0}masterTrack/{0}resolution", nsPrefix);
            string projectnamePath    = string.Format("{0}masterTrack/{0}seqName", nsPrefix);
            string projectcommentPath = string.Format("{0}masterTrack/{0}comment", nsPrefix);
            string trackPath          = string.Format("{0}vsTrack", nsPrefix);
            string tracknamePath      = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "trackName" : "name");
            string trackcommentPath   = string.Format("{0}comment", nsPrefix);
            string tracknoPath        = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "vsTrackNo" : "tNo");
            string partPath           = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "musicalPart" : "vsPart");
            string partnamePath       = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "partName" : "name");
            string partcommentPath    = string.Format("{0}comment", nsPrefix);
            string notePath           = string.Format("{0}note", nsPrefix);
            string postickPath        = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "posTick" : "t");
            string durtickPath        = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "durTick" : "dur");
            string notenumPath        = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "noteNum" : "n");
            string velocityPath       = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "velocity" : "v");
            string lyricPath          = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "lyric" : "y");
            string phonemePath        = string.Format("{0}{1}", nsPrefix, nsPrefix == "v3:" ? "phnms" : "p");
            string playtimePath       = string.Format("{0}playTime", nsPrefix);
            string partstyleattrPath  = string.Format("{0}{1}/{0}{2}", nsPrefix, nsPrefix == "v3:" ? "partStyle" : "pStyle", nsPrefix == "v3:" ? "attr" : "v");
            string notestyleattrPath  = string.Format("{0}{1}/{0}{2}", nsPrefix, nsPrefix == "v3:" ? "noteStyle" : "nStyle", nsPrefix == "v3:" ? "attr" : "v");

            uproject.BPM        = Convert.ToDouble(root.SelectSingleNode(bpmPath, nsmanager).InnerText) / 100;
            uproject.BeatPerBar = int.Parse(root.SelectSingleNode(beatperbarPath, nsmanager).InnerText);
            uproject.BeatUnit   = int.Parse(root.SelectSingleNode(beatunitPath, nsmanager).InnerText);
            uproject.Resolution = int.Parse(root.SelectSingleNode(resolutionPath, nsmanager).InnerText);
            uproject.FilePath   = file;
            uproject.Name       = root.SelectSingleNode(projectnamePath, nsmanager).InnerText;
            uproject.Comment    = root.SelectSingleNode(projectcommentPath, nsmanager).InnerText;

            int preMeasure       = int.Parse(root.SelectSingleNode(premeasurePath, nsmanager).InnerText);
            int partPosTickShift = -preMeasure * uproject.Resolution * uproject.BeatPerBar * 4 / uproject.BeatUnit;

            USinger usinger = new USinger();

            uproject.Singers.Add(usinger);

            foreach (XmlNode track in root.SelectNodes(trackPath, nsmanager)) // track
            {
                UTrack utrack = new UTrack()
                {
                    Singer = usinger, TrackNo = uproject.Tracks.Count
                };
                uproject.Tracks.Add(utrack);

                utrack.Name    = track.SelectSingleNode(tracknamePath, nsmanager).InnerText;
                utrack.Comment = track.SelectSingleNode(trackcommentPath, nsmanager).InnerText;
                utrack.TrackNo = int.Parse(track.SelectSingleNode(tracknoPath, nsmanager).InnerText);

                foreach (XmlNode part in track.SelectNodes(partPath, nsmanager)) // musical part
                {
                    UVoicePart upart = new UVoicePart();
                    uproject.Parts.Add(upart);

                    upart.Name    = part.SelectSingleNode(partnamePath, nsmanager).InnerText;
                    upart.Comment = part.SelectSingleNode(partcommentPath, nsmanager).InnerText;
                    upart.PosTick = int.Parse(part.SelectSingleNode(postickPath, nsmanager).InnerText) + partPosTickShift;
                    upart.DurTick = int.Parse(part.SelectSingleNode(playtimePath, nsmanager).InnerText);
                    upart.TrackNo = utrack.TrackNo;

                    foreach (XmlNode note in part.SelectNodes(notePath, nsmanager))
                    {
                        UNote unote = uproject.CreateNote();

                        unote.PosTick             = int.Parse(note.SelectSingleNode(postickPath, nsmanager).InnerText);
                        unote.DurTick             = int.Parse(note.SelectSingleNode(durtickPath, nsmanager).InnerText);
                        unote.NoteNum             = int.Parse(note.SelectSingleNode(notenumPath, nsmanager).InnerText);
                        unote.Lyric               = note.SelectSingleNode(lyricPath, nsmanager).InnerText;
                        unote.Phonemes[0].Phoneme = note.SelectSingleNode(phonemePath, nsmanager).InnerText;

                        unote.Expressions["velocity"].Data = int.Parse(note.SelectSingleNode(velocityPath, nsmanager).InnerText);

                        foreach (XmlNode notestyle in note.SelectNodes(notestyleattrPath, nsmanager))
                        {
                            if (notestyle.Attributes["id"].Value == "opening")
                            {
                                unote.Expressions["opening"].Data = int.Parse(notestyle.InnerText);
                            }
                            else if (notestyle.Attributes["id"].Value == "accent")
                            {
                                unote.Expressions["accent"].Data = int.Parse(notestyle.InnerText);
                            }
                            else if (notestyle.Attributes["id"].Value == "decay")
                            {
                                unote.Expressions["decay"].Data = int.Parse(notestyle.InnerText);
                            }
                        }
                        unote.PitchBend.Points[0].X = -uproject.TickToMillisecond(Math.Min(15, unote.DurTick / 3));
                        unote.PitchBend.Points[1].X = -unote.PitchBend.Points[0].X;
                        upart.Notes.Add(unote);
                    }
                }
            }

            return(uproject);
        }
Ejemplo n.º 10
0
        public static UProject Load(string file)
        {
            XmlDocument vsqx = new XmlDocument();

            vsqx.Load(file);

            XmlNamespaceManager nsmanager = new XmlNamespaceManager(vsqx.NameTable);

            nsmanager.AddNamespace("v3", vsq3NameSpace);
            nsmanager.AddNamespace("v4", vsq4NameSpace);

            XmlNode root;
            string  nsPrefix;

            // Detect vsqx version
            if ((root = vsqx.SelectSingleNode("v3:vsq3", nsmanager)) != null)
            {
                nsPrefix = "v3:";
            }
            else if ((root = vsqx.SelectSingleNode("v4:vsq4", nsmanager)) != null)
            {
                nsPrefix = "v4:";
            }
            else
            {
                throw new FileFormatException("Unrecognizable VSQx file format.");
            }

            UProject uproject = new UProject();

            Ustx.AddDefaultExpressions(uproject);
            uproject.RegisterExpression(new UExpressionDescriptor("opening", "ope", 0, 100, 100));

            string bpmPath            = $"{nsPrefix}masterTrack/{nsPrefix}tempo/{nsPrefix}{(nsPrefix == "v3:" ? "bpm" : "v")}";
            string beatperbarPath     = $"{nsPrefix}masterTrack/{nsPrefix}timeSig/{nsPrefix}{(nsPrefix == "v3:" ? "nume" : "nu")}";
            string beatunitPath       = $"{nsPrefix}masterTrack/{nsPrefix}timeSig/{nsPrefix}{(nsPrefix == "v3:" ? "denomi" : "de")}";
            string premeasurePath     = $"{nsPrefix}masterTrack/{nsPrefix}preMeasure";
            string resolutionPath     = $"{nsPrefix}masterTrack/{nsPrefix}resolution";
            string projectnamePath    = $"{nsPrefix}masterTrack/{nsPrefix}seqName";
            string projectcommentPath = $"{nsPrefix}masterTrack/{nsPrefix}comment";
            string trackPath          = $"{nsPrefix}vsTrack";
            string tracknamePath      = $"{nsPrefix}{(nsPrefix == "v3:" ? "trackName" : "name")}";
            string trackcommentPath   = $"{nsPrefix}comment";
            string tracknoPath        = $"{nsPrefix}{(nsPrefix == "v3:" ? "vsTrackNo" : "tNo")}";
            string partPath           = $"{nsPrefix}{(nsPrefix == "v3:" ? "musicalPart" : "vsPart")}";
            string partnamePath       = $"{nsPrefix}{(nsPrefix == "v3:" ? "partName" : "name")}";
            string partcommentPath    = $"{nsPrefix}comment";
            string notePath           = $"{nsPrefix}note";
            string postickPath        = $"{nsPrefix}{(nsPrefix == "v3:" ? "posTick" : "t")}";
            string durtickPath        = $"{nsPrefix}{(nsPrefix == "v3:" ? "durTick" : "dur")}";
            string notenumPath        = $"{nsPrefix}{(nsPrefix == "v3:" ? "noteNum" : "n")}";
            string velocityPath       = $"{nsPrefix}{(nsPrefix == "v3:" ? "velocity" : "v")}";
            string lyricPath          = $"{nsPrefix}{(nsPrefix == "v3:" ? "lyric" : "y")}";
            string phonemePath        = $"{nsPrefix}{(nsPrefix == "v3:" ? "phnms" : "p")}";
            string playtimePath       = $"{nsPrefix}playTime";
            string partstyleattrPath  = $"{nsPrefix}{(nsPrefix == "v3:" ? "partStyle" : "pStyle")}/{nsPrefix}{(nsPrefix == "v3:" ? "attr" : "v")}";
            string notestyleattrPath  = $"{nsPrefix}{(nsPrefix == "v3:" ? "noteStyle" : "nStyle")}/{nsPrefix}{(nsPrefix == "v3:" ? "attr" : "v")}";

            uproject.bpm        = Convert.ToDouble(root.SelectSingleNode(bpmPath, nsmanager).InnerText) / 100;
            uproject.beatPerBar = int.Parse(root.SelectSingleNode(beatperbarPath, nsmanager).InnerText);
            uproject.beatUnit   = int.Parse(root.SelectSingleNode(beatunitPath, nsmanager).InnerText);
            uproject.resolution = int.Parse(root.SelectSingleNode(resolutionPath, nsmanager).InnerText);
            uproject.FilePath   = file;
            uproject.name       = root.SelectSingleNode(projectnamePath, nsmanager).InnerText;
            uproject.comment    = root.SelectSingleNode(projectcommentPath, nsmanager).InnerText;

            int preMeasure       = int.Parse(root.SelectSingleNode(premeasurePath, nsmanager).InnerText);
            int partPosTickShift = -preMeasure * uproject.resolution * uproject.beatPerBar * 4 / uproject.beatUnit;

            USinger usinger = new USinger("");

            foreach (XmlNode track in root.SelectNodes(trackPath, nsmanager)) // track
            {
                UTrack utrack = new UTrack()
                {
                    Singer = usinger, TrackNo = uproject.tracks.Count
                };
                uproject.tracks.Add(utrack);

                //utrack.Name = track.SelectSingleNode(tracknamePath, nsmanager).InnerText;
                //utrack.Comment = track.SelectSingleNode(trackcommentPath, nsmanager).InnerText;
                utrack.TrackNo = int.Parse(track.SelectSingleNode(tracknoPath, nsmanager).InnerText);

                foreach (XmlNode part in track.SelectNodes(partPath, nsmanager)) // musical part
                {
                    UVoicePart upart = new UVoicePart();
                    uproject.parts.Add(upart);

                    upart.name     = part.SelectSingleNode(partnamePath, nsmanager).InnerText;
                    upart.comment  = part.SelectSingleNode(partcommentPath, nsmanager).InnerText;
                    upart.position = int.Parse(part.SelectSingleNode(postickPath, nsmanager).InnerText) + partPosTickShift;
                    upart.Duration = int.Parse(part.SelectSingleNode(playtimePath, nsmanager).InnerText);
                    upart.trackNo  = utrack.TrackNo;

                    foreach (XmlNode note in part.SelectNodes(notePath, nsmanager))
                    {
                        UNote unote = uproject.CreateNote();

                        unote.position = int.Parse(note.SelectSingleNode(postickPath, nsmanager).InnerText);
                        unote.duration = int.Parse(note.SelectSingleNode(durtickPath, nsmanager).InnerText);
                        unote.tone     = int.Parse(note.SelectSingleNode(notenumPath, nsmanager).InnerText);
                        unote.lyric    = note.SelectSingleNode(lyricPath, nsmanager).InnerText;
                        if (unote.lyric == "-")
                        {
                            unote.lyric = "...";
                        }

                        unote.phonemeExpressions.Add(new UExpression("vel")
                        {
                            index = 0,
                            value = int.Parse(note.SelectSingleNode(velocityPath, nsmanager).InnerText) * 100 / 64,
                        });
                        foreach (XmlNode notestyle in note.SelectNodes(notestyleattrPath, nsmanager))
                        {
                            if (notestyle.Attributes["id"].Value == "opening")
                            {
                                unote.phonemeExpressions.Add(new UExpression("ope")
                                {
                                    index = 0,
                                    value = int.Parse(notestyle.InnerText) * 100 / 127,
                                });
                            }
                            else if (notestyle.Attributes["id"].Value == "accent")
                            {
                                unote.phonemeExpressions.Add(new UExpression("atk")
                                {
                                    index = 0,
                                    value = int.Parse(notestyle.InnerText) * 2,
                                });
                            }
                            else if (notestyle.Attributes["id"].Value == "decay")
                            {
                                unote.phonemeExpressions.Add(new UExpression("dec")
                                {
                                    index = 0,
                                    // V4 default is 50. Translate it to no effect in OU. V4 dec 100 roughly maps to OU 50.
                                    value = Math.Max(0, int.Parse(notestyle.InnerText) - 50),
                                });
                            }
                        }

                        unote.pitch.data[0].X = -(float)uproject.TickToMillisecond(Math.Min(15, unote.duration / 3));
                        unote.pitch.data[1].X = -unote.pitch.data[0].X;
                        upart.notes.Add(unote);
                    }
                }
            }

            uproject.AfterLoad();
            uproject.Validate();
            return(uproject);
        }
Ejemplo n.º 11
0
        private List <int> BuildPitchData(UPhoneme phoneme, UVoicePart part, UProject project)
        {
            int  leftBound  = phoneme.Parent.position + phoneme.position - project.MillisecondToTick(phoneme.preutter);
            int  rightBound = phoneme.Parent.position + phoneme.position + phoneme.Duration - project.MillisecondToTick(phoneme.tailIntrude - phoneme.tailOverlap);
            var  leftNote   = phoneme.Parent;
            var  rightNote  = phoneme.Parent;
            bool oneMore    = true;

            while ((leftBound < leftNote.RightBound || oneMore) && leftNote.Prev != null && leftNote.Prev.End == leftNote.position)
            {
                leftNote = leftNote.Prev;
                if (leftBound >= leftNote.RightBound)
                {
                    oneMore = false;
                }
            }
            oneMore = true;
            while ((rightBound > rightNote.LeftBound || oneMore) && rightNote.Next != null && rightNote.Next.position == rightNote.End)
            {
                rightNote = rightNote.Next;
                if (rightBound <= rightNote.LeftBound)
                {
                    oneMore = false;
                }
            }

            // Collect pitch curve and vibratos.
            var   points      = new List <PitchPoint>();
            var   vibratos    = new List <Tuple <double, double, UVibrato> >();
            var   note        = leftNote;
            float vel         = Velocity;
            var   strechRatio = Math.Pow(2, 1.0 - vel / 100);
            float correction  = (float)(phoneme.oto.Preutter * (strechRatio - 1));

            while (true)
            {
                var offsetMs = (float)project.TickToMillisecond(note.position - phoneme.Parent.position);
                foreach (var point in note.pitch.data)
                {
                    var newpp = point.Clone();
                    newpp.X += offsetMs + correction;
                    newpp.Y -= (phoneme.Parent.tone - note.tone) * 10;
                    points.Add(newpp);
                }
                if (note.vibrato.length != 0)
                {
                    double vibratoStartMs = project.TickToMillisecond(note.position + note.duration * (1 - note.vibrato.length / 100) - phoneme.Parent.position);
                    double vibratoEndMs   = project.TickToMillisecond(note.End - phoneme.Parent.position);
                    vibratos.Add(Tuple.Create(vibratoStartMs, vibratoEndMs, note.vibrato));
                }
                if (note == rightNote)
                {
                    break;
                }
                note = note.Next;
            }

            // Expand curve if necessary.
            float startMs = (float)(project.TickToMillisecond(phoneme.position) - phoneme.oto.Preutter);
            float endMs   = (float)(project.TickToMillisecond(phoneme.End) - phoneme.tailIntrude + phoneme.tailOverlap);

            if (points.First().X > startMs)
            {
                points.Insert(0, new PitchPoint(startMs, points.First().Y));
            }
            if (points.Last().X < endMs)
            {
                points.Add(new PitchPoint(endMs, points.Last().Y));
            }

            // Interpolation.
            var       pitches      = new List <int>();
            const int intervalTick = 5;
            float     intervalMs   = (float)project.TickToMillisecond(intervalTick);
            float     currMs       = startMs;
            int       i            = 0;
            int       vibrato      = 0;

            while (currMs < endMs)
            {
                while (points[i + 1].X < currMs)
                {
                    i++;
                }
                var pit = MusicMath.InterpolateShape(points[i].X, points[i + 1].X, points[i].Y, points[i + 1].Y, currMs, points[i].shape) * 10;
                while (vibrato < vibratos.Count - 1 && vibratos[vibrato].Item2 < currMs)
                {
                    vibrato++;
                }
                if (vibrato < vibratos.Count && vibratos[vibrato].Item1 <= currMs && currMs < vibratos[vibrato].Item2)
                {
                    pit += InterpolateVibrato(vibratos[vibrato].Item3, currMs - vibratos[vibrato].Item1, vibratos[vibrato].Item2 - vibratos[vibrato].Item1, project);
                }
                pitches.Add((int)pit);
                currMs += intervalMs;
            }

            return(pitches);
        }