Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how to set TidByets to Tbyets ?
#1
i am using indy udp server component

i want to get its Adata as Tbyets how can i do that ??

To be more clear i need to compress some data using the folllowing unit

and send this data through udp and decompress it when it arrived

alaw data


Code:
unit alaw;

interface
uses Classes, Sysutils;

function Encodeaudio(audio : Tbytes): TBytes;
function Decodeaudio(audio : Tbytes): TBytes;
function linearToALawSample(sample : SmallInt ): Byte;

var
cClip : Integer = 32635;
aLawCompressTable :  array[0..127] of Byte  = ( 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 );

aLawDecompressTable: array[0..255] of Smallint = ( -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, -344, -328, -376, -360, -280, -264, -312, -296, -472, -456, -504, -488, -408, -392, -440, -424, -88, -72, -120, -104, -24, -8, -56, -40, -216, -200, -248, -232, -152, -136, -184, -168, -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, -688, -656, -752, -720, -560, -528, -624, -592, -944, -912, -1008, -976, -816, -784, -880, -848, 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 344, 328, 376, 360, 280, 264, 312, 296, 472, 456, 504, 488, 408, 392, 440, 424, 88, 72, 120, 104, 24, 8, 56, 40, 216, 200, 248, 232, 152, 136, 184, 168, 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 688, 656, 752, 720, 560, 528, 624, 592, 944, 912, 1008, 976, 816, 784, 880, 848 );


implementation

function Encodeaudio(audio : Tbytes) : TBytes;
var
alength : Integer;
offset : Integer;
count : Integer;
sample : smallint;
byte1 : smallint;
byte2 : smallint;
encoded : TBytes;
i : integer;

begin
offset := 0;
sample := 0;

alength := Length(audio);
count := alength div 2;
SetLength(encoded, count);

for i  := 0 to count -1 do
begin
byte1 := audio[offset] And $FF;
offset := offset + 1;
byte2 := audio[offset] shl 8;
offset := offset + 1;
sample := byte1 Or byte2;
encoded[i] := linearToALawSample(sample)

end;


result := encoded;

end;

function linearToALawSample(sample : SmallInt ) : Byte;
var
sign : integer;
exponent : integer;
mantissa : integer;
s : integer;
begin

sign := ((Not sample) shr 8) And $80;

If (sign <> $80)  Then
begin
sample := Not sample;
end;

If ( sample > cClip ) Then
begin
sample := cClip;
end;


If ( sample >= 256 ) Then
begin

exponent := aLawCompressTable[(sample shr 8) And $7F];
mantissa := (sample shr (exponent + 3)) And $0F;
s := (exponent shl 4) Or mantissa;

end else
begin
s := (sample shl 4)
end;

s := (sign Xor $55) Xor s;

Result := s;

end;


function Decodeaudio(audio : Tbytes) : TBytes;
var
alength : integer;
offset :  integer;
i :  integer;
s : smallint;
decoded : TBytes;
begin
alength := Length(audio);
SetLength(decoded, alength * 2);
offset := 0;
for i := 0 to alength -1 do
begin
s := aLawDecompressTable[audio[i] And $FF];
decoded[offset] := s;
offset := offset + 1;
decoded[offset] := s shr 8;
offset := offset + 1;
end;
result := decoded;



end;

end.



Data that i try to send



Code:
procedure Taudiofrm.recorderData(Sender: TObject; const Buffer: Pointer;
 BufferSize: Cardinal; var FreeIt: Boolean);
var
Bytes: TIdBytes;
begin


if (Buffer <> nil) and (BufferSize > 0) And (udpreciver.Active) then
begin
udpreciver.SendBuffer(ip, port, RawToBytes(Buffer^, Buffersize));
end;

end;



data i try to receive


Code:
procedure Taudiofrm.udpreciverUDPRead(AThread: TIdUDPListenerThread;
 const AData: TIdBytes; ABinding: TIdSocketHandle);
var
AudioDataSize: Integer;
begin
AudioDataSize := Length(AData);

if (AudioDataSize > 10) then
begin
if BlockAlign > 1 then
Dec(AudioDataSize, AudioDataSize mod BlockAlign);

