<commit_before>package hxd.snd.webaudio;
#if (js && !useal)

import hxd.snd.webaudio.AudioTypes;
import hxd.snd.Driver.DriverFeature;
import js.html.audio.*;

class Driver implements hxd.snd.Driver {

	public var ctx : AudioContext;
	public var masterGain(get, never) : GainNode;
	public var destination(get, set) : AudioNode;

	var playbackPool : Array<BufferPlayback>;

	public function new()
	{
		playbackPool = [];

		ctx = Context.get();
	}

	/**
		Returns free AudioBuffer instance corresponding to sample count, amount of channels and sample-rate.
	**/
	public inline function getBuffer(channels : Int, sampleCount : Int, rate : Int) : AudioBuffer {
		return Context.getBuffer(channels, sampleCount, rate);
	}

	/**
		Puts AudioBuufer back to it's pool.
	**/
	public inline function putBuffer( buf : AudioBuffer ) {
		Context.putBuffer(buf);
	}

	/**
		Returns free Gain node
	**/
	public inline function getGain():GainNode
	{
		return Context.getGain();
	}

	public inline function putGain(gain:GainNode) {
		Context.putGain(gain);
	}

	public function hasFeature (d : DriverFeature) : Bool {
		switch (d) {
			case MasterVolume: return true;
		}
	}

	public function setMasterVolume (value : Float) : Void {
		masterGain.gain.value = value;
	}

	public function setListenerParams (position : h3d.Vector, direction : h3d.Vector, up : h3d.Vector, ?velocity : h3d.Vector) : Void {
		ctx.listener.setPosition(-position.x, position.y, position.z);
		ctx.listener.setOrientation(-direction.x, direction.y, direction.z, -up.x, up.y, up.z);
		// TODO: Velocity
	}

	public function createSource () : SourceHandle {
		var s = new SourceHandle();
		s.driver = this;
		s.gain = getGain();
		s.updateDestination();
		return s;
	}

	public function playSource (source : SourceHandle) : Void {
		if ( !source.playing ) {
			source.playing = true;
			if ( source.buffers.length != 0 ) {
				var time = ctx.currentTime;
				for ( b in source.buffers ) {
					if ( b.consumed ) continue;
					time = b.start(ctx, source, time);
				}
			}
		}
	}

	public function stopSource (source : SourceHandle) : Void {
		source.playing = false;
		source.sampleOffset = 0;
	}

	public function setSourceVolume (source : SourceHandle, value : Float) : Void {
		source.gain.gain.value = value;
	}

	public function destroySource (source : SourceHandle) : Void {
		stopSource(source);
		source.gain.disconnect();
		source.driver = null;
		putGain(source.gain);
		source.gain = null;
		for ( b in source.buffers ) {
			b.stop();
			b.clear();
			playbackPool.push(b);
		}
		source.buffers = [];
	}

	public function createBuffer () : BufferHandle {
		var b = new BufferHandle();
		b.samples = 0;
		return b;
	}

