Skip to content

Commit d5e4a69

Browse files
Upload 11edo-optimized files
1 parent 6e1223b commit d5e4a69

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+41675
-0
lines changed

editor/ArrayBufferReader.ts

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright (c) 2012-2022 John Nesky and contributing authors, distributed under the MIT license, see accompanying the LICENSE.md file.
2+
3+
// Note: All methods are big endian.
4+
export class ArrayBufferReader {
5+
private _readIndex: number = 0;
6+
private _data: DataView;
7+
8+
constructor(data: DataView) {
9+
this._data = data;
10+
}
11+
12+
public getReadIndex(): number {
13+
return this._readIndex;
14+
}
15+
16+
public readUint32(): number {
17+
if (this._readIndex + 4 > this._data.byteLength) throw new Error("Reading past the end of the buffer.");
18+
const result: number = this._data.getUint32(this._readIndex, false);
19+
this._readIndex += 4;
20+
return result;
21+
}
22+
23+
public readUint24(): number {
24+
return (this.readUint8() << 16) | (this.readUint8() << 8) | (this.readUint8());
25+
}
26+
27+
public readUint16(): number {
28+
if (this._readIndex + 2 > this._data.byteLength) throw new Error("Reading past the end of the buffer.");
29+
const result: number = this._data.getUint16(this._readIndex, false);
30+
this._readIndex += 2;
31+
return result;
32+
}
33+
34+
public readUint8(): number {
35+
if (this._readIndex + 1 > this._data.byteLength) throw new Error("Reading past the end of the buffer.");
36+
const result: number = this._data.getUint8(this._readIndex);
37+
this._readIndex++;
38+
return result;
39+
}
40+
41+
public readInt8(): number {
42+
if (this._readIndex + 1 > this._data.byteLength) throw new Error("Reading past the end of the buffer.");
43+
const result: number = this._data.getInt8(this._readIndex);
44+
this._readIndex++;
45+
return result;
46+
}
47+
48+
public peakUint8(): number {
49+
if (this._readIndex + 1 > this._data.byteLength) throw new Error("Reading past the end of the buffer.");
50+
return this._data.getUint8(this._readIndex);
51+
}
52+
53+
public readMidi7Bits(): number {
54+
const result: number = this.readUint8();
55+
if (result >= 0x80) console.log("7 bit value contained 8th bit! value " + result + ", index " + this._readIndex);
56+
return result & 0x7f;
57+
}
58+
59+
public readMidiVariableLength(): number {
60+
let result: number = 0;
61+
for (let i: number = 0; i < 4; i++) {
62+
const nextByte: number = this.readUint8();
63+
result += nextByte & 0x7f;
64+
if (nextByte & 0x80) {
65+
result = result << 7;
66+
} else {
67+
break;
68+
}
69+
}
70+
return result;
71+
}
72+
73+
public skipBytes(length: number): void {
74+
this._readIndex += length;
75+
}
76+
77+
public hasMore(): boolean {
78+
return this._data.byteLength > this._readIndex;
79+
}
80+
81+
public getReaderForNextBytes(length: number): ArrayBufferReader {
82+
if (this._readIndex + length > this._data.byteLength) throw new Error("Reading past the end of the buffer.");
83+
const result: ArrayBufferReader = new ArrayBufferReader(new DataView(this._data.buffer, this._data.byteOffset + this._readIndex, length));
84+
this.skipBytes(length);
85+
return result;
86+
}
87+
}

