Example #1
0
static int iio_driver_bufsize (iio_driver_t *driver, jack_nframes_t nframes) {
    printf("iio_driver_bufsize\n");

    jack_nframes_t period_sizeOrig=driver->period_size;
    jack_time_t period_usecsOrig = driver->period_usecs;
    unsigned long wait_timeOrig = driver->wait_time;
    double maxDelayUSecsOrig=driver->maxDelayUSecs;

    driver->period_size = nframes;
    driver->period_usecs = driver->wait_time = getUSecs(nframes, driver->sample_rate);

    //Debugger<<"wait_time = "<<driver->wait_time<<endl;

    /* tell the engine to change its buffer size */
    if (driver->engine->set_buffer_size(driver->engine, nframes)) {
        jack_error ("iio: cannot set engine buffer size to %d ", nframes);
        driver->period_size=period_sizeOrig;
        driver->period_usecs=period_usecsOrig;
        driver->wait_time=wait_timeOrig;
        driver->maxDelayUSecs=maxDelayUSecsOrig;
        return -1;
    }

    return 0;
}
Example #2
0
jack_driver_t *driver_initialize (jack_client_t *client, const JSList * params) {
    printf("driver_initialize \n");

    iio_driver_t *driver = (iio_driver_t *) calloc (1, sizeof (iio_driver_t));
    driver->IIO_devices=NULL; // indicate that the iio class hasn't been created yet
    if (driver) {
        jack_driver_nt_init((jack_driver_nt_t *) driver);

        driver->write         = (JackDriverReadFunction)       iio_driver_write;
        driver->read          = (JackDriverReadFunction)       iio_driver_read;
        driver->null_cycle    = (JackDriverNullCycleFunction)  iio_driver_null_cycle;
        driver->nt_attach     = (JackDriverNTAttachFunction)   iio_driver_attach;
        driver->nt_stop       = (JackDriverNTStopFunction)     iio_driver_stop;
        driver->nt_start      = (JackDriverNTStartFunction)    iio_driver_start;
        driver->nt_detach     = (JackDriverNTDetachFunction)   iio_driver_detach;
        driver->nt_bufsize    = (JackDriverNTBufSizeFunction)  iio_driver_bufsize;
        driver->nt_run_cycle  = (JackDriverNTRunCycleFunction) iio_driver_run_cycle;

        driver->engine = NULL; // setup the required driver variables.
        driver->client = client;
        driver->last_wait_ust = 0;

        driver->sample_rate = IIO_DEFAULT_READ_FS; // IIO sample rate is fixed.
        driver->period_size = IIO_DEFAULT_PERIOD_SIZE;
        driver->nperiods    = IIO_DEFAULT_PERIOD_COUNT;

        driver->capture_channels  = IIO_DEFAULT_CAPUTURE_PORT_COUNT; // The default number of physical input channels - a very large number, to be reduced.
        driver->capture_ports     = NULL;
        driver->playback_channels = 0; // currently doesn't support playback.
        driver->playback_ports    = NULL;


        const JSList *pnode = params; // param pointer
        while (pnode != NULL) {
            const jack_driver_param_t *param = (const jack_driver_param_t *) pnode->data;
            switch (param->character) {

            case 'i': // we are specifying the number of capture channels
                driver->capture_channels = param->value.ui;
                break;
            case 'p':
                driver->period_size = param->value.ui;
                break;
            case 'n':
                driver->nperiods = param->value.ui;
                break;

            }
            pnode = jack_slist_next(pnode);
        }

        driver->period_usecs = driver->wait_time = getUSecs(driver->period_size, driver->sample_rate);
        driver->maxDelayUSecs=driver->period_usecs*driver->nperiods; // the mmap max delay is currently unknown
        cout<<"max delay = "<<driver->maxDelayUSecs<<" us"<<endl;
        driver->capture_channels=4;
        jack_info("created DUMMY iio driver ... dummy_iio|%" PRIu32 "|%" PRIu32 "|%lu|%u|%u", driver->sample_rate, driver->period_size, driver->wait_time, driver->capture_channels, driver->playback_channels);
        return (jack_driver_t *) driver;

    } else
        jack_error("iio driver_initialise: iio_driver_t malloc() failed: %s: %s@%i", strerror(errno), __FILE__, __LINE__);

    // if we get here, there was a problem.
    iio_driver_delete((iio_driver_t *) driver);
    return NULL;
}
Example #3
0
/**
 * This is a more realistic example with separation of received data creation (mocking) and its processing
 */
