예제 #1
0
        /// <summary>
        /// <see cref="GroorineFile"/> の新しいインスタンスを初期化します。
        /// </summary>
        /// <param name="ct"></param>
        /// <param name="tracks"></param>
        /// <param name="resolution"></param>
        /// <param name="title"></param>
        /// <param name="copyright"></param>
        internal GroorineFile(ConductorTrack ct, ObservableCollection <Track> tracks, short resolution, string title, string copyright, long?loopStart = null)
        {
            Tracks = tracks;

            foreach (Track t in tracks)
            {
                foreach (NoteEvent ne in t.Events.OfType <NoteEvent>().Where(e => e.Channel == 9 && e.Gate < resolution))
                {
                    ne.Gate = resolution;
                }
            }
            Resolution = resolution;
            Title      = title;
            Copyright  = copyright;
            Conductor  = ct;
            LoopStart  = loopStart;

            if (Tracks?.Count > 0)
            {
                Length = Tracks.Max(mt => mt.Length);
            }
        }
예제 #2
0
        public MidiFile Generate(int size)
        {
            var ct = new ConductorTrack(new ObservableCollection <MetaEvent>(new List <TempoEvent>()
            {
                new TempoEvent {
                    Tempo = bpmCandidates.Random()
                }
            }), 480);
            var tracks          = new ObservableCollection <Track>();
            var drumIsAvailable = Extension.Random(10) < 5;
            var channels        = Extension.Random(1, 17);

            if (units == null)
            {
                return(null);
            }
            for (int ch = 0; ch < channels; ch++)
            {
                var events = new ObservableCollection <MidiEvent>();
                if (units[ch] == null)
                {
                    continue;
                }

                events.Add(new ProgramEvent {
                    Channel = (byte)ch, ProgramNo = (byte)pcCandidates[ch].Random()
                });

                var unit = startUnitCandidates[ch].Random();

                unit = unit ?? units[ch].ToList().Random().Value.Random();

                if (unit == default)
                {
                    continue;
                }

                var currentTick = 0L;
                for (int i = 0; i < size; i++)
                {
                    if (unit.Notes.Length == 0)
                    {
                        break;
                    }
                    foreach (var note in unit.Notes)
                    {
                        events.Add(new NoteEvent {
                            Note = note.Note, Gate = note.Gate, Velocity = note.Velocity, Channel = note.Channel, Tick = currentTick
                        });
                    }
                    // 候補がなくなったら終了
                    if (unit.Candidates.Count == 0)
                    {
                        break;
                    }

                    unit         = units[ch][unit.Candidates.Random()].Random();
                    currentTick += unit.Notes[0].Gate + unit.Notes[0].Wait;
                }
                events.Add(new EndOfTrackEvent {
                    Channel = (byte)ch, Tick = currentTick
                });
                tracks.Add(new Track(events));
            }

            // チャンネル数がドラムパートに届かなかった場合50%でドラムが入る
            if (channels < 9 && drumIsAvailable && units[9] != null && units[9].Count > 0)
            {
                var events = new ObservableCollection <MidiEvent>();
                var unit   = units[9].ToList().Random().Value?.Random();

                var currentTick = 0L;

                for (int i = 0; i < size; i++)
                {
                    if (unit.Notes.Length == 0)
                    {
                        continue;
                    }
                    foreach (var note in unit.Notes)
                    {
                        events.Add(new NoteEvent {
                            Note = note.Note, Gate = note.Gate, Velocity = note.Velocity, Channel = note.Channel, Tick = currentTick
                        });
                    }
                    // 候補がなくなったら終了
                    if (unit.Candidates.Count == 0)
                    {
                        break;
                    }

                    unit         = units[9][unit.Candidates.Random()].Random();
                    currentTick += unit.Notes[0].Gate + unit.Notes[0].Wait;
                }

                tracks.Add(new Track(events));
            }


            return(new MidiFile(ct, tracks, 480, $"AI Generated Song {DateTime.Now.ToString()}", ""));
        }