Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.07.2015, 09:44   #11
Programmer0
Пользователь
 
Регистрация: 05.05.2015
Сообщений: 55
По умолчанию

Тут пока без управления передачей. Но главное - передача независимая. Сейчас пытаюсь разделить, чтобы с левого канала линейного входа звук передавался на один хост, с правого - на другой.
Потом планируется увеличение количества хостов. Но там ещё неизвестно, как будет управление передачей.
Вообщем, большое вам спасибо!
Programmer0 вне форума Ответить с цитированием
Старый 07.07.2015, 09:51   #12
Programmer0
Пользователь
 
Регистрация: 05.05.2015
Сообщений: 55
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
И еще 2 программки с жатием GSM, нагрузка на сеть уменьшилась, качество вроде не потерянно, но есть небольшая задержка.
За GSM отдельно большое спасибо! Ещё не смотрел. Но как раз при увеличении хостов будет в тему. Спасибо!
Programmer0 вне форума Ответить с цитированием
Старый 07.07.2015, 09:52   #13
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

)) Зачем дублировать функцию потока вы можете все в одной функции создавать. Сейчас напишу как

Код:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
  procedure OnWaveMessage(var msg:TMessage); message MM_WIM_DATA;
  public
    { Public declarations }
  end;

//Задаем тип структуре передающих UDP
  type
    PParamUDP = ^TParamUDP;
    TParamUDP = record
    hWorkUDPThead: Dword; // Хендел потока
    Host: String; // Хост для передачи
    Port: Integer; // Порт для передачи
    SendMemoryStream: TMemoryStream; // Задаем для каждого UDP свой передающий буфер иначе если общий то у некоторых будет глотание звука так как очищается после передачи
    end;

var
  Form1: TForm1;
  ParamUDPArray: array[0..99] of TParamUDP; // Структура UDP передатчиков но это статически созданные, можно конечно создавать отдельно каждого

   waveformat: TWAVEFORMATEX;
  Wavein: HWAVEIN;
  WaveHdr:array [0..buff_count-1] of TWaveHdr;
  bufsize:Cardinal;
  bytes:integer;
  n:integer;
  fstop:boolean;


implementation

{$R *.dfm}


function WorkUDPThead(Param: Pointer): Integer;
var
  IdUDPClient: TIdUDPClient;
begin
try
  IdUDPClient:= TIdUDPClient.Create(nil);
  PParamUDP(Param).SendMemoryStream:= TMemoryStream.Create;

    IdUDPClient.BufferSize:= Bufsize;
    IdUDPClient.Host:=PParamUDP(Param).Host;
    IdUDPClient.Port:= PParamUDP(Param).Port;

  IdUDPClient.Active:= true;
  PParamUDP(Param).Started:= true;

while PParamUDP(Param).Started do
begin
if PParamUDP(Param)^.SendMemoryStream.Size > 0 then
begin
PParamUDP(Param).SendMemoryStream.Position:= 0;
idUDPClient.Sendbuffer(PParamUDP(Param).SendMemoryStream.Memory^, PParamUDP(Param).SendMemoryStream.Size);
PParamUDP(Param).SendMemoryStream.Clear;
end
else
sleep(1);
end;
     finally
 IdUDPClient.Free;
 PParamUDP(Param).SendMemoryStream.Destroy;
 PParamUDP(Param).SendMemoryStream:= nil;
 CloseHandle(PParamUDP(Param).hWorkUDPThead);
 fillChar(PParamUDP(Param)^, SizeOf(TParamUDP), 0);
  endthread(0);
  end;
end;

//Останавливаем все потоки
procedure StopUDP;
var
  i: Integer;
begin
  for i:= 0 to Length(ParamUDPArray) -1 do
   ParamUDPArray[i].Started:= false;
  end;

procedure TForm1.OnWaveMessage(var msg:TMessage);
var
  i: integer;
begin
    if not fstop then begin
        if n=buff_count then
          n:=0;
        for i:= 0 to Length(ParamUDPArray) -1 do
        if ParamUDPArray[i].SendMemoryStream <> nil then
        ParamUDPArray[i].SendMemoryStream.Write(WaveHdr[n].lpData^,WaveHdr[n].dwBufferLength);
        waveInPrepareHeader(waveIn,@WaveHdr[n],sizeof(Twavehdr));
        waveInAddBuffer(wavein,@WaveHdr[n],sizeof(TwaveHdr));
        UpDate;
        inc(n);
        end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
    ThId: Dword;
begin
    If button1.Caption='Начать отправку' then
    begin
        n:=0;
        fstop:=false;
       //Задаем первый хост
        ParamUDPArray[0].Host:= '169.254.233.61';
        ParamUDPArray[0].Port:= 10090 ;
        ParamUDPArray[0].hWorkUDPThead:= BeginThread(nil, 0, @WorkUDPThead, @ParamUDPArray[0], 0, ThId);
     //Задаем второй хост
        ParamUDPArray[1].Host:= '169.254.124.227';
        ParamUDPArray[1].Port:= 10090 ;
        ParamUDPArray[1].hWorkUDPThead:= BeginThread(nil, 0, @WorkUDPThead, @ParamUDPArray[1], 0, ThId);
