Example #1
0
        public static IEnumerable<Track> ParseMidi(string fileName)
        {
            var tracks = new List<Track>();
            var file = new MidiFile(fileName);

            var tempo = 120;
            for(var trackNumber = 0; trackNumber < file.Tracks; ++trackNumber)
            {
                var events = file.Events[trackNumber];
                var tempoEvent = events.FirstOrDefault(c => c is TempoEvent) as TempoEvent;

                if(tempoEvent != null)
                {
                    tempo = (int)tempoEvent.Tempo;
                }
            }

            var channel = 0;
            for(var trackNumber = 0; trackNumber < file.Tracks; ++trackNumber, ++channel)
            {
                var phrases = new List<Phrase>();

                var events = file.Events[trackNumber];
                var path = events.FirstOrDefault(c => c is PatchChangeEvent) as PatchChangeEvent;
                if(path != null && PatchChangeEvent.GetPatchName(path.Patch) == "Steel Drums")
                {
                    continue;
                }

                var mediaPatch = PatchChangeEvent.GetPatchName(path?.Patch ?? 0)
                    .IndexOf("bass", StringComparison.InvariantCultureIgnoreCase) != -1
                    ? MediaPatch.Bass
                    : MediaPatch.CleanGuitar;

                var notes =
                    events.OfType<NoteOnEvent>().GroupBy(c => c.AbsoluteTime);

                long lastTime = 0;
                foreach(var noteCollection in notes)
                {
                    if(noteCollection.Key - lastTime > 0)
                    {
                        var pauseTime = noteCollection.Key - lastTime;

                        phrases.Add(new Phrase(pauseTime / WholeNoteDuration));
                    }

                    var duration = noteCollection.Max(c => c.NoteLength);
                    var phrase = new Phrase
                    {
                        Duration = duration / WholeNoteDuration,
                        Notes = noteCollection.Select(c => Note.FromId(c.NoteNumber)).ToArray()
                    };

                    lastTime = noteCollection.Key + duration;

                    phrases.Add(phrase);
                }

                tracks.Add(new Track
                {
                    Tempo = tempo,
                    Patch = mediaPatch,
                    Phrases = phrases.ToArray(),
                    Channel = channel
                });
            }

            return tracks;
        }
        private ISampleProvider CreateSampleProvider(Phrase phrase, int offset, bool letRingPhrase)
        {
            if(phrase.Notes?.Any() ?? false)
            {
                var phraseDuration = phrase.GetPhraseSeconds(Tempo);
                var additionalDuration = LetRingEnabled || letRingPhrase
                    ? CurrentLetRingFadeOut
                    : 0;

                var sampleProviders = phrase.Notes.Select(n => MediaBank.GetMedia(n)?.ToSampleProvider())
                    .Where(s => s != null).ToArray();

                if(sampleProviders.Any())
                {
                    var phraseSampleProvider =
                        new FadeOutSampleProvider(sampleProviders.Length > 1
                            ? new DelayedMixingSampleProvider(sampleProviders, DefaultChordNotesDelay, false)
                            : sampleProviders.Single(),
                            phraseDuration + additionalDuration, DefaultFadeOutTime);
                    if(offset > 0)
                    {
                        return new OffsetSampleProvider(phraseSampleProvider)
                        {
                            DelayBySamples = offset
                        };
                    }

                    return phraseSampleProvider;
                }
            }

            return null;
        }
Example #3
0
        public static Track ParseString(string songStr)
        {
            var phrases = new List<Phrase>();

            if(!string.IsNullOrWhiteSpace(songStr))
            {
                var noteModifier = PlayingCommand.None;

                foreach(var token in songStr.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries))
                {
                    if(token.StartsWith("=")) //command
                    {
                        var command = new Phrase(PlayingCommand.None);

                        switch(token)
                        {
                            case "=LROn=":
                                command.Command = PlayingCommand.LetItRingOn;
                                break;

                            case "=LROff=":
                                command.Command = PlayingCommand.LetItRingOff;
                                break;

                            case "=LRw=":
                                command.Command = PlayingCommand.LetRingWhole;
                                break;

                            case "=LRh=":
                                command.Command = PlayingCommand.LetRingHalf;
                                break;

                            case "=LRq=":
                                command.Command = PlayingCommand.LetRingQuarter;
                                break;

                            case "=LR=":
                                noteModifier = PlayingCommand.LetRingNotes;
                                continue;

                            default:
                                throw new Exception($"Unknown command: {token}");
                        }

                        phrases.Add(command);
                    }
                    else
                    {
                        try
                        {
                            var dots = token.Count(c => c == '.');
                            var duration = token[token.Length - 1 - dots];
                            var phraseDuration = Durations.ContainsKey(duration) ? Durations[duration] : Durations['w'];
                            if(dots > 0)
                            {
                                var tempDuration = phraseDuration;
                                for(var i = 0; i < dots; i++)
                                {
                                    tempDuration /= 2;
                                    phraseDuration += tempDuration;
                                }
                            }

                            var notesString = token.Substring(0, token.Length - 1 - dots);
                            var notes =
                                notesString.Split(new[] {'_'}, StringSplitOptions.RemoveEmptyEntries)
                                    .Select(Note.FromString);

                            var phrase = new Phrase(phraseDuration, notes.Distinct().ToArray()) {Command = noteModifier};
                            noteModifier = PlayingCommand.None;

                            phrases.Add(phrase);
                        }
                        catch(Exception)
                        {
                            throw new Exception($"Unable to parse phrase: {token}");
                        }
                    }
                }
            }

            return new Track
            {
                Patch = MediaPatch.CleanGuitar,
                Phrases = phrases,
                Tempo = 60,
                Channel = 0
            };
        }