예제 #1
0
        public void MultiPlay(long tick)
        {
            if (Track.Count > 0)
            {
                SeqData curr = Track.Peek();

                if (tick > curr.TickTime)
                {
                    // Stop playing note
                    if (!curr.Play)
                    {
                        for (int i = 0; i < instruments.Length; i++)
                        {
                            // Find motor that was playing this note and stop it
                            if (instruments[i].Note.NoteId == curr.NoteId)
                            {
                                instruments[i].Motor.Speed = 0;
                                instruments[i].Note        = curr;
                                break;
                            }
                        }

                        Track.Dequeue();
                    }
                    // Play note
                    else
                    {
                        // Figure out if this is a chord
                        List <SeqData> chordNotes = new List <SeqData>();
                        while (Track.Peek().TickTime == curr.TickTime && Track.Peek().Play)
                        {
                            chordNotes.Add(Track.Dequeue());
                        }

                        chordNotes = chordNotes.OrderByDescending(n => n.NoteId).ToList();

                        foreach (SeqData chordNote in chordNotes)
                        {
                            for (int i = 0; i < instruments.Length; i++)
                            {
                                // Find a motor that is free and play the note
                                if (instruments[i].Note == null || !instruments[i].Note.Play)
                                //|| (instruments[i].Note.NoteId < curr.NoteId))  // if the new note is a higher pitch, play the new note(I'm assuming it's the melody)
                                {
                                    double freq = Pitch.GetFrequency(chordNote.NoteId);
                                    while (freq < Pitch.GetFrequency(39) / 2)
                                    {
                                        freq *= 2;
                                    }

                                    while (freq > Pitch.GetFrequency(51) * 2)
                                    {
                                        freq /= 2;
                                    }

                                    instruments[i].Motor.Speed = freq / 2;

                                    if (OctaveOffset < 0)
                                    {
                                        instruments[i].Motor.Speed /= 2 * Math.Abs(OctaveOffset);
                                    }
                                    else if (OctaveOffset > 0)
                                    {
                                        instruments[i].Motor.Speed *= 2 * Math.Abs(OctaveOffset);
                                    }

                                    instruments[i].Note = chordNote;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                foreach (Instrument inst in instruments)
                {
                    inst.Motor.Speed = 0;
                }
                Done = true;
                return;
            }

            foreach (Instrument inst in instruments)
            {
                inst.Motor.Run();
            }
        }