StreamFunction * MonteCarloRun::genStreamFunc()
{
    switch(_modType)
    {
    case (AMC::ModType::AM_DSB_FC):
        return new AmFunction(new cosFunction(_freq()), _modIndex(), _fc(), AmDemod::SideBand::DOUBLE, 0);

    case (AMC::ModType::AM_DSB_SC):
        return new AmFunction(new cosFunction(_freq()), _modIndex(), _fc(), AmDemod::SideBand::DOUBLE, 1);

    case (AMC::ModType::AM_LSB_FC):
        return new AmFunction(new cosFunction(_freq()), _modIndex(), _fc(), AmDemod::SideBand::LOWER, 0);

    case (AMC::ModType::AM_LSB_SC):
        return new AmFunction(new cosFunction(_freq()), _modIndex(), _fc(), AmDemod::SideBand::LOWER, 1);

    case (AMC::ModType::AM_USB_FC):
        return new AmFunction(new cosFunction(_freq()), _modIndex(), _fc(), AmDemod::SideBand::UPPER, 0);

    case (AMC::ModType::AM_USB_SC):
        return new AmFunction(new cosFunction(_freq()), _modIndex(), _fc(), AmDemod::SideBand::UPPER, 1);

    case (AMC::ModType::FM):
        return new FmFunction(new cosFunction(_freq()), _fmModIndex(), _fc());

    case (AMC::ModType::ASK_2):
        return new DigitalFunction(new MAskFunction(2), _digiFreq(), _fc());

    case (AMC::ModType::MASK):
        return new DigitalFunction(new MAskFunction(std::pow(2, _constSize())), _digiFreq(), _fc());

    case (AMC::ModType::PSK_2):
        return new DigitalFunction(new MPskFunction(2), _digiFreq(), _fc());

    case (AMC::ModType::MPSK):
        return new DigitalFunction(new MPskFunction(std::pow(2, _constSize())), _digiFreq(), _fc());

    case (AMC::ModType::MQAM):
        return new DigitalFunction(new MQamFunction(std::pow(2, _constSize())), _digiFreq(), _fc());

    default:
        return new StreamFunction();
    }
}
StreamFunction * MonteCarloRun::genStreamFunc()
{
    boost::shared_lock<boost::shared_mutex> modTypeLock(*_modType->getMutex());
    AMC::ModType tempModType = _modType->getData();
    modTypeLock.unlock();

    boost::shared_lock<boost::shared_mutex> fcLock(*_modType->getMutex());
    double fc = _fc->getData();
    fcLock.unlock();

    StreamFunction * baseFunc;

    switch(tempModType)
    {
    case (AMC::ModType::AM_DSB_FC):
        baseFunc = new AmFunction(new cosFunction(_freq()), _modIndex(), fc, AmDemod::SideBand::DOUBLE, 0);
        break;

    case (AMC::ModType::AM_DSB_SC):
        baseFunc = new AmFunction(new cosFunction(_freq()), _modIndex(), fc, AmDemod::SideBand::DOUBLE, 1);
        break;

    case (AMC::ModType::AM_LSB_FC):
        baseFunc = new AmFunction(new cosFunction(_freq()), _modIndex(), fc, AmDemod::SideBand::LOWER, 0);
        break;

    case (AMC::ModType::AM_LSB_SC):
        baseFunc = new AmFunction(new cosFunction(_freq()), _modIndex(), fc, AmDemod::SideBand::LOWER, 1);
        break;

    case (AMC::ModType::AM_USB_FC):
        baseFunc = new AmFunction(new cosFunction(_freq()), _modIndex(), fc, AmDemod::SideBand::UPPER, 0);
        break;

    case (AMC::ModType::AM_USB_SC):
        baseFunc = new AmFunction(new cosFunction(_freq()), _modIndex(), fc, AmDemod::SideBand::UPPER, 1);
        break;

    case (AMC::ModType::FM):
        baseFunc = new FmFunction(new cosFunction(_freq()), _fmModIndex(), fc);
        break;

    case (AMC::ModType::ASK_2):
        baseFunc = new DigitalFunction(new MAskFunction(2), _digiFreq(), fc);
        break;

    case (AMC::ModType::MASK):
        baseFunc = new DigitalFunction(new MAskFunction(std::pow(2, _constSize())), _digiFreq(), fc);
        break;

    case (AMC::ModType::PSK_2):
        baseFunc = new DigitalFunction(new MPskFunction(2), _digiFreq(), fc);
        break;

    case (AMC::ModType::MPSK):
        baseFunc = new DigitalFunction(new MPskFunction(std::pow(2, _constSize())), _digiFreq(), fc);
        break;

    case (AMC::ModType::MQAM):
        baseFunc = new DigitalFunction(new MQamFunction(std::pow(2, _constSize())), _digiFreq(), fc);
        break;

    default:
        baseFunc = new StreamFunction();
        break;
    }

    return new AwgnFunction(baseFunc, _snr(), _rate, 10e3);
}