示例#1
0
        public async Task <SongSimplification> AddSongSimplificationAsync(SongSimplification simpl)
        {
            try
            {
                Context.SongSimplifications.Add(simpl);
                await Context.SaveChangesAsync();

                var newNotes = simpl.Notes.Where(n => n.Id == 0).ToList();
                foreach (var n in newNotes)
                {
                    Context.Notes.Add(n);
                }
                await Context.SaveChangesAsync();

                foreach (var n in simpl.Notes)
                {
                    Context.SongSimplificationNotes.Add(new SongSimplificationNote
                    {
                        NoteId = n.Id,
                        SongSimplificationId = simpl.Id
                    });
                }
                await Context.SaveChangesAsync();
            }
            catch (Exception fdsafasdfa)
            {
            }
            return(simpl);
        }
        public static List <Melody> GetMelodiesOfSimplification(SongSimplification simpl)
        {
            var retObj = new List <Melody>();

            for (byte i = 0; i < simpl.NumberOfVoices; i++)
            {
                var voiceNotes = GetNonPercusionNotesOfVoice(simpl.Notes, i);
                if (voiceNotes.Count == 0)
                {
                    continue;
                }
                if (VoiceIsMelodic(voiceNotes))
                {
                    var melody = new Melody(voiceNotes);
                    melody.SongSimplificationId = simpl.Id;
                    melody.Voice      = i;
                    melody.Instrument = voiceNotes[0].Instrument;
                    retObj.Add(melody);
                }
            }
            // If we couldn't find any voice that is a melody, then the melody is
            // given by the highest notes of the combined notes
            if (retObj.Count == 0)
            {
                var melody = new Melody(GetNonPercusionNotes(simpl.Notes));
                melody.SongSimplificationId = simpl.Id;
                melody.Voice      = melody.Notes[0].Voice;
                melody.Instrument = melody.Notes[0].Instrument;
                retObj.Add(melody);
            }
            return(retObj);
        }
示例#3
0
        public async Task <ActionResult> SimplifySongs()
        {
            var currentPage = 0;

            while (true)
            {
                currentPage++;
                var songs = await Repository.GetSongsAsync(currentPage, 3);

                if (songs == null)
                {
                    break;
                }
                foreach (var song in songs)
                {
                    var simpl = await Repository.GetSongSimplificationAsync(song.Id, 0);

                    var simpl1 = new SongSimplification()
                    {
                        Notes = simpl.Notes.Select(n => n.Clone())
                                .OrderBy(x => x.StartSinceBeginningOfSongInTicks).ToList(),
                        SimplificationVersion = 1,
                        SongId         = simpl.SongId,
                        NumberOfVoices = simpl.NumberOfVoices
                    };
                    simpl1.Notes = SimplificationUtilities.RemoveBendings(simpl1.Notes);
                    simpl1.Notes = SimplificationUtilities.RemoveEmbelishments(simpl1.Notes);

                    await Repository.AddSongSimplificationAsync(simpl1);

                    var simpl2 = new SongSimplification()
                    {
                        Notes = simpl1.Notes.Select(n => n.Clone())
                                .OrderBy(x => x.StartSinceBeginningOfSongInTicks).ToList(),
                        SimplificationVersion = 2,
                        SongId         = simpl.SongId,
                        NumberOfVoices = simpl.NumberOfVoices
                    };
                    simpl2.Notes = SimplificationUtilities.RemoveNonEssentialNotes(simpl2.Notes, 80);

                    await Repository.AddSongSimplificationAsync(simpl2);

                    var simpl3 = new SongSimplification()
                    {
                        Notes = simpl2.Notes.Select(n => n.Clone())
                                .OrderBy(x => x.StartSinceBeginningOfSongInTicks).ToList(),
                        SimplificationVersion = 3,
                        SongId         = simpl.SongId,
                        NumberOfVoices = simpl.NumberOfVoices
                    };
                    simpl3.Notes = SimplificationUtilities.RemoveNonEssentialNotes(simpl3.Notes, 80);

                    await Repository.AddSongSimplificationAsync(simpl3);
                }
            }

            return(null);
        }
