Exemple #1
0
/* Initialize resampling signal vectors */
void init_resampler(signalVector **lpf,
	   	    signalVector **buf,
		    signalVector **hist,
		    int tx)
{
	int P, Q, taps, hist_len;
	float cutoff_freq;

	if (tx) {
		LOG(INFO) << "Initializing Tx resampler";
		P = OUTRATE;
		Q = INRATE;
		taps = 651;
		hist_len = INHISTORY;
	} else {
		LOG(INFO) << "Initializing Rx resampler";
		P = INRATE;
		Q = OUTRATE;
		taps = 961;
		hist_len = OUTHISTORY;
	}

	if (!*lpf) {
		cutoff_freq = (P < Q) ? (1.0/(float) Q) : (1.0/(float) P);
		*lpf = createLPF(cutoff_freq, taps, P);
	}

	if (!*buf) {
		*buf = new signalVector();
	}

	if (!*hist);
		*hist = new signalVector(hist_len);
}
// assumes filter group delay is 0.5*(length of filter)
signalVector *polyphaseResampleVector(signalVector &wVector,
				      int P, int Q,
				      signalVector *LPF)

{
 
  bool deleteLPF = false;
 
  if (LPF==NULL) {
    float cutoffFreq = (P < Q) ? (1.0/(float) Q) : (1.0/(float) P);
    LPF = createLPF(cutoffFreq/3.0,100*POLYPHASESPAN+1,Q);
    deleteLPF = true;
  }

  signalVector *resampledVector = new signalVector((int) ceil(wVector.size()*(float) P / (float) Q));
  resampledVector->fill(0);
  resampledVector->isRealOnly(wVector.isRealOnly());
  signalVector::iterator newItr = resampledVector->begin();

  //FIXME: need to update for real-only vectors
  int outputIx = (LPF->size()-1)/2/Q; //((P > Q) ? P : Q); 
  while (newItr < resampledVector->end()) {
    int outputBranch = (outputIx*Q) % P; 
    int inputOffset = (outputIx*Q - outputBranch)/P;
    signalVector::const_iterator inputItr = wVector.begin() + inputOffset;
    signalVector::const_iterator filtItr  = LPF->begin() + outputBranch;
    while (inputItr >= wVector.end()) {
      inputItr--;
      filtItr+=P;
    }
    complex sum = 0.0;
    if (!LPF->isRealOnly()) {
      while ( (inputItr >= wVector.begin()) && (filtItr < LPF->end()) ) {
	sum += (*inputItr)*(*filtItr);
	inputItr--;
	filtItr += P;
      }
    }
    else {
      while ( (inputItr >= wVector.begin()) && (filtItr < LPF->end()) ) {
	sum += (*inputItr)*(filtItr->real());
	inputItr--;
	filtItr += P;
      }
    }
    *newItr = sum;
    newItr++;
    outputIx++;
  }
      
  if (deleteLPF) delete LPF;

  return resampledVector;
}
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;

}