reorginization and new sound format

This commit is contained in:
MathMan05 2024-11-30 22:47:50 -06:00
parent 7c46e70304
commit 6788c54ad6
12 changed files with 595 additions and 186 deletions

View file

@ -113,6 +113,7 @@ return gulp
"src/**/*.webp", "src/**/*.webp",
"src/**/*.gif", "src/**/*.gif",
"src/**/*.svg", "src/**/*.svg",
"src/**/*.jasf",
],{encoding:false}) ],{encoding:false})
.pipe(plumber()) // Prevent pipe breaking caused by errors .pipe(plumber()) // Prevent pipe breaking caused by errors
.pipe(gulp.dest("dist")); .pipe(gulp.dest("dist"));

View file

@ -0,0 +1,37 @@
# Jank Audio format
This is a markdown file that will try to describe the jank client audio format in sufficient detail so people will know how this weird custom format works into the future.
This is a byte-aligned format, which uses the sequence jasf in asci as a magic number at the start.
the next 8 bits will decide how many voices this file has/will provide, if the value is 255 you'll instead have a 16 bit number that follows for how many voices there are, this *should* be unused, but I wouldn't be totally surprised if it did get used.
then it'll parse for that many voices, which will be formatted like the following:
name:String8;
length:f32; **if this is 0, this is not an custom sound and is instead refering to something else which will be explained later™**
Given a non-zero length, this will parse the sounds as following:
|instruction | description |
| ---------- | ----------- |
| 000 | read float32 and use as value |
| 001 | read time(it'll always be a value between 0 and 1) |
| 002 | read frequency in hz |
| 003 | the constant PI |
| 004 | Math.sin() on the following sequence |
| 005 | multiplies the next two expressions |
| 006 | adds the next two expressions |
| 007 | divides the first expression by the second |
| 008 | subtracts the second expression by the first |
| 009 | first expression to the power of the second |
| 010 | first expression to the modulo of the second |
| 011 | absolute power of the next expression |
| 012 | round the next expression |
| 013 | Math.cos() on the next expression |
> note
> this is likely to expand in the future as more things are needed, but this is just how it is right now.
Once you've read all of the sounds in the file, you can move on to parsing the tracks.
This starts out by reading a u16 to find out how many tracks there are, then you'll go on to try and parse that many.
each track will then read a u16 to find out how long it is, then it'll read bytes as the following.
it'll first read the index(which is either a u8 or u16 depending on if the amount of voices was u8 or u16), which is the index of the voice 1-indexed, then if it's not 0 it'll parse two float32s in this order, the volume then the pitch of the sound, if it was 0 it'll instead read one 32f as a delay in the track. if it's a default sound it'll also read a third 32f for length
then finally you'll parse the audios which are the complete tracks. you'll first parse a u16 to get how many audios there are, then for each audio you'll first parse a string8 for the name, then a u16 for the length then according to the length you'll go on to parse a u16 to get the track (1-indexed again) where if it's 0 you'll instead add a delay according to the next f32, how many ever times according to the length.

View file

@ -1,181 +1,34 @@
class AVoice{ import { BinRead } from "../utils/binaryUtils.js";
audioCtx: AudioContext; import { Track } from "./track.js";
info: { wave: string | Function; freq: number };
playing: boolean; export class Audio{
myArrayBuffer: AudioBuffer; name:string;
gainNode: GainNode; tracks:(Track|number)[];
buffer: Float32Array; constructor(name:string,tracks:(Track|number)[]){
source: AudioBufferSourceNode; this.tracks=tracks;
constructor(wave: string | Function, freq: number, volume = 1){ this.name=name;
this.audioCtx = new window.AudioContext();
this.info = { wave, freq };
this.playing = false;
this.myArrayBuffer = this.audioCtx.createBuffer(
1,
this.audioCtx.sampleRate,
this.audioCtx.sampleRate
);
this.gainNode = this.audioCtx.createGain();
this.gainNode.gain.value = volume;
this.gainNode.connect(this.audioCtx.destination);
this.buffer = this.myArrayBuffer.getChannelData(0);
this.source = this.audioCtx.createBufferSource();
this.source.buffer = this.myArrayBuffer;
this.source.loop = true;
this.source.start();
this.updateWave();
} }
get wave(): string | Function{ static parse(read:BinRead,trackarr:Track[]):Audio{
return this.info.wave; const name=read.readString8();
} const length=read.read16();
get freq(): number{ const tracks:(Track|number)[]=[]
return this.info.freq; for(let i=0;i<length;i++){
} let index=read.read16();
set wave(wave: string | Function){ if(index===0){
this.info.wave = wave; tracks.push(read.readFloat32());
this.updateWave(); }else{
} tracks.push(trackarr[index-1]);
set freq(freq: number){
this.info.freq = freq;
this.updateWave();
}
updateWave(): void{
const func = this.waveFunction();
for(let i = 0; i < this.buffer.length; i++){
this.buffer[i] = func(i / this.audioCtx.sampleRate, this.freq);
} }
} }
waveFunction(): Function{ return new Audio(name,tracks)
if(typeof this.wave === "function"){
return this.wave;
} }
switch(this.wave){ async play(){
case"sin": for(const thing of this.tracks){
return(t: number, freq: number)=>{ if(thing instanceof Track){
return Math.sin(t * Math.PI * 2 * freq); thing.play();
}; }else{
case"triangle": await new Promise((res)=>setTimeout(res,thing));
return(t: number, freq: number)=>{
return Math.abs(((4 * t * freq) % 4) - 2) - 1;
};
case"sawtooth":
return(t: number, freq: number)=>{
return((t * freq) % 1) * 2 - 1;
};
case"square":
return(t: number, freq: number)=>{
return(t * freq) % 2 < 1 ? 1 : -1;
};
case"white":
return(_t: number, _freq: number)=>{
return Math.random() * 2 - 1;
};
}
return new Function();
}
play(): void{
if(this.playing){
return;
}
this.source.connect(this.gainNode);
this.playing = true;
}
stop(): void{
if(this.playing){
this.source.disconnect();
this.playing = false;
} }
} }
static noises(noise: string): void{
switch(noise){
case"three": {
const voicy = new AVoice("sin", 800);
voicy.play();
setTimeout(_=>{
voicy.freq = 1000;
}, 50);
setTimeout(_=>{
voicy.freq = 1300;
}, 100);
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case"zip": {
const voicy = new AVoice((t: number, freq: number)=>{
return Math.sin((t + 2) ** Math.cos(t * 4) * Math.PI * 2 * freq);
}, 700);
voicy.play();
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case"square": {
const voicy = new AVoice("square", 600, 0.4);
voicy.play();
setTimeout(_=>{
voicy.freq = 800;
}, 50);
setTimeout(_=>{
voicy.freq = 1000;
}, 100);
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case"beep": {
const voicy = new AVoice("sin", 800);
voicy.play();
setTimeout(_=>{
voicy.stop();
}, 50);
setTimeout(_=>{
voicy.play();
}, 100);
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case "join":{
const voicy = new AVoice("triangle", 600,.1);
voicy.play();
setTimeout(_=>{
voicy.freq=800;
}, 75);
setTimeout(_=>{
voicy.freq=1000;
}, 150);
setTimeout(_=>{
voicy.stop();
}, 200);
break;
}
case "leave":{
const voicy = new AVoice("triangle", 850,.5);
voicy.play();
setTimeout(_=>{
voicy.freq=700;
}, 100);
setTimeout(_=>{
voicy.stop();
voicy.freq=400;
}, 180);
setTimeout(_=>{
voicy.play();
}, 200);
setTimeout(_=>{
voicy.stop();
}, 250);
break;
}
}
}
static get sounds(){
return["three", "zip", "square", "beep"];
} }
} }
export{ AVoice as AVoice };

View file

@ -19,6 +19,7 @@
<p>I want to let the sound system of jank not be so hard coded, but I still need to work on everything a bit before that can happen. Thanks for your patience.</p> <p>I want to let the sound system of jank not be so hard coded, but I still need to work on everything a bit before that can happen. Thanks for your patience.</p>
<h3>why does this tool need to exist?</h3> <h3>why does this tool need to exist?</h3>
<p>For size reasons jank does not use normal sound files, so I need to make this whole format to be more adaptable</p> <p>For size reasons jank does not use normal sound files, so I need to make this whole format to be more adaptable</p>
<button id="download">Download the sounds</button>
</body> </body>
<script src="/audio/page.js" type="module"></script> <script src="/audio/page.js" type="module"></script>

View file

@ -1,3 +1,157 @@
import { BinWrite } from "../utils/binaryUtils.js";
import { setTheme } from "../utils/utils.js"; import { setTheme } from "../utils/utils.js";
import { Play } from "./play.js";
setTheme(); setTheme();
const w=new BinWrite(2**12);
w.writeStringNo("jasf");
w.write8(4);
w.writeString8("sin");
w.write32Float(0);
w.writeString8("triangle");
w.write32Float(0);
w.writeString8("square");
w.write32Float(0);
w.writeString8("custom");
w.write32Float(150);
//return Math.sin(((t + 2) ** Math.cos(t * 4)) * Math.PI * 2 * freq);
//Math.sin((((t+2)**Math.cos((t*4)))*((Math.PI*2)*f)))
w.write8(4);//sin
w.write8(5)//times
{
w.write8(9);//Power
{
w.write8(6);//adding
w.write8(1);//t
w.write8(0);w.write32Float(2);//2
}
w.write8(13);//cos
w.write8(5);// times
w.write8(1);//t
w.write8(0);w.write32Float(4);//4
}
{
w.write8(5)//times
w.write8(5)//times
w.write8(3);//PI
w.write8(0);w.write32Float(2);//2
w.write8(2);//freq
}
w.write16(4);//3 tracks
w.write16(1);//zip
w.write8(4);
w.write32Float(1)
w.write32Float(700)
w.write16(3);//beep
{
w.write8(1);
w.write32Float(1)
w.write32Float(700);
w.write32Float(50);
w.write8(0);
w.write32Float(100);
w.write8(1);
w.write32Float(1)
w.write32Float(700);
w.write32Float(50);
}
w.write16(5);//three
{
w.write8(1);
w.write32Float(1)
w.write32Float(800);
w.write32Float(50);
w.write8(0);
w.write32Float(50);
w.write8(1);
w.write32Float(1)
w.write32Float(1000);
w.write32Float(50);
w.write8(0);
w.write32Float(50);
w.write8(1);
w.write32Float(1)
w.write32Float(1300);
w.write32Float(50);
}
w.write16(5);//square
{
w.write8(3);
w.write32Float(1)
w.write32Float(600);
w.write32Float(50);
w.write8(0);
w.write32Float(50);
w.write8(3);
w.write32Float(1)
w.write32Float(800);
w.write32Float(50);
w.write8(0);
w.write32Float(50);
w.write8(3);
w.write32Float(1)
w.write32Float(1000);
w.write32Float(50);
}
w.write16(4);//2 audio
w.writeString8("zip");
w.write16(1);
w.write16(1);
w.writeString8("beep");
w.write16(1);
w.write16(2);
w.writeString8("three");
w.write16(1);
w.write16(3);
w.writeString8("square");
w.write16(1);
w.write16(4);
const buff=w.getBuffer();
const play=Play.parseBin(buff);
/*
const zip=play.audios.get("square");
if(zip){
setInterval(()=>{
zip.play()
},1000)
;
console.log(play.voices[3][0].info.wave)
};
*/
console.log(play,buff);
const download=document.getElementById("download");
if(download){
download.onclick=()=>{
const blob = new Blob([buff], { type: "binary" });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = "sounds.jasf";
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(downloadUrl);
}
}

48
src/webpage/audio/play.ts Normal file
View file

@ -0,0 +1,48 @@
import { BinRead } from "../utils/binaryUtils.js";
import { Track } from "./track.js";
import { AVoice } from "./voice.js";
import { Audio } from "./audio.js";
export class Play{
voices:[AVoice,string][]
tracks:Track[]
audios:Map<string,Audio>;
constructor(voices:[AVoice,string][],tracks:Track[],audios:Map<string,Audio>){
this.voices=voices;
this.tracks=tracks;
this.audios=audios;
}
static parseBin(buffer:ArrayBuffer){
const read=new BinRead(buffer);
if(read.readStringNo(4)!=="jasf") throw new Error("this is not a jasf file");
let voices=read.read8();
let six=false;
if(voices===255){
voices=read.read16();
six=true;
}
const voiceArr:[AVoice,string][]=[];
for(let i=0;i<voices;i++){
voiceArr.push(AVoice.getVoice(read));
}
const tracks=read.read16();
const trackArr:Track[]=[];
for(let i=0;i<tracks;i++){
trackArr.push(Track.parse(read,voiceArr,six));
}
const audios=read.read16();
const audioArr=new Map<string,Audio>();
for(let i=0;i<audios;i++){
const a=Audio.parse(read,trackArr);
audioArr.set(a.name,a)
}
return new Play(voiceArr,trackArr,audioArr);
}
static async playURL(url:string){
const res=await fetch(url);
const arr=await res.arrayBuffer();
return this.parseBin(arr);
}
}

Binary file not shown.

View file

@ -0,0 +1,46 @@
import { BinRead } from "../utils/binaryUtils.js";
import { AVoice } from "./voice.js";
export class Track{
seq:(AVoice|number)[];
constructor(playing:(AVoice|number)[]){
this.seq=playing;
}
static parse(read:BinRead,play:[AVoice,string][],six:boolean):Track{
const length=read.read16();
const play2:(AVoice|number)[]=[];
for(let i=0;i<length;i++){
let index:number;
if(six){
index=read.read16();
}else{
index=read.read8();
}
if(index===0){
play2.push(read.readFloat32());
continue;
}
index--;
if(!play[index]) throw new Error("voice not found");
const [voice]=play[index];
let temp:AVoice;
if((voice.info.wave instanceof Function)){
temp=voice.clone(read.readFloat32(),read.readFloat32());
}else{
temp=voice.clone(read.readFloat32(),read.readFloat32(),read.readFloat32());
}
play2.push(temp);
}
return new Track(play2);
}
async play(){
for(const thing of this.seq){
if(thing instanceof AVoice){
thing.playL();
}else{
await new Promise((res)=>setTimeout(res,thing));
}
}
}
}

246
src/webpage/audio/voice.ts Normal file
View file

@ -0,0 +1,246 @@
import { BinRead } from "../utils/binaryUtils.js";
class AVoice{
audioCtx: AudioContext;
info: { wave: string | Function; freq: number };
playing: boolean;
myArrayBuffer: AudioBuffer;
gainNode: GainNode;
buffer: Float32Array;
source: AudioBufferSourceNode;
length=1;
constructor(wave: string | Function, freq: number, volume = 1,length=1000){
this.length=length;
this.audioCtx = new window.AudioContext();
this.info = { wave, freq };
this.playing = false;
this.myArrayBuffer = this.audioCtx.createBuffer(
1,
this.audioCtx.sampleRate*length/1000,
this.audioCtx.sampleRate
);
this.gainNode = this.audioCtx.createGain();
this.gainNode.gain.value = volume;
this.gainNode.connect(this.audioCtx.destination);
this.buffer = this.myArrayBuffer.getChannelData(0);
this.source = this.audioCtx.createBufferSource();
this.source.buffer = this.myArrayBuffer;
this.source.loop = true;
this.source.start();
this.updateWave();
}
clone(volume:number,freq:number,length=this.length){
return new AVoice(this.wave,freq,volume,length);
}
get wave(): string | Function{
return this.info.wave;
}
get freq(): number{
return this.info.freq;
}
set wave(wave: string | Function){
this.info.wave = wave;
this.updateWave();
}
set freq(freq: number){
this.info.freq = freq;
this.updateWave();
}
updateWave(): void{
const func = this.waveFunction();
for(let i = 0; i < this.buffer.length; i++){
this.buffer[i] = func(i / this.audioCtx.sampleRate, this.freq);
}
}
waveFunction(): Function{
if(typeof this.wave === "function"){
return this.wave;
}
switch(this.wave){
case"sin":
return(t: number, freq: number)=>{
return Math.sin(t * Math.PI * 2 * freq);
};
case"triangle":
return(t: number, freq: number)=>{
return Math.abs(((4 * t * freq) % 4) - 2) - 1;
};
case"sawtooth":
return(t: number, freq: number)=>{
return((t * freq) % 1) * 2 - 1;
};
case"square":
return(t: number, freq: number)=>{
return(t * freq) % 2 < 1 ? 1 : -1;
};
case"white":
return(_t: number, _freq: number)=>{
return Math.random() * 2 - 1;
};
}
return new Function();
}
play(): void{
if(this.playing){
return;
}
this.source.connect(this.gainNode);
this.playing = true;
}
playL(){
this.play();
setTimeout(()=>{
this.stop();
},this.length);
}
stop(): void{
if(this.playing){
this.source.disconnect();
this.playing = false;
}
}
static noises(noise: string): void{
switch(noise){
case"three": {
const voicy = new AVoice("sin", 800);
voicy.play();
setTimeout(_=>{
voicy.freq = 1000;
}, 50);
setTimeout(_=>{
voicy.freq = 1300;
}, 100);
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case"zip": {
const voicy = new AVoice((t: number, freq: number)=>{
return Math.sin((t + 2) ** Math.cos(t * 4) * Math.PI * 2 * freq);
}, 700);
voicy.play();
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case"square": {
const voicy = new AVoice("square", 600, 0.4);
voicy.play();
setTimeout(_=>{
voicy.freq = 800;
}, 50);
setTimeout(_=>{
voicy.freq = 1000;
}, 100);
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case"beep": {
const voicy = new AVoice("sin", 800);
voicy.play();
setTimeout(_=>{
voicy.stop();
}, 50);
setTimeout(_=>{
voicy.play();
}, 100);
setTimeout(_=>{
voicy.stop();
}, 150);
break;
}
case "join":{
const voicy = new AVoice("triangle", 600,.1);
voicy.play();
setTimeout(_=>{
voicy.freq=800;
}, 75);
setTimeout(_=>{
voicy.freq=1000;
}, 150);
setTimeout(_=>{
voicy.stop();
}, 200);
break;
}
case "leave":{
const voicy = new AVoice("triangle", 850,.5);
voicy.play();
setTimeout(_=>{
voicy.freq=700;
}, 100);
setTimeout(_=>{
voicy.stop();
voicy.freq=400;
}, 180);
setTimeout(_=>{
voicy.play();
}, 200);
setTimeout(_=>{
voicy.stop();
}, 250);
break;
}
}
}
static get sounds(){
return["three", "zip", "square", "beep"];
}
static getVoice(read:BinRead):[AVoice,string]{
const name = read.readString8();
let length=read.readFloat32();
let special:Function|string
if(length!==0){
special=this.parseExpression(read);
}else{
special=name;
length=1;
}
return [new AVoice(special,0,0,length),name]
}
static parseExpression(read:BinRead):Function{
return new Function("t","f",`return ${this.PEHelper(read)};`);
}
static PEHelper(read:BinRead):string{
let state=read.read8();
switch(state){
case 0:
return ""+read.readFloat32();
case 1:
return "t";
case 2:
return "f";
case 3:
return `Math.PI`
case 4:
return `Math.sin(${this.PEHelper(read)})`;
case 5:
return `(${this.PEHelper(read)}*${this.PEHelper(read)})`;
case 6:
return `(${this.PEHelper(read)}+${this.PEHelper(read)})`;
case 7:
return `(${this.PEHelper(read)}/${this.PEHelper(read)})`;
case 8:
return `(${this.PEHelper(read)}-${this.PEHelper(read)})`;
case 9:
return `(${this.PEHelper(read)}**${this.PEHelper(read)})`;
case 10:
return `(${this.PEHelper(read)}%${this.PEHelper(read)})`;
case 11:
return `Math.abs(${this.PEHelper(read)})`;
case 12:
return `Math.round(${this.PEHelper(read)})`;
case 13:
return `Math.cos(${this.PEHelper(read)})`;
default:
throw new Error("unexpected case found!");
}
}
}
export{ AVoice as AVoice };

View file

@ -1,6 +1,6 @@
"use strict"; "use strict";
import{ Message }from"./message.js"; import{ Message }from"./message.js";
import{ AVoice }from"./audio/audio.js"; import{ AVoice }from"./audio/voice.js";
import{ Contextmenu }from"./contextmenu.js"; import{ Contextmenu }from"./contextmenu.js";
import{ Guild }from"./guild.js"; import{ Guild }from"./guild.js";
import{ Localuser }from"./localuser.js"; import{ Localuser }from"./localuser.js";
@ -1403,7 +1403,12 @@ class Channel extends SnowFlake{
); );
} }
notify(message: Message, deep = 0){ notify(message: Message, deep = 0){
AVoice.noises(this.localuser.getNotificationSound()); if(this.localuser.play){
const voice=this.localuser.play.audios.get(this.localuser.getNotificationSound());
if(voice){
voice.play();
}
}
if(!("Notification" in window)){ if(!("Notification" in window)){
}else if(Notification.permission === "granted"){ }else if(Notification.permission === "granted"){
let noticontent: string | undefined | null = message.content.textContent; let noticontent: string | undefined | null = message.content.textContent;

View file

@ -1,7 +1,7 @@
import{ Guild }from"./guild.js"; import{ Guild }from"./guild.js";
import{ Channel }from"./channel.js"; import{ Channel }from"./channel.js";
import{ Direct }from"./direct.js"; import{ Direct }from"./direct.js";
import{ AVoice }from"./audio/audio.js"; import{ AVoice }from"./audio/voice.js";
import{ User }from"./user.js"; import{ User }from"./user.js";
import{ getapiurls, SW }from"./utils/utils.js"; import{ getapiurls, SW }from"./utils/utils.js";
import { getBulkInfo, setTheme, Specialuser } from "./utils/utils.js"; import { getBulkInfo, setTheme, Specialuser } from "./utils/utils.js";
@ -14,6 +14,7 @@ import { Role } from "./role.js";
import { VoiceFactory } from "./voice.js"; import { VoiceFactory } from "./voice.js";
import { I18n, langmap } from "./i18n.js"; import { I18n, langmap } from "./i18n.js";
import { Emoji } from "./emoji.js"; import { Emoji } from "./emoji.js";
import { Play } from "./audio/play.js";
const wsCodesRetry = new Set([4000,4001,4002, 4003, 4005, 4007, 4008, 4009]); const wsCodesRetry = new Set([4000,4001,4002, 4003, 4005, 4007, 4008, 4009]);
@ -40,6 +41,7 @@ class Localuser{
channelids: Map<string, Channel> = new Map(); channelids: Map<string, Channel> = new Map();
readonly userMap: Map<string, User> = new Map(); readonly userMap: Map<string, User> = new Map();
voiceFactory?:VoiceFactory; voiceFactory?:VoiceFactory;
play?:Play;
instancePing = { instancePing = {
name: "Unknown", name: "Unknown",
}; };
@ -51,6 +53,9 @@ class Localuser{
this.userinfo.localuserStore = e; this.userinfo.localuserStore = e;
} }
constructor(userinfo: Specialuser | -1){ constructor(userinfo: Specialuser | -1){
Play.playURL("/audio/sounds.jasf").then((_)=>{
this.play=_;
})
if(userinfo === -1){ if(userinfo === -1){
return; return;
} }
@ -1234,8 +1239,7 @@ class Localuser{
} }
{ {
const sounds = AVoice.sounds; const sounds = AVoice.sounds;
tas tas.addSelect(
.addSelect(
I18n.getTranslation("localuser.notisound"), I18n.getTranslation("localuser.notisound"),
_=>{ _=>{
this.setNotificationSound(sounds[_]); this.setNotificationSound(sounds[_]);
@ -1244,7 +1248,12 @@ class Localuser{
{ defaultIndex: sounds.indexOf(this.getNotificationSound()) } { defaultIndex: sounds.indexOf(this.getNotificationSound()) }
) )
.watchForChange(_=>{ .watchForChange(_=>{
AVoice.noises(sounds[_]); if(this.play){
const voice=this.play.audios.get(sounds[_])
if(voice){
voice.play();
}
}
}); });
} }

View file

@ -20,6 +20,11 @@ class BinRead{
readString16(){ readString16(){
return this.readStringNo(this.read16()); return this.readStringNo(this.read16());
} }
readFloat32(){
const float = this.view.getFloat32(this.i);
this.i += 4;
return float;
}
readStringNo(length: number){ readStringNo(length: number){
const array = new Uint8Array(length); const array = new Uint8Array(length);
for(let i = 0; i < length; i++){ for(let i = 0; i < length; i++){
@ -38,6 +43,10 @@ class BinWrite{
this.buffer=new ArrayBuffer(maxSize); this.buffer=new ArrayBuffer(maxSize);
this.view=new DataView(this.buffer, 0); this.view=new DataView(this.buffer, 0);
} }
write32Float(numb:number){
this.view.setFloat32(this.i,numb);
this.i+=4;
}
write16(numb:number){ write16(numb:number){
this.view.setUint16(this.i,numb); this.view.setUint16(this.i,numb);
this.i+=2; this.i+=2;