📄 unaconfserver.pas
字号:
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 + -