VOIP From One Simulink Session to Another

by

 

17 Jan 2008 (Updated )

Use the Signal Processing Blockset to enable voice communications between different workstations.

dspUDPReceive(block)
function dspUDPReceive(block)
% dspUDPReceive A UDP server
%
% Copyright 2007-2009 The MathWorks, Inc.
%

% Declare the array of java sockets (used by instantces of this class).
persistent socket

if ~exist('socket','var') || isempty(socket)
    socket = {};
end

% Register parameters: port, outputLength, sampleTime
block.NumDialogPrms     = 3;
block.DialogPrmsTunable = {'Nontunable','Nontunable','Nontunable'};
port         = block.DialogPrm(1).Data;
outputLength = block.DialogPrm(2).Data;
sampleTime   = block.DialogPrm(3).Data;

% Set up some static variables
bufferSize = max(8192, outputLength);
timeout    = 1; % timeout in milliseconds

% Register number of ports
block.NumInputPorts  = 0;
block.NumOutputPorts = 1;

% Setup port properties to be inherited or dynamic
block.SetPreCompOutPortInfoToDynamic;

% Override output port properties
block.OutputPort(1).DatatypeID  = 3; % uint8
block.OutputPort(1).Dimensions  = outputLength;
block.OutputPort(1).Complexity  = 'Real';
block.OutputPort(1).SamplingMode = 'Sample';

% Register sample times
block.SampleTimes = [sampleTime 0];

%% Options
block.SetAccelRunOnTLC(false);

block.RegBlockMethod('CheckParameters', @mdlCheckParameters);
block.RegBlockMethod('SetOutputPortDimensions', @mdlSetOutputPortDimensionInfo);
block.RegBlockMethod('SetOutputPortDataType', @mdlSetOutputPortDataType);
block.RegBlockMethod('SetOutputPortComplexSignal', @mdlSetOutputPortComplexSignal);
block.RegBlockMethod('PostPropagationSetup', @mdlSetWorkWidths);

block.RegBlockMethod('ProcessParameters', @mdlProcessParameters);
block.RegBlockMethod('InitializeConditions', @mdlInitializeConditions);
block.RegBlockMethod('Start', @mdlStart);
block.RegBlockMethod('Outputs', @mdlOutputs);
block.RegBlockMethod('Terminate', @mdlTerminate);

%block.RegBlockMethod('WriteRTW', @mdlRTW);

%% The initialization steps
    function mdlCheckParameters(block)
        port = block.DialogPrm(1).Data;
        if ~strcmp(class(port), 'double')
            error('Invalid parameter');
        end
        outputLength = block.DialogPrm(2).Data;
        if ~strcmp(class(outputLength), 'double')
            error('Invalid parameter');
        end
        sampleTime = block.DialogPrm(3).Data;
        if ~strcmp(class(sampleTime), 'double')
            error('Invalid parameter');
        end
    end

    function mdlSetOutputPortDimensionInfo(block, idx, di)
        block.OutputPort(idx).Dimensions = di;
    end

    function mdlSetOutputPortDataType(block, idx, dt)
        block.OutputPort(idx).DataTypeID  = 3;
    end

    function mdlSetOutputPortComplexSignal(block, idx, c)
        block.OutputPort(idx).Complexity = c;
    end

    function mdlSetWorkWidths(block)
        block.NumDworks = 2;
        block.Dwork(1).Name            = 'nextSocket';
        block.Dwork(1).Dimensions      = 1;
        block.Dwork(1).DatatypeID      = 0; % real
        block.Dwork(1).Complexity      = 'Real';
        block.Dwork(1).UsedAsDiscState = true;

        block.Dwork(2).Name            = 'buffer';
        block.Dwork(2).Dimensions      = bufferSize;
        block.Dwork(2).DatatypeID      = 3; % uint8
        block.Dwork(2).Complexity      = 'Real';
        block.Dwork(2).UsedAsDiscState = true;
        % Register all tunable parameters as runtime parameters.
        block.AutoRegRuntimePrms;
    end

    function mdlInitializeConditions(block)
    end

%% The runtime loop
    function mdlProcessParameters(block)
        block.AutoUpdateRuntimePrms;
    end

    function mdlStart(block)
        block.Dwork(1).Data = length(socket) +1;
        try
            % Attempt to create the socket
            socket{block.Dwork(1).Data} = java.net.DatagramSocket(port);
            socket{block.Dwork(1).Data}.setSoTimeout(timeout);
        catch
            error('An error was reported opening a UDP Socket on port %d: %s',...
                port, lasterr);
            block.Dwork(1).Data = 0;
        end
    end

    function mdlOutputs(block)
        data = javaArray('java.lang.Byte', outputLength);
        
        totalAmtRead = 0;
        while totalAmtRead < outputLength
            try
                packet = java.net.DatagramPacket(block.Dwork(2).Data,...
                    outputLength-totalAmtRead);
            catch
                error('Error creating DatagramPacket: %s', lasterr);
            end
            try
                socket{block.Dwork(1).Data}.receive(packet);
                amtRead = packet.getLength();
                signed = double(packet.getData());
                signed = signed(1:amtRead);
                signed(signed < 0) = 256 + signed(signed < 0);
                block.OutputPort(1).Data(totalAmtRead+1:totalAmtRead+amtRead) = uint8(signed);
                totalAmtRead = totalAmtRead + amtRead;
            catch
                % warning('Data underrun: emitting zeros.');
                % We could warn about invalid data here, but we just
                % return zeros for now.
                block.OutputPort(1).Data(totalAmtRead+1:outputLength) = uint8(0);
                break
            end
        end
    end

    function mdlTerminate(block)
        if block.Dwork(1).Data
            socket{block.Dwork(1).Data}.close;
            socket(block.Dwork(1).Data) = [];
            block.Dwork(1).Data = 0;
        end
    end

end


Contact us