Пример #1
0
        public void Play(List <Note> song, int key, List <int> chords)
        {
            lock (playingLock)
            {
                if (isCurrentlyPlaying)
                {
                    return;
                }

                isCurrentlyPlaying = true;
                stopPlayback       = false;

                List <Note>   copyOfSong   = new List <Note>(song);
                List <int>    copyOfChords = new List <int>(chords);
                SongAndChords param        = new SongAndChords()
                {
                    Song = copyOfSong, Key = key, Chords = copyOfChords
                };

                playingThread = new Thread(new ParameterizedThreadStart(DoPlay));
                playingThread.Start(param);
            }
        }
Пример #2
0
        private void DoPlay(object objSong)
        {
            SongAndChords param = (SongAndChords)objSong;
            List <Note>   song  = (List <Note>)param.Song;

            int[] chords         = param.Chords.ToArray();
            int   key            = param.Key;
            int   currentSongPos = 0;
            int   lastChordOn    = 0;

            using (OutputDevice outDevice = new OutputDevice(0))
            {
                ChannelMessageBuilder builder = new ChannelMessageBuilder();

                // turn first chord on
                Note(true, key + chords[0], builder, outDevice);
                lastChordOn = key + Scales.Major[chords[0]];

                foreach (Note n in song)
                {
                    lock (playingLock)
                    {
                        if (stopPlayback)
                        {
                            break;
                        }
                    }

                    // turn on current note
                    Note(true, n.Id, builder, outDevice);

                    int sixteenthsToNextBarline = (int)(Math.Ceiling(currentSongPos / 16.0f) * 16.0f) - currentSongPos;
                    int noteSleep = (int)n.Length;

                    if (noteSleep >= sixteenthsToNextBarline)
                    {
                        Thread.Sleep(SixteenthNoteLengthInMs * sixteenthsToNextBarline);
                        noteSleep -= sixteenthsToNextBarline;

                        // we have a barline in the middle of this node, switch chords here

                        // last chord off
                        Note(false, lastChordOn, builder, outDevice);
                        currentSongPos += sixteenthsToNextBarline;

                        // if no the end of the song
                        if (currentSongPos < chords.Length * 16)
                        {
                            // this chord on
                            int newChord = chords[currentSongPos / 16];
                            Note(true, key + Scales.Major[newChord], builder, outDevice);
                            lastChordOn = key + Scales.Major[newChord];
                        }
                    }

                    if (noteSleep > 0)
                    {
                        Thread.Sleep(SixteenthNoteLengthInMs * noteSleep);
                        currentSongPos += noteSleep;
                    }

                    // turn off current note
                    Note(false, n.Id, builder, outDevice);
                }

                // turn last chord off
                Note(false, lastChordOn, builder, outDevice);
            }
        }