Example #1
0
    private IEnumerator PlayMelody()
    {
        InitRhythmCounters();
        CalculateWaitingByBpm();
        yield return(new WaitForSeconds(1));

        m_KeepPlaying = true;

        if (m_IsPlayback)
        {
            m_CurrentPlaybackMusicUnitIndex = 0;
            if (m_CurrentMusicSequence.m_MusicUnits.Count == 0)
            {
                m_KeepPlaying = false;
                if (OnPlaybackEnd != null)
                {
                    OnPlaybackEnd();
                }
                yield break;
            }

            m_CurrentMusicUnit = m_CurrentMusicSequence.m_MusicUnits.ToList()[m_CurrentPlaybackMusicUnitIndex];
            m_CurrentRhythm    = m_CurrentMusicUnit.m_Rhythm;
        }
        else
        {
            // Pick up first a random rhythm
            m_CurrentRhythm = m_Rhythms.m_Rhythms[m_Rhythms.GetRandomWeightedIndex()];

            // Set up saving data
            m_CurrentMusicUnit = new MusicUnit
            {
                m_Rhythm = m_CurrentRhythm,
                m_Notes  = new List <int> [m_CurrentRhythm.Length]
            };
            m_CurrentMusicSequence.m_MusicUnits.Enqueue(m_CurrentMusicUnit);
            if (m_CurrentMusicSequence.m_MusicUnits.Count >= m_MaxMusicUnitsToKeep)
            {
                m_CurrentMusicSequence.m_MusicUnits.Dequeue();
            }
        }

        while (m_KeepPlaying)
        {
            // Calculate next rhythm wait time
            m_NextWait = m_CurrentRhythm[m_CurrentRhythmPos] * m_WaitTimeForA16Th;

            float duration  = m_NextWait / 2;
            bool  firstBeat = m_BeatCounter == 0;
            if (!m_IsPlayback)
            {
                // Calculate next note
                if (Mathf.Approximately(m_PerlinNoise, 0f))
                {
                    m_PerlinNoise = 1f;
                }

                int nextNote = ((int)Mathf.Ceil(m_PerlinNoise * m_NotesNb)) - 1;
                // Ensure we stay inside boundaries
                if (nextNote < 0)
                {
                    nextNote = 0;
                }

                // Play note(s)
                PlayNotes(nextNote, duration, firstBeat);
            }
            else
            {
                if (m_CurrentMusicUnit.m_Notes[m_CurrentRhythmPos] == null)
                {
                    m_KeepPlaying = false;
                    if (OnPlaybackEnd != null)
                    {
                        OnPlaybackEnd();
                    }
                    break;
                }

                m_CurrentMusicUnit.m_Notes[m_CurrentRhythmPos].ForEach(note => PlayNote(note, duration, firstBeat));
            }


            // -------------

            m_CurrentRhythmPos++;
            // End of rhythm, we need to pick up a new rhythm
            if (m_CurrentRhythmPos >= m_CurrentRhythm.Length)
            {
                if (m_IsPlayback)
                {
                    m_CurrentPlaybackMusicUnitIndex++;
                    if (m_CurrentMusicSequence.m_MusicUnits.Count == m_CurrentPlaybackMusicUnitIndex)
                    {
                        m_KeepPlaying = false;
                        if (OnPlaybackEnd != null)
                        {
                            OnPlaybackEnd();
                        }
                        break;
                    }

                    m_CurrentMusicUnit = m_CurrentMusicSequence.m_MusicUnits.ToList()[m_CurrentPlaybackMusicUnitIndex];
                    m_CurrentRhythm    = m_CurrentMusicUnit.m_Rhythm;
                }
                else
                {
                    m_CurrentRhythm = m_Rhythms.m_Rhythms[m_Rhythms.GetRandomWeightedIndex()];
                }

                m_CurrentRhythmPos = 0;

                if (!m_IsPlayback)
                {
                    m_CurrentMusicUnit = new MusicUnit
                    {
                        m_Rhythm = m_CurrentRhythm,
                        m_Notes  = new List <int> [m_CurrentRhythm.Length]
                    };
                    m_CurrentMusicSequence.m_MusicUnits.Enqueue(m_CurrentMusicUnit);
                    if (m_CurrentMusicSequence.m_MusicUnits.Count >= m_MaxMusicUnitsToKeep)
                    {
                        m_CurrentMusicSequence.m_MusicUnits.Dequeue();
                    }
                }

                // Increment beat as well
                m_BeatCounter++;
                m_BeatCounter = Mathf.Min(m_BeatCounter, m_BeatCounter % m_BeatsPerBar);
            }

            yield return(new WaitForSeconds(m_NextWait));
        }
    }
        /// <summary>
        ///     指定ポイント数の音声データを読み込む。
        ///     モノラルなら、Left/Rightどちらにも格納される。
        /// </summary>
        /// <param name="size">データサイズ[point]</param>
        /// <returns>ファイルを完読すると、0を書き込んで返す</returns>
        public MusicUnit[] Read(int size)
        {
            MusicUnit[] music = new MusicUnit[size];  // これにデータを格納して返す
            int         i;

            if (this.IsOpenStatus)
            {
                for (i = 0; i < size && this.ReadWaveDataSize < this.file_info.Wave_Data_Size; i++)
                {
                    if (this.ReadWaveDataSize < this.file_info.Wave_Data_Size)
                    {
                        // まず左を埋める
                        if (this.file_info.Resolution_Bit == 8)
                        {
                            music[i].Left = (int)reader.ReadSByte();
                        }
                        if (this.file_info.Resolution_Bit == 16)
                        {
                            music[i].Left = (int)reader.ReadInt16();
                        }
                        if (this.file_info.Resolution_Bit == 24)
                        {
                            music[i].Left = this.ReadInt24(this.reader);
                        }
                        if (this.file_info.Resolution_Bit == 32)
                        {
                            music[i].Left = (int)reader.ReadInt32();
                        }
                        // 次に、ステレオ音源なら右を埋める
                        switch (this.file_info.Channel)
                        {
                        case Channel.Stereo:
                            if (this.file_info.Resolution_Bit == 8)
                            {
                                music[i].Right = (int)reader.ReadSByte();
                            }
                            if (this.file_info.Resolution_Bit == 16)
                            {
                                music[i].Right = (int)reader.ReadInt16();
                            }
                            if (this.file_info.Resolution_Bit == 24)
                            {
                                music[i].Right = this.ReadInt24(this.reader);
                            }
                            if (this.file_info.Resolution_Bit == 32)
                            {
                                music[i].Right = (int)reader.ReadInt32();
                            }
                            break;

                        case Channel.Monoral:
                            music[i].Right = music[i].Left;
                            break;
                        }
                        this.ReadWaveDataSize += (UInt32)this.file_info.Block_Size; // 読み込んだデータ量を更新
                    }
                    else
                    {
                        music[i].Left  = 0;                                         // 読めるデータが無くなると、0を書き込んで返す
                        music[i].Right = 0;
                    }
                }
            }
            return(music);
        }