示例#4
0
        public static IEnumerable <Note> QuantizeNotes(SongSimplification songSimplification, List <Bar> bars)
        {
            int standardTicksPerQuarterNote = 96;

            foreach (var n in songSimplification.Notes)
            {
                int i = 0;
                while (i < bars.Count &&
                       bars[i].TicksFromBeginningOfSong <= n.EndSinceBeginningOfSongInTicks)
                {
                    i++;
                }
                yield return(QuantizeNote(n.Clone(), standardTicksPerQuarterNote, bars[i - 1].HasTriplets));
            }
        }
示例#5
0
        /// <summary>
        /// We want to know if there are durations that are multiple of 3
        /// in the bar. If the bar has triplets, then when we quantize the
        /// notes in the bar we must aproximate points to values that
        /// are multiple of 3 and not only powers of 2
        /// </summary>
        /// <param name="song"></param>
        /// <param name="bar"></param>
        /// <returns></returns>
        public static bool HasBarTriplets(SongSimplification songSimplification, Bar bar)
        {
            int standardTicksPerQuarterNote = 96;
            var notes             = GetNotesOfBar(bar, songSimplification);
            var lengthsOfTriplets = GetPossibleLengthsOfTriplets(standardTicksPerQuarterNote);
            int numberOfTriplets  = 0;

            foreach (var n in notes)
            {
                foreach (var q in lengthsOfTriplets)
                {
                    if (IsDurationEssentiallyTheSame(n, q))
                    {
                        numberOfTriplets++;
                        break;
                    }
                }
            }
            return(numberOfTriplets * 2 > notes.Count);
        }
        public static List <Note> GetNotesOfBar(Bar bar, SongSimplification songSimplification)
        {
            int standardTicksPerQuarterNote = 96;
            var retObj = new List <Note>();

            foreach (var n in songSimplification.Notes)
            {
                int barLengthInTicks = bar.TimeSignature.Numerator * (int)standardTicksPerQuarterNote;
                var barStart         = bar.TicksFromBeginningOfSong;
                var noteStart        = n.StartSinceBeginningOfSongInTicks;
                var noteEnd          = n.EndSinceBeginningOfSongInTicks;
                var barEnd           = bar.TicksFromBeginningOfSong + barLengthInTicks;
                if (barEnd < noteStart || noteEnd <= barStart)
                {
                    continue;
                }

                if (!retObj.Contains(n))
                {
                    retObj.Add(n);
                }
            }
            return(retObj.OrderBy(x => x.StartSinceBeginningOfSongInTicks).ToList());
        }
        public static SongSimplification GetSimplificationZeroOfSong(string base64encodedMidiFile)
        {
            var  notesObj                     = new List <Note>();
            var  midiFile                     = MidiFile.Read(base64encodedMidiFile);
            long songDuration                 = GetSongDurationInTicks(base64encodedMidiFile);
            var  isSustainPedalOn             = false;
            var  notesOnBecauseOfSustainPedal = new List <Note>();
            var  instrumentOfChannel          = new byte[16];

            short chunkNo = -1;

            foreach (TrackChunk chunk in midiFile.Chunks)
            {
                chunkNo++;
                var  currentNotes = new List <Note>();
                long currentTick  = 0;

                foreach (MidiEvent eventito in chunk.Events)
                {
                    currentTick += eventito.DeltaTime;

                    if (eventito is ProgramChangeEvent)
                    {
                        var pg = eventito as ProgramChangeEvent;
                        instrumentOfChannel[pg.Channel] = (byte)pg.ProgramNumber.valor;
                        continue;
                    }

                    if (IsSustainPedalEventOn(eventito))
                    {
                        isSustainPedalOn = true;
                        continue;
                    }

                    if (IsSustainPedalEventOff(eventito))
                    {
                        isSustainPedalOn = false;
                        foreach (var n in notesOnBecauseOfSustainPedal)
                        {
                            ProcessNoteOff(n.Pitch, currentNotes, notesObj, currentTick,
                                           n.Instrument, (byte)chunkNo);
                        }
                        continue;
                    }
                    if (eventito is NoteOnEvent)
                    {
                        NoteOnEvent noteOnEvent = eventito as NoteOnEvent;
                        if (noteOnEvent.Velocity > 0 || isSustainPedalOn == false)
                        {
                            ProcessNoteOn(noteOnEvent.NoteNumber, noteOnEvent.Velocity,
                                          currentNotes, notesObj, currentTick,
                                          instrumentOfChannel[noteOnEvent.Channel],
                                          IsPercussionEvent(eventito), (byte)chunkNo);
                        }
                        continue;
                    }
                    if (eventito is NoteOffEvent && isSustainPedalOn == false)
                    {
                        NoteOffEvent noteOffEvent = eventito as NoteOffEvent;
                        ProcessNoteOff(noteOffEvent.NoteNumber, currentNotes, notesObj, currentTick,
                                       instrumentOfChannel[noteOffEvent.Channel], (byte)chunkNo);
                        continue;
                    }
                    if (eventito is PitchBendEvent)
                    {
                        PitchBendEvent bendito = eventito as PitchBendEvent;
                        foreach (var notita in currentNotes)
                        {
                            PitchBendEvent maldito = bendito.Clone() as PitchBendEvent;
                            maldito.DeltaTime = currentTick;
                            notita.PitchBending.Add(new PitchBendItem
                            {
                                Note  = notita,
                                Pitch = maldito.PitchValue,
                                TicksSinceBeginningOfSong = maldito.DeltaTime
                            });
                        }
                        continue;
                    }
                }
            }

            var retObj = new SongSimplification()
            {
                Notes = notesObj,
                SimplificationVersion = 0,
                NumberOfVoices        = chunkNo
            };

            return(retObj);
        }
        /// <summary>
        /// Generates the list of bar entities of a midi file
        /// </summary>
        /// <param name="base64encodedMidiFile"></param>
        /// <returns></returns>
        public static List <Bar> GetBarsOfSong(string base64encodedMidiFile, SongSimplification songSimplification)
        {
            List <Bar> retObj    = new List <Bar>();
            int        barNumber = 1;

            var ticksPerBeat        = GetTicksPerBeatOfSong(base64encodedMidiFile);
            var songDurationInTicks = GetSongDurationInTicks(base64encodedMidiFile);
            var timeSignatureEvents = GetEventsOfType(base64encodedMidiFile, MidiEventType.TimeSignature);
            var setTempoEvents      = GetEventsOfType(base64encodedMidiFile, MidiEventType.SetTempo);

            timeSignatureEvents = ConvertDeltaTimeToAccumulatedTime(timeSignatureEvents);
            var TempoEvents = QuantizeTempos(ConvertDeltaTimeToAccumulatedTime(setTempoEvents));

            //status
            TimeSignatureEvent currentTimeSignature = new TimeSignatureEvent
            {
                Numerator   = 4,
                Denominator = 4
            };

            if (timeSignatureEvents.Count > 0)
            {
                currentTimeSignature = (TimeSignatureEvent)timeSignatureEvents[0];
            }

            int currentTempo = 500000;

            int  timeSigIndex = 0;
            int  tempoIndex   = 0;
            long currentTick  = 0;

            while (currentTick < songDurationInTicks)
            {
                if (TempoEvents.Count > 0)
                {
                    currentTempo = (int)TempoEvents[tempoIndex].MicrosecondsPerQuarterNote;
                }
                long timeOfNextTimeSignatureEvent = songDurationInTicks;
                if (timeSignatureEvents.Count - 1 > timeSigIndex)
                {
                    timeOfNextTimeSignatureEvent = timeSignatureEvents[timeSigIndex + 1].DeltaTime;
                }
                long timeOfNextSetTempoEvent = songDurationInTicks;
                if (TempoEvents.Count - 1 > tempoIndex)
                {
                    timeOfNextSetTempoEvent = TempoEvents[tempoIndex + 1].DeltaTime;
                }

                long lastTickOfBarToBeAdded = currentTimeSignature.Numerator * ticksPerBeat + currentTick;

                while ((lastTickOfBarToBeAdded <= timeOfNextTimeSignatureEvent && lastTickOfBarToBeAdded <= timeOfNextSetTempoEvent) ||
                       (lastTickOfBarToBeAdded > songDurationInTicks))
                {
                    var timeSignature = new TimeSignature
                    {
                        Numerator   = currentTimeSignature.Numerator,
                        Denominator = currentTimeSignature.Denominator
                    };
                    var bar = new Bar
                    {
                        BarNumber = barNumber++,
                        TicksFromBeginningOfSong          = currentTick,
                        TimeSignature                     = timeSignature,
                        TempoInMicrosecondsPerQuarterNote = currentTempo
                    };
                    bar.HasTriplets = HasBarTriplets(songSimplification, bar);
                    retObj.Add(bar);
                    currentTick            += currentTimeSignature.Numerator * ticksPerBeat;
                    lastTickOfBarToBeAdded += currentTimeSignature.Numerator * ticksPerBeat;
                    if (currentTick >= songDurationInTicks)
                    {
                        break;
                    }
                }
                if (lastTickOfBarToBeAdded >= timeOfNextTimeSignatureEvent)
                {
                    timeSigIndex++;
                }
                if (lastTickOfBarToBeAdded >= timeOfNextSetTempoEvent)
                {
                    tempoIndex++;
                }
            }
            return(retObj);
        }
示例#9
0
 public async Task UpdateSongSimplificationAsync(SongSimplification simpl)
 {
     Context.SongSimplifications.Update(simpl);
     await Context.SaveChangesAsync();
 }
        /// <summary>
        /// Looks for unique chords and all their occurrences in a song simplification
        /// The key of the dictionary returned is the chord expressed as a sequence
        /// of pitches separated by commas (like "40,46,54"). The pitches are sorted
        /// </summary>
        /// <param name="simpl"></param>
        /// <returns></returns>
        public static Dictionary <string, List <ChordOccurrence> > GetChordsOfSimplification(SongSimplification simpl)
        {
            var durationOfHalfBeatInTicks = 48;
            var retObj = new Dictionary <string, List <ChordOccurrence> >();
            // We create a dictionary where the keys are points it time
            // one for every half beat of the song and the values are the notes
            // played in that half beat
            // The assumption is that we don't have more than 2 chords in 1 beat
            // Since a note can last several beats, the same note and
            // the same chord can be in many entries
            // of the dictionary
            var beatNotes = new Dictionary <long, List <Note> >();

            foreach (Note n in simpl.Notes)
            {
                if (n.IsPercussion)
                {
                    continue;
                }
                var startBeat = n.StartSinceBeginningOfSongInTicks / durationOfHalfBeatInTicks;
                var endBeat   = n.EndSinceBeginningOfSongInTicks / durationOfHalfBeatInTicks;
                for (var i = startBeat; i <= endBeat; i++)
                {
                    if (!beatNotes.ContainsKey(i))
                    {
                        beatNotes[i] = new List <Note>();
                    }
                    beatNotes[i].Add(n);
                }
            }
            // Now we look at the notes played in each half beat.
            // We group the notes according to their start and stop times
            // The notes that start and stop simultatneously are
            // candidates for a chord
            foreach (var slice in beatNotes.Keys)
            {
                var sliceNotes = beatNotes[slice];
                if (sliceNotes.Count < 2)
                {
                    continue;
                }
                var possibleChords = new List <List <Note> >();
                foreach (var n in sliceNotes)
                {
                    var isNoteProcessed = false;
                    foreach (var possibleChord in possibleChords)
                    {
                        if (IsNoteSimultaneousWithGroup(possibleChord, n))
                        {
                            possibleChord.Add(n);
                            isNoteProcessed = true;
                        }
                    }
                    if (!isNoteProcessed)
                    {
                        var possibleChord = new List <Note>();
                        possibleChord.Add(n);
                        possibleChords.Add(possibleChord);
                    }
                }
                // We have now in possibleChords a list of groups of notes
                // We select the ones that have at least 2 notes
                if (possibleChords.Count > 0)
                {
                    foreach (var possibleChord in possibleChords)
                    {
                        if (possibleChord.Count < 2 ||
                            !NotesGenerateHarmony(possibleChord))
                        {
                            continue;
                        }
                        var thisChord = new Chord(possibleChord);
                        if (!retObj.ContainsKey(thisChord.PitchesAsString))
                        {
                            retObj[thisChord.PitchesAsString] = new List <ChordOccurrence>();
                        }
                        var chordOccurrence = new ChordOccurrence
                        {
                            StartTick            = possibleChord.FirstOrDefault().StartSinceBeginningOfSongInTicks,
                            EndTick              = possibleChord.FirstOrDefault().EndSinceBeginningOfSongInTicks,
                            SongSimplificationId = simpl.Id
                        };
                        if (!IsOccurrenceAlreadyInList(retObj[thisChord.PitchesAsString], chordOccurrence))
                        {
                            retObj[thisChord.PitchesAsString].Add(chordOccurrence);
                        }
                    }
                }
            }
            return(retObj);
        }