⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unaconfserver.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 3 页
字号:
	    logMessage(className + '.execute() - SENT: connId=' + int2str(rx.r_connId) + '; len=' + int2str(rx.r_len));
  {$ENDIF }
	    //
	    idx := f_master.getClientIndex(rx.r_connId);
	    if (0 <= idx) then begin
	      //
	      if (0 = res) then begin
		//
		inc(f_sentOK[idx]);
	      end
	      else begin
		//
		inc(f_sentFail[idx]);
	      end;
	    end;
	    //
	    mrealloc(rx.r_data);	// release data
	  end;
	  //
  {$IFDEF CS_LOG_MAX }
	  logMessage(className + '.execute() - done, clean up complete.');
  {$ENDIF }
	  //
	finally
	  f_records.clear();
	  f_records.unlock();
	end;
      end
      else
	f_records.waitForData(40);	// not too long, since thread may be asked to stop
      //
    except
      // thread must survive
{$IFDEF DEBUG_NASTY_EXCEPTION }
      on E: EExternal do
	logMessage(className + '.execute() - got exception [' + E.Message + '], info: ' + base64encode(E.ExceptionRecord, sizeOf(E.ExceptionRecord)));

      on E: Exception do
	logMessage(className + '.execute() - got exception [' + E.Message + ']');

{$ELSE}
      Sleep(10);
{$ENDIF }
    end;
  end;
  //
  result :=0
end;


{ unaConfClientServer }

// --  --
procedure unaConfServerClass.afterConstruction();
var
  i: int;
begin
  inherited;
  //
  f_mixer := unaWaveExclusiveMixerDevice.create(false, true, 10);
  f_mixBuf := nil;
  //
  setAudioFormat();
  //
  f_ipServer := unaConfIPServer.createServer(self);
  f_ipServer.maxClients := c_maxClients;
  f_ipServer.udpTimeout := 0;
  //
  f_senderThread := unaCSSendThread.create(self);
  //
  f_clientLock := unaInProcessGate.create();
  //
  for i := 0 to c_maxClients - 1 do begin
    //
    with (f_clients[i]) do begin
      //
      r_connId := 0;
      //
      r_codecIn := TunavclWaveCodecDevice.create(nil);
      r_codecIn.inputIsPcm := false;
      r_codecIn.formatTagImmunable := false;
      r_codecIn.isFormatProvider := false;
      //
      r_codecOut := TunavclWaveCodecDevice.create(nil);
      r_codecOut.inputIsPcm := true;
      r_codecOut.formatTagImmunable := false;
      r_codecOut.isFormatProvider := false;
      r_codecOut.autoActivate := false;
      r_codecOut.onDataAvailable := onCodecOutDA;
      //
      r_mixerStream := f_mixer.addStream();
    end;
  end;
  //
  interval := 1000 div c_ticksPerSecond;	// 40 ms
  //
{$IFDEF CS_LOG_MAX }
  logMessage(className + '.afterConstruction() - server created, interval=' + int2str(interval));
{$ENDIF }
end;

// --  --
procedure unaConfServerClass.beforeDestruction();
var
  i: int;
begin
{$IFDEF CS_LOG_MAX }
  logMessage(className + '.beforeDestruction() - server about to be destroyed..');
{$ENDIF }
  //
  stop();
  //
  for i := 0 to c_maxClients - 1 do begin
    //
    with (f_clients[i]) do begin
      //
      freeAndNil(r_codecIn);
      freeAndNil(r_codecOut);
      //
      f_mixer.removeStream(r_mixerStream);
      r_mixerStream := nil;
    end;
  end;
  //
  freeAndNil(f_senderThread);	// stop sending anything
  freeAndNil(f_mixer);		// stop mixing
  freeAndNil(f_ipServer);	// stop server
  //
  f_mixBufSize := 0;
  mrealloc(f_mixBuf);
  //
  freeAndNil(f_clientLock);
  //
  inherited;
  //
{$IFDEF CS_LOG_MAX }
  logMessage(className + '.beforeDestruction() - server destroyed.');
{$ENDIF }
end;

