Beispiel #1
0
    public void SpawnObjects(double tick, double beatsPerSecond)
    {
        if (index.note >= notes.Count)
        {
            return;                                    //end of song
        }
        Song.Note nextNote          = notes[index.note];
        double    tenSecondsInTicks = beatsPerSecond * 3 * resolution;

        if (nextNote.timestamp < tick + MetersToTickDistance(4f))         //spawn tick + 10 seconds?
        {
            //Debug.Log("New Note");
            try
            {
                bool       longNote   = (nextNote.duration > 0);
                int        poolNumber = (int)nextNote.fred + (longNote ? 5 : 0);
                NoteModel  noteModel  = pool.note[poolNumber][index.noteModel[poolNumber] % pool.noteSize];
                GameObject newNote    = noteModel.gameObject;
                noteModel.myTransform.rotation = cam.rotation;
                newNote.SetActive(true);
                NoteInstance noteInstance = pool.noteInstance[index.noteInstance % pool.noteInstanceSize];
                index.noteInstance++;
                noteInstance.Update(noteModel, nextNote.timestamp, nextNote.fred, nextNote.duration, nextNote.star, nextNote.hammerOn);
                noteInstance.seen = false;
                activeNotes.Add(noteInstance);

                index.note++;
                index.noteModel[poolNumber]++;
                SpawnObjects(tick, beatsPerSecond);
            }
            catch (System.Exception e)
            {
                Debug.LogError(e.Message + " - " + e.StackTrace);
            }
        }
    }