	public function setBufferData (buffer : BufferHandle, data : haxe.io.Bytes, size : Int, format : Data.SampleFormat, channelCount : Int, samplingRate : Int) : Void {
		var sampleCount = Std.int(size / hxd.snd.Data.formatBytes(format) / channelCount);
		buffer.samples = sampleCount;
		if (sampleCount == 0) return;

		if ( buffer.inst == null ) {
			buffer.inst = getBuffer(channelCount, sampleCount, samplingRate);
		} else if ( buffer.inst.sampleRate != samplingRate || buffer.inst.numberOfChannels != channelCount || buffer.inst.length != sampleCount ) {
			putBuffer(buffer.inst);
			buffer.inst = getBuffer(channelCount, sampleCount, samplingRate);
		}
		switch (format)
		{
			case UI8:
				var ui8 = new hxd.impl.TypedArray.Uint8Array(data.getData());
				if (channelCount == 1) {
					var chn = buffer.inst.getChannelData(0);
					for ( i in 0...sampleCount ) {
						chn[i] = ui8[i] / 0xff;
					}
				} else {
					var left = buffer.inst.getChannelData(0);
					var right = buffer.inst.getChannelData(1);
					// TODO: 3+ channels
					var r = 0;
					for ( i in 0...sampleCount ) {
						left[i] = ui8[r] / 0xff;
						right[i] = ui8[r+1] / 0xff;
						r += channelCount;
					}
				}
			case I16:
				var i16 = new hxd.impl.TypedArray.Int16Array(data.getData());
				if (channelCount == 1) {
					var chn = buffer.inst.getChannelData(0);
					for ( i in 0...sampleCount ) {
						chn[i] = i16[i] / 0x8000;
					}
				} else {
					var left = buffer.inst.getChannelData(0);
					var right = buffer.inst.getChannelData(1);
					// TODO: 3+ channels
					var r = 0;
					for ( i in 0...sampleCount ) {
						left[i] = i16[r] / 0x8000;<commit_msg>Fix sampling rate value on JS on 8 bit WAV files (#1093)<commit_after>package hxd.snd.webaudio;
#if (js && !useal)

import hxd.snd.webaudio.AudioTypes;
import hxd.snd.Driver.DriverFeature;
import js.html.audio.*;

class Driver implements hxd.snd.Driver {

	public var ctx : AudioContext;
	public var masterGain(get, never) : GainNode;
	public var destination(get, set) : AudioNode;

	var playbackPool : Array<BufferPlayback>;

	public function new()
	{
		playbackPool = [];

		ctx = Context.get();
	}

	/**
		Returns free AudioBuffer instance corresponding to sample count, amount of channels and sample-rate.
	**/
	public inline function getBuffer(channels : Int, sampleCount : Int, rate : Int) : AudioBuffer {
		return Context.getBuffer(channels, sampleCount, rate);
	}

	/**
		Puts AudioBuufer back to it's pool.
	**/
	public inline function putBuffer( buf : AudioBuffer ) {
		Context.putBuffer(buf);
	}

	/**
		Returns free Gain node
	**/
	public inline function getGain():GainNode
	{
		return Context.getGain();
	}

	public inline function putGain(gain:GainNode) {
		Context.putGain(gain);
	}

	public function hasFeature (d : DriverFeature) : Bool {
		switch (d) {
			case MasterVolume: return true;
		}
	}

	public function setMasterVolume (value : Float) : Void {
		masterGain.gain.value = value;
	}

	public function setListenerParams (position : h3d.Vector, direction : h3d.Vector, up : h3d.Vector, ?velocity : h3d.Vector) : Void {
		ctx.listener.setPosition(-position.x, position.y, position.z);
		ctx.listener.setOrientation(-direction.x, direction.y, direction.z, -up.x, up.y, up.z);
		// TODO: Velocity
	}

	public function createSource () : SourceHandle {
		var s = new SourceHandle();
		s.driver = this;
		s.gain = getGain();
		s.updateDestination();
		return s;
	}

	public function playSource (source : SourceHandle) : Void {
		if ( !source.playing ) {
			source.playing = true;
			if ( source.buffers.length != 0 ) {
				var time = ctx.currentTime;
				for ( b in source.buffers ) {
					if ( b.consumed ) continue;
					time = b.start(ctx, source, time);
				}
			}
		}
	}

	public function stopSource (source : SourceHandle) : Void {
		source.playing = false;
		source.sampleOffset = 0;
	}

	public function setSourceVolume (source : SourceHandle, value : Float) : Void {
		source.gain.gain.value = value;
	}

	public function destroySource (source : SourceHandle) : Void {
		stopSource(source);
		source.gain.disconnect();
		source.driver = null;
		putGain(source.gain);
		source.gain = null;
		for ( b in source.buffers ) {
			b.stop();
			b.clear();
			playbackPool.push(b);
		}
		source.buffers = [];
	}

	public function createBuffer () : BufferHandle {
		var b = new BufferHandle();
		b.samples = 0;
		return b;
	}

	public function setBufferData (buffer : BufferHandle, data : haxe.io.Bytes, size : Int, format : Data.SampleFormat, channelCount : Int, samplingRate : Int) : Void {
		var sampleCount = Std.int(size / hxd.snd.Data.formatBytes(format) / channelCount);
		buffer.samples = sampleCount;
		if (sampleCount == 0) return;

		if ( buffer.inst == null ) {
			buffer.inst = getBuffer(channelCount, sampleCount, samplingRate);
		} else if ( buffer.inst.sampleRate != samplingRate || buffer.inst.numberOfChannels != channelCount || buffer.inst.length != sampleCount ) {
			putBuffer(buffer.inst);
			buffer.inst = getBuffer(channelCount, sampleCount, samplingRate);
		}
		switch (format)
		{
			case UI8:
				var ui8 = new hxd.impl.TypedArray.Uint8Array(data.getData());
				if (channelCount == 1) {
					var chn = buffer.inst.getChannelData(0);
					for ( i in 0...sampleCount ) {
						chn[i] = (ui8[i] - 0x80) / 0x80;
					}
				} else {
					var left = buffer.inst.getChannelData(0);
					var right = buffer.inst.getChannelData(1);
					// TODO: 3+ channels
					var r = 0;
					for ( i in 0...sampleCount ) {
						left[i] = (ui8[r] - 0x80) / 0x80;
						right[i] = (ui8[r+1] - 0x80) / 0x80;
						r += channelCount;
					}
				}
			case I16:
				var i16 = new hxd.impl.TypedArray.Int16Array(data.getData());
				if (channelCount == 1) {
					var chn = buffer.inst.getChannelData(0);
					for ( i in 0...sampleCount ) {
						chn[i] = i16[i] / 0x8000;
					}
				} else {
					var left = buffer.inst.getChannelData(0);
					var right = buffer.inst.getChannelData(1);
					// TODO: 3+ channels
					var r = 0;
					for ( i in 0...sampleCount ) {
						left[i] = i16[r] / 0x8000;
{'fraction_non_alphanumeric': 0.13362265874828688, 'fraction_numerical': 0.014618547281863865, 'mean_word_length': 3.1522048364153625, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6508756', 'n_tokens_mistral': 3480, 'n_tokens_neox': 2938, 'n_words': 739}