public bool unloadOnDemandAudioForSoundMarkerIfAllowed(SoundMarker marker, SoundFile soundFile) { if (!onDemandIsActive) { return false; } Debug.LogWarning("ON-DEMAND should NOT be Loaded: " + soundFile.filename, this); // FIRST - make sure no other SoundMarkers are using the SoundFile IEnumerable<SoundMarker> otherMarkersUsingSoundFile = layoutManager.SoundMarkersUsingSoundFileID( soundFile.filename, hotspotIDToExclude: marker.hotspot.id); foreach (SoundMarker otherMarker in otherMarkersUsingSoundFile) { if (otherMarker.onDemandAudioShouldBeLoaded) { return false; } } // UNLOAD Synced Marker friends if none of them need to be loaded IEnumerable<SoundMarker> syncedMarkers = layoutManager.layout.getSynchronisedMarkers(marker.hotspot.id); Debug.LogError("unloadOnDemandAudioForSoundMarkerIsPossible: " + marker.gameObject.name); if (syncedMarkers == null || !atLeastOneSyncedMarkerClipShouldBeLoaded(syncedMarkers)) { Debug.LogError (" UNLOAD ON DEMAND!"); // We should UNLOAD this AudioClip... layoutManager.UnloadSoundMarkerAndSyncedClips(marker, syncedMarkers); canvasControl.editSoundOverlay.refreshDebugText(); return true; } return false; }
static SoundFile() { defaultSoundFile = new SoundFile(Resources.Load <AudioClip>("Default")); defaultSoundFile.soundName = "Placeholder Sound"; warningSoundFile = new SoundFile(Resources.Load <AudioClip>("air.wav")); // Old Filename: 'VoiceOver' warningSoundFile.soundName = "Tracking warning"; }
// Loads a soundfile object from a metafile, as well as preloading the audio public static IEnumerator LoadSoundFileFromMeta(string filename, Dictionary <string, SoundFile> into) { // Load the metadata SoundFile sf = ReadFromMeta(filename); sf.loadState = LoadState.Loading; // Get and bind the assoc soundfile string url = "file://" + sf.wavPath; // System.Text.Encoding.UTF8 using (UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.WAV)) { yield return(req.SendWebRequest()); if (req.isNetworkError) { Debug.Log(req.error); sf.loadState = LoadState.Fail; } else { AudioClip ac = DownloadHandlerAudioClip.GetContent(req); sf.clip = ac; sf.loadState = LoadState.Success; into[sf.filename] = sf; } } }
public void ListCellClicked(CanvasListCell <SoundFile> listCell, SoundFile sf) { // !!! SoundFile binding OCCURS ON ConfirmButtonClicked() if (canvasDelegate == null) { return; } VoiceOver.main.StopPreview(); //canvasDelegate.LoadSoundClipsExclusivelyForCurrentLayout( if (canvasDelegate.IsOnDemandActive()) { canvasDelegate.RefreshLoadStateForSoundMarkers( completion: () => { if (sf.loadState == LoadState.Success && sf.clip != null) { return; } canvasDelegate.LoadClipInSoundFile(sf, completion: (SoundFile returnedSoundFile) => { VoiceOver.main.PlayPreview(returnedSoundFile); listCell.ReloadUI(); }); }); } else { // ON-DEMAND is NOT active VoiceOver.main.PlayPreview(sf); listCell.ReloadUI(); } }
static SoundFile() { defaultSoundFile = new SoundFile(Resources.Load <AudioClip>("Default")); defaultSoundFile.soundName = "Placeholder Sound"; warningSoundFile = new SoundFile(Resources.Load <AudioClip>("VoiceOver")); warningSoundFile.soundName = "Tracking warning"; }
// Load all Audio File's into the SoundFile dictionary public void LoadSoundMetaFiles(Action completion) { // Make sure all 'audio files on disk' have meta files SoundFile.CreateNewMetas(); // Populate the SoundFile dictionary int numLoaded = 0; Dictionary <string, SoundFile> sfDict = this.soundDictionary; foreach (var filename in SoundFile.metaFiles) { SoundFile newSoundFile = SoundFile.ReadFromMeta(filename); // If the SoundFile has already been loaded, don't reload it if (sfDict.TryGetValue(newSoundFile.filename, out SoundFile sf)) { if (sf.loadState == LoadState.Success) { ++numLoaded; } continue; } newSoundFile.loadState = LoadState.NotLoaded; sfDict[newSoundFile.filename] = newSoundFile; } layoutManagerDelegate?.LayoutManagerLoadedAudioClipsChanged(this, hotspotCount: layout != null ? layout.hotspots.Count : 0); // Debug.Log("Reloaded Metafiles... " + numLoaded + " SoundClip(s) are loaded. " // + ( SoundFile.metaFiles.Count() - numLoaded ) + " NOT loaded."); completion(); }
private void UserDidEnterOnDemandLoadTrigger() { if (_onDemandAudioShouldBeLoaded) { return; } _onDemandAudioShouldBeLoaded = true; // Debug.LogWarning("ON-DEMAND SHOULD be Loaded: " + this.hotspot.soundFile.filename, this); // Markers with Infinite Max Distance should be ignored if (hotspot.hasInfiniteMaxDistance) { return; } SoundFile sf = hotspot.soundFile; if (sf.isDefaultSoundFile) { return; } // Skip the default soundFile // We should LOAD this AudioClip... markerDelegate?.loadOnDemandAudioForSoundMarker(this, sf); // This will also load synchronised SoundMarkers }
// private void UserDidEnterOnDemandUnloadTrigger() { // } // - - - - - - - - - - - - - - - - - - - - - - - // private void UserDidExitOnDemandLoadTrigger() { // } private void UserDidExitOnDemandUnloadTrigger() { if (!_onDemandAudioShouldBeLoaded) { return; } _onDemandAudioShouldBeLoaded = false; // Debug.LogWarning("ON-DEMAND should NOT be Loaded: " + this.hotspot.soundFile.filename, this); // Markers with Infinite Max Distance should be ignored if (hotspot.hasInfiniteMaxDistance) { return; } SoundFile sf = hotspot.soundFile; if (sf.isDefaultSoundFile) { return; } // Skip the default soundFile // We should UNLOAD this AudioClip... (if all other Synced SoundMarkers shouldBeUnloaded) markerDelegate?.unloadOnDemandAudioForSoundMarkerIfAllowed(this, sf); // This will also load synchronised SoundMarkers }
private void PlayThis(SoundFile sf, bool playOnLoop = false) { AdjustVolume(voiceOver: true); audioSource.clip = sf.clip; audioSource.loop = playOnLoop; audioSource.Play(); }
private static IEnumerator loadSoundFileClip(SoundFile sf, System.Action <SoundFile> completion = null) { if (sf.isDefaultSoundFile || (sf.loadState == LoadState.Success && sf.clip != null)) { // ALREADY LOADED! if (completion != null) { completion(sf); } yield break; } sf.loadState = LoadState.Loading; // Get and bind the assoc soundfile string url = "file://" + sf.soundFilepath; // System.Text.Encoding.UTF8 using (UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(url, MP3_otherwise_WAV ? AudioType.MPEG : AudioType.WAV)) { DownloadHandlerAudioClip dHandler = req.downloadHandler as DownloadHandlerAudioClip; // dHandler.streamAudio = true; dHandler.compressed = true; yield return(req.SendWebRequest()); // if (dHandler.isDone) { // Debug.Log("Get Audio clip IS DONE"); // } else { // Debug.Log("Get Audio clip is NOT done"); // } if (req.error != null) { Debug.Log(req.error + " for: " + url); sf.loadState = LoadState.Fail; } else { AudioClip ac = DownloadHandlerAudioClip.GetContent(req); if (ac != null) { // Debug.Log("AudioClip loadState: " + ac.loadState + " - " + sf.filename); if (sf.clip != null) { GameObject.Destroy(sf.clip); } sf.clip = ac; sf.loadState = LoadState.Success; sf.duration = Mathf.RoundToInt(ac.length); sf.Save(); } } } // Debug.LogWarning("SoundFile::loadSoundFileClip WILL call completion..."); if (completion != null) { completion(sf); } }
public void BindSoundFile(SoundFile sf) { if (SoundMarkerIsSelected()) { layoutManager.Bind(objectSelection.selectedMarker, sf, reloadSoundClips: true); } else { // Another use case? Debug.Log("NO SSO SELECTD"); } }
private void PlayThis(SoundFile sf, bool playOnLoop = false, float volume = 1.0f) { _voiceOverDelegate?.voiceOverWillStart(); audioSource.clip = sf.clip; audioSource.loop = playOnLoop; audioSource.volume = volume; audioSource.Play(); }
public void RecordNewSound() { var stamp = System.DateTime.Now.ToString(); var sf = new SoundFile(stamp); AudioSource audioSource = GetComponent <AudioSource>(); audioSource.clip = Microphone.Start("Built-in Microphone", true, 10, 44100); audioSource.Play(); }
// -------------------------- // ACTUAL IMPLEMENTATIONS BELOW /* ####### # # ###### ####### # # # # # ###### # # ## # # # # ## ## # # ## # # # # # # # # # # # # # # # # # # # # # # # # # # # ##### # # ##### # # # # # # # # # # # # # # # # # # # # ####### # # # # # # # # ## # # # # # # # # ## # # ####### # # ###### ####### # # # # # # ###### ####### */ void loadClipInSoundFile(SoundFile soundFile, Action <SoundFile> completion) { LoadClipInSoundFileOnCoroutine(soundFile, marker: null, completion: (SoundFile returnedSoundFile) => { if (completion != null) { completion(returnedSoundFile); } }); }
void unloadSoundMarkerAndSyncedClips(SoundMarker marker, IEnumerable <SoundMarker> syncedMarkers) { SoundFile markerSF = marker.hotspot.soundFile; if (!markerSF.isDefaultSoundFile && (markerSF.loadState == LoadState.Success || markerSF.clip != null)) { // Unload the first marker // marker.SetAudioPauseState(true); marker.OnDemandNullifyAudioClip(); if (destroyImmediate) { UnityEngine.GameObject.DestroyImmediate(markerSF.clip, allowDestroyingAssets: false); } else { UnityEngine.GameObject.Destroy(markerSF.clip); } markerSF.clip = null; markerSF.loadState = LoadState.NotLoaded; } // - - - - - - - - - - - - - - - - - - - // Unload Synced Markers if (syncedMarkers != null) { foreach (SoundMarker syncedMarker in syncedMarkers) { SoundFile syncedSF = syncedMarker.hotspot.soundFile; if (!syncedSF.isDefaultSoundFile && (syncedSF.loadState == LoadState.Success || syncedSF.clip != null)) { // syncedMarker.SetAudioPauseState(true); syncedMarker.OnDemandNullifyAudioClip(); if (destroyImmediate) { UnityEngine.GameObject.DestroyImmediate(syncedSF.clip, allowDestroyingAssets: false); } else { UnityEngine.GameObject.Destroy(syncedSF.clip); } syncedSF.clip = null; syncedSF.loadState = LoadState.NotLoaded; } } } // - - - - - - - - - - - - - - - - - - - _managerDelegate?.OnDemandLoadingLoadedAudioClipsChanged(this); }
// =================================================== /* # ####### ##### ### ##### # # # # # # # # # # # # # # # # # # #### # # # # # # # # # # # # # # # # # ####### ####### ##### ### ##### */ // =================================================== private void loadAllAudioClipsIntoMemory(List <SoundMarker> markers, Layout layout, Action completion) { if (_managerDelegate == null || layout == null) { return; } Dictionary <string, SoundFile> sfDict = _managerDelegate.getSoundDictionary(); int numLoaded = _managerDelegate.getNumLoadedInSoundDictionary(); // UnityEngine.Debug.LogWarning("loadAllAudioClipsIntoMemory: " + numLoaded); LambdaWaiter <SoundFile> lambdaWaiter = new LambdaWaiter <SoundFile>(); HashSet <SoundFile> loadingOrLoadedSoundFiles = new HashSet <SoundFile>(); foreach (SoundMarker marker in markers) { SoundFile sf; if (!sfDict.TryGetValue(marker.hotspot.soundID, out sf)) { continue; } // The Marker SHOULD be loaded loadingOrLoadedSoundFiles.Add(sf); LoadClipInSoundFileOnCoroutine(sf, marker, lambdaWaiter.AddCallback((SoundFile returnedSoundFile) => { })); } foreach (SoundFile sf in sfDict.Values) { if (loadingOrLoadedSoundFiles.Contains(sf)) { continue; } loadingOrLoadedSoundFiles.Add(sf); // sf.loadState = LoadState.Loading; _managerDelegate?.StartCoroutineOn(SoundFile.LoadClipInSoundFile(sf, lambdaWaiter.AddCallback((SoundFile returnedSoundFile) => { }))); } lambdaWaiter.WaitForAllCallbacks(() => { _managerDelegate?.OnDemandLoadingLoadedAudioClipsChanged(this); if (completion != null) { completion(); } }); }
public void Bind(SoundMarker obj, SoundFile sf, bool reloadSoundClips) { // bind these obj.hotspot.Set(sf.filename); obj.LaunchNewClip(sf.clip); // When a new binding occurs, we SHOULD refresh the loaded sound clips // if (reloadSoundClips) { LoadSoundClipsExclusivelyForCurrentLayout(() => { }); } if (reloadSoundClips && layout.onDemandActive) { RefreshLoadStateForSoundMarkers(MainController.soundMarkers, () => { }); } }
// -------------------------- public void LoadClipInSoundFile(SoundFile soundFile, Action <SoundFile> completion) { if (_operationQueue.Count < 1) { loadClipInSoundFile(soundFile, completion: (SoundFile sf) => { completion(sf); this.performNextOperationInQueue(); }); } else { UnityEngine.Debug.LogError("ENQUEUE LoadClipInSoundFile"); _operationQueue.Enqueue(new LoadAudioClipOperation(soundFile, completion)); } }
public void loadOnDemandAudioForSoundMarker(SoundMarker marker, SoundFile soundFile) { if (!onDemandIsActive) { return; } Debug.LogWarning("ON-DEMAND SHOULD be Loaded: " + soundFile.filename); // Debug.Log("loadOnDemandAudioForSoundMarker: " + soundFile.filename); layoutManager.LoadSoundMarkerAndSyncedClips(marker, completion: (HashSet<SoundMarker> loadedMarkers) => { Debug.LogWarning( "loadOnDemandAudioForSoundMarker COMPLETE!"); canvasControl.editSoundOverlay.refreshDebugText(); // foreach (var loadedMarker in loadedMarkers) { // } }); }
void loadSoundMarkerAndSyncedClips(SoundMarker marker, Layout layout, Action <HashSet <SoundMarker> > completion) { HashSet <SoundFile> loadingOrLoadedSoundFiles = new HashSet <SoundFile>(); HashSet <SoundMarker> loadingOrLoadedMarkers = new HashSet <SoundMarker>(); LambdaWaiter <SoundFile> lambdaWaiter = new LambdaWaiter <SoundFile>(); // Load the SoundFile for the marker passed in SoundFile markerSF = marker.hotspot.soundFile; loadingOrLoadedSoundFiles.Add(markerSF); loadingOrLoadedMarkers.Add(marker); if (!markerSF.isDefaultSoundFile) { LoadClipInSoundFileOnCoroutine(markerSF, marker, lambdaWaiter.AddCallback((SoundFile returnedSoundFile) => { })); } // - - - - - - - - - - - - - - - - - - - // Load the Synced Markers IEnumerable <SoundMarker> syncedMarkers = layout.getSynchronisedMarkers(marker.hotspot.id); if (syncedMarkers != null) { foreach (SoundMarker syncedMarker in syncedMarkers) { SoundFile syncedSF = syncedMarker.hotspot.soundFile; loadingOrLoadedSoundFiles.Add(syncedSF); loadingOrLoadedMarkers.Add(syncedMarker); if (!markerSF.isDefaultSoundFile) { LoadClipInSoundFileOnCoroutine(syncedSF, syncedMarker, lambdaWaiter.AddCallback((SoundFile returnedSoundFile) => { })); } } } // - - - - - - - - - - - - - - - - - - - // Wait for loading to complete lambdaWaiter.WaitForAllCallbacks(() => { if (completion != null) { completion(loadingOrLoadedMarkers); } }); }
public void refreshDebugText() { if (canvasDelegate == null || canvasDelegate.objectSelection == null || canvasDelegate.objectSelection.selectedMarker == null || canvasDelegate.objectSelection.selectedMarker.hotspot == null) { return; } SoundFile markerSoundFile = canvasDelegate.objectSelection.selectedMarker.hotspot.soundFile; if (markerSoundFile == null) { return; } debugText.text = markerSoundFile.filename + (markerSoundFile.loadState == LoadState.Success ? " is LOADED" : " is NOT loaded"); }
public static void CreateNewMetas() { // Get list of soundFiles listed in metafiles List <string> foundFilenamesWithData = new List <string>(); foreach (string filename in SoundFile.metaFiles) { foundFilenamesWithData.Add(ReadFromMeta(filename).soundFilepath); } // look for wavs without metas and create them foreach (string filename in SoundFile.soundFilenames) { if (!foundFilenamesWithData.Contains(filename)) { SoundFile sf = new SoundFile(filename); sf.Save(); } } }
public void OnDemandSoundFileClipWasLoaded(SoundFile sf) { //Debug.LogWarning("SoundMarker::OnDemandSoundFileClipWasLoaded " + sf.filename); // ---------------------- // !!! This is important, otherwise we hear an artifact when the clip is assigned (Caused by Resonance) resonance.enabled = false; // ---------------------- setAudioClip(sf.clip); if (!_audioSrc.isPlaying) { _audioSrc.UnPause(); _audioSrc.Play(); } // ---------------------- // !!! This is important, otherwise we hear an artifact when the clip is assigned (Caused by Resonance) resonance.enabled = true; // ---------------------- }
// -------------------------- private void LoadClipInSoundFileOnCoroutine(SoundFile sf, SoundMarker marker, System.Action <SoundFile> completion = null) { if (sf.isDefaultSoundFile || (sf.loadState == LoadState.Success && sf.clip != null)) { if (marker != null) { marker.OnDemandSoundFileClipWasLoaded(sf); } completion(sf); return; } sf.loadState = LoadState.Loading; _managerDelegate?.StartCoroutineOn(SoundFile.LoadClipInSoundFile(sf, completion: (SoundFile returnedSoundFile) => { _managerDelegate?.OnDemandLoadingLoadedAudioClipsChanged(this); if (marker != null) { marker.OnDemandSoundFileClipWasLoaded(returnedSoundFile); } completion(returnedSoundFile); })); }
public void LoadSoundFiles(Action completion) { var into = this.soundDictionary; // A nice little alias for it // Make sure we have data for every wav SoundFile.CreateNewMetas(); // load all sound files from their metas foreach (var filename in SoundFile.metaFiles) { SoundFile sf = SoundFile.ReadFromMeta(filename); string wavName = sf.filename; // If the SoundFile has already been loaded, don't reload it if (soundDictionary.ContainsKey(wavName)) { continue; } layoutManagerDelegate?.StartCoroutineOn(SoundFile.LoadSoundFileFromMeta(filename, into)); } layoutManagerDelegate?.StartCoroutineOn(SoundFile.AwaitLoading(into, completion)); }
public void PlayPreview(SoundFile sf) { PlayThis(sf, playOnLoop: true); }
public void SoundMarkerSelected(SoundMarker selectedMarker) { // Change the InputField text soundNameInputField.text = selectedMarker.hotspot.name; soundLabelResizeText.text = selectedMarker.hotspot.name; // Change the 2D UI representation soundAppearanceImage.sprite = selectedMarker.iconSprite; soundShapeImage.sprite = selectedMarker.soundShapeSprite; // Set the trigger and loop toggles triggerPlaybackToggle.isOn = selectedMarker.hotspot.triggerPlayback; playOnceToggle.isOn = selectedMarker.hotspot.playOnce; loopAudioToggle.isOn = selectedMarker.hotspot.loopAudio; bool loopAudioInteractable = selectedMarker.hotspot.triggerPlayback; if (selectedMarker.hotspot.playOnce) { loopAudioInteractable = false; } loopAudioToggle.interactable = loopAudioInteractable; SetTriggerVisualInteractiveState(loopAudioToggle, loopAudioInteractable, selectedMarker.hotspot.loopAudio); pitchSlider.value = selectedMarker.hotspot.pitchBend; volumeSlider.value = selectedMarker.hotspot.soundVolume; // Filter values freqCutoffSlider.value = selectedMarker.hotspot.freqCutoff; phaserSlider.value = selectedMarker.hotspot.phaserLevel; distortionSlider.value = selectedMarker.hotspot.distortion; echoSlider.value = selectedMarker.hotspot.echoMagnitude; updateSyncedMarkersUI(selectedMarker); // Change the colour of the UI updateUIColor(selectedMarker.color, notifyDelegate: false); // Color newCol = selectedSound.color; // repositionImage.color = newCol; // soundAppearanceImage.color = newCol; // soundColorImage.color = newCol; // minRadiusSlider.SetColorTint(newCol); // maxRadiusSlider.SetColorTint(newCol); // UnityEngine.UI.ColorBlock cols = soundSrcButton.colors; // cols.normalColor = newCol; // cols.highlightedColor = newCol.ColorWithBrightness(-0.15f); // cols.pressedColor = newCol.ColorWithBrightness(-0.3f); // soundSrcButton.colors = cols; minRadiusSlider.SetSliderRadius(selectedMarker.soundMinDist, notifyDelegate: false); maxRadiusSlider.SetSliderRadius(selectedMarker.soundMaxDist, notifyDelegate: false); SoundFile markerSoundFile = selectedMarker.hotspot.soundFile; if (markerSoundFile.isDefaultSoundFile) { soundFilenameText.text = "Tap to change sound"; } else { soundFilenameText.text = "\"" + markerSoundFile.filenameWithExtension + "\""; } int charLimit = 21; int charsOver = soundFilenameText.text.Length - charLimit; float percentOverCharLimit = (charsOver > 0) ? (charsOver / 8f) : 0; soundFilenameText.fontSize = 36 - (int)(8 * percentOverCharLimit); refreshDebugText(); // debugText.text = selectedMarker.userHasHeardSound ? "User HAS heard" : "NOT heard"; }
public void LoadClipInSoundFile(SoundFile soundFile, System.Action <SoundFile> completion) { onDemandLoadingManager.LoadClipInSoundFile(soundFile, completion); }
private void Awake() { preloadInstance = this; }
// Loads a soundfile object from a metafile, as well as preloading the audio // public static IEnumerator LoadSoundFileFromMeta(string filename, Dictionary<string, SoundFile> into, System.Action completion = null) { // // Load the metadata // SoundFile sf = ReadFromMeta(filename); // yield return loadSoundFileClip(sf, completion); // } public static IEnumerator LoadClipInSoundFile(SoundFile sf, System.Action <SoundFile> completion = null) { yield return(loadSoundFileClip(sf, completion)); }