// и так далее но можно и с внешнего файла хосты грузить

        button1.Caption:='Остановить отправку';
        for i:=0 to buff_count-1 do begin
            waveInPrepareHeader(waveIn,@WaveHdr[i],sizeof(Twavehdr));
            waveInAddBuffer(wavein,@WaveHdr[i],sizeof(TwaveHdr));
            end;
        waveInStart(waveIn);
        end
    else
        begin
        fstop:=true;
        button1.Caption:='Начать отправку';
        StopUDP;
        for i:=0 to buff_count-1 do
        waveInUnprepareHeader(Wavein,@WaveHdr[i],sizeof(TwaveHdr));
        waveInStop(Wavein);
        end;
end;


procedure TForm1.FormCreate(Sender: TObject);
var
    i:integer;
begin
    with waveformat do begin
        nChannels:=1;
        wFormatTag:=WAVE_FORMAT_PCM;
        nSamplesPerSec:=sampleRate;
        wBitsPerSample:=16;
        nBlockAlign:=nChannels * wBitsPerSample div 8;
        nAvgBytesPerSec:=sampleRate * nChannels * wBitsPerSample div 8;
        cbSize:=0;
        end;
    bufsize:=waveformat.nAvgBytesPerSec*2 div 16;

    waveInOpen(@Wavein,WAVE_MAPPER,addr(waveformat),self.Handle,0,CALLBACK_WINDOW);
    for i:=0 to buff_count-1 do begin
        WaveHdr[i].lpData:=Pchar(GlobalAlloc(GMEM_FIXED, bufsize));
        WaveHdr[i].dwBufferLength:=bufsize;
        WaveHdr[i].dwFlags:=0;
        end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  StopUDP;
    Sleep(1000); //небольшая пауза для завершения потоков
    waveInClose(Wavein);
end;

Последний раз редактировалось Aliens_wolfs; 07.07.2015 в 16:54.
Aliens_wolfs вне форума Ответить с цитированием
Старый 07.07.2015, 16:51   #14
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

до 100 потоков но можно и увеличить в глобальном параметре то что выше ParamUDPArray: array[0..99] of TParamUDP
Либо можно с внешнего текстового файла список хостов грузить если хотите могу показать
Aliens_wolfs вне форума Ответить с цитированием
Старый 08.07.2015, 08:14   #15
Programmer0
Пользователь
 
Регистрация: 05.05.2015
Сообщений: 55
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
)) Зачем дублировать функцию потока вы можете все в одной функции создавать. Сейчас напишу как
Да, так гораздо красивее. Спасибо.
Programmer0 вне форума Ответить с цитированием
Старый 08.07.2015, 08:16   #16
Programmer0
Пользователь
 
Регистрация: 05.05.2015
Сообщений: 55
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
до 100 потоков но можно и увеличить в глобальном параметре то что выше ParamUDPArray: array[0..99] of TParamUDP
Либо можно с внешнего текстового файла список хостов грузить если хотите могу показать
Хочу Если не трудно.
Programmer0 вне форума Ответить с цитированием
Старый 08.07.2015, 09:27   #17
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

Работа с файлом хостов, вот та часть кода в Button1Click где нужно сделать изменения, остальной код остается преждним, предварительно создайте текстовый файл в папке с проектом HostSend.txt
и впишите в него строки примерно такие:
127.0.0.1:10090
169.254.233.61:10090
169.254.124.227:10090

и т.д. в том же виде

Код:
// Новая функция разбора ip и порта из строки хоста
function ExtractHostPort(const S: string; out Host: String; out Port: DWord): Boolean;
var
  i, e: Integer;
begin
 Result := False;
  i := Pos(':', S);
  if (i > 0) then
  begin
    Host := Copy(S, 1, i - 1);
    if pos('.', Host)<>0 then
    begin
    val(Copy(S, i + 1, Length(S)), Port, e);
    Result := True;
   end;
  end;
end;

// Ну и наша кнопка запуска передачи
procedure TForm1.Button1Click(Sender: TObject);
var
ThId: Dword;
i: integer;
Host: String;
Port: DWord;
begin
    If button1.Caption='Начать отправку' then
    begin
        n:=0;
        fstop:=false;

// Работаем с файлом хостов
    With TStringList.Create do
    begin
       LoadFromFile(ExtractFilePath(Application.ExeName) + '\HostSend.txt');
       For i:= 0 to Count -1 do
// применяем нашу новую функцию по разбору строки хоста
       if  ExtractHostPort(Strings[i], Host, Port) then
       begin
       ParamUDPArray[i].Host:= Host;
       ParamUDPArray[i].Port:= Port;
       ParamUDPArray[i].hWorkUDPThead:= BeginThread(nil, 0, @WorkUDPThead, @ParamUDPArray[i], 0, ThId);
        end;
    free;
end;
        button1.Caption:='Остановить отправку';
        for i:=0 to buff_count-1 do begin
            waveInPrepareHeader(waveIn,@WaveHdr[i],sizeof(Twavehdr));
            waveInAddBuffer(wavein,@WaveHdr[i],sizeof(TwaveHdr));
            end;
        waveInStart(waveIn);
        end
    else
        begin
        fstop:=true;
        button1.Caption:='Начать отправку';
        StopUDP;
        for i:=0 to buff_count-1 do
        waveInUnprepareHeader(Wavein,@WaveHdr[i],sizeof(TwaveHdr));
        waveInStop(Wavein);
        end;
end;

Последний раз редактировалось Aliens_wolfs; 08.07.2015 в 12:56.
Aliens_wolfs вне форума Ответить с цитированием
Старый 08.07.2015, 12:45   #18
Programmer0
Пользователь
 
Регистрация: 05.05.2015
Сообщений: 55
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
Работа с файлом хостов
Спасибо большое! В строке
Код:
ParamUDPArray[i].hWorkUDPThead:= BeginThread(nil, 0, @WorkUDPThead, @ParamUDPArray[1], 0, ThId);
надо i вместо 1
Код:
ParamUDPArray[i].hWorkUDPThead:= BeginThread(nil, 0, @WorkUDPThead, @ParamUDPArray[i], 0, ThId);
и все отлично.

Последний раз редактировалось Programmer0; 08.07.2015 в 13:47.
Programmer0 вне форума Ответить с цитированием
Старый 08.07.2015, 12:56   #19
Aliens_wolfs
Форумчанин
 
Регистрация: 16.12.2009
Сообщений: 902
По умолчанию

А да поторопился не заметил, все исправил)

Последний раз редактировалось Aliens_wolfs; 08.07.2015 в 13:14.
Aliens_wolfs вне форума Ответить с цитированием
Старый 08.07.2015, 13:19   #20
Programmer0
Пользователь
 
Регистрация: 05.05.2015
Сообщений: 55
По умолчанию

Цитата:
Сообщение от Aliens_wolfs Посмотреть сообщение
А да поторопился не заметил, исправил)
А вы не подскажите в следующем вопросе. Нужно звук с левого канала линейного входа передавать на одну группу хостов, а с правого - на другую. Пытаюсь делать так(пока для двух хостов):
Код:
procedure TForm1.OnWaveMessage(var msg:TMessage);
var
  buffer_L:      Pointer;
  buffer_R:      Pointer;
  psample:      PChar;
  psample_L:    PChar;
  psample_R:    PChar;
  len: cardinal;
  i:integer;
begin
    if not fstop then begin
        if n=buff_count then
          n:=0;
        len:=WaveHdr[n].dwBufferLength div 2;
        buffer_L:=allocmem(len);
        buffer_R:=allocmem(len);
        psample:=WaveHdr[n].lpData;
        psample_L:=buffer_L;
        psample_R:=buffer_R;
        for i:=0 to len div 2-1 do
            Begin
            psample_L^:=psample^;
            inc(psample);
            inc(psample_L);
            psample_R^:=psample^;
            inc(psample);
            inc(psample_R);
            end;

        ParamUDPArray[0].SendMemoryStream.Write(buffer_L^, len);
        ParamUDPArray[1].SendMemoryStream.Write(buffer_R^, len);
        freemem(buffer_L);
        freemem(buffer_R);

        waveInPrepareHeader(waveIn,@WaveHdr[n],sizeof(Twavehdr));
        waveInAddBuffer(wavein,@WaveHdr[n],sizeof(TwaveHdr));
        inc(n);
        end;
end;
В настройках записи ставлю 2 канала:
Код:
with waveformat do begin
        nChannels:=2;
        wFormatTag:=WAVE_FORMAT_PCM;
        nSamplesPerSec:=sampleRate;
        wBitsPerSample:=8;
        nBlockAlign:=nChannels * wBitsPerSample div 8;
        nAvgBytesPerSec:=sampleRate * nBlockAlign;
        cbSize:=0;
        end;
    bufsize:=waveformat.nAvgBytesPerSec*2 div 8;
В принимающей проге - один канал, остальные настройки те же.

В результате звук воспроизводиться с прерываниями. Что не так?

Последний раз редактировалось Programmer0; 08.07.2015 в 13:31.
Programmer0 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно передать несколько разнородных данных из одной формы в другую? tumanovalex C# (си шарп) 2 21.05.2011 10:05
Как передать несколько значений checkbox? snikers987 PHP 12 13.12.2010 18:29
ServerSocket и несколько хостов. noname Incognito Работа с сетью в Delphi 4 15.07.2010 12:59
Передать звук по Блутуф связи new123 Помощь студентам 1 25.04.2009 20:53
передать несколько файлов indy SeЯgey Работа с сетью в Delphi 5 31.05.2008 21:03