Чтобы управлять звуковым микшером Behringer X32 , мне нужно отправить сообщение OSC, например /ch/01/mix/fader ,f .3
, чтобы переместить фейдер на 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 Rio с распространяемой версией Indy 10 . Я могу создать модуль в Lazarus с Lnet , который работает отлично. Но мое основное приложение в 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 CCCD) для текстовой строки "/ ch / 01 / mix / fader, f .4". Документация сообщений, на которые отвечает X32, представляет собой длинную таблицу похожих сообщений с различными параметрами. например, "/ ch / 01 / mix / mute on", "/ bus / 1 / dyn / ratio, i 2" и т. д. Это все в соответствии с протоколом Open Sound Control.
Как всегда,Вы - окончательный источник мудрости Инди, так что, спасибо. Я отредактирую это примечание после моих результатов с фактическим устройством.
ОБНОВЛЕНИЕ :
Подтверждено, что добавление 8-битной кодировки текста в команду Send работает с X32. Ура! В результате этого возникает пара вопросов:
Является ли одна отправляющая конструкция предпочтительнее другой?
Где я должен был прочитать / узнать большеоб этих деталях Indy?