TThread.Queue(nil,
procedure
var
AudioData : Pointer;
begin
try
if not Player.Active then
begin
Player.Active := True;
Player.WaitForStart;
end;
except
end;

AudioData := AudioBuffer.BeginUpdate(AudioDataSize);
try
BytesToRaw(AData, AudioData^, AudioDataSize);
finally
AudioBuffer.EndUpdate;
end;
end);
end else
begin
TThread.Queue(nil,
procedure
begin
Player.Active := False;
Player.WaitForStop;
end
);
end;
end;


i am not actually sure how do i get the correct data using Tidbyets
Reply
#2
(01-02-2019, 08:58 PM)Madammar Wrote: i want to get its Adata as Tbyets how can i do that ??

You have two choices:

1. make a separate copy of the bytes as needed:

Code:
procedure Taudiofrm.recorderData(Sender: TObject; const Buffer: Pointer; BufferSize: Cardinal; var FreeIt: Boolean);
var
  Bytes: TBytes;
begin
  if (Buffer <> nil) and (BufferSize > 0) And (udpreciver.Active) then
  begin
    SetLength(Bytes, BufferSize);
    Move(Buffer^, Bytes[0], BufferSize);
    Bytes := Encodeaudio(Bytes);
    udpreciver.SendBuffer(ip, port, RawToBytes(Bytes[0], Length(Bytes)));
  end;
end;

procedure Taudiofrm.udpreciverUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
var
  Bytes: TBytes;
  AudioDataSize: Integer;
begin
  SetLength(Bytes, Length(AData));
  BytesToRaw(AData, Bytes[0], Length(AData));
  Bytes := Decodeaudio(Bytes);
  AudioDataSize := Length(Bytes);
  if (AudioDataSize > 10) then
  begin
    if BlockAlign > 1 then
      Dec(AudioDataSize, AudioDataSize mod BlockAlign);

    TThread.Queue(nil,
      procedure
      var
        AudioData : Pointer;
      begin
        try
          if not Player.Active then
          begin
            Player.Active := True;
            Player.WaitForStart;
          end;
        except
        end;

        AudioData := AudioBuffer.BeginUpdate(AudioDataSize);
        try
          Move(Bytes[0], AudioData^, AudioDataSize);
        finally
          AudioBuffer.EndUpdate;
        end;
      end
    );
  end else
  begin
    TThread.Queue(nil,
      procedure
      begin
        Player.Active := False;
        Player.WaitForStop;
      end
    );
  end;
end;

2. type-cast, since TBytes and TIdBytes are both dynamic arrays of bytes, so they are essentially the same thing in memory even though they are different types:

Code:
procedure Taudiofrm.recorderData(Sender: TObject; const Buffer: Pointer; BufferSize: Cardinal; var FreeIt: Boolean);
type
  PIdBytes = ^TIdBytes;
var
  Bytes: TBytes;
begin
  if (Buffer <> nil) and (BufferSize > 0) And (udpreciver.Active) then
  begin
    SetLength(Bytes, BufferSize);
    Move(Buffer^, Bytes[0], BufferSize);
    Bytes := Encodeaudio(Bytes);
    udpreciver.SendBuffer(ip, port, PIdBytes(@Bytes)^);
  end;
end;

procedure Taudiofrm.udpreciverUDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle);
type
  PBytes = ^TBytes;
var
  Bytes: TBytes;
  AudioDataSize: Integer;
begin
  Bytes := Decodeaudio(PBytes(@AData)^);
  AudioDataSize := Length(Bytes);
  if (AudioDataSize > 10) then
  begin
    if BlockAlign > 1 then
      Dec(AudioDataSize, AudioDataSize mod BlockAlign);

    TThread.Queue(nil,
      procedure
      var
        AudioData : Pointer;
      begin
        try
          if not Player.Active then
          begin
            Player.Active := True;
            Player.WaitForStart;
          end;
        except
        end;

        AudioData := AudioBuffer.BeginUpdate(AudioDataSize);
        try
          Move(Bytes[0], AudioData^, AudioDataSize);
        finally
          AudioBuffer.EndUpdate;
        end;
      end
    );
  end else
  begin
    TThread.Queue(nil,
      procedure
      begin
        Player.Active := False;
        Player.WaitForStop;
      end
    );
  end;
end;

Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)