首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Indy 10 UdpClient与开放式声音控制

Indy 10 UdpClient与开放式声音控制
EN

Stack Overflow用户
提问于 2019-11-01 20:04:17
回答 1查看 383关注 0票数 0

要控制贝林格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模块。但我的主要应用是在德尔菲,在那里我需要这种能力。正如你所看到的,我尝试过几种不同的方法,结果都是一样的。

我该如何发送合适的字符?

代码语言:javascript
复制
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一起工作。干杯!由于这一点,有几个问题:

  1. 是一个优先于另一个的发送构造?
  2. ,我应该在哪里阅读/了解更多关于Indy?

的详细信息?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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,而不丢失数据,例如:

代码语言:javascript
复制
B1 := ToBytes(OSCCommandStr, IndyTextEncoding_8Bit); // not ASCII or UTF8!
IdUDPClient2.SendBuffer(B1);
代码语言:javascript
复制
IdUDPClient2.Send(OSCCommandStr, IndyTextEncoding_8Bit); // not ASCII or UTF8!
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58665261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档