Beispiel #2
0
        public double outputToMidi(Song output)
        {
            //5 Tracks (Just in case; so far MIDIOut is currently utilizing 2: 1 for instrument and another for notes). Each track added to sequence right after
            Track[] track   = new Track[5];
            double  songLen = 0;

            for (int i = 0; i < 5; i++)
            {
                track[i] = new Track();
                sequence.Add(track[i]);
            }
            //Set the tempo (assuming Song.Tempo is in bpm)
            tempoBuilder.Tempo = (int)(1.0 / output.Tempo * 60000000);
            tempoBuilder.Build();
            track[0].Insert(0, tempoBuilder.Result);
            //Set instrument

            /*builder.Command = ChannelCommand.ProgramChange;
             * //builder.Data1 = (int)GeneralMidiInstrument.AcousticGrandPiano;
             * builder.Data2 = 0;
             * builder.Build();
             * track[1].Insert(0, builder.Result);*/
            //Tick position
            int pos = 0;
            //Note length
            int len = 0;
            //MidiChannel number
            int c = 1;

            //Set MidiChannel number to 1
            builder.MidiChannel = c;
            //Iterate through the chord voice and turn them on; Each iteration will save the note and length values
            int startOfSegment = 0;

            for (int i = 0; i < output.songData.Count; i++)
            {
                startOfSegment = pos;
                for (int j = 0; j < output.songData[i].chordPattern.Count; j++)
                {
                    //Reset channel values to stop outOfBoundsException : Austin
                    c = 1;
                    builder.MidiChannel = c;
                    foreach (var item in (output.songData[i].chordPattern[j].chordVoice))
                    {
                        String note = item.noteValue; //C, C#, D, D#, E, F, F#, G, G#, A, A#
                        len = item.length;            //in 16th notes
                        //Switch note on
                        builder.Command = ChannelCommand.ProgramChange;
                        if (output.Genre == "Generic" || output.Genre == "Jazz")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.AcousticGrandPiano;
                        }
                        else if (output.Genre == "Classical")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.Violin;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ElectricGuitarMuted;
                        }
                        builder.Data2 = 0;
                        builder.Build();
                        track[1].Insert(pos, builder.Result);
                        builder.Command = ChannelCommand.NoteOn;
                        builder.Data1   = midiValOfNote(note);
                        if (output.Genre == "Generic")
                        {
                            builder.Data2 = 100;
                        }
                        else if (output.Genre == "Classical")
                        {
                            builder.Data2 = 80;
                        }
                        else if (output.Genre == "Jazz")
                        {
                            builder.Data2 = 110;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock")
                        {
                            builder.Data2 = 120;
                        }

                        builder.Build();                      //Build the message
                        track[1].Insert(pos, builder.Result); //Insert into Track 1 at tick position 'pos'
                        //Increment MIDI channel by 1
                        c += 1;
                        builder.MidiChannel = c;
                    }//endforeach

                    /*Tick position increment; This will be based on the last note of the previous chord, but I think it's safe to assume that its length will be the same as the rest of the chord tones of that chord.
                     * PpqnClock.PpqnMinValue is the minimum PPQ value (24) set by the class library PpqnClock.*/
                    songLen            += len / 4;
                    pos                += (PpqnClock.PpqnMinValue / 4 * len);
                    c                   = 1;
                    builder.MidiChannel = c;

                    foreach (var item in (output.songData[i].chordPattern[j].chordVoice))
                    {
                        String note = item.noteValue;
                        len = item.length;
                        //Set Note Off
                        builder.Command = ChannelCommand.NoteOff;
                        builder.Data1   = midiValOfNote(note);
                        builder.Data2   = 0;                  //Set volume to mute
                        builder.Build();                      //Build the message
                        track[1].Insert(pos, builder.Result); //Insert into Track 1 at tick position 'pos'
                        //Increment MIDI channel by 1
                        c += 1;
                        builder.MidiChannel = c;
                        //songLen += item.length / 16;
                    } //endforeach
                }     //endfor

                for (int q = 0; q < output.songData[i].melodies.Count(); q++)
                {
                    pos = startOfSegment;
                    for (int j = 0; j < output.songData[i].melodies[q].melodicLine.Count(); j++)
                    {
                        Song.Note outputNote = output.songData[i].melodies[q].melodicLine[j];
                        String    note       = outputNote.noteValue;
                        int       noteLength = outputNote.length; //in 16th notes
                        //Switch note on
                        builder.Command = ChannelCommand.ProgramChange;
                        if (output.Genre == "Generic")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ElectricGuitarJazz;
                        }
                        else if (output.Genre == "Classical")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.Violin;
                        }
                        else if (output.Genre == "Twelve-tone")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.AcousticGrandPiano;
                        }
                        else if (output.Genre == "Jazz")
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.AltoSax;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock" && q == 0)
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ChoirAahs;
                        }
                        else if (output.Genre == "4-Chord Pop/Rock" && q == 1)
                        {
                            builder.Data1 = (int)GeneralMidiInstrument.ElectricBassPick;
                        }
                        builder.Data2 = 0;
                        builder.Build();
                        track[q + 2].Insert(pos, builder.Result);
                        builder.Command = ChannelCommand.NoteOn;
                        builder.Data1   = midiValOfNote(note);
                        builder.Data2   = 127;                    //Set volume to max
                        builder.Build();                          //Build the message
                        track[q + 2].Insert(pos, builder.Result); //Insert into Track 1 at tick position 'pos'
                        //Increment MIDI channel by 1
                        pos += (PpqnClock.PpqnMinValue / 4 * noteLength);
                        //Set Note Off
                        builder.Command = ChannelCommand.NoteOff;
                        builder.Data1   = midiValOfNote(note);
                        builder.Data2   = 0; //Set volume to mute
                        builder.Build();     //Build the message
                        track[q + 2].Insert(pos, builder.Result);
                    }
                }
            }//endfor
             //Submits file to the C:\BlottoBeats Folder where it is stored until another song is generated

            /*if (!Directory.Exists(@"C:\BlottoBeats"))
             * {
             *  Directory.CreateDirectory(@"C:\BlottoBeats");
             *
             * }*/
            if (File.Exists("temp.mid"))
            {
                File.Delete("temp.mid");
            }

            sequence.Save("temp.mid");

            return(((double)pos) / (PpqnClock.PpqnMinValue / 4) / 4 / output.Tempo * 60);

            //Code to play sequence in client. Currently not functioning
            //s.Sequence = sequence;
            //s.Start();
        }
    private int LoadChartNotes(string[] chart, int i, List <Song.Note> list, uint resolution)
    {
        int timeout = 100000;

        while (i < timeout)
        {
            if (chart[i].Contains("{"))
            {
                //Debug.Log("Start reading Notes");
                i++;
                break;
            }
            i++;
        }
        uint starPowerEndsAt = 0;

        while (i < timeout)
        {
            if (chart[i].Contains("}"))
            {
                //Debug.Log("End reading Notes");
                break;
            }
            string line = chart[i];
            if (line.Contains(" = "))
            {
                string[] splitted     = line.Split(new string[] { " = " }, System.StringSplitOptions.None);
                string[] noteSplitted = splitted[1].Split(" "[0]);
                uint     timestamp    = uint.Parse(splitted[0]);
                if (noteSplitted[0] == "N")
                {
                    bool      hammeron     = false;
                    uint      fred         = uint.Parse(noteSplitted[1]);
                    Song.Note previousNote = null;
                    if (list.Count > 0)
                    {
                        previousNote = list[list.Count - 1];
                        if (previousNote.timestamp == timestamp)                        //double notes no hammeron
                        {
                            previousNote.hammerOn = false;
                        }
                        else
                        {
                            hammeron = (timestamp < previousNote.timestamp + (resolution / 2)) && (previousNote.fred != fred) && (previousNote.timestamp != timestamp);
                        }
                    }
                    if (uint.Parse(noteSplitted[1]) < 5)
                    {
                        list.Add(new Song.Note(timestamp, fred, uint.Parse(noteSplitted[2]), timestamp <= starPowerEndsAt, hammeron));
                    }
                }
                if (noteSplitted[0] == "S")
                {
                    starPowerEndsAt = timestamp + uint.Parse(noteSplitted[2]);
                    //also set previous note to star
                    int traceBack = 1;
                    while (traceBack < 5)
                    {
                        if (list[list.Count - traceBack].timestamp == timestamp)
                        {
                            list[list.Count - traceBack].star = true;
                            traceBack++;
                            continue;
                        }
                        break;
                    }
                }
            }
            i++;
        }
        return(i);
    }