Я искал способ получить звуковую амплитуду звука, воспроизводимого в данный момент времени, и API OpenFL предложил методы leftPeak
и rightPeak
класса SoundChannel
. После нескольких тестов я мог наблюдать, что значение, возвращаемое методом, всегда было одинаковым: 1 (предполагается, что оно возвращает значение от 0 до 1)!
После поиска в исходном коде я смог обнаружить что leftPeak
и rightPeak
были только опубликованными c свойствами, установленными в конструкторе нашего SoundChannel
объекта, но никогда не обновляющимися, и нет функции, объясняющей, как это сделать.
Может пожалуйста, поддержите меня, разработайте метод, чтобы вернуть амплитуду обратно?
Я положил код класса чуть ниже, чтобы подтвердить то, что я сказал!
Заранее спасибо.
#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