bool example3()
{
#pragma pack(push, 1)
    struct Sample
    {
        uint16_t i;
        uint16_t q;
    };
    struct Header
    {
        uint16_t frameIndex;
        uint8_t  blockIndex;
        uint8_t  filler;
    };

    static const int samplesPerBlock = (512 - sizeof(Header)) / sizeof(Sample);

    struct ProtectedBlock
    {
        Sample samples[samplesPerBlock];
    };
    struct SuperBlock
    {
        Header         header;
        ProtectedBlock protectedBlock;
    };
#pragma pack(pop)

    if (cm256_init())
    {
        return false;
    }

    cm256_encoder_params params;

    // Number of bytes per file block
    params.BlockBytes = sizeof(ProtectedBlock);

    // Number of blocks
    params.OriginalCount = 128;  // Superframe = set of protected frames

    // Number of additional recovery blocks generated by encoder
    params.RecoveryCount = 32;

    SuperBlock* txBuffer = new SuperBlock[params.OriginalCount+params.RecoveryCount];
    ProtectedBlock* txRecovery = new ProtectedBlock[params.RecoveryCount];
    cm256_block txDescriptorBlocks[params.OriginalCount+params.RecoveryCount];
    int frameCount = 0;

    // Fill original data
    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; ++i)
    {
        txBuffer[i].header.frameIndex = frameCount;
        txBuffer[i].header.blockIndex = i;

        if (i < params.OriginalCount)
        {
            txBuffer[i].protectedBlock.samples[0].i = i; // marker
        }
        else
        {
            memset((void *) &txBuffer[i].protectedBlock, 0, sizeof(ProtectedBlock));
        }

        txDescriptorBlocks[i].Block = (void *) &txBuffer[i].protectedBlock;
        txDescriptorBlocks[i].Index = txBuffer[i].header.blockIndex;
    }

    // Generate recovery data

    long long ts = getUSecs();

    if (cm256_encode(params, txDescriptorBlocks, txRecovery))
    {
        std::cerr << "example2: encode failed" << std::endl;
        delete[] txBuffer;
        delete[] txRecovery;
        return false;
    }

    long long usecs = getUSecs() - ts;

    std::cerr << "Encoded in " << usecs << " microseconds" << std::endl;

    // insert recovery data in sent data
    for (int i = 0; i < params.RecoveryCount; i++)
    {
        txBuffer[params.OriginalCount+i].protectedBlock = txRecovery[i];
    }

    SuperBlock* rxBuffer = new SuperBlock[params.OriginalCount + params.RecoveryCount]; // received blocks
    int k = 0;

    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; i++)
    {
        if (i % 5 != 4)
        {
            rxBuffer[k] = txBuffer[i];
            k++;
        }
    }

    Sample *samplesBuffer = new Sample[samplesPerBlock * params.OriginalCount];
    ProtectedBlock* retrievedDataBuffer = (ProtectedBlock *) samplesBuffer;
    ProtectedBlock* recoveryBuffer = new ProtectedBlock[params.OriginalCount];      // recovery blocks with maximum size

    cm256_block rxDescriptorBlocks[params.OriginalCount];
    int recoveryStartIndex;
    k = 0;

    for (int i = 0; i < params.OriginalCount; i++)
    {
        int blockIndex = rxBuffer[i].header.blockIndex;

        if (blockIndex < params.OriginalCount) // it's an original block
        {
            retrievedDataBuffer[blockIndex] = rxBuffer[i].protectedBlock;
            rxDescriptorBlocks[i].Block = (void *) &retrievedDataBuffer[blockIndex];
            rxDescriptorBlocks[i].Index = blockIndex;
        }
        else // it's a recovery block
        {
            if (k == 0)
            {
                recoveryStartIndex = i;
            }

            recoveryBuffer[k] = rxBuffer[i].protectedBlock;
            rxDescriptorBlocks[i].Block = (void *) &recoveryBuffer[k];
            rxDescriptorBlocks[i].Index = blockIndex;
            k++;
        }
    }

    ts = getUSecs();

    if (cm256_decode(params, rxDescriptorBlocks))
    {
        delete[] txBuffer;
        delete[] txRecovery;
        delete[] rxBuffer;
        delete[] samplesBuffer;
        delete[] recoveryBuffer;

        return false;
    }

    usecs = getUSecs() - ts;

    for (int i = 0; i < k; i++) // recover missing blocks
    {
        int blockIndex = rxDescriptorBlocks[recoveryStartIndex+i].Index;
        retrievedDataBuffer[blockIndex] = recoveryBuffer[i];
    }

    for (int i = 0; i < params.OriginalCount; i++)
    {
        std::cerr << i << ":"
                << (unsigned int) rxDescriptorBlocks[i].Index << ":"
                << (unsigned int) retrievedDataBuffer[i].samples[0].i << std::endl;
    }

    std::cerr << "Decoded in " << usecs << " microseconds" << std::endl;

    delete[] txBuffer;
    delete[] txRecovery;
    delete[] rxBuffer;
    delete[] samplesBuffer;
    delete[] recoveryBuffer;

    return true;
}
Example #4
0
bool example4()
{
#pragma pack(push, 1)
    struct Sample
    {
        uint16_t i;
        uint16_t q;
    };
    struct Header
    {
        uint16_t frameIndex;
        uint8_t  blockIndex;
        uint8_t  filler[5];
    };

    static const int samplesPerBlock = (512 - sizeof(Header)) / sizeof(Sample);

    struct ProtectedBlock
    {
        Sample samples[samplesPerBlock];
    };
    struct SuperBlock
    {
        Header         header;
        ProtectedBlock protectedBlock;
    };
#pragma pack(pop)

    if (cauchy_256_init())
    {
        std::cerr << "cauchy_256_init error" << std::endl;
        return false;
    }

    // Number of bytes per file block
    int BlockBytes = sizeof(ProtectedBlock);

    // Number of data blocks
    int OriginalCount = 128;  // Superframe = set of protected frames

    // Number of additional recovery blocks generated by encoder
    int RecoveryCount = 25;

    SuperBlock txBuffer[256];
    ProtectedBlock txRecovery[256];
    const unsigned char *dataPtrs[256];
    int frameCount = 0;

    // Fill original data
    for (int i = 0; i < OriginalCount; i++)
    {
        txBuffer[i].header.frameIndex = frameCount;
        txBuffer[i].header.blockIndex = i;
        dataPtrs[i] = (const unsigned char *) &txBuffer[i].protectedBlock;

        for (int k = 0; k < samplesPerBlock; k++)
        {
            txBuffer[i].protectedBlock.samples[k].i = rand();
            txBuffer[i].protectedBlock.samples[k].q = rand();
        }
    }

    // Generate recovery data

    long long ts = getUSecs();

    if (cauchy_256_encode(OriginalCount, RecoveryCount, dataPtrs, (void *) txRecovery, BlockBytes))
    {
        std::cerr << "example4: encode failed" << std::endl;
        return false;
    }

    long long usecs = getUSecs() - ts;

    std::cerr << "Encoded in " << usecs << " microseconds" << std::endl;

    // insert recovery data in sent data
    for (int i = 0; i < RecoveryCount; i++)
    {
        txBuffer[OriginalCount + i].header.frameIndex = frameCount;
        txBuffer[OriginalCount + i].header.blockIndex = i + OriginalCount;
        txBuffer[OriginalCount + i].protectedBlock = txRecovery[i];
    }

    SuperBlock* rxBuffer = new SuperBlock[256]; // received blocks
    int nbRxBlocks = 0;

    for (int i = 0; i < OriginalCount + RecoveryCount; i++)
    {
        if (i % 6 != 4)
        //if (i != 101)
        {
            rxBuffer[nbRxBlocks] = txBuffer[i];
            nbRxBlocks++;
        }
    }

    std::cerr << "exemple4: nbRxBlocks: " << nbRxBlocks << " OriginalCount: " << OriginalCount << std::endl;

    Sample *samplesBuffer = new Sample[samplesPerBlock * OriginalCount];
    ProtectedBlock* retrievedDataBuffer = (ProtectedBlock *) samplesBuffer;
    ProtectedBlock* recoveryBuffer = new ProtectedBlock[OriginalCount];      // recovery blocks with maximum size
    bool blockZeroRetrieved = false;
    int recoveryCount = 0;
    int nbBlocks = 0;
    Block blockInfo[256];

    std::cerr << "receive..." << std::endl;

    for (int i = 0; i < nbRxBlocks; i++)
    {
        int blockIndex = rxBuffer[i].header.blockIndex;

        if (nbBlocks < OriginalCount) // not enough data store it
        {
            blockInfo[i].data = (unsigned char *) &rxBuffer[i].protectedBlock;
            blockInfo[i].row = blockIndex;

            if (blockIndex < OriginalCount)
            {
                retrievedDataBuffer[blockIndex] = rxBuffer[i].protectedBlock;
            }
            else
            {
                recoveryCount++;
            }
        }

        nbBlocks++;

        if (nbBlocks == OriginalCount)
        {
            ts = getUSecs();

            if (cauchy_256_decode(OriginalCount, RecoveryCount, blockInfo, BlockBytes))
            {
                std::cerr << "example4: decode failed" << std::endl;
                return false;
            }

            usecs = getUSecs() - ts;

            for (int ir = 0; ir < recoveryCount; ir++)
            {
                int retBlockIndex = blockInfo[OriginalCount - recoveryCount + ir].row;
                retrievedDataBuffer[retBlockIndex] = *((ProtectedBlock *) blockInfo[OriginalCount - recoveryCount + ir].data);
                std::cerr << "Recovery #" << ir << ": " << retBlockIndex << std::endl;
            }
        }
    }

    std::cerr << "final..." << std::endl;

    for (int i = 0; i < OriginalCount; i++)
    {
        bool compOKi = true;
        bool compOKq = true;

        for (int k = 0; k < samplesPerBlock; k++)
        {
            if (retrievedDataBuffer[i].samples[k].i != txBuffer[i].protectedBlock.samples[k].i)
            {
                std::cerr << i << ": error: " << k << ": i: " << retrievedDataBuffer[i].samples[k].i << "/" << txBuffer[i].protectedBlock.samples[k].i << std::endl;
                compOKi = false;
                break;
            }

            if (retrievedDataBuffer[i].samples[k].q != txBuffer[i].protectedBlock.samples[k].q)
            {
                std::cerr << i << ": error: " << k << ": q: " << retrievedDataBuffer[i].samples[k].q << "/" << txBuffer[i].protectedBlock.samples[k].q << std::endl;
                compOKq = false;
                break;
            }
        }

        if (compOKi && compOKq)
        {
            std::cerr << i << ": OK" << std::endl;
        }
    }

    std::cerr << "Decoded in " << usecs << " microseconds" << std::endl;

    delete[] samplesBuffer;
    delete[] recoveryBuffer;

    return true;
} // example4
Example #5
0
bool example2()
{
    static const int payloadSize = 256; // represents 4 subframes of 64 bytes
#pragma pack(push, 1)
    struct ProtectedBlock
    {
        uint8_t blockIndex;
        uint8_t data[payloadSize];
    };
    struct SuperBlock
    {
        uint8_t        frameIndex;
        uint8_t        blockIndex;
        ProtectedBlock protectedBlock;
    };
#pragma pack(pop)

    if (cm256_init())
    {
        return false;
    }

    cm256_encoder_params params;

    // Number of bytes per file block
    params.BlockBytes = sizeof(ProtectedBlock);

    // Number of blocks
    params.OriginalCount = 128;  // Superframe = set of protected frames

    // Number of additional recovery blocks generated by encoder
    params.RecoveryCount = 32;

    SuperBlock* txBuffer = new SuperBlock[params.OriginalCount+params.RecoveryCount];
    ProtectedBlock* txRecovery = new ProtectedBlock[params.RecoveryCount];
    cm256_block txDescriptorBlocks[params.OriginalCount+params.RecoveryCount];
    int frameCount = 0;

    // Fill original data
    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; ++i)
    {
        txBuffer[i].frameIndex = frameCount;
        txBuffer[i].blockIndex = i;

        if (i < params.OriginalCount)
        {
            txBuffer[i].protectedBlock.blockIndex = i;

            for (int j = 0; j < payloadSize; ++j)
            {
                txBuffer[i].protectedBlock.data[j] = i;
            }

            txDescriptorBlocks[i].Block = (void *) &txBuffer[i].protectedBlock;
            txDescriptorBlocks[i].Index = txBuffer[i].blockIndex;
        }
        else
        {
            memset((void *) &txBuffer[i].protectedBlock, 0, sizeof(ProtectedBlock));
            txDescriptorBlocks[i].Block = (void *) &txBuffer[i].protectedBlock;
            txDescriptorBlocks[i].Index = i;
        }
    }

    // Generate recovery data

    long long ts = getUSecs();

    if (cm256_encode(params, txDescriptorBlocks, txRecovery))
    {
        std::cerr << "example2: encode failed" << std::endl;
        delete[] txBuffer;
        delete[] txRecovery;
        return false;
    }

    long long usecs = getUSecs() - ts;

    std::cerr << "Encoded in " << usecs << " microseconds" << std::endl;

    // insert recovery data in sent data
    for (int i = 0; i < params.RecoveryCount; i++)
    {
        txBuffer[params.OriginalCount+i].protectedBlock = txRecovery[i];
    }

    SuperBlock* rxBuffer = new SuperBlock[params.OriginalCount];
    cm256_block rxDescriptorBlocks[params.OriginalCount];
    int k = 0;

    for (int i = 0; i < params.OriginalCount+params.RecoveryCount; i++)
    {
        if (k < params.OriginalCount)
        {
            if (i % 5 != 4)
            {
                rxBuffer[k] = txBuffer[i];
                rxDescriptorBlocks[k].Block = (void *) &rxBuffer[k].protectedBlock;
                rxDescriptorBlocks[k].Index = rxBuffer[k].blockIndex;
                k++;
            }
        }
    }

    ts = getUSecs();

    if (cm256_decode(params, rxDescriptorBlocks))
    {
        delete[] txBuffer;
        delete[] txRecovery;
        delete[] rxBuffer;

        return false;
    }

    usecs = getUSecs() - ts;

    for (int i = 0; i < params.OriginalCount; i++)
    {
        std::cerr << i << ":"
                << (unsigned int) rxBuffer[i].blockIndex << ":"
                << (unsigned int) rxBuffer[i].protectedBlock.blockIndex << ":"
                << (unsigned int) rxBuffer[i].protectedBlock.data[0] << std::endl;
    }

    std::cerr << "Decoded in " << usecs << " microseconds" << std::endl;

    delete[] txBuffer;
    delete[] txRecovery;
    delete[] rxBuffer;

    return true;
}