void RadioInterface::driveReceiveRadio() { if (!mOn) return; if (mReceiveFIFO.size() > 8) return; pullBuffer(); GSM::Time rcvClock = mClock.get(); rcvClock.decTN(receiveOffset); unsigned tN = rcvClock.TN(); int rcvSz = rcvCursor/2; int readSz = 0; const int symbolsPerSlot = gSlotLen + 8; // while there's enough data in receive buffer, form received // GSM bursts and pass up to Transceiver // Using the 157-156-156-156 symbols per timeslot format. while (rcvSz > (symbolsPerSlot + (tN % 4 == 0))*samplesPerSymbol) { signalVector rxVector((symbolsPerSlot + (tN % 4 == 0)*samplesPerSymbol)); unUSRPifyVector(rcvBuffer+readSz*2,rxVector); GSM::Time tmpTime = rcvClock; if (rcvClock.FN() >= 0) { LOG(DEEPDEBUG) << "FN: " << rcvClock.FN(); radioVector* rxBurst = new radioVector(rxVector,tmpTime); mReceiveFIFO.put(rxBurst); } mClock.incTN(); rcvClock.incTN(); //if (mReceiveFIFO.size() >= 16) mReceiveFIFO.wait(8); LOG(DEBUG) << "receiveFIFO: wrote radio vector at time: " << mClock.get() << ", new size: " << mReceiveFIFO.size() ; readSz += (symbolsPerSlot+(tN % 4 == 0))*samplesPerSymbol; rcvSz -= (symbolsPerSlot+(tN % 4 == 0))*samplesPerSymbol; tN = rcvClock.TN(); } if (readSz > 0) { memcpy(rcvBuffer,rcvBuffer+2*readSz,sizeof(short)*2*(rcvCursor-readSz)); rcvCursor = rcvCursor-2*readSz; } }
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; }