示例#1
0
 /// <summary>
 /// Stops the AudioSource and disposes references. DOES NOT stop ELIAS!
 /// </summary>
 public void Dispose()
 {
     audioSource.Stop();
     audioSource = null;
     elias       = null;
     gcHandle.Free();
 }
示例#2
0
 private void InitializeElias()
 {
     if ((elias == null || oldProject != selectedProject) && IsProjectSelected())
     {
         elias = new EliasHelper(GetSelectedProjectPath(), (uint)AudioSettings.outputSampleRate);
     }
 }
示例#3
0
 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);
 }
示例#4
0
 private void InitializeElias()
 {
     if ((elias == null || oldProject != selectedProject) && IsProjectSelected())
     {
         elias = new EliasHelper(GetSelectedProjectPath());
     }
 }
示例#5
0
 private void Start()
 {
     elias = new EliasHelper(file, eliasChannelCount, eliasFramesPerBuffer);
     if (playOnStart)
     {
         StartElias();
     }
 }
示例#6
0
 /// <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");
     }
 }
示例#7
0
    /// <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);
    }
示例#8
0
 public elias_event_play_stinger CreatePlayerStingerEvent(EliasHelper elias)
 {
     return(new elias_event_play_stinger(
                (uint)flags,
                preWaitTimeMs,
                transitionPresetName == "" ? 0 : elias.GetTransitionPresetIndex(transitionPresetName),
                name,
                level));
 }
示例#9
0
 /// <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");
     }
 }
示例#10
0
    /// <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");
    }
示例#11
0
    /// <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");
    }
示例#12
0
 /// <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");
     }
 }
示例#13
0
 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));
 }
示例#14
0
    /// <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");
    }
示例#15
0
 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));
 }
示例#17
0
    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);
    }
示例#18
0
    /// <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);
    }
示例#19
0
 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.
 }
示例#20
0
 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);
 }
示例#21
0
    /// <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);
    }
示例#22
0
 /// <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");
 }
示例#23
0
    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();
        }
    }
示例#24
0
 /// <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");
 }
示例#25
0
 /// <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);
 }
示例#26
0
 /// <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);
 }
示例#27
0
 /// <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);