/// <summary> /// Prepares media for playback /// </summary> /// <param name="filename"></param> private void LoadMedia(PlayListEntry entry) { FMOD.RESULT result; //load a new sound result = _system.createSound(entry.FileName, FMOD.MODE._2D | FMOD.MODE.NONBLOCKING | FMOD.MODE.CREATESTREAM, out _sound); CheckError(result); //how to determine the media is ready? an event perhaps? FMOD.OPENSTATE openState; uint percentBuffered; bool starving; bool diskBusy; //check to see if it is ready _sound.getOpenState(out openState, out percentBuffered, out starving, out diskBusy); //check state while (openState == FMOD.OPENSTATE.LOADING) { _sound.getOpenState(out openState, out percentBuffered, out starving, out diskBusy); Thread.Sleep(25); } Length = GetLength(); }
private void timer_Tick(object sender, System.EventArgs e) { FMOD.RESULT result; FMOD.OPENSTATE openstate = 0; uint percentbuffered = 0; bool starving = false; bool busy = false; if (soundcreated) { result = sound.getOpenState(ref openstate, ref percentbuffered, ref starving, ref busy); ERRCHECK(result); if (openstate == FMOD.OPENSTATE.READY && channel == null) { result = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel); ERRCHECK(result); } } if (channel != null) { uint ms = 0; bool playing = false; bool paused = false; for (;;) { FMOD.TAG tag = new FMOD.TAG(); if (sound.getTag(null, -1, ref tag) != FMOD.RESULT.OK) { break; } if (tag.datatype == FMOD.TAGDATATYPE.STRING) { textBox.Text = tag.name + " = " + Marshal.PtrToStringAnsi(tag.data) + " (" + tag.datalen + " bytes)"; } else { break; } } result = channel.getPaused(ref paused); ERRCHECK(result); result = channel.isPlaying(ref playing); ERRCHECK(result); result = channel.getPosition(ref ms, FMOD.TIMEUNIT.MS); ERRCHECK(result); statusBar.Text = "Time " + (ms / 1000 / 60) + ":" + (ms / 1000 % 60) + ":" + (ms / 10 % 100) + (openstate == FMOD.OPENSTATE.BUFFERING ? " Buffering..." : (openstate == FMOD.OPENSTATE.CONNECTING ? " Connecting..." : (paused ? " Paused " : (playing ? " Playing " : " Stopped ")))) + "(" + percentbuffered + "%)" + (starving ? " STARVING" : " "); } if (system != null) { system.update(); } }
public void PlaySound() { bool state = true; while (state) { FMOD.OPENSTATE openstate = 0; uint percentbuffered = 0; bool starving = false; bool busy = false; FMOD.RESULT result = sounds.getOpenState(ref openstate, ref percentbuffered, ref starving, ref busy); ErrorCheck(result); if (openstate == FMOD.OPENSTATE.READY && channels == null) { result = system.playSound(FMOD.CHANNELINDEX.FREE, sounds, false, ref channels); ErrorCheck(result); channels.setVolume(0.0f); state = false; } } }
private void timer_Tick(object sender, System.EventArgs e) { FMOD.RESULT result; FMOD.OPENSTATE openstate = 0; if (soundcreated) { uint percentbuffered = 0; bool starving = false; bool busy = false; result = sound.getOpenState(ref openstate, ref percentbuffered, ref starving, ref busy); ERRCHECK(result); if (openstate == FMOD.OPENSTATE.READY && channel == null) { result = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel); ERRCHECK(result); } } if (channel != null) { uint ms = 0; bool playing = false; bool paused = false; int tagsupdated = 0; int numtags = 0; result = sound.getNumTags(ref numtags, ref tagsupdated); ERRCHECK(result); if (tagsupdated != 0) { for (;;) { FMOD.TAG tag = new FMOD.TAG(); if (sound.getTag(null, -1, ref tag) != FMOD.RESULT.OK) { break; } if (tag.datatype == FMOD.TAGDATATYPE.STRING) { FMOD.SOUND_FORMAT format = FMOD.SOUND_FORMAT.NONE; int channels = 0; int bits = 0; sound.getFormat(ref gSoundType, ref format, ref channels, ref bits); if (tag.name == "ARTIST") { if (Marshal.PtrToStringAnsi(tag.data) != gCurrentTrackArtist) { gCurrentTrackArtist = Marshal.PtrToStringAnsi(tag.data); gUpdateFileName = true; } } if (tag.name == "TITLE") { if (Marshal.PtrToStringAnsi(tag.data) != gCurrentTrackTitle) { gCurrentTrackTitle = Marshal.PtrToStringAnsi(tag.data); gUpdateFileName = true; } } break; } else { break; } } } result = channel.isPlaying(ref playing); if (result != FMOD.RESULT.OK || !playing) { sound.release(); sound = null; channel = null; } else { result = channel.getPaused(ref paused); ERRCHECK(result); result = channel.getPosition(ref ms, FMOD.TIMEUNIT.MS); ERRCHECK(result); statusBar.Text = "Time " + (ms / 1000 / 60) + ":" + (ms / 1000 % 60) + ":" + (ms / 10 % 100) + (paused ? " Paused " : playing ? " Playing" : " Stopped"); } } if (sound != null) { uint percentbuffered = 0; bool starving = false; bool busy = false; sound.getOpenState(ref openstate, ref percentbuffered, ref starving, ref busy); if (openstate == FMOD.OPENSTATE.ERROR) { sound.release(); sound = null; channel = null; } } if (openstate == FMOD.OPENSTATE.ERROR) { statusBar.Text = "Error occurred or stream ended. Restarting stream.."; result = system.createSound(url, (FMOD.MODE.HARDWARE | FMOD.MODE._2D | FMOD.MODE.CREATESTREAM | FMOD.MODE.NONBLOCKING), ref exinfo, ref sound); ERRCHECK(result); } if (system != null) { system.update(); } }
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); } }