首页 > 解决方案 > 如何使用 OpenFL 计算幅度

问题描述

我一直在寻找一种方法来获取在给定时间播放的声音的音频幅度,OpenFL API 提出了leftPeak和类的rightPeak方法SoundChannel。经过几次测试,我可以观察到该方法返回的值始终相同:1(它应该返回一个介于 0 和 1 之间的值)!

在搜索源代码后,我发现它只是公共属性,在我们对象的构造函数中设置leftPeak,但从未更新,并且没有解释如何执行此操作的函数。rightPeakSoundChannel

你能支持我开发恢复振幅的方法吗?

我把课程代码放在它下面,以确认我所说的!

先感谢您。


#if !flash
import openfl.events.Event;
import openfl.events.EventDispatcher;
#if lime
import lime.media.AudioSource;
#end

/**
    The SoundChannel class controls a sound in an application. Every sound is
    assigned to a sound channel, and the application can have multiple sound
    channels that are mixed together. The SoundChannel class contains a
    `stop()` method, properties for monitoring the amplitude
    (volume) of the channel, and a property for assigning a SoundTransform
    object to the channel.

    @event soundComplete Dispatched when a sound has finished playing.
**/
#if !openfl_debug
@:fileXml('tags="haxe,release"')
@:noDebug
#end
@:access(openfl.media.SoundMixer)
@:final @:keep class SoundChannel extends EventDispatcher
{
    /**
        The current amplitude(volume) of the left channel, from 0(silent) to 1
        (full amplitude).
    **/
    public var leftPeak(default, null):Float;

    /**
        When the sound is playing, the `position` property indicates in
        milliseconds the current point that is being played in the sound file.
        When the sound is stopped or paused, the `position` property
        indicates the last point that was played in the sound file.

        A common use case is to save the value of the `position`
        property when the sound is stopped. You can resume the sound later by
        restarting it from that saved position.

        If the sound is looped, `position` is reset to 0 at the
        beginning of each loop.
    **/
    public var position(get, set):Float;

    /**
        The current amplitude(volume) of the right channel, from 0(silent) to 1
        (full amplitude).
    **/
    public var rightPeak(default, null):Float;

    /**
        The SoundTransform object assigned to the sound channel. A SoundTransform
        object includes properties for setting volume, panning, left speaker
        assignment, and right speaker assignment.
    **/
    public var soundTransform(get, set):SoundTransform;

    @:noCompletion private var __isValid:Bool;
    @:noCompletion private var __soundTransform:SoundTransform;
    #if lime
    @:noCompletion private var __source:AudioSource;
    #end

    #if openfljs
    @:noCompletion private static function __init__()
    {
        untyped Object.defineProperties(SoundChannel.prototype, {
            "position": {
                get: untyped __js__("function () { return this.get_position (); }"),
                set: untyped __js__("function (v) { return this.set_position (v); }")
            },
            "soundTransform": {
                get: untyped __js__("function () { return this.get_soundTransform (); }"),
                set: untyped __js__("function (v) { return this.set_soundTransform (v); }")
            },
        });
    }
    #end

    @:noCompletion private function new(source:#if lime AudioSource #else Dynamic #end = null, soundTransform:SoundTransform = null):Void
    {
        super(this);

        leftPeak = 1;
        rightPeak = 1;

        if (soundTransform != null)
        {
            __soundTransform = soundTransform;
        }
        else
        {
            __soundTransform = new SoundTransform();
        }

        #if lime
        if (source != null)
        {
            __source = source;
            __source.onComplete.add(source_onComplete);
            __isValid = true;

            __source.play();
        }
        #end

        SoundMixer.__registerSoundChannel(this);
    }

    /**
        Stops the sound playing in the channel.
    **/
    public function stop():Void
    {
        SoundMixer.__unregisterSoundChannel(this);

        if (!__isValid) return;

        #if lime
        __source.stop();
        #end
        __dispose();
    }

    @:noCompletion private function __dispose():Void
    {
        if (!__isValid) return;

        #if lime
        __source.onComplete.remove(source_onComplete);
        __source.dispose();
        __source = null;
        #end
        __isValid = false;
    }

    @:noCompletion private function __updateTransform():Void
    {
        this.soundTransform = soundTransform;
    }

    // Get & Set Methods
    @:noCompletion private function get_position():Float
    {
        if (!__isValid) return 0;

        #if lime
        return __source.currentTime + __source.offset;
        #else
        return 0;
        #end
    }

    @:noCompletion private function set_position(value:Float):Float
    {
        if (!__isValid) return 0;

        #if lime
        __source.currentTime = Std.int(value) - __source.offset;
        #end
        return value;
    }

    @:noCompletion private function get_soundTransform():SoundTransform
    {
        return __soundTransform.clone();
    }

    @:noCompletion private function set_soundTransform(value:SoundTransform):SoundTransform
    {
        if (value != null)
        {
            __soundTransform.pan = value.pan;
            __soundTransform.volume = value.volume;

            var pan = SoundMixer.__soundTransform.pan + __soundTransform.pan;

            if (pan < -1) pan = -1;
            if (pan > 1) pan = 1;

            var volume = SoundMixer.__soundTransform.volume * __soundTransform.volume;

            if (__isValid)
            {
                #if lime
                __source.gain = volume;

                var position = __source.position;
                position.x = pan;
                position.z = -1 * Math.sqrt(1 - Math.pow(pan, 2));
                __source.position = position;

                return value;
                #end
            }
        }

        return value;
    }

    // Event Handlers
    @:noCompletion private function source_onComplete():Void
    {
        SoundMixer.__unregisterSoundChannel(this);

        __dispose();
        dispatchEvent(new Event(Event.SOUND_COMPLETE));
    }
}
#else
typedef SoundChannel = flash.media.SoundChannel;
#end

标签: haxeopenfl

解决方案


推荐阅读