Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -0,0 +1,107 @@
package kha.audio2;
import js.Syntax;
import js.Browser;
import js.html.URL;
import js.html.audio.AudioContext;
import js.html.audio.AudioProcessingEvent;
import js.html.audio.ScriptProcessorNode;
import kha.internal.IntBox;
import kha.js.AEAudioChannel;
import kha.Sound;
class Audio {
public static var disableGcInteractions = false;
static var intBox: IntBox = new IntBox(0);
static var buffer: Buffer;
@:noCompletion public static var _context: AudioContext;
static var processingNode: ScriptProcessorNode;
static function initContext(): Void {
try {
_context = new AudioContext();
return;
}
catch (e:Dynamic) {}
try {
Syntax.code("this._context = new webkitAudioContext();");
return;
}
catch (e:Dynamic) {}
}
@:noCompletion
public static function _init(): Bool {
initContext();
if (_context == null)
return false;
Audio.samplesPerSecond = Math.round(_context.sampleRate);
var bufferSize = 1024 * 2;
buffer = new Buffer(bufferSize * 4, 2, Std.int(_context.sampleRate));
processingNode = _context.createScriptProcessor(bufferSize, 0, 2);
processingNode.onaudioprocess = function(e: AudioProcessingEvent) {
var output1 = e.outputBuffer.getChannelData(0);
var output2 = e.outputBuffer.getChannelData(1);
if (audioCallback != null) {
intBox.value = e.outputBuffer.length * 2;
audioCallback(intBox, buffer);
for (i in 0...e.outputBuffer.length) {
output1[i] = buffer.data.get(buffer.readLocation);
buffer.readLocation += 1;
output2[i] = buffer.data.get(buffer.readLocation);
buffer.readLocation += 1;
if (buffer.readLocation >= buffer.size) {
buffer.readLocation = 0;
}
}
}
else {
for (i in 0...e.outputBuffer.length) {
output1[i] = 0;
output2[i] = 0;
}
}
}
processingNode.connect(_context.destination);
return true;
}
public static var samplesPerSecond: Int;
public static var audioCallback: kha.internal.IntBox->Buffer->Void;
static var virtualChannels: Array<VirtualStreamChannel> = [];
public static function wakeChannels() {
SystemImpl.mobileAudioPlaying = true;
for (channel in virtualChannels) {
channel.wake();
}
}
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
// var source = _context.createMediaStreamSource(cast sound.compressedData.getData());
// source.connect(_context.destination);
var element = Browser.document.createAudioElement();
#if kha_debug_html5
var blob = new js.html.Blob([sound.compressedData.getData()], {type: "audio/ogg"});
#else
var blob = new js.html.Blob([sound.compressedData.getData()], {type: "audio/mp4"});
#end
element.src = URL.createObjectURL(blob);
element.loop = loop;
var channel = new AEAudioChannel(element, loop);
if (SystemImpl.mobileAudioPlaying) {
channel.play();
return channel;
}
else {
var virtualChannel = new VirtualStreamChannel(channel, loop);
virtualChannels.push(virtualChannel);
return virtualChannel;
}
}
}

View File

@ -0,0 +1,126 @@
package kha.audio2;
import kha.js.AEAudioChannel;
import kha.audio1.AudioChannel;
enum abstract PlayMode(Int) {
var Stopped;
var Paused;
var Playing;
}
class VirtualStreamChannel implements kha.audio1.AudioChannel {
var aeChannel: AEAudioChannel;
var mode = PlayMode.Playing;
var lastTickTime: Float;
var lastPosition: Float;
var looping: Bool;
public function new(aeChannel: AEAudioChannel, looping: Bool) {
this.aeChannel = aeChannel;
this.looping = looping;
lastTickTime = Scheduler.realTime();
lastPosition = 0;
}
public function wake(): Void {
updatePosition();
aeChannel.position = lastPosition;
aeChannel.play();
}
function updatePosition(): Void {
var now = Scheduler.realTime();
switch (mode) {
case Stopped:
lastPosition = 0;
case Paused:
// nothing
case Playing:
lastPosition += now - lastTickTime;
while (lastPosition > length) {
lastPosition -= length;
}
}
lastTickTime = now;
}
public function play(): Void {
if (SystemImpl.mobileAudioPlaying) {
aeChannel.play();
}
else {
updatePosition();
mode = Playing;
}
}
public function pause(): Void {
if (SystemImpl.mobileAudioPlaying) {
aeChannel.pause();
}
else {
updatePosition();
mode = Paused;
}
}
public function stop(): Void {
if (SystemImpl.mobileAudioPlaying) {
aeChannel.stop();
}
else {
updatePosition();
mode = Stopped;
}
}
public var length(get, never): Float; // Seconds
function get_length(): Float {
return aeChannel.length;
}
public var position(get, set): Float; // Seconds
function get_position(): Float {
if (SystemImpl.mobileAudioPlaying) {
return aeChannel.position;
}
else {
updatePosition();
return lastPosition;
}
}
function set_position(value: Float): Float {
if (SystemImpl.mobileAudioPlaying) {
return aeChannel.position = value;
}
else {
updatePosition();
return lastPosition = value;
}
}
public var volume(get, set): Float;
function get_volume(): Float {
return aeChannel.volume;
}
function set_volume(value: Float): Float {
return aeChannel.volume = value;
}
public var finished(get, never): Bool;
function get_finished(): Bool {
if (SystemImpl.mobileAudioPlaying) {
return aeChannel.finished;
}
else {
return mode == Stopped || (!looping && position >= length);
}
}
}