Beispiel #1
0
        public void InitiateLoadedSound(SoundResource soundResource)
        {
            float dummy         = 0f;
            int   dummyI        = 0;
            float baseFrequency = 0;

            FMOD.Sound sound = (FMOD.Sound)soundResource.SoundGlue.InnerSoundObject;

            ERRCHECK(sound.set3DMinMaxDistance(minMaxDistance.X, minMaxDistance.Y));
            ERRCHECK(sound.getDefaults(ref baseFrequency, ref dummy, ref dummy, ref dummyI));
            ERRCHECK(sound.setDefaults(soundResource.PlaybackSpeed * baseFrequency, soundResource.Volume, 0f, (int)soundResource.Priority));
            soundResource.BaseFrequency = baseFrequency;
            if (soundResource.SoundGroupEnum != SoundGroups.Default)
            {
                ERRCHECK(sound.setSoundGroup((FMOD.SoundGroup)SoundManager.Instance.GetSoundGroup(soundResource.SoundGroupEnum).SoundGroupGlue.InnerSoundGroupObject));
            }
        }
Beispiel #2
0
        IEnumerator StreamCR()
        {
            /*
             * FMOD seems to like this
             */
            yield return(new WaitForSeconds(2f));

            this.streamCaught = false;
            this.trackChanged = false;

            for (;;)
            {
                if (this.isPaused)
                {
                    yield return(null);
                }

                if (this.finished)
                {
                    this.Stop();
                    yield break;
                }

                result = system.update();
                ERRCHECK(result, "system.update", false);

                result = sound.getOpenState(out openstate, out bufferFillPercentage, out starving, out deviceBusy);
                ERRCHECK(result, "sound.getOpenState", false);

                LOG(LogLevel.DEBUG, "Stream open state: {0}, buffer fill {1} starving {2} networkBusy {3}", openstate, bufferFillPercentage, starving, deviceBusy);

                if (!this.streamCaught)
                {
                    int c = 0;
                    do
                    {
                        result = system.update();
                        ERRCHECK(result, "system.update", false);

                        result = sound.getOpenState(out openstate, out bufferFillPercentage, out starving, out deviceBusy);
                        ERRCHECK(result, "sound.getOpenState", false);

                        LOG(LogLevel.DEBUG, "Stream open state: {0}, buffer fill {1} starving {2} networkBusy {3}", openstate, bufferFillPercentage, starving, deviceBusy);

                        if (result == FMOD.RESULT.OK && openstate == FMOD.OPENSTATE.READY)
                        {
                            /*
                             * stream caught
                             */
                            FMOD.SOUND_TYPE   _streamType;
                            FMOD.SOUND_FORMAT _streamFormat;
                            int _streamBits;

                            result = sound.getFormat(out _streamType, out _streamFormat, out this.streamChannels, out _streamBits);
                            ERRCHECK(result, "sound.getFormat");

                            float freq; int prio;
                            result = sound.getDefaults(out freq, out prio);
                            ERRCHECK(result, "sound.getDefaults");

                            LOG(LogLevel.INFO, "Stream format {0} {1} {2} channels {3} bits {4} samplerate", _streamType, _streamFormat, this.streamChannels, _streamBits, freq);

                            if (this is AudioStream)
                            {
                                // compensate for the stream samplerate
                                this.GetComponent <AudioSource>().pitch = ((float)(freq * this.streamChannels) / (float)(AudioSettings.outputSampleRate * (int)AudioSettings.speakerMode));
                            }

                            this.StreamStarting((int)freq);

                            this.streamCaught = true;

                            this.isPlaying = true;

                            if (this.OnPlaybackStarted != null)
                            {
                                this.OnPlaybackStarted.Invoke(this.gameObjectName);
                            }

                            break;
                        }
                        else
                        {
                            /*
                             * Unable to stream
                             */
                            if (++c > 60)
                            {
                                if (this.url.StartsWith("http"))
                                {
                                    LOG(LogLevel.ERROR, "Can't start playback. Please make sure that correct audio type of stream is selected and network is reachable.");
#if UNITY_EDITOR
                                    LOG(LogLevel.ERROR, "If everything seems to be ok, restarting the editor often helps while having trouble connecting to especially OGG streams.");
#endif
                                }
                                else
                                {
                                    LOG(LogLevel.ERROR, "Can't start playback. Unrecognized audio type.");
                                }

                                this.Stop();

                                yield break;
                            }
                        }

                        yield return(new WaitForSeconds(0.1f));
                    } while (result != FMOD.RESULT.OK || openstate != FMOD.OPENSTATE.READY);
                }

                if (this.StreamStarving())
                {
                    LOG(LogLevel.WARNING, "Stream buffer starving - stopping playback");

                    this.Stop();

                    yield break;
                }

                FMOD.TAG streamTag;

                /*
                 *  Read any tags that have arrived, this could happen if a radio station switches
                 *  to a new song.
                 */
                while (sound.getTag(null, -1, out streamTag) == FMOD.RESULT.OK)
                {
                    if (!this.trackChanged)
                    {
                        this.tags         = new string[tagcount];
                        this.tagindex     = 0;
                        this.trackChanged = true;
                    }

                    if (streamTag.datatype == FMOD.TAGDATATYPE.STRING)
                    {
                        string tagData = Marshal.PtrToStringAnsi(streamTag.data, (int)streamTag.datalen);
                        tags[tagindex] = string.Format("{0} = {1}", streamTag.name, tagData);
                        tagindex       = (tagindex + 1) % tagcount;
                    }
                    else if (streamTag.type == FMOD.TAGTYPE.FMOD)
                    {
                        /* When a song changes, the samplerate may also change, so compensate here. */
                        if (streamTag.name == "Sample Rate Change")
                        {
                            // TODO: actual float and samplerate change test - is there a way to test this ?

                            float defFrequency;
                            int   defPriority;
                            result = sound.getDefaults(out defFrequency, out defPriority);
                            ERRCHECK(result, "sound.getDefaults");

                            LOG(LogLevel.INFO, "Stream samplerate change from {0}", defFrequency);

                            // float frequency = *((float*)streamTag.data);
                            float[] frequency = new float[1];
                            Marshal.Copy(streamTag.data, frequency, 0, sizeof(float));

                            LOG(LogLevel.INFO, "Stream samplerate change to {0}", frequency[0]);

                            result = sound.setDefaults(frequency[0], defPriority);
                            ERRCHECK(result, "sound.setDefaults");

                            /*
                             * need to restart audio when changing samplerate..
                             */
                            if (this is AudioStream)
                            {
                                // compensate for the stream samplerate
                                this.GetComponent <AudioSource>().pitch = ((float)(frequency[0] * this.streamChannels) / (float)(AudioSettings.outputSampleRate * (int)AudioSettings.speakerMode));
                            }
                        }
                    }
                }

                if (this.trackChanged)
                {
                    // TODO: track changed event
                    LOG(LogLevel.INFO, "Track changed {0}", this.tags[0]); // print tags[0] for info only - might be anything
                    this.trackChanged = false;
                }

                yield return(null);
            }
        }