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)); } }
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); } }