3356
* FUNCTION: doGetPlayrec(int nlhs, mxArray *plhs[],
3357
* int nrhs, const mxArray *prhs[])
3359
* Inputs: nlhs - number of mexFunction output arguments
3360
* plhs - pointer to array of mexFunction output arguments
3361
* nrhs - number of mexFunction input arguments
3362
* prhs - pointer to array of mexFunction input arguments
3364
* The first element of plhs is always used and so must be valid
3365
* (this is not checked). Additionally, if (nlhs >= 2) then the
3366
* second element of plhs must also be valid. The first element
3367
* of prhs must also be valid and must point to an mxArray (the
3368
* type of mxArray is checked).
3370
* Returns: true, or aborts with an error if not in full initialisation
3373
* Description: Returns all recorded samples available for the page specified.
3374
* The page required is identified by its page number, supplied as
3375
* the first element of prhs. An array is always returned in the
3376
* first element of plhs, and if (nlhs >= 2) then an array is also
3377
* returned in the second element of plhs. The first of these
3378
* contains the recorded data in an MxN array where M is the
3379
* number of samples that have been recorded (if the page is
3380
* currently being processed this will be the number of valid
3381
* samples at the specific point in time) and N is the number
3382
* of channels of data. The second array is a 1xN array
3383
* containing the channel number asssociated with each channel
3384
* of data in the first array. If the page requested does not
3385
* exist, or contains no recorded data (either because there are
3386
* no channels set to record, or because the page is waiting to be
3387
* processed) then the array(s) returned are empty.
3391
bool doGetPlayrec(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
3393
StreamPageStruct *psps;
3394
ChanBufStruct *pcbs;
3395
ChanBufStruct *pcbsBoth[2];
3397
resample_error rerr = RESAMPLE_OK;
3399
mxArray *mxRecChanList;
3400
mxArray *mxPlayChanList;
3401
unsigned int *pChanListBoth[2];
3402
unsigned int recSamples, recSamplesTmp;
3403
unsigned int channels[2];
3404
unsigned int recResPlanId = 0;
3407
/* SRC_DATA recData;*/
3409
validateState(BASIC_INIT | FULL_INIT, 0);
3413
mexErrMsgTxt("An error has occurred - in full initialisation yet "
3414
"_pstreamInfo is NULL.");
3417
/* Configure return values to defaults, and then change if necessary */
3418
plhs[0] = mxCreateNumericMatrix(0, 0, mxSAMPLE, mxREAL);
3419
if (nlhs > 1) plhs[1] = mxCreateNumericMatrix(0, 0, mxSAMPLE, mxREAL);
3420
if (nlhs > 2) plhs[2] = mxCreateNumericMatrix(0, 0, mxSAMPLE, mxREAL);
3423
if (!_pstreamInfo->pfirstStreamPage)
3428
/* There must be one element on rhs before function is called */
3429
if (!mxIsNumeric(prhs[0]) || mxIsComplex(prhs[0])
3430
|| (mxGetN(prhs[0]) != 1) || (mxGetM(prhs[0]) != 1)
3431
|| (mxGetScalar(prhs[0]) != (int)mxGetScalar(prhs[0])))
3437
/* Try and find requested stream. */
3438
psps = _pstreamInfo->pfirstStreamPage;
3442
if (psps->pageNum == (int)mxGetScalar(prhs[0]))
3445
psps = psps->pnextStreamPage;
3450
/* page does not exist, so return immediately */
3454
/* Found the required page */
3456
/* Determine the maximum number of samples recorded by finding the longest
3457
* buffer, and then limiting to how far through the page we currently are.
3458
* This allows for different length buffers in the future.
3465
pcbsBoth[0] = psps->pfirstRecChan;
3466
pcbsBoth[1] = psps->pfirstPlayChan;
3472
/* Check for valid buffer */
3473
if (pcbs->pbuffer && (pcbs->bufLen > 0))
3475
recSamplesTmp = max(recSamples, pcbs->bufLen);
3478
pcbs = pcbs->pnextChanBuf;
3485
/* Check for valid buffer */
3486
if (pcbs->pbuffer && (pcbs->bufLen > 0))
3490
pcbs = pcbs->pnextChanBuf;
3495
/* We will do resampling */
3496
if (psps->pagePos != recSamplesTmp)
3498
/* Page was not yet finished, do something harmless. */
3499
recSamples = (unsigned int) ( psps->pageLengthRec * psps->pagePos / ((double)recSamples));
3503
recSamples = psps->pageLengthRec;
3508
recSamples = recSamplesTmp;
3512
/* If there are no samples recorded, no need to continue */
3513
if ((recSamples == 0) || (channels[0] == 0) || (channels[1] == 0))
3518
/* This initialises all elements to zero, so for shorter channels no
3519
* problems should arise. Although on exit MATLAB frees the arrays created
3520
* above, do so here for completeness
3522
mxDestroyArray(plhs[0]);
3524
plhs[0] = mxCreateNumericMatrix(recSamples, channels[0] + channels[1], mxSAMPLE, mxREAL);
3525
poutBuf = (SAMPLE*)mxGetData(plhs[0]);
3527
/* Create the channel list, but only return it if its required */
3528
mxRecChanList = mxCreateNumericMatrix(1, channels[0], mxUNSIGNED_INT, mxREAL);
3529
mxPlayChanList = mxCreateNumericMatrix(1, channels[0], mxUNSIGNED_INT, mxREAL);
3530
pChanListBoth[0] = (unsigned int*)mxGetData(mxRecChanList);
3531
pChanListBoth[1] = (unsigned int*)mxGetData(mxPlayChanList);
3534
if (poutBuf && pChanListBoth[0] && pChanListBoth[1])
3537
for (ii = 0; ii < 2; ii++)
3539
pcbs = pcbsBoth[ii];
3541
/* Copy the data across, decrement recChannels to make sure
3542
* the end of the buffer isn't overwritten
3544
while (pcbs && (channels[ii] > 0))
3546
if (pcbs->pbuffer && (pcbs->bufLen > 0))
3550
/* Do just a copy if no resampling should be done*/
3551
memcpy(poutBuf, pcbs->pbuffer,
3552
min(recSamples, pcbs->bufLen) * sizeof(SAMPLE));
3556
rerr = resample_execute(rec_resplan[recResPlanId],
3557
pcbs->pbuffer, pcbs->bufLen,
3558
poutBuf, recSamples);
3559
if (rerr != RESAMPLE_OK)
3561
mexWarnMsgTxt("Resampling returned an error. This should not happen.");
3567
poutBuf += recSamples;
3569
*pChanListBoth[ii]++ = pcbs->channel + 1; /* Add 1 for base 1 channels */
3572
pcbs = pcbs->pnextChanBuf;
3579
mxDestroyArray(plhs[1]);
3580
plhs[1] = mxPlayChanList;
3584
mxDestroyArray(plhs[22]);
3585
plhs[2] = mxRecChanList;
3326
3591
* FUNCTION: doGetRec(int nlhs, mxArray *plhs[],
3327
3592
* int nrhs, const mxArray *prhs[])