editor/ArrayBufferWriter.ts

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright (c) 2012-2022 John Nesky and contributing authors, distributed under the MIT license, see accompanying the LICENSE.md file.
2+
3+
function transfer(source: ArrayBuffer, length: number): ArrayBuffer {
4+
const dest: ArrayBuffer = new ArrayBuffer(length);
5+
let nextOffset = 0;
6+
let leftBytes = Math.min(source.byteLength, dest.byteLength);
7+
const wordSizes = [8, 4, 2, 1];
8+
for (const wordSize of wordSizes) {
9+
if (leftBytes >= wordSize) {
10+
const done = transferWith(wordSize, source, dest, nextOffset, leftBytes);
11+
nextOffset = done.nextOffset;
12+
leftBytes = done.leftBytes;
13+
}
14+
}
15+
return dest;
16+
function transferWith(wordSize: number, source: ArrayBuffer, dest: ArrayBuffer, nextOffset: number, leftBytes: number) {
17+
let ViewClass: any = Uint8Array;
18+
switch (wordSize) {
19+
case 8:
20+
ViewClass = Float64Array;
21+
break;
22+
case 4:
23+
ViewClass = Float32Array;
24+
break;
25+
case 2:
26+
ViewClass = Uint16Array;
27+
break;
28+
case 1:
29+
ViewClass = Uint8Array;
30+
break;
31+
default:
32+
ViewClass = Uint8Array;
33+
break;
34+
}
35+
36+
const view_source = new ViewClass(source, nextOffset, (leftBytes / wordSize) | 0);
37+
const view_dest = new ViewClass(dest, nextOffset, (leftBytes / wordSize) | 0);
38+
for (let i: number = 0; i < view_dest.length; i++) {
39+
view_dest[i] = view_source[i];
40+
}
41+
return {
42+
nextOffset: view_source.byteOffset + view_source.byteLength,
43+
leftBytes: leftBytes - view_dest.length * wordSize,
44+
}
45+
}
46+
}
47+
48+
// Note: All methods are big endian.
49+
export class ArrayBufferWriter {
50+
private _writeIndex: number = 0;
51+
private _fileSize: number = 0;
52+
private _arrayBuffer: ArrayBuffer;
53+
private _data: DataView;
54+
55+
constructor(initialCapacity: number) {
56+
this._arrayBuffer = new ArrayBuffer(initialCapacity);
57+
this._data = new DataView(this._arrayBuffer);
58+
}
59+
60+
private _addBytes(numBytes: number): void {
61+
this._fileSize += numBytes;
62+
if (this._fileSize > this._arrayBuffer.byteLength) {
63+
this._arrayBuffer = transfer(this._arrayBuffer, Math.max(this._arrayBuffer.byteLength * 2, this._fileSize));
64+
this._data = new DataView(this._arrayBuffer);
65+
}
66+
}
67+
68+
public getWriteIndex(): number {
69+
return this._writeIndex;
70+
}
71+
72+
public rewriteUint32(index: number, value: number): void {
73+
this._data.setUint32(index, value >>> 0, false);
74+
}
75+
76+
public writeUint32(value: number): void {
77+
value = value >>> 0;
78+
this._addBytes(4);
79+
this._data.setUint32(this._writeIndex, value, false);
80+
this._writeIndex = this._fileSize;
81+
}
82+
83+
public writeUint24(value: number): void {
84+
value = value >>> 0;
85+
this._addBytes(3);
86+
this._data.setUint8(this._writeIndex, (value >> 16) & 0xff);
87+
this._data.setUint8(this._writeIndex + 1, (value >> 8) & 0xff);
88+
this._data.setUint8(this._writeIndex + 2, (value) & 0xff);
89+
this._writeIndex = this._fileSize;
90+
}
91+
92+
public writeUint16(value: number): void {
93+
value = value >>> 0;
94+
this._addBytes(2);
95+
this._data.setUint16(this._writeIndex, value, false);
96+
this._writeIndex = this._fileSize;
97+
}
98+
99+
public writeUint8(value: number): void {
100+
value = value >>> 0;
101+
this._addBytes(1);
102+
this._data.setUint8(this._writeIndex, value);
103+
this._writeIndex = this._fileSize;
104+
}
105+
106+
public writeInt8(value: number): void {
107+
value = value | 0;
108+
this._addBytes(1);
109+
this._data.setInt8(this._writeIndex, value);
110+
this._writeIndex = this._fileSize;
111+
}
112+
113+
public writeMidi7Bits(value: number): void {
114+
value = value >>> 0;
115+
if (value >= 0x80) throw new Error("7 bit value contained 8th bit!");
116+
this._addBytes(1);
117+
this._data.setUint8(this._writeIndex, value);
118+
this._writeIndex = this._fileSize;
119+
}
120+
121+
public writeMidiVariableLength(value: number): void {
122+
value = value >>> 0;
123+
if (value > 0x0fffffff) throw new Error("writeVariableLength value too big.");
124+
let startWriting: boolean = false;
125+
for (let i: number = 0; i < 4; i++) {
126+
const shift: number = 21 - i * 7;
127+
const bits: number = (value >>> shift) & 0x7f;
128+
if (bits != 0 || i == 3) startWriting = true; // skip leading zero bytes, but always write the last byte even if it's zero.
129+
if (startWriting) this.writeUint8((i == 3 ? 0x00 : 0x80) | bits);
130+
}
131+
}
132+
133+
public writeMidiAscii(string: string): void {
134+
this.writeMidiVariableLength(string.length);
135+
for (let i: number = 0; i < string.length; i++) {
136+
const charCode: number = string.charCodeAt(i);
137+
if (charCode > 0x7f) throw new Error("Trying to write unicode character as ascii.");
138+
this.writeUint8(charCode); // technically charCodeAt returns 2 byte values, but this string should contain exclusively 1 byte values.
139+
}
140+
}
141+
142+
public toCompactArrayBuffer(): ArrayBuffer {
143+
return transfer(this._arrayBuffer, this._fileSize);
144+
}
145+
}

0 commit comments

Comments
 (0)