/// <summary> /// Stops the AudioSource and disposes references. DOES NOT stop ELIAS! /// </summary> public void Dispose() { audioSource.Stop(); audioSource = null; elias = null; gcHandle.Free(); }
private void InitializeElias() { if ((elias == null || oldProject != selectedProject) && IsProjectSelected()) { elias = new EliasHelper(GetSelectedProjectPath(), (uint)AudioSettings.outputSampleRate); } }
public bool ReadCallback(float[] data) { currentDataIndex = 0; while (currentDataIndex < data.Length) { if (bufferedLength > 0) { int length = Math.Min(data.Length - currentDataIndex, bufferedLength); Array.Copy(dataBuffer, 0, data, currentDataIndex, length); currentDataIndex += length; bufferedLength -= length; if (bufferedLength > 0) { Array.Copy(dataBuffer, length, dataBuffer, 0, bufferedLength); } } else { EliasWrapper.elias_result_codes r = EliasWrapper.elias_read_samples(elias.Handle, Marshal.UnsafeAddrOfPinnedArrayElement(dataBuffer, 0)); bufferedLength = elias.FramesPerBuffer * elias.ChannelCount; EliasHelper.LogResult(r, "Failed to render"); if (r != EliasWrapper.elias_result_codes.elias_result_success) { return(false); } } } return(true); }
private void InitializeElias() { if ((elias == null || oldProject != selectedProject) && IsProjectSelected()) { elias = new EliasHelper(GetSelectedProjectPath()); } }
private void Start() { elias = new EliasHelper(file, eliasChannelCount, eliasFramesPerBuffer); if (playOnStart) { StartElias(); } }
/// <summary> /// Run an action preset. /// </summary> public void RunActionPreset(string preset, bool ignoreRequiredThemeMissmatch = false) { EliasWrapper.elias_result_codes r = EliasWrapper.elias_run_action_preset(elias.Handle, preset); if (ignoreRequiredThemeMissmatch == false || r != EliasWrapper.elias_result_codes.elias_error_requiredthememismatch) { EliasHelper.LogResult(r, "Problems running an action preset"); } }
/// <summary> /// Get the current theme. /// </summary> public string GetActiveTheme() { uint id = (uint)EliasWrapper.elias_get_active_theme_index(Handle, new double[0]); string name; EliasWrapper.elias_result_codes r = EliasWrapper.elias_get_theme_name_wrapped(Handle, id, out name); EliasHelper.LogResult(r, "Failed to get active theme"); return(name); }
public elias_event_play_stinger CreatePlayerStingerEvent(EliasHelper elias) { return(new elias_event_play_stinger( (uint)flags, preWaitTimeMs, transitionPresetName == "" ? 0 : elias.GetTransitionPresetIndex(transitionPresetName), name, level)); }
/// <summary> /// Stop the rendering of the theme. This function must not be called while any other Elias calls are in progress with the same handle in another thread. /// The exception is if the engine has its own background threads; these will automatically be shut down. /// IMPORTANT: This function must never use thread unsafe calls, as it can be called from either the audio thread in case of failure to render, or the main thread, (game). /// </summary> public void Stop() { isEliasStarted = false; if (elias != null) { EliasWrapper.elias_result_codes r = EliasWrapper.elias_stop(elias.Handle); EliasHelper.LogResult(r, "Problems stopping"); } }
/// <summary> /// Lock and unlock the mixer in order to allow many changes to be made without the risk of running one or more buffers ahead in between your changes. /// Note that multiple calls to elias_lock_mixer may be made in succession, as long as the same number of calls to elias_unlock_mixer are made (a recursive mutex, in other words). /// If you forget to unlock the mixer, the music will stop and you will get deadlocks. /// </summary> public void LockMixer() { if (elias.Handle == IntPtr.Zero) { return; } EliasWrapper.elias_result_codes r = EliasWrapper.elias_lock_mixer(elias.Handle); EliasHelper.LogResult(r, "Problems locking the mixer"); }
/// <summary> /// Queue an elias_event. /// </summary> public void QueueEvent(elias_event @event) { if (elias.Handle == IntPtr.Zero) { return; } EliasWrapper.elias_result_codes r = EliasWrapper.elias_queue_event_wrapped(elias.Handle, @event); EliasHelper.LogResult(r, "Problems queing an event"); }
/// <summary> /// Stop the rendering of the theme. This function must not be called while any other Elias calls are in progress with the same handle in another thread. /// The exception is if the engine has its own background threads; these will automatically be shut down. /// IMPORTANT: This function must never use thread unsafe calls, as it can be called from either the audio thread in case of failure to render, or the main thread, (game). /// </summary> public void Stop() { shouldStop = false; isEliasStarted = false; if (elias.Handle != IntPtr.Zero) { EliasWrapper.elias_result_codes r = EliasWrapper.elias_stop(elias.Handle); EliasHelper.LogResult(r, "Problems stopping"); } }
public elias_event_set_send_volume CreateSetSendVolumeEvent(EliasHelper elias) { return(new elias_event_set_send_volume( (uint)flags, (uint)preWaitTimeMs, (uint)elias.GetBusIndex(busName), slot, volume, (uint)fadeTimeMS)); }
/// <summary> /// Clear all queued events. /// </summary> public void ClearEvents() { if (elias.Handle == IntPtr.Zero) { return; } EliasWrapper.elias_result_codes r = EliasWrapper.elias_clear_events(elias.Handle); EliasHelper.LogResult(r, "Problems clearing events"); }
public EliasAudioReader(EliasHelper eliasHelper, AudioSource audioSourceTarget, bool useProceduralClip) { elias = eliasHelper; audioSource = audioSourceTarget; dataBuffer = new float[elias.FramesPerBuffer * elias.ChannelCount]; if (useProceduralClip) { AudioClip clip = AudioClip.Create("elias clip", elias.FramesPerBuffer * elias.ChannelCount, elias.ChannelCount, elias.SampleRate, true, PCMReadCallback); audioSource.clip = clip; } // By not having any audio clip, and making sure ELIAS is the first effect on the Audio Source, ELIAS is treated as the "source". audioSource.loop = true; gcHandle = GCHandle.Alloc(dataBuffer, GCHandleType.Pinned); }
public override elias_event_set_effect_parameter CreateSetEffectParameterEvent(EliasHelper elias) { EliasWrapper.elias_effect_parameter effectParam = new EliasWrapper.elias_effect_parameter(); effectParam.type = (uint)elias_effect_parameter_types.elias_effect_parameter_bool; effectParam.value.bool_value = (byte)(value ? 1 : 0); return(new elias_event_set_effect_parameter( (uint)flags, (uint)preWaitTimeMs, (uint)elias.GetBusIndex(busName), slot, parameterIndex, effectParam, (uint)sweepTimeMS)); }
private bool StartWithActionPreset() { bool success; string name; EliasWrapper.elias_result_codes r = EliasWrapper.elias_get_action_preset_name_wrapped(elias.Handle, (uint)actionPreset, out name); EliasHelper.LogResult(r, "Problems getting an action preset name"); string theme; r = EliasWrapper.elias_get_action_preset_required_initial_theme_wrapped(elias.Handle, name, out theme); EliasHelper.LogResult(r, "Problems with getting the required initial theme for an action preset"); success = StartWithActionPreset(name); return(success); }
/// <summary> /// Get the current theme. /// </summary> public string GetActiveTheme() { if (Handle == IntPtr.Zero) { return(""); } uint id = (uint)EliasWrapper.elias_get_active_theme_index(Handle, null); string name; EliasWrapper.elias_result_codes r = EliasWrapper.elias_get_theme_name_wrapped(Handle, id, out name); EliasHelper.LogResult(r, "Failed to get active theme"); return(name); }
public elias_event_set_level CreateSetLevelEvent(EliasHelper elias) { return(new elias_event_set_level( (uint)flags, (uint)preWaitTimeMs, transitionPresetName == "" ? 0 : elias.GetTransitionPresetIndex(transitionPresetName), elias.GetThemeIndex(themeName), level, elias.GetGroupIndex(trackGroupName), jumpToBar, (uint)suggestedMaxTimeMs, elias.GetStingerIndex("", stingerName))); //Note: By not passing in a theme name, we are getting the stinger index of the currently playing theme. //This is required when changing themes, as the stinger that plays is from the theme that is transitioned away from. }
public EliasAudioReader(EliasHelper eliasHelper, uint eliasFramesPerBufferOut, AudioSource audioSourceTarget, bool useProceduralClip) { elias = eliasHelper; eliasFramesPerBufferExternal = eliasFramesPerBufferOut; audioSource = audioSourceTarget; dataBuffer = new float[eliasFramesPerBufferExternal * elias.ChannelCount]; //This following part is normally only used when useHighLatencyMode in EliasPlayer is set to true. if (useProceduralClip) { AudioClip clip = AudioClip.Create("elias clip", elias.FramesPerBuffer * elias.ChannelCount, elias.ChannelCount, elias.SampleRate, true, PCMReadCallback); audioSource.clip = clip; } // By not having any audio clip, and making sure ELIAS is the first effect on the Audio Source, ELIAS is treated as the "source". audioSource.loop = true; gcHandle = GCHandle.Alloc(dataBuffer, GCHandleType.Pinned); }
/// <summary> /// Start ELIAS with a elias_event_set_level event. This function must not be called from more than one thread at the same time. /// </summary> public bool StartTheme(elias_event_set_level setLevel) { if (elias.Handle == IntPtr.Zero) { return(false); } if (AudioSettings.outputSampleRate == 0) { Debug.LogError("Unity's AudioSettings.outputSampleRate is reporting 0, so the Elias Plugin is unable to determine what sample rate would be correct to use! " + "This may cause the speed of the audio to play at the wrong rate. Please set a sample rate for Unity in the Project settings."); } EliasWrapper.elias_result_codes r = EliasWrapper.elias_start_background_wrapped(elias.Handle, setLevel, AudioSettings.outputSampleRate != 0 ? (uint)AudioSettings.outputSampleRate : (uint)eliasSampleRate, (uint)eliasFramesPerBuffer); EliasHelper.LogResult(r, setLevel.ToString()); return(r == EliasWrapper.elias_result_codes.elias_result_success); }
/// <summary> /// Lock and unlock the mixer in order to allow many changes to be made without the risk of running one or more buffers ahead in between your changes. /// Note that multiple calls to elias_lock_mixer may be made in succession, as long as the same number of calls to elias_unlock_mixer are made (a recursive mutex, in other words). /// If you forget to unlock the mixer, the music will stop and you will get deadlocks. /// </summary> public void UnlockMixer() { EliasWrapper.elias_result_codes r = EliasWrapper.elias_unlock_mixer(elias.Handle); EliasHelper.LogResult(r, "Problems unlocking the mixer"); }
public void Start() { if (elias == null) { if (eliasChannelCount < 0 || eliasChannelCount == 3 || eliasChannelCount == 7 || eliasChannelCount > 8) { Debug.LogError("Invalid channel count set for Elias, disabling the player: " + eliasChannelCount); this.enabled = false; return; } if (AudioSettings.outputSampleRate == 0) { Debug.LogError("Unity's AudioSettings.outputSampleRate is reporting 0, so the Elias Plugin is unable to determine what sample rate would be correct to use! " + "This may cause the speed of the audio to play at the wrong rate. Please set a sample rate for Unity in the Project settings."); } // The Elias internal resampling requires that the buffer sizes allocated are large enough to hold enough samples to get the framesPerBuffer set in the elias_start_* calls. // It also requires the buffer sizes to be a power of 2. int internalEliasBufferSize = eliasFramesPerBuffer; if (AudioSettings.outputSampleRate < eliasSampleRate) { //In case unity's output sample rate is reporting 0, then we double our assumed buffer size to be able to handle resampling if needed. int minBufferSizeRequiredForResampling = (int)((float)eliasFramesPerBuffer * (AudioSettings.outputSampleRate != 0 ? ((float)eliasSampleRate / (float)AudioSettings.outputSampleRate) : 2)); int nextPowerOf2BufferSize = 1; while (nextPowerOf2BufferSize < minBufferSizeRequiredForResampling) { nextPowerOf2BufferSize *= 2; } internalEliasBufferSize = nextPowerOf2BufferSize; } //-1 is the default for the sample rate setting as older projects would not have set it at all. int sampleRateToUse = eliasSampleRate == -1 ? AudioSettings.outputSampleRate : eliasSampleRate; string basePath = Application.streamingAssetsPath; #if UNITY_ANDROID && !UNITY_EDITOR string baseApkPath = Application.dataPath; baseApkPath = baseApkPath.Remove(baseApkPath.LastIndexOf('/') + 1); baseApkPath += "base.apk"; if (File.Exists(baseApkPath) && (Application.dataPath != baseApkPath)) { basePath = "jar:file://" + Application.dataPath; basePath = basePath.Remove(basePath.LastIndexOf('/') + 1); basePath += "base.apk"; basePath += "!/assets"; } #endif if (customBasePath != "") { basePath = customBasePath; } elias = new EliasHelper(Path.Combine(basePath, file), Path.GetDirectoryName(Path.Combine(basePath, file)), (ushort)internalEliasBufferSize, (byte)eliasChannelCount, (uint)sampleRateToUse, null, null, eliasCachePageCount, eliasCachePageSize, deserializeProjectOnStart); if (elias.Handle == IntPtr.Zero) { Debug.LogError("Elias failed to initialize, disabling the EliasPlayer!"); this.enabled = false; } } if (playOnStart && deserializeProjectOnStart) { StartElias(); } }
/// <summary> /// Clear all queued events. /// </summary> public void ClearEvents() { EliasWrapper.elias_result_codes r = EliasWrapper.elias_clear_events(elias.Handle); EliasHelper.LogResult(r, "Problems clearing events"); }
/// <summary> /// Start ELIAS with a elias_event_set_level event. This function must not be called from more than one thread at the same time. /// </summary> public bool StartTheme(elias_event_set_level setLevel) { EliasWrapper.elias_result_codes r = EliasWrapper.elias_start_wrapped(elias.Handle, setLevel); EliasHelper.LogResult(r, setLevel.ToString()); return(r == EliasWrapper.elias_result_codes.elias_result_success); }
/// <summary> /// Start ELIAS with an action preset. This function must not be called from more than one thread at the same time. /// </summary> public bool StartWithActionPreset(string preset) { EliasWrapper.elias_result_codes r = EliasWrapper.elias_start_with_action_preset(elias.Handle, preset); EliasHelper.LogResult(r, preset); return(r == EliasWrapper.elias_result_codes.elias_result_success); }
/// <summary> /// Queue an elias_event. /// </summary> public void QueueEvent(elias_event @event) { EliasWrapper.elias_result_codes r = EliasWrapper.elias_queue_event_wrapped(elias.Handle, @event); EliasHelper.LogResult(r, "Problems queing an event"); }
abstract public elias_event_set_effect_parameter CreateSetEffectParameterEvent(EliasHelper elias);