import { EventDispatcher } from '../events/EventDispatcher'; import { SoundTransform } from './SoundTransform'; import { release } from '@awayfl/swf-loader'; import { SecurityDomain } from '../SecurityDomain'; import { Event } from '../events/Event'; import { EventBase, IAudioChannel } from '@awayjs/core'; import { ISoundSource, SoundMixer } from './SoundMixer'; import { BaseAudioChannel } from '@awayjs/core/dist/lib/managers/BaseAudioChannel'; /** * Dispatched when a sound has finished playing. * @eventType flash.events.Event.SOUND_COMPLETE * [Event(name="soundComplete", type="flash.events.Event")] * * 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. */ export class SoundChannel extends EventDispatcher implements ISoundSource { // for AVM1: public axCallPublicProperty(value1: any, value2: any): any { return null; } public axGetPublicProperty(value: any): any { return null; } public axSetPublicProperty(value: any, value2: any): any { return null; } public axHasPublicProperty(value: any): any { return null; } public axDeletePublicProperty(value: any): any { return null; } public axGetEnumerableKeys(): string[] { return []; } private _soundTransform: SoundTransform; private _channel: IAudioChannel; /* internal */ init (channel: IAudioChannel | null, transform: SoundTransform) { this._channel = channel; if (!this._channel) { return; } this._channel.addEventListener(BaseAudioChannel.COMPLETE, this.soundCompleteInternal.bind(this)); this.soundTransform = transform; SoundMixer._registerSoundSource(this); } /** * The current amplitude (volume) of the left channel, from 0 (silent) to 1 (full amplitude). */ public get leftPeak(): number { release || console.log('leftPeak not implemented yet in flash/SoundChannel'); return 0; } /** * 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 get position(): number { return this._channel ? this._channel.currentTime : 0; } /** * The current amplitude (volume) of the right channel, from 0 (silent) to 1 (full amplitude). */ public get rightPeak(): number { release || console.log('rightPeak not implemented yet in flash/SoundChannel'); return 0; } /** * 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 get soundTransform(): SoundTransform { // we not create this in the constructor, because it gets overwritten from Sound in most cases anyway // but we still need a Soundtransform to be available in the getter if (!this._soundTransform) { this._soundTransform = new ( this.sec).flash.media.SoundTransform(); } return this._soundTransform; } public set soundTransform(value: SoundTransform) { if (this._channel) { this._channel.volume = (value.volume == null) ? 0 : value.volume; this._channel.pan = (value.pan == null) ? 0 : value.pan; } this._soundTransform = value; } private soundCompleteInternal(event: EventBase) { this._stopInternally(); // we should dispatch sound events to channel, because some games use this const complete = new ( this.sec).flash.events.Event(Event.SOUND_COMPLETE); this.dispatchEvent(complete); } private _stopInternally() { SoundMixer._unregisterSoundSource(this); } /** * Stops the sound playing in the channel. * @langversion 3.0 * @playerversion Flash 9 * @playerversion Lite 4 * @refpath */ public stop() { if (!this._channel) { release || console.log('SoundChannel.stop: No sound exists'); return; } this._stopInternally(); this._channel.stop(); } // for ISoundSource stopSound() { this.stop(); } // for ISoundSource updateSoundLevels(volume: number) { if (!this._channel) { return; } this._soundTransform.volume = volume; this._channel.volume = volume; } }