Merge pull request #23 from jwetzell/osc-array-type

add support for osc array types
This commit is contained in:
2024-10-14 19:47:54 -05:00
committed by GitHub
4 changed files with 63 additions and 7 deletions
+47 -5
View File
@@ -33,12 +33,29 @@ export function messageToBuffer(message: OSCMessage): Uint8Array {
throw new Error('problem encoding address'); throw new Error('problem encoding address');
} }
const typeString = message.args.map((arg) => arg.type).join(''); let typeString = ','
const typesBuffer = oscTypeConverterMap.s.toBuffer(`,${typeString}`);
const flatOSCArgs: OSCArg[] = []
message.args.forEach((oscArg)=> {
if(Array.isArray(oscArg)){
typeString += '['
oscArg.forEach((oscArg)=>{
typeString += oscArg.type
flatOSCArgs.push(oscArg)
})
typeString += ']'
}else {
typeString += oscArg.type
flatOSCArgs.push(oscArg)
}
})
const typesBuffer = oscTypeConverterMap.s.toBuffer(typeString);
if (typesBuffer === undefined) { if (typesBuffer === undefined) {
throw new Error('problem encoding types'); throw new Error('problem encoding types');
} }
const argsBuffer = argsToBuffer(message.args); const argsBuffer = argsToBuffer(flatOSCArgs);
const buffer = new Uint8Array(addressBuffer.length + typesBuffer.length + argsBuffer.length); const buffer = new Uint8Array(addressBuffer.length + typesBuffer.length + argsBuffer.length);
buffer.set(addressBuffer, 0); buffer.set(addressBuffer, 0);
buffer.set(typesBuffer, addressBuffer.length); buffer.set(typesBuffer, addressBuffer.length);
@@ -51,7 +68,7 @@ export function messageFromBuffer(bytes: Uint8Array): [OSCMessage | undefined, U
throw new Error('osc message must start with a /'); throw new Error('osc message must start with a /');
} }
const oscArgs: OSCArg[] = []; const oscArgs: (OSCArg | OSCArg[])[] = [];
const [address, bytesAfterAddress] = oscTypeConverterMap.s.fromBuffer(bytes); const [address, bytesAfterAddress] = oscTypeConverterMap.s.fromBuffer(bytes);
if (typeof address === 'string') { if (typeof address === 'string') {
@@ -61,9 +78,30 @@ export function messageFromBuffer(bytes: Uint8Array): [OSCMessage | undefined, U
throw new Error('osc type string must start with a ,'); throw new Error('osc type string must start with a ,');
} }
let argsBuffer = bytesAfterType; let argsBuffer = bytesAfterType;
let oscArrayArg: OSCArg[] = [];
let insideArgArray = false;
for (let index = 1; index < typeString.length; index++) { for (let index = 1; index < typeString.length; index++) {
const argType = typeString.charAt(index) as OSCType; const argType = typeString.charAt(index) as OSCType;
if (argType === '['){
if (insideArgArray){
throw new Error('osc arg array opened without closing previous arg array')
}
oscArrayArg = [];
insideArgArray = true;
continue;
}
if (argType === ']'){
if (!insideArgArray){
throw new Error('osc arg array closed without opening arg array')
}
oscArgs.push(oscArrayArg);
oscArrayArg = [];
insideArgArray = false;
continue;
}
const oscTypeConverter = oscTypeConverterMap[argType]; const oscTypeConverter = oscTypeConverterMap[argType];
if (oscTypeConverter === undefined) { if (oscTypeConverter === undefined) {
throw new Error('unknown OSC type'); throw new Error('unknown OSC type');
@@ -74,7 +112,11 @@ export function messageFromBuffer(bytes: Uint8Array): [OSCMessage | undefined, U
type: argType, type: argType,
value: value, value: value,
}; };
oscArgs.push(arg); if(insideArgArray){
oscArrayArg.push(arg)
}else {
oscArgs.push(arg);
}
} }
argsBuffer = remainingBytes; argsBuffer = remainingBytes;
} }
+2 -2
View File
@@ -1,4 +1,4 @@
export type OSCType = 's' | 'i' | 'f' | 'b' | 'T' | 'F' | 't' | 'r' | 'N'; export type OSCType = 's' | 'i' | 'f' | 'b' | 'T' | 'F' | 't' | 'r' | 'N' | '[' | ']';
export type OSCArg = { export type OSCArg = {
type: OSCType; type: OSCType;
value: string | number | Uint8Array | boolean | OSCTimeTag | OSCColor | bigint | null; value: string | number | Uint8Array | boolean | OSCTimeTag | OSCColor | bigint | null;
@@ -20,7 +20,7 @@ export type OSCBundle = {
export type OSCMessage = { export type OSCMessage = {
address: string; address: string;
args: OSCArg[]; args: (OSCArg | OSCArg[])[];
}; };
export type OSCTypeConverter = { export type OSCTypeConverter = {
@@ -65,6 +65,13 @@ const tests = [
]), ]),
expected: { address: '/hello', args: [{ type: 'd', value: 12.7654763 }] }, expected: { address: '/hello', args: [{ type: 'd', value: 12.7654763 }] },
}, },
{
description: 'simple address array arg',
bytes: new Uint8Array([
47, 104, 101, 108, 108, 111, 0, 0, 44, 91, 100, 105, 93, 0, 0, 0, 0x40, 0x29, 0x87, 0xec, 0x82, 0x74, 0xb9, 0xe6, 0, 0, 3, 232
]),
expected: { address: '/hello', args: [[{ type: 'd', value: 12.7654763 }, { type: 'i', value: 1000}]] },
},
{ {
description: 'osc 1.0 spec example 1', description: 'osc 1.0 spec example 1',
bytes: new Uint8Array([ bytes: new Uint8Array([
@@ -60,6 +60,13 @@ const tests = [
47, 104, 101, 108, 108, 111, 0, 0, 44, 100, 0, 0, 0x40, 0x29, 0x87, 0xec, 0x82, 0x74, 0xb9, 0xe6, 47, 104, 101, 108, 108, 111, 0, 0, 44, 100, 0, 0, 0x40, 0x29, 0x87, 0xec, 0x82, 0x74, 0xb9, 0xe6,
]), ]),
}, },
{
description: 'simple address array arg',
message: { address: '/hello', args: [[{ type: 'd', value: 12.7654763 }, { type: 'i', value: 1000}]] },
expected: new Uint8Array([
47, 104, 101, 108, 108, 111, 0, 0, 44, 91, 100, 105, 93, 0, 0, 0, 0x40, 0x29, 0x87, 0xec, 0x82, 0x74, 0xb9, 0xe6, 0, 0, 3, 232
]),
},
{ {
description: 'osc 1.0 spec example 1', description: 'osc 1.0 spec example 1',
message: { address: '/oscillator/4/frequency', args: [{ type: 'f', value: 440 }] }, message: { address: '/oscillator/4/frequency', args: [{ type: 'f', value: 440 }] },