Ejemplo n.º 1
0
        public async Task <Unit> Handle(MoveNoteCommand request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            IReturnDbContext dbContext = this._returnDbContextFactory.CreateForEditContext();

            // Get data
            Note?note = await dbContext.Notes
                        .Include(x => x.Lane)
                        .Include(x => x.Group)
                        .Include(x => x.Retrospective)
                        .FirstOrDefaultAsync(x => x.Id == request.NoteId, cancellationToken);

            if (note == null)
            {
                throw new NotFoundException(nameof(Note), request.NoteId);
            }

            NoteGroup?newTargetGroup = null;

            if (request.GroupId != null)
            {
                newTargetGroup = await dbContext.NoteGroups.Include(x => x.Lane).
                                 FirstOrDefaultAsync(x => x.Id == request.GroupId, cancellationToken);

                if (newTargetGroup == null)
                {
                    throw new NotFoundException(nameof(NoteGroup), request.GroupId.Value);
                }
            }

            // Validate
            if (newTargetGroup != null && note.Lane.Id != newTargetGroup.Lane.Id)
            {
                throw new InvalidOperationException("Invalid move command: this would result in a lane change.");
            }

            NoteGroup involvedGroup = newTargetGroup ??
                                      note.Group ??
                                      throw new InvalidOperationException("Note move from ungrouped to ungrouped");

            await this._securityValidator.EnsureAddOrUpdate(note.Retrospective, involvedGroup);

            // Update
            note.GroupId = newTargetGroup?.Id;
            note.Group   = newTargetGroup;

            await dbContext.SaveChangesAsync(cancellationToken);

            // Broadcast
            var broadcast =
                new NoteMovedNotification(note.Retrospective.UrlId.StringId, (int)note.Lane.Id, note.Id, note.GroupId);

            await this._mediator.Publish(broadcast, cancellationToken);

            return(Unit.Value);
        }
Ejemplo n.º 2
0
        public async Task <Note?> GetNoteAsyn(int noteId)
        {
            var response = await Client.GetStringAsync("https://localhost:44342/api/Notes/" + noteId.ToString());

            Note?note = JsonConvert.DeserializeObject <Note>(response);

            return(note);
        }
Ejemplo n.º 3
0
        public override Result Process(Note[] notes, Note?prev, Note?next, Note?prevNeighbour, Note?nextNeighbour)
        {
            // The overall logic is:
            // 1. Remove consonant: "duang" -> "uang".
            // 2. Lookup the trailing sound in vowel table: "uang" -> "_ang".
            // 3. Split the total duration and returns "duang" and "_ang".
            var    note  = notes[0];
            string vowel = string.Empty;

            if (note.lyric.Length > 2 && cSet.Contains(note.lyric.Substring(0, 2)))
            {
                // First try to find consonant "zh", "ch" or "sh", and extract vowel.
                vowel = note.lyric.Substring(2);
            }
            else if (note.lyric.Length > 1 && cSet.Contains(note.lyric.Substring(0, 1)))
            {
                // Then try to find single character consonants, and extract vowel.
                vowel = note.lyric.Substring(1);
            } // Otherwise we don't need the vowel.
            string phoneme0 = note.lyric;
            // We will need to split the total duration for phonemes, so we compute it here.
            int totalDuration = notes.Sum(n => n.duration);

            // Lookup the vowel split table. For example, "uang" will match "_ang".
            if (vDict.TryGetValue(vowel, out var phoneme1))
            {
                // Now phoneme0="duang" and phoneme1="_ang",
                // try to give "_ang" 120 ticks, but no more than half of the total duration.
                int length1 = 120;
                if (length1 > totalDuration / 2)
                {
                    length1 = totalDuration / 2;
                }
                return(new Result {
                    phonemes = new Phoneme[] {
                        new Phoneme()
                        {
                            phoneme = phoneme0,
                        },
                        new Phoneme()
                        {
                            phoneme = phoneme1,
                            position = totalDuration - length1,
                        }
                    },
                });
            }
            // Not spliting is needed. Return as is.
            return(new Result {
                phonemes = new Phoneme[] {
                    new Phoneme()
                    {
                        phoneme = phoneme0,
                    }
                },
            });
        }
