要控制贝林格X32音频混频器,我必须发送一条OSC消息,如/ch/01/mix/fader ,f .3,以将fader移动到30%。根据OSC协议,混频器期望.3作为一个4字符字符串出现-在十六进制中它是3E 99 99 9A。所以有特殊的角色。
TIdUDPClient被赋予了3E 99 99 9A的字符,但是它发送了3E 3F 3F 3F。同样,.4想成为3E CC CC CD,但是3E 3F 3F 3F被发送了。
当您进入.5和更大的版本时,当字符在3F下面时,事情又重新开始了。例如,.6应该是3F 19 99 9A,并以3F 19 3F 3F的形式出现。
很明显,贝林格人只看了前两个字。
我使用的是Delphi 和随它一起发行的Indy 10版本。我可以在Lazarus中创建一个运行良好的Lnet模块。但我的主要应用是在德尔菲,在那里我需要这种能力。正如你所看到的,我尝试过几种不同的方法,结果都是一样的。
我该如何发送合适的字符?
procedure TCPForm1.OSCSendMsg;
var
OutValueStr: String;
I: Integer;
J: Tbytes;
B1: TIdbytes;
begin
If Length(CommandStr) > 0 then begin
OscCommandStr := PadStr(CommandStr); //convert CommandStr to OSC string
If TypeStr='' then OscCommandStr := OscCommandStr+','+#0+#0+#0;
If Length(TypeStr) = 1 then begin
If TypeStr='i' then Begin // Parameter is an integer
I := swapendian(IValue); //change to big endian
OscCommandStr := OscCommandStr+','+TypeStr+#0+#0+IntToCharStr(I);
OutValueStr := IntToStr(IValue);
end;
If TypeStr='f' then Begin // Parameter is a float (real)
I := swapendian(PInteger(@FValue)^); //typecast & change to big endian
//I := htonl(PInteger(@FValue)^); //typecast & change to big endian
//J := MakeOSCFloat(FValue);
OscCommandStr := OscCommandStr+','+TypeStr+#0+#0+IntToCharStr(I);
//OscCommandStr := OscCommandStr+','+TypeStr+#0+#0+char(J[0])+char(J[1])+char(J[2])+char(J[3]);
OutValueStr := FloatToStr(FValue);
end;
end;
//IdUDPClient2.Send(OSCCommandStr,IndyTextEncoding_UTF8);
//IdUDPClient2.Send(OSCCommandStr);
B1 := toBytes(OSCCommandStr);
IdUDPClient2.SendBuffer(B1);
if loglevel>0 then logwrite('OSC= '+ hexstr(OSCCommandStr));
Wait(UDPtime);
// if loglevel>0 then logwrite('OSC '+ OSCCommandStr);
end;
end;
function TCPForm1.IntToCharStr(I : Integer) : String;
var
CharStr : String;
MyArray: array [0..3] of Byte;
J: Integer;
begin
For J :=0 to 3 do MyArray[J] := 0;
Move(I, MyArray, 4); //typeset conversion from integer to array of byte
CharStr := '';
For J :=0 to 3 do //convert array of byte to string
CharStr := CharStr+char(MyArray[J]);
IntToCharStr := CharStr;
end;更新
系统不让我把这个作为答案,所以.
谢谢你雷米。至少就X32软件模拟器而言,添加8位文本编码会给出正确的响应。我得等到明天才能在剧院里测试真正的混音器。如果我们控制通信的两端,字节数组可能会更好。实际上,我不能更改X32,它希望得到文本字符串"/ch/01/mix/fader,f .4“的填充字符串(十六进制: 2F 63 68 2F 30 31 2F 6D 69 78 2F 66 61 65 72 00 00 00 2C 66 00 00 e CC CD)。X32响应的消息文档是一个包含不同参数的类似消息的长表。例如“/ch/01/mix/静音on”、“/bus/1/dyn/mute、I2”等。这一切都符合开放声音控制协议。
一如既往,你是印地智慧的决定性源泉,所以,谢谢你。我将在使用实际设备的结果之后编辑这张便条。
更新
确认将8位文本编码添加到发送命令中可以与X32一起工作。干杯!由于这一点,有几个问题:
的详细信息?
发布于 2019-11-01 22:58:34
3F是ASCII '?'字符。当Unicode字符被编码为不支持该Unicode字符的字节编码时,您将看到该字符正在发送。例如,Indy的默认文本编码是 US-ASCII ,除非您另行指定(通过IdGlobal.pas单元中的GIdDefaultTextEncoding变量,或通过各种类属性或方法参数),而且unless不支持Unicode字符> U+007F。
似乎您正在处理的是二进制协议,而不是文本协议,那么为什么要使用字符串来创建其消息呢?我认为字节数组更有意义。
至少,尝试使用Indy的8位文本编码(通过IdGlobal.pas单元中的IdGlobal.pas函数)将Unicode字符U+0000..U+00FF转换为字节0x00.0xFF,而不丢失数据,例如:
B1 := ToBytes(OSCCommandStr, IndyTextEncoding_8Bit); // not ASCII or UTF8!
IdUDPClient2.SendBuffer(B1);IdUDPClient2.Send(OSCCommandStr, IndyTextEncoding_8Bit); // not ASCII or UTF8!https://stackoverflow.com/questions/58665261
复制相似问题