/* Resample a signal vector * * The input vector is deallocated and the pointer returned with a vector * of any unconverted samples. */ signalVector *resmpl_sigvec(signalVector *hist, signalVector **vec, signalVector *lpf, double in_rate, double out_rate, int chunk_sz) { signalVector *resamp_vec; int num_chunks = (*vec)->size() / chunk_sz; /* Truncate to a chunk multiple */ signalVector trunc_vec(num_chunks * chunk_sz); (*vec)->segmentCopyTo(trunc_vec, 0, num_chunks * chunk_sz); /* Update sample buffer with remainder */ *vec = segment(*vec, trunc_vec.size(), (*vec)->size() - trunc_vec.size()); /* Add history and resample */ signalVector input_vec(*hist, trunc_vec); resamp_vec = polyphaseResampleVector(input_vec, in_rate, out_rate, lpf); /* Update history */ trunc_vec.segmentCopyTo(*hist, trunc_vec.size() - hist->size(), hist->size()); return resamp_vec; }
void RadioInterface::pullBuffer(void) { writingRadioLock.lock(); // These timestamps are in samples @ 400 kHz. while (readTimestamp > writeTimestamp - (TIMESTAMP) 2*OUTCHUNK) { LOG(DEEPDEBUG) << "waiting..." << readTimestamp << " " << writeTimestamp; wroteRadioSignal.wait(writingRadioLock); //wroteRadioSignal.wait(writingRadioLock,1); } writingRadioLock.unlock(); bool localUnderrun; // receive receiveVector short* shortVector = new short[OUTCHUNK*2]; int samplesRead = usrp->readSamples(shortVector,OUTCHUNK,&overrun,readTimestamp,&localUnderrun); underrun |= localUnderrun; readTimestamp += (TIMESTAMP) samplesRead; while (samplesRead < OUTCHUNK) { int oldSamplesRead = samplesRead; samplesRead += usrp->readSamples(shortVector+2*samplesRead, OUTCHUNK-samplesRead, &overrun, readTimestamp, &localUnderrun); underrun |= localUnderrun; readTimestamp += (TIMESTAMP) (samplesRead - oldSamplesRead); } signalVector *receiveVector = unUSRPifyVector(shortVector,samplesRead); delete []shortVector; if (!rcvLPF) { int P = INRATE; int Q = OUTRATE; float cutoffFreq = (P < Q) ? (1.0/(float) Q) : (1.0/(float) P); rcvLPF = createLPF(cutoffFreq,961,P); } signalVector *retVector = NULL; if (!rcvHistory) { rcvHistory = new signalVector(OUTHISTORY); rcvHistory->fill(0); } // resample received data to multiple of GSM symbol rate signalVector inputVector(*rcvHistory,*receiveVector); retVector = polyphaseResampleVector(inputVector, INRATE,OUTRATE,rcvLPF); // push sampled data to back of receive buffer signalVector *tmp = retVector; retVector = new signalVector(retVector->size()-INHISTORY); tmp->segmentCopyTo(*retVector,INHISTORY,tmp->size()-INHISTORY); delete tmp; LOG(DEEPDEBUG) << "converted " << receiveVector->size() << " radio samples into " << retVector->size() << " transceiver samples "; // update history of received data receiveVector->segmentCopyTo(*rcvHistory,receiveVector->size()-OUTHISTORY,OUTHISTORY); delete receiveVector; if (rcvBuffer) { signalVector *tmp = rcvBuffer; rcvBuffer = new signalVector(*tmp,*retVector); delete tmp; delete retVector; } else rcvBuffer = retVector; }
void RadioInterface::pushBuffer(void) { if (sendBuffer->size() < INCHUNK) { return; } int numChunks = sendBuffer->size()/INCHUNK; signalVector* truncatedBuffer = new signalVector(numChunks*INCHUNK); sendBuffer->segmentCopyTo(*truncatedBuffer,0,numChunks*INCHUNK); if (!sendLPF) { int P = OUTRATE; int Q = INRATE; float cutoffFreq = (P < Q) ? (1.0/(float) Q) : (1.0/(float) P); sendLPF = createLPF(cutoffFreq,651,P); } // resample data to USRP sample rate signalVector *inputVector = new signalVector(*sendHistory,*truncatedBuffer); signalVector *resampledVector = polyphaseResampleVector(*inputVector, OUTRATE, INRATE,sendLPF); delete inputVector; // Set transmit gain and power here. scaleVector(*resampledVector, usrp->fullScaleInputValue()); short *resampledVectorShort = USRPifyVector(*resampledVector); // start the USRP when we actually have data to send to the USRP. if (!started) { started = true; LOG(INFO) << "Starting USRP"; usrp->start(); LOG(DEBUG) << "USRP started"; usrp->updateAlignment(10000); usrp->updateAlignment(10000); } // send resampleVector writingRadioLock.lock(); int samplesWritten = usrp->writeSamples(resampledVectorShort+OUTHISTORY*2, (resampledVector->size()-OUTHISTORY), &underrun, writeTimestamp); //LOG(DEEPDEBUG) << "writeTimestamp: " << writeTimestamp << ", samplesWritten: " << samplesWritten; writeTimestamp += (TIMESTAMP) samplesWritten; wroteRadioSignal.signal(); writingRadioLock.unlock(); LOG(DEEPDEBUG) << "converted " << truncatedBuffer->size() << " transceiver samples into " << samplesWritten << " radio samples "; delete resampledVector; delete []resampledVectorShort; // update the history of sent data truncatedBuffer->segmentCopyTo(*sendHistory,truncatedBuffer->size()-INHISTORY, INHISTORY); // update the buffer, i.e. keep the samples we didn't send signalVector *tmp = sendBuffer; sendBuffer = new signalVector(sendBuffer->size()-truncatedBuffer->size()); tmp->segmentCopyTo(*sendBuffer,truncatedBuffer->size(), sendBuffer->size()); delete tmp; delete truncatedBuffer; }