Ejemplo n.º 4
0
        public double GetFrequency(Note?tuningNote = null)
        {
            if (tuningNote == null)
            {
                tuningNote = new Note?(Note.A4);
            }
            int dist = (int)(this.GetStep() - tuningNote.Value.GetStep());

            return(440.0 * Math.Pow(1.0594630943592953, (double)dist));
        }
Ejemplo n.º 5
0
 private void popNextNote()
 {
     if (songNotes.Count > 0)
     {
         nextNote = songNotes[0];
         songNotes.RemoveAt(0);
     }
     else
     {
         nextNote = null;
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Calculates the note's frequency in Hz.
        /// </summary>
        /// <param name="tuningNote">Optional note to use for tuning, this is Note.A4 (440 Hz) by default.</param>
        /// <returns>Frequency in Hz.</returns>
        public double GetFrequency(Note?tuningNote = null)
        {
            if (!tuningNote.HasValue)
            {
                tuningNote = Note.A4;
            }

            int    dist = GetStep() - tuningNote.Value.GetStep();
            double freq = 440 * Math.Pow(1.0594630943592952645618252949463, dist);

            return(freq);
        }
Ejemplo n.º 7
0
 public override Result Process(Note[] notes, Note?prev, Note?next, Note?prevNeighbour, Note?nextNeighbour)
 {
     // Note that even when input has multiple notes, only the leading note is used to produce phoneme.
     // This is because the 2nd+ notes will always be extender notes, i.e., with lyric "..." or "...<number>".
     // For this simple phonemizer, all these notes maps to a single phoneme.
     return(new Result {
         phonemes = new Phoneme[] {
             new Phoneme {
                 phoneme = notes[0].lyric,
             }
         }
     });
 }
        private async void OnDeleteNoteClicked(object?sender, EventArgs e)
        {
            if (_currentNote is null)
            {
                return;
            }

            await _guiContext.InvokeAsync(async() =>
            {
                DialogResult msg = MessageBox.Show("Delete selected note?", "Delete Note", MessageBoxButtons.YesNo);
                if (msg == DialogResult.Yes)
                {
                    var current = await _noteRepository.GetAsync(_currentNote.Id);
                    await _noteRepository.DeleteAsync(current);
                    _currentNote = null;
                    _eventService.Publish <RefreshListEvent>(new());
                }
            });
        }
Ejemplo n.º 9
0
        private static void AddIntroApplauseEvent(InstrumentalArrangement arrangement, Action <string> Log)
        {
            Level firstPhraseLevel;

            if (arrangement.Levels.Count == 1)
            {
                firstPhraseLevel = arrangement.Levels[0];
            }
            else
            {
                // Find the first phrase that has difficulty levels
                int firstPhraseId = arrangement.PhraseIterations
                                    .First(pi => arrangement.Phrases[pi.PhraseId].MaxDifficulty > 0)
                                    .PhraseId;
                var firstPhrase = arrangement.Phrases[firstPhraseId];
                firstPhraseLevel = arrangement.Levels[firstPhrase.MaxDifficulty];
            }

            Note?firstNote = null;

            if (firstPhraseLevel.Notes.Count > 0)
            {
                firstNote = firstPhraseLevel.Notes[0];
            }

            Chord?firstChord = null;

            if (firstPhraseLevel.Chords.Count > 0)
            {
                firstChord = firstPhraseLevel.Chords[0];
            }

            int applauseStartTime = GetMinTime(firstNote, firstChord) + IntroCrowdReactionDelay;
            int applauseEndTime   = applauseStartTime + IntroApplauseLength;

            var startEvent = new Event("E3", applauseStartTime);
            var stopEvent  = new Event("E13", applauseEndTime);

            arrangement.Events.InsertByTime(startEvent);
            arrangement.Events.InsertByTime(stopEvent);

            Log($"Added intro applause event (E3) at time: {applauseStartTime.TimeToString()}.");
        }
        public NotePresenter(
            ILogger <NotePresenter> logger,
            INoteView view,
            IEventService eventService,
            IRepository <Note> noteRepository,
            IGuiContext guiContext)
        {
            _logger         = logger;
            _view           = view;
            _eventService   = eventService;
            _noteRepository = noteRepository;
            _guiContext     = guiContext;

            _view.SaveNoteClicked   += OnSaveNoteClicked;
            _view.DeleteNoteClicked += OnDeleteNoteClicked;

            _eventService.Subscribe <NoteCreatedEvent>(e =>
            {
                _currentNote = new Note();
                _logger.LogInformation(nameof(NoteCreatedEvent));
                _view.SetNote(_currentNote);
                _saved = false;
                _view.SaveButtonEnabled   = true;
                _view.DeleteButtonEnabled = false;
            });

            _eventService.Subscribe <SelectedNoteChangedEvent>(e =>
            {
                _currentNote = e.SelectedNote;
                _logger.LogInformation(nameof(SelectedNoteChangedEvent));
                if (_currentNote is not null)
                {
                    _logger.LogWarning("current not is not null");
                    _view.SetNote(_currentNote);
                    _saved = true;
                    _view.SaveButtonEnabled   = false;
                    _view.DeleteButtonEnabled = true;
                }
            });
        }
Ejemplo n.º 11
0
        public async Task <Unit> Handle(UpdateNoteCommand request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            using IReturnDbContext editDbContext = this._returnDbContext.CreateForEditContext();

            Note?note = await editDbContext.Notes
                        .Include(x => x.Retrospective)
                        .Include(x => x.Participant)
                        .FirstOrDefaultAsync(x => x.Id == request.Id, cancellationToken);

            if (note == null)
            {
                throw new NotFoundException(nameof(Note), request.Id);
            }

            // Validate operation
            await this._securityValidator.EnsureAddOrUpdate(note.Retrospective, note);

            // Update the note
            note.Text = request.Text ?? String.Empty;

            await editDbContext.SaveChangesAsync(cancellationToken);

            var notification = new NoteUpdatedNotification(NoteUpdate.FromNote(note));

            if (note.Retrospective.CurrentStage == RetrospectiveStage.Writing)
            {
                notification = new NoteUpdatedNotification(new NoteUpdate(note.Id, this._textAnonymizingService.AnonymizeText(notification.Note.Text)));
            }

            await this._mediator.Publish(notification, cancellationToken);

            return(Unit.Value);
        }
        private async void OnSaveNoteClicked(object?sender, EventArgs e)
        {
            if (_currentNote is null)
            {
                return;
            }

            var current = await _noteRepository.GetAsync(_currentNote.Id);

            // If it doesnt exist, create
            if (current is null)
            {
                _currentNote.Notes = _view.GetNoteText();
                await _noteRepository.InsertAsync(_currentNote);
            }
            else
            {
                current.Notes = _view.GetNoteText();
                _currentNote  = current;
                await _noteRepository.UpdateAsync(_currentNote);
            }
            _eventService.Publish <RefreshListEvent>(new(_currentNote));
        }
Ejemplo n.º 13
0
        public override Result Process(Note[] notes, Note?prev, Note?next, Note?prevNeighbour, Note?nextNeighbour)
        {
            var note = notes[0];
            // Get the symbols of previous note.
            var prevSymbols = prevNeighbour == null ? null : GetSymbols(prevNeighbour.Value);
            // Get the symbols of current note.
            var symbols = GetSymbols(note);

            if (symbols == null || symbols.Length == 0)
            {
                // No symbol is found for current note.
                if (note.lyric == "-" && prevSymbols != null)
                {
                    // The user is using a tail "-" note to produce a "<something> -" sound.
                    return(new Result {
                        phonemes = new Phoneme[] {
                            new Phoneme()
                            {
                                phoneme = $"{prevSymbols.Last()} -",
                            }
                        },
                    });
                }
                // Otherwise assumes the user put in an alias.
                return(new Result {
                    phonemes = new Phoneme[] {
                        new Phoneme()
                        {
                            phoneme = note.lyric,
                        }
                    },
                });
            }
            // Find phone types of symbols.
            var isVowel = symbols.Select(s => mergedG2p.IsVowel(s)).ToArray();
            // Arpasing aligns the first vowel at 0 and shifts leading consonants to negative positions,
            // so we need to find the first vowel.
            int firstVowel = Array.IndexOf(isVowel, true);
            var phonemes   = new Phoneme[symbols.Length];
            // Creates the first diphone using info of the previous note.
            string prevSymbol = prevSymbols == null ? "-" : prevSymbols.Last();
            string phoneme    = $"{prevSymbol} {symbols[0]}";

            if (!singer.TryGetMappedOto(phoneme, note.tone, out var _))
            {
                // Arpasing voicebanks are often incomplete. If the voicebank doesn't have this diphone, fallback to use a more likely to exist one.
                phoneme = $"- {symbols[0]}";
            }
            phonemes[0] = new Phoneme {
                phoneme = phoneme,
            };
            // The 2nd+ diphones.
            for (int i = 1; i < symbols.Length; i++)
            {
                // The logic is very similar to creating the first diphone.
                phonemes[i] = new Phoneme {
                    phoneme = GetPhonemeOrFallback(symbols[i - 1], symbols[i], note.tone),
                };
            }

            // Alignments
            // Alignment is where a user use "...n" (n is a number) to align n-th phoneme with an extender note.
            // We build the aligment points first, these are the phonemes must be aligned to a certain position,
            // phonemes that are not aligment points are distributed in-between.
            alignments.Clear();
            if (firstVowel > 0)
            {
                // If there are leading consonants, add the first vowel as an align point.
                alignments.Add(Tuple.Create(firstVowel, 0));
            }
            else
            {
                firstVowel = 0;
            }
            int position = 0;

            for (int i = 0; i < notes.Length; ++i)
            {
                string alignmentHint = notes[i].lyric;
                if (alignmentHint.StartsWith("..."))
                {
                    alignmentHint = alignmentHint.Substring(3);
                }
                else
                {
                    position += notes[i].duration;
                    continue;
                }
                // Parse the number n in "...n".
                if (int.TryParse(alignmentHint, out int index))
                {
                    index--; // Convert from 1-based index to 0-based index.
                    if (index > 0 && (alignments.Count == 0 || alignments.Last().Item1 < index) && index < phonemes.Length)
                    {
                        // Adds a alignment point.
                        // Some details in the if condition:
                        // 1. The first phoneme cannot be user-aligned.
                        // 2. The index must be incrementing, otherwise ignored.
                        // 3. The index must be within range.
                        alignments.Add(Tuple.Create(index, position));
                    }
                }
                position += notes[i].duration;
            }
            alignments.Add(Tuple.Create(phonemes.Length, position));

            int startIndex = 0;
            int startTick  = -ConsonantLength * firstVowel;

            foreach (var alignment in alignments)
            {
                // Distributes phonemes between two aligment points.
                DistributeDuration(isVowel, phonemes, startIndex, alignment.Item1, startTick, alignment.Item2);
                startIndex = alignment.Item1;
                startTick  = alignment.Item2;
            }
            alignments.Clear();

            MapPhonemes(notes, phonemes, singer);
            return(new Result {
                phonemes = phonemes,
            });
        }
Ejemplo n.º 14
0
 public KeyScoreCard(Note targetKey)
 {
     _targetKey = targetKey;
     Init();
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Phonemize a consecutive sequence of notes. This is the main logic of a phonemizer.
 /// </summary>
 /// <param name="notes">A note and its extender notes. Always one or more.</param>
 /// <param name="prev">The note before the leading note, if exists.</param>
 /// <param name="next">The note after the last extender note, if exists.</param>
 /// <param name="prevNeighbour">Same as prev if is immediate neighbour, otherwise null.</param>
 /// <param name="nextNeighbour">Same as next if is immediate neighbour, otherwise null.</param>
 public abstract Result Process(Note[] notes, Note?prev, Note?next, Note?prevNeighbour, Note?nextNeighbour);
Ejemplo n.º 16
0
 /// <inheritdoc />
 public int CompareTo(Note?other)
 {
     return(0);
 }