// --  --
function codecInfo(codec: TunavclWaveCodecDevice): string;
begin
  result := 'SRC: ' + codec.codec.srcFormatInfo + ' -> DST: ' + codec.codec.dstFormatInfo;
end;

// --  --
procedure unaConfServerClass.checkDriver(codec: TunavclWaveCodecDevice);
begin
  codec.close();
  //
  try
{$IFDEF USE_INSTALLABLE_DRIVERS }
    if ((nil = codec.driver) and (unacdm_installable <> codec.driverMode)) then begin
      //
      codec.close();
      //
      case (codec.formatTag) of

	WAVE_FORMAT_ALAW,
	WAVE_FORMAT_MULAW:
	  codec.driverLibrary := 'msg711.acm';

	WAVE_FORMAT_ADPCM:
	  codec.driverLibrary := 'msadp32.acm';

	WAVE_FORMAT_GSM610:
	  codec.driverLibrary := 'msgsm32.acm';

	112, WAVE_FORMAT_LH_CODEC + 1:
	  codec.driverLibrary := 'lhacm.acm';

	WAVE_FORMAT_MSG723:
	  codec.driverLibrary := 'msg723.acm';

{$IFDEF DEBUG_DUMMY_CODEC }
	12345678:
	  codec.driverLibrary := '12345678.acm';
{$ENDIF}

	else
	  error(c_unaconfserr_unknownDriver, codec.formatTag);

      end;
      //
      codec.driverMode := unacdm_installable;
    end;
{$ENDIF }
  finally
    codec.open();
    //
    if (nil = codec.driver) then begin
      //
      error(c_unaconfserr_driverNotFound, codec.formatTag);
      //
{$IFDEF CS_LOG_MAX }
      logMessage(className + '.checkDriver() - codec has no driver: ' + codecInfo(codec));
{$ENDIF }
    end;
  end;
end;

// --  --
function unaConfServerClass.disconnectClient(connId: unsigned): bool;
begin
{$IFDEF CS_LOG_MAX }
  logMessage(className + '.disconnectClient() - about to send "goodbye" the client, connId=' + int2str(connId));
{$ENDIF }
  // send goodbye to client
  result := (0 = f_ipServer.sendPacket(connId, cmd_inOutIPPacket_bye));
end;

// --  --
procedure unaConfServerClass.error(code, info: int);
begin
  if (assigned(f_onError)) then begin
    //
    f_onError(self, code, info);
    //
{$IFDEF CS_LOG_MAX }
    logMessage(className + '.error() - code=' + int2str(code) + '; info=' + int2str(info));
{$ENDIF }
  end;
end;

// --  --
function unaConfServerClass.getClientIndex(connId: unsigned): int;
var
  i: unsigned;
begin
  result := -1;
  i := 0;
  while (i < c_maxClients) do begin
    //
    if (f_clients[i].r_connId = connId) then begin
      //
      result := i;
      break;
    end;
    //
    inc(i);
  end;
end;

