function genCampaign(fname, config)
% GENCAMPAIGN Generates an eCall testlab campaign file.
%   GENCAMPAIGN(FNAME, CONFIG) Writes the campaign generated 
%   using CONFIG to file FNAME. Default FNAME is 'campaign.txt'.
%
% Copyright 2008, Research In Motion Limited.
% All rights reserved.
% $Id: //depot/rel/dsp/ecall/2/ml/genCampaign.m#1 $

if nargin < 1 || isempty(fname)
    fname = 'campaign.txt';
end

allConditions = {
    {'fr', 'na', {'ci7', 'ci10', 'ci13', 'ci16', [], 'rssi100', 'rssi95', 'rssi90'}}
    {'amr', '12_2', {'ci13', 'ci16', [], 'rssi95', 'rssi90'}}
    {'amr', '10_2', {'ci10', 'ci13'}}
    {'amr', '7_95', {'ci10'}}
    {'amr', '7_4', {'ci10'}}
    {'amr', '6_7', {'ci7'}}
    {'amr', '5_9', {'ci4', 'ci7'}}
    {'amr', '5_15', {'ci4'}}
    {'amr', '4_75', {'ci1', 'ci4', 'rssi100', 'rssi95', 'rssi90'}}
};

switch(config)
case 'full'
    s.nTrials = 100;
    s.delay = [10 30] * 8000/1000;
    conditions = allConditions;
case 'short'
    s.nTrials = 1;
    s.delay = [10 30] * 8000/1000;
    conditions = allConditions;
case 'demo'
    s.nTrials = 100;
    s.delay = 0;
    conditions = {
        {'bypass', 'na', {[]}}
    };
end

% The testlab software support MSDs of variable length, but we fix it at 140
s.msdLength = 140;

% Index of the first test case starts at 1
s.index = 1;

fid = fopen(fname, 'wt');

for codecIndex = 1:length(conditions)
    codec = conditions{codecIndex};
    for radioIndex = 1:length(codec{3})
        radio  = codec{3}{radioIndex};
        for n = 1:s.nTrials
            q.n = s.index;
            s.index = s.index + 1;

            % The MSD is written in hex (2 characters per byte)
            q.msd = bin2dec(char((rand(s.msdLength, 8)>.5) + '0'));
            q.msd = sprintf('%02x', q.msd);

            % codecType can be one of:
            %   'amr'       Adaptive Multi Rate
            %   'fr',       GSM Full Rate
            %   'none',     Codec bypassed, but delay, impairment included
            %   'bypass'    All channel blocks bypassed
            q.codecType = codec{1};

            % codecMode can be one of:
            % 'na', '12_2', '10_2', '7_95', '7_4', '6_7', '5_9', '5_15' '4_75'
            q.codecMode = codec{2};

            % vad can be: 1 = AMR VAD 1, 2 = AMR VAD 2 
            q.vad = round(rand(1)) + 1;

            % *Delay1/*Delay2 are in samples and can take on values in the range
            % [0:240] (0 - 30ms)
            q.ulDelay1 = round(rand(1)*(s.delay(end)-s.delay(1)))+s.delay(1);
            q.ulDelay2 = round(rand(1)*(s.delay(end)-s.delay(1)))+s.delay(1);
            q.dlDelay1 = round(rand(1)*(s.delay(end)-s.delay(1)))+s.delay(1);
            q.dlDelay2 = round(rand(1)*(s.delay(end)-s.delay(1)))+s.delay(1);

            % ulErrorPattern/dlErrorPattern are either filenames or '-' to
            % indicate clean channel
            % ulErrorPatternIndex/dlErrorPatternIndex are random integers
            % specifying the starting frame within the pattern (the frame
            % number is calculated modulo the pattern length)
            if ~isempty(radio)
                q.ulErrorPattern = sprintf('%s-%s-%s.if1', ...
                    q.codecType, q.codecMode, radio);
                q.ulErrorPatternIndex = floor(rand*2^31);
                q.dlErrorPattern = sprintf('%s-%s-%s.if1', ...
                    q.codecType, q.codecMode, radio);
                q.dlErrorPatternIndex = floor(rand*2^31);
            else
                q.ulErrorPattern = '-';
                q.ulErrorPatternIndex = 0;
                q.dlErrorPattern = '-';
                q.dlErrorPatternIndex = 0;
            end

            fprintf(fid, '%d %s %s %s %d %d %d %s %d %d %d %s %d\n', ...
                q.n, ...
                q.msd, ...
                q.codecType, ...        
                q.codecMode, ...
                q.vad, ...
                q.ulDelay1, ...
                q.ulDelay2, ...
                q.ulErrorPattern, ...
                q.ulErrorPatternIndex, ...
                q.dlDelay1, ...
                q.dlDelay2, ...
                q.dlErrorPattern, ...
                q.dlErrorPatternIndex);
        end
    end
end

fclose(fid);
