forked from LeenkxTeam/LNXSDK
		
	Update lib/aura/Sources/aura/channels/Html5StreamChannel.hx
This commit is contained in:
		| @ -4,9 +4,15 @@ package aura.channels; | ||||
|  | ||||
| import js.Browser; | ||||
| import js.html.AudioElement; | ||||
| import js.html.audio.AudioContext; | ||||
| import js.html.audio.ChannelSplitterNode; | ||||
| import js.html.audio.ChannelMergerNode; | ||||
| import js.html.audio.GainNode; | ||||
| import js.html.audio.MediaElementAudioSourceNode; | ||||
| import js.html.URL; | ||||
|  | ||||
| import kha.SystemImpl; | ||||
| import kha.js.MobileWebAudio; | ||||
| import kha.js.MobileWebAudioChannel; | ||||
|  | ||||
| import aura.threading.Message; | ||||
| @ -30,20 +36,67 @@ import aura.types.AudioBuffer; | ||||
| class Html5StreamChannel extends BaseChannel { | ||||
| 	static final virtualChannels: Array<Html5StreamChannel> = []; | ||||
|  | ||||
| 	final audioContext: AudioContext; | ||||
| 	final audioElement: AudioElement; | ||||
| 	final source: MediaElementAudioSourceNode; | ||||
|  | ||||
| 	final gain: GainNode; | ||||
| 	final leftGain: GainNode; | ||||
| 	final rightGain: GainNode; | ||||
| 	final attenuationGain: GainNode; | ||||
| 	final splitter: ChannelSplitterNode; | ||||
| 	final merger: ChannelMergerNode; | ||||
|  | ||||
| 	var virtualPosition: Float; | ||||
| 	var lastUpdateTime: Float; | ||||
|  | ||||
| 	var dopplerRatio: Float = 1.0; | ||||
| 	var pitch: Float = 1.0; | ||||
|  | ||||
| 	public function new(sound: kha.Sound, loop: Bool) { | ||||
| 		audioContext = new AudioContext(); | ||||
| 		audioElement = Browser.document.createAudioElement(); | ||||
| 		source = audioContext.createMediaElementSource(audioElement); | ||||
|  | ||||
| 		final mimeType = #if kha_debug_html5 "audio/ogg" #else "audio/mp4" #end; | ||||
| 		final blob = new js.html.Blob([sound.compressedData.getData()], {type: mimeType}); | ||||
| 		final soundData: js.lib.ArrayBuffer = sound.compressedData.getData(); | ||||
| 		final blob = new js.html.Blob([soundData], {type: mimeType}); | ||||
|  | ||||
| 		// TODO: if removing channels, use revokeObjectUrl() ? | ||||
| 		// 	see https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL | ||||
| 		audioElement.src = URL.createObjectURL(blob); | ||||
| 		audioElement.loop = loop; | ||||
| 		untyped audioElement.preservesPitch = false; | ||||
|  | ||||
| 		splitter = audioContext.createChannelSplitter(2); | ||||
| 		leftGain = audioContext.createGain(); | ||||
| 		rightGain = audioContext.createGain(); | ||||
| 		attenuationGain = audioContext.createGain(); | ||||
| 		merger = audioContext.createChannelMerger(2); | ||||
| 		gain = audioContext.createGain(); | ||||
|  | ||||
| 		source.connect(splitter); | ||||
|  | ||||
| 		// The sound data needs to be decoded because `sounds.channels` returns `0`. | ||||
| 		audioContext.decodeAudioData(soundData, function (buffer) { | ||||
| 			// TODO: add more cases for Quad and 5.1 ? - https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API#audio_channels | ||||
| 			switch (buffer.numberOfChannels) { | ||||
| 				case 1: | ||||
| 					splitter.connect(leftGain, 0); | ||||
| 					splitter.connect(rightGain, 0); | ||||
| 				case 2: | ||||
| 					splitter.connect(leftGain, 0); | ||||
| 					splitter.connect(rightGain, 1); | ||||
| 				default: | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		leftGain.connect(merger, 0, 0); | ||||
| 		rightGain.connect(merger, 0, 1); | ||||
| 		merger.connect(attenuationGain); | ||||
| 		attenuationGain.connect(gain); | ||||
|  | ||||
| 		gain.connect(audioContext.destination); | ||||
|  | ||||
| 		if (isVirtual()) { | ||||
| 			virtualChannels.push(this); | ||||
| @ -130,15 +183,32 @@ class Html5StreamChannel extends BaseChannel { | ||||
| 		switch (message.id) { | ||||
| 			// Because we're using a HTML implementation here, we cannot use the | ||||
| 			// LinearInterpolator parameters | ||||
| 			case ChannelMessageID.PVolume: audioElement.volume = cast message.data; | ||||
| 			case ChannelMessageID.PVolume: attenuationGain.gain.value = cast message.data; | ||||
| 			case ChannelMessageID.PPitch: | ||||
| 				pitch = cast message.data; | ||||
| 				updatePlaybackRate(); | ||||
| 			case ChannelMessageID.PDopplerRatio: | ||||
| 			case ChannelMessageID.PDstAttenuation: | ||||
| 				dopplerRatio = cast message.data; | ||||
| 				updatePlaybackRate(); | ||||
| 			case ChannelMessageID.PDstAttenuation: gain.gain.value = cast message.data; | ||||
| 			case ChannelMessageID.PVolumeLeft: leftGain.gain.value = cast message.data; | ||||
| 			case ChannelMessageID.PVolumeRight: rightGain.gain.value = cast message.data; | ||||
|  | ||||
| 			default: | ||||
| 				super.parseMessage(message); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	function updatePlaybackRate() { | ||||
| 		try { | ||||
| 			audioElement.playbackRate = pitch * dopplerRatio; | ||||
| 		} | ||||
| 		catch (e) { | ||||
| 			// Ignore. Unfortunately some browsers only support a certain range | ||||
| 			// of playback rates, but this is not explicitly specified, so there's | ||||
| 			// not much we can do here. | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /** | ||||
| @ -147,10 +217,50 @@ class Html5StreamChannel extends BaseChannel { | ||||
| 	https://github.com/Kode/Kha/commit/12494b1112b64e4286b6a2fafc0f08462c1e7971 | ||||
| **/ | ||||
| class Html5MobileStreamChannel extends BaseChannel { | ||||
| 	final audioContext: AudioContext; | ||||
| 	final khaChannel: kha.js.MobileWebAudioChannel; | ||||
|  | ||||
| 	final leftGain: GainNode; | ||||
| 	final rightGain: GainNode; | ||||
| 	final attenuationGain: GainNode; | ||||
| 	final splitter: ChannelSplitterNode; | ||||
| 	final merger: ChannelMergerNode; | ||||
|  | ||||
| 	var dopplerRatio: Float = 1.0; | ||||
| 	var pitch: Float = 1.0; | ||||
|  | ||||
| 	public function new(sound: kha.Sound, loop: Bool) { | ||||
| 		audioContext = MobileWebAudio._context; | ||||
| 		khaChannel = new kha.js.MobileWebAudioChannel(cast sound, loop); | ||||
|  | ||||
| 		@:privateAccess khaChannel.gain.disconnect(audioContext.destination); | ||||
| 		@:privateAccess khaChannel.source.disconnect(@:privateAccess khaChannel.gain); | ||||
|  | ||||
| 		splitter = audioContext.createChannelSplitter(2); | ||||
| 		leftGain = audioContext.createGain(); | ||||
| 		rightGain = audioContext.createGain(); | ||||
| 		merger = audioContext.createChannelMerger(2); | ||||
| 		attenuationGain = audioContext.createGain(); | ||||
|  | ||||
| 		@:privateAccess khaChannel.source.connect(splitter); | ||||
|  | ||||
| 		// TODO: add more cases for Quad and 5.1 ? - https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Basic_concepts_behind_Web_Audio_API#audio_channels | ||||
| 		switch (sound.channels) { | ||||
| 			case 1: | ||||
| 				splitter.connect(leftGain, 0); | ||||
| 				splitter.connect(rightGain, 0); | ||||
| 			case 2: | ||||
| 				splitter.connect(leftGain, 0); | ||||
| 				splitter.connect(rightGain, 1); | ||||
| 			default: | ||||
| 		} | ||||
|  | ||||
| 		leftGain.connect(merger, 0, 0); | ||||
| 		rightGain.connect(merger, 0, 1); | ||||
| 		merger.connect(attenuationGain); | ||||
| 		attenuationGain.connect(@:privateAccess khaChannel.gain); | ||||
|  | ||||
| 		@:privateAccess khaChannel.gain.connect(audioContext.destination); | ||||
| 	} | ||||
|  | ||||
| 	public function play(retrigger: Bool) { | ||||
| @ -181,12 +291,26 @@ class Html5MobileStreamChannel extends BaseChannel { | ||||
| 			// LinearInterpolator parameters | ||||
| 			case ChannelMessageID.PVolume: khaChannel.volume = cast message.data; | ||||
| 			case ChannelMessageID.PPitch: | ||||
| 				pitch = cast message.data; | ||||
| 				updatePlaybackRate(); | ||||
| 			case ChannelMessageID.PDopplerRatio: | ||||
| 			case ChannelMessageID.PDstAttenuation: | ||||
| 				dopplerRatio = cast message.data; | ||||
| 				updatePlaybackRate(); | ||||
| 			case ChannelMessageID.PDstAttenuation: attenuationGain.gain.value = cast message.data; | ||||
| 			case ChannelMessageID.PVolumeLeft: leftGain.gain.value = cast message.data; | ||||
| 			case ChannelMessageID.PVolumeRight: rightGain.gain.value = cast message.data; | ||||
|  | ||||
| 			default: | ||||
| 				super.parseMessage(message); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	function updatePlaybackRate() { | ||||
| 		try { | ||||
| 			@:privateAccess khaChannel.source.playbackRate.value = pitch * dopplerRatio; | ||||
| 		} | ||||
| 		catch (e) {} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| #end | ||||
|  | ||||
		Reference in New Issue
	
	Block a user