mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-27 02:50:38 -04:00 
			
		
		
		
	Refactor SFFT.
This commit is contained in:
		
							parent
							
								
									1e77911e9c
								
							
						
					
					
						commit
						d1a833b43f
					
				| @ -67,7 +67,8 @@ private: | ||||
| public: | ||||
| 	sfft(int len); | ||||
| 	~sfft(); | ||||
| 	void run(const cmplx& input, cmplx *result); | ||||
| 	void run(const cmplx& input); | ||||
| 	void fetch(float *result); | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
| @ -36,6 +36,8 @@ LoRaDemod::LoRaDemod(SampleSink* sampleSink) : | ||||
| 	m_chirp = 0; | ||||
| 	m_angle = 0; | ||||
| 	m_bin = 0; | ||||
| 	m_result = 0; | ||||
| 	m_count = 0; | ||||
| 
 | ||||
| 	loraFilter = new sfft(LORA_SFFT_LEN); | ||||
| } | ||||
| @ -52,25 +54,28 @@ void LoRaDemod::configure(MessageQueue* messageQueue, Real Bandwidth) | ||||
| 	cmd->submit(messageQueue, this); | ||||
| } | ||||
| 
 | ||||
| // Detecting the header needs an sfft with the opposite rotation
 | ||||
| int  LoRaDemod::detect(Complex c) | ||||
| { | ||||
| 	int i, result; | ||||
| 	Real peak, mag; | ||||
| 	cmplx bins[LORA_SFFT_LEN]; | ||||
| 	int i; | ||||
| 	float peak; | ||||
| 	float mag[LORA_SFFT_LEN]; | ||||
| 
 | ||||
| 	// TODO: don`t need per-sample sliding FFT time resolution
 | ||||
| 	loraFilter->run(c, bins); | ||||
| 	peak = mag = 0; | ||||
| 	result = 0; | ||||
| 	loraFilter->run(c); | ||||
| 	if (++m_count & 31) | ||||
| 		return m_result; | ||||
| 
 | ||||
| 	// process spectrum every 32 samples
 | ||||
| 	loraFilter->fetch(mag); | ||||
| 	peak = 0.0f; | ||||
| 	m_result = 0; | ||||
| 	for (i = 0; i < LORA_SFFT_LEN; i++) { | ||||
| 		mag = bins[i].real() * bins[i].real() | ||||
| 			+ bins[i].imag() * bins[i].imag(); | ||||
| 		if (mag > peak) { | ||||
| 			peak = mag; | ||||
| 			result = i; | ||||
| 		if (mag[i] > peak) { | ||||
| 			peak = mag[i]; | ||||
| 			m_result = i; | ||||
| 		} | ||||
| 	} | ||||
| 	return result; | ||||
| 	return m_result; | ||||
| } | ||||
| 
 | ||||
| void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool pO) | ||||
| @ -91,7 +96,7 @@ void LoRaDemod::feed(SampleVector::const_iterator begin, SampleVector::const_ite | ||||
| 
 | ||||
| 			m_bin = (m_bin + newangle) & (LORA_SFFT_LEN - 1); | ||||
| 			Complex nangle(cos(M_PI*2*m_bin/LORA_SFFT_LEN),sin(M_PI*2*m_bin/LORA_SFFT_LEN)); | ||||
| 			m_sampleBuffer.push_back(Sample(nangle.real() * 1000, nangle.imag() * 1000)); | ||||
| 			m_sampleBuffer.push_back(Sample(nangle.real() * 500, nangle.imag() * 500)); | ||||
| 			m_sampleDistanceRemain += (Real)m_sampleRate / m_Bandwidth; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -71,6 +71,8 @@ private: | ||||
| 	int m_chirp; | ||||
| 	int m_angle; | ||||
| 	int m_bin; | ||||
| 	int m_result; | ||||
| 	int m_count; | ||||
| 
 | ||||
| 	sfft* loraFilter; | ||||
| 
 | ||||
|  | ||||
| @ -136,6 +136,8 @@ LoRaDemodGUI::LoRaDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : | ||||
| 	ui->glSpectrum->setDisplayWaterfall(true); | ||||
| 	ui->glSpectrum->setDisplayMaxHold(true); | ||||
| 
 | ||||
| 	setTitleColor(Qt::magenta); | ||||
| 
 | ||||
| 	m_channelMarker = new ChannelMarker(this); | ||||
| 	m_channelMarker->setColor(Qt::magenta); | ||||
| 	m_channelMarker->setBandwidth(7813); | ||||
|  | ||||
| @ -40,7 +40,7 @@ | ||||
|      </widget> | ||||
|     </item> | ||||
|     <item row="1" column="0"> | ||||
|      <widget class="QLabel" name="label"> | ||||
|      <widget class="QLabel" name="mabel"> | ||||
|       <property name="text"> | ||||
|        <string>Spreading</string> | ||||
|       </property> | ||||
|  | ||||
| @ -224,22 +224,24 @@ sfft::~sfft() | ||||
| // Sliding FFT, cmplx input, cmplx output
 | ||||
| // FFT is computed for each value from first to last
 | ||||
| // Values are not stable until more than "len" samples have been processed.
 | ||||
| // Copies the frequencies to a pointer.
 | ||||
| void sfft::run(const cmplx& input, cmplx *result) | ||||
| void sfft::run(const cmplx& input) | ||||
| { | ||||
| 	cmplx & de = delay[ptr]; | ||||
| 	const cmplx z( input.real() - k2 * de.real(), input.imag() - k2 * de.imag()); | ||||
| 	de = input; | ||||
| 
 | ||||
| 	++ptr ; | ||||
| 	if( ptr >= fftlen ) ptr = 0 ; | ||||
| 	if (++ptr >= fftlen) | ||||
| 		ptr = 0; | ||||
| 
 | ||||
| 	// It is more efficient to have vrot and bins very close to each other.
 | ||||
| 	for(	vrot_bins_pair | ||||
| 			*itr = vrot_bins + first, | ||||
| 			*end = vrot_bins + last ; | ||||
| 		itr != end ; | ||||
| 		++itr, result++ ) { | ||||
| 		*result = itr->bins = (itr->bins + z) * itr->vrot; | ||||
| 	} | ||||
| 	for (vrot_bins_pair *itr = vrot_bins + first, *end = vrot_bins + last; itr != end ; ++itr) | ||||
| 		itr->bins = (itr->bins + z) * itr->vrot; | ||||
| } | ||||
| 
 | ||||
| // Copies the frequencies to a pointer.
 | ||||
| void sfft::fetch(float *result) | ||||
| { | ||||
| 	for (vrot_bins_pair *itr = vrot_bins, *end = vrot_bins + last;  itr != end; ++itr, ++result) | ||||
| 		*result = itr->bins.real() * itr->bins.real() | ||||
|                         + itr->bins.imag() * itr->bins.imag(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user