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; }
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; }
/** * 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; }
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
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; }