【发布时间】:2026-02-10 08:20:03
【问题描述】:
要控制 Behringer X32 音频混音器,我必须发送类似/ch/01/mix/fader ,f .3 的 OSC 消息来将推子移动到 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。
显然 Behringer 只查看那里的前两个字符。
我正在使用 Delphi Rio 和随它一起分发的 Indy 10 版本。我可以使用 Lnet 在 Lazarus 中创建一个可以正常工作的模块。但是我的主要应用程序是在 Delphi 中,我需要这种能力。如您所见,我尝试了几种不同的方法,但结果相同。
如何发送正确的字符?
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 并且它想要获得填充字符串(十六进制:2F 63 68 2F 30 31 2F 6D 69 78 2F 66 61 64 65 72 00 00 00 00 2C 66 00 00 3E CC CC CD) 用于文本字符串“/ch/01/mix/fader ,f .4”。 X32 响应的消息文档是一长串具有不同参数的类似消息。例如“/ch/01/mix/mute on”、“/bus/1/dyn/ratio ,i 2”等。这都是符合Open Sound Control协议的。
一如既往,你是印地智慧的权威来源,所以,谢谢你。我将在使用实际设备获得结果后编辑此注释。
更新:
确认向发送命令添加 8 位文本编码适用于 X32。干杯!因此有几个问题:
一个发送结构是否优于另一个?
我应该在哪里阅读/了解有关 Indy 的这些详细信息?
【问题讨论】:
-
不能使用 ansi 字符(ansistring)发送此消息还是需要特定的二进制格式?
-
OSC 协议特定于字符、填充和字节序使用。看看我的答案。
-
回复您已删除的答案:这不是冒犯任何人的问题,只是答案是为了答案,而不是为 cmets。如果您认为@Remy 的回答已经回答了您所问的问题,您需要做的就是单击其 LHS 上的勾号图标。这对读者很有用,因为它告诉他们答案值得一看(人头马总是如此),即它有助于提高信噪比。
-
@Dgbaxter UDP 仅对字节进行操作,而不对字符串进行操作。字符串作为字节传输。您无需更改 X32 上的任何内容即可在您自己的代码中使用字节数组(例如,您的
ToBytes()示例)。我认为您需要阅读 8 位字符串和 8 位字节之间的相关性。它们是相同的数据。您可以使用字节数组来构建您的 OSC 消息,尤其是对于不涉及人类可读字符的部分。只是需要考虑...
标签: delphi indy indy10 osc delphi-10.3-rio