// --  --
function unaConfServerClass.getAudioFormat(out format: unavclWavePipeFormatExchange): bool;
begin
  with format.r_format do begin
    //
    formatTag := f_outFormatTag;
    //
    formatOriginal.pcmSamplesPerSecond := f_samplingRate;
    formatOriginal.pcmBitsPerSample := f_bitsPerSample;
    formatOriginal.pcmNumChannels := f_numChannels;
  end;
  //
{$IFDEF CS_LOG_MAX }
  logMessage(className + '.getAudioFormat() - returned (formatTag=' + int2str(f_outFormatTag) + '; SPS=' + int2str(f_samplingRate) + '; BPS=' + int2str(f_bitsPerSample) + '; NC=' + int2str(f_numChannels));
{$ENDIF }
  //
{$IFDEF USE_INSTALLABLE_DRIVERS }
  format.r_driverMode := ord(unacdm_installable);
  case (f_outFormatTag) of

    WAVE_FORMAT_ALAW,
    WAVE_FORMAT_MULAW:
      wstr2array('msg711.acm', format.r_driverLib);

    WAVE_FORMAT_ADPCM:
      wstr2array('msadp32.acm', format.r_driverLib);

    WAVE_FORMAT_GSM610:
      wstr2array('msgsm32.acm', format.r_driverLib);

    112, WAVE_FORMAT_LH_CODEC + 1:
      wstr2array('lhacm.acm', format.r_driverLib);

    WAVE_FORMAT_MSG723:
      wstr2array('msg723.acm', format.r_driverLib);

{$IFDEF DEBUG_DUMMY_CODEC }
    12345678:
      wstr2array('12345678.acm', format.r_driverLib);
{$ENDIF}

    else
      error(c_unaconfserr_unknownDriver, f_outFormatTag);

  end;
{$ELSE }
  format.r_driverMode := ord(unacdm_acm);
{$ENDIF }
  //
  result := true;
end;

// --  --
function unaConfServerClass.getClientIndex(codecOut: tObject): int;
var
  i: unsigned;
begin
  result := -1;
  i := 0;
  while (i < c_maxClients) do begin
    //
    if (f_clients[i].r_codecOut = codecOut) then begin
      //
      result := i;
      break;
    end;
    //
    inc(i);
  end;
end;

// --  --
function unaConfServerClass.getClientOptions(clientIndex: unsigned): unsigned;
begin
  result := f_ipServer.clientOptions[clientIndex];
end;

// --  --
function unaConfServerClass.getSrvIsActive(): bool;
begin
  result := f_ipServer.isActive;
end;

// --  --
procedure unaConfServerClass.onAC2(connectionId: unsigned; var accept: bool);
var
  freeIndex: int;
begin
  if (f_clientLock.enter(1000)) then begin
    //
    try
      accept := accept and (clientCount < c_maxClients);
      //
      if (assigned(f_onAC)) then
	f_onAC(self, connectionId, accept);
      //
      if (accept) then begin
	//
	freeIndex := getClientIndex(0);
	if (0 <= freeIndex) then begin
	  f_clients[freeIndex].r_connId := connectionId;
	  //
	  inc(f_clientCount);
	end
	else begin
	  // should not be here
	  accept := false;
	  if (assigned(f_onAC)) then
	    f_onAC(self, connectionId, accept);
	end;
      end;
    finally
      f_clientLock.leave();
    end;
  end
  else
    accept := false;
end;

// --  --
procedure unaConfServerClass.onCE2(connectionId: unsigned; connected: bool);
var
  clientIndex: int;
begin
  if (f_clientLock.enter(1000)) then
    try
      //
      if (assigned(f_onCE)) then
	f_onCE(self, connectionId, connected);
      //
      if (connected) then begin
	// -- already done in acceptClient --
	// -- f_clients.add(connectionId) --
{$IFDEF CS_LOG_MAX }
	logMessage(className + '.onCE2() - client connection was added, connId=' + int2str(connectionId));
{$ENDIF }
      end
      else begin
	//
	clientIndex := getClientIndex(connectionId);
	if (0 <= clientIndex) then begin
	  // close devices
	  f_clients[clientIndex].r_codecIn.close();
	  f_clients[clientIndex].r_codecOut.close();
	  f_clients[clientIndex].r_mixerStream.clear();
	  f_clients[clientIndex].r_connId := 0;	// mark as free
	  //
	  dec(f_clientCount);
	end;
	//
{$IFDEF CS_LOG_MAX }
	logMessage(className + '.onCE2() - client connection was removed, connId=' + int2str(connectionId) + '; index=' + int2str(clientIndex));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -