mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-10-31 13:00:26 -04:00 
			
		
		
		
	
						commit
						4ee2eb532a
					
				| @ -1938,6 +1938,10 @@ void FT8::soft_decode(const FFTEngine::ffts_t &c79, float ll174[]) | |||||||
| //
 | //
 | ||||||
| void FT8::soft_decode_mags(FT8Params& params, const std::vector<std::vector<float>>& mags_, int nbSymbolBits, float ll174[]) | void FT8::soft_decode_mags(FT8Params& params, const std::vector<std::vector<float>>& mags_, int nbSymbolBits, float ll174[]) | ||||||
| { | { | ||||||
|  |     if ((nbSymbolBits > 16) || (nbSymbolBits < 1)) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     std::vector<std::vector<float>> mags = convert_to_snr_gen(params, nbSymbolBits, mags_); |     std::vector<std::vector<float>> mags = convert_to_snr_gen(params, nbSymbolBits, mags_); | ||||||
|     // statistics to decide soft probabilities.
 |     // statistics to decide soft probabilities.
 | ||||||
|     // distribution of strongest tones, and
 |     // distribution of strongest tones, and
 | ||||||
| @ -1949,8 +1953,8 @@ void FT8::soft_decode_mags(FT8Params& params, const std::vector<std::vector<floa | |||||||
|     int lli = 0; |     int lli = 0; | ||||||
|     int zoX = 1<<(nbSymbolBits-1); |     int zoX = 1<<(nbSymbolBits-1); | ||||||
|     int zoY = nbSymbolBits; |     int zoY = nbSymbolBits; | ||||||
|     int *zeroi = new int[zoX*zoY]; |     std::vector<int> zeroi(zoX*zoY); | ||||||
|     int *onei = new int[zoX*zoY]; |     std::vector<int> onei(zoX*zoY); | ||||||
| 
 | 
 | ||||||
|     for (int biti = 0; biti < nbSymbolBits; biti++) |     for (int biti = 0; biti < nbSymbolBits; biti++) | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -370,9 +370,9 @@ void LDPC::ft8_crc(int msg1[], int msglen, int out[14]) | |||||||
|     // the new FT8 polynomial for 14-bit CRC, 0x2757,
 |     // the new FT8 polynomial for 14-bit CRC, 0x2757,
 | ||||||
|     // with leading 1 bit.
 |     // with leading 1 bit.
 | ||||||
|     int div[] = {1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1}; |     int div[] = {1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1}; | ||||||
| 
 |  | ||||||
|     // append 14 zeros.
 |     // append 14 zeros.
 | ||||||
|     int *msg = (int *)malloc(sizeof(int) * (msglen + 14)); |     int *msg = (int *)malloc(sizeof(int) * (msglen + 14)); | ||||||
|  | 
 | ||||||
|     for (int i = 0; i < msglen + 14; i++) |     for (int i = 0; i < msglen + 14; i++) | ||||||
|     { |     { | ||||||
|         if (i < msglen) |         if (i < msglen) | ||||||
| @ -396,7 +396,7 @@ void LDPC::ft8_crc(int msg1[], int msglen, int out[14]) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     for (int i = 0; i < 14; i++) |     for (int i = 0; i < msglen + 14; i++) | ||||||
|     { |     { | ||||||
|         out[i] = msg[msglen + i]; |         out[i] = msg[msglen + i]; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -90,8 +90,8 @@ private: | |||||||
|     // Top area of each buffer is not used by writer, as it's used by the reader
 |     // Top area of each buffer is not used by writer, as it's used by the reader
 | ||||||
|     // for copying the last few samples of the previous buffer, so it can
 |     // for copying the last few samples of the previous buffer, so it can
 | ||||||
|     // be processed contiguously
 |     // be processed contiguously
 | ||||||
|     const int m_buffers = 3; |     static const int m_buffers = 3; | ||||||
|     const int m_bufferSize = 200000; |     static const int m_bufferSize = 200000; | ||||||
|     Real *m_sampleBuffer[3];            //!< Each buffer is m_bufferSize samples
 |     Real *m_sampleBuffer[3];            //!< Each buffer is m_bufferSize samples
 | ||||||
|     QSemaphore m_bufferWrite[3];        //!< Semaphore to control write access to the buffers
 |     QSemaphore m_bufferWrite[3];        //!< Semaphore to control write access to the buffers
 | ||||||
|     QSemaphore m_bufferRead[3];         //!< Semaphore to control read access from the buffers
 |     QSemaphore m_bufferRead[3];         //!< Semaphore to control read access from the buffers
 | ||||||
|  | |||||||
| @ -30,9 +30,11 @@ namespace ldpctool { | |||||||
| template <typename TYPE> | template <typename TYPE> | ||||||
| class LDPCEncoder | class LDPCEncoder | ||||||
| { | { | ||||||
| 	LDPCInterface *ldpc; | 	LDPCInterface *ldpc = nullptr; | ||||||
| 	int N, K, R; | 	int N = 2; | ||||||
| 	bool initialized; |     int K = 1; | ||||||
|  |     int R = 1; | ||||||
|  | 	bool initialized = false; | ||||||
| 
 | 
 | ||||||
| 	TYPE one() | 	TYPE one() | ||||||
| 	{ | 	{ | ||||||
| @ -43,9 +45,10 @@ class LDPCEncoder | |||||||
| 		return b < TYPE(0) ? -a : b > TYPE(0) ? a : TYPE(0); | 		return b < TYPE(0) ? -a : b > TYPE(0) ? a : TYPE(0); | ||||||
| 	} | 	} | ||||||
| public: | public: | ||||||
| 	LDPCEncoder() : initialized(false) | 	LDPCEncoder() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	void init(LDPCInterface *it) | 	void init(LDPCInterface *it) | ||||||
| 	{ | 	{ | ||||||
| 		if (initialized) | 		if (initialized) | ||||||
|  | |||||||
| @ -77,18 +77,29 @@ public: | |||||||
| template <typename TYPE, typename ALG> | template <typename TYPE, typename ALG> | ||||||
| class LDPCDecoder | class LDPCDecoder | ||||||
| { | { | ||||||
| 	TYPE *bnl, *pty, *inp, *out; | private: | ||||||
| 	uint16_t *pos; | 	TYPE *bnl = nullptr; | ||||||
| 	uint8_t *cnc; | 	TYPE *pty = nullptr; | ||||||
|  | 	TYPE *inp = nullptr; | ||||||
|  | 	TYPE *out = nullptr; | ||||||
|  | 	uint16_t *pos  = nullptr; | ||||||
|  | 	uint8_t *cnc  = nullptr; | ||||||
| 	ALG alg; | 	ALG alg; | ||||||
| 	int M, N, K, R, q, CNL, LT; | 	int M = 0; | ||||||
| 	bool initialized; | 	int N = 0; | ||||||
|  | 	int K = 0; | ||||||
|  | 	int R = 0; | ||||||
|  | 	int q = 0; | ||||||
|  | 	int CNL = 0; | ||||||
|  | 	int LT = 0; | ||||||
|  | 	bool initialized = false; | ||||||
| 
 | 
 | ||||||
| 	void reset() | 	void reset() | ||||||
| 	{ | 	{ | ||||||
| 		for (int i = 0; i < LT; ++i) | 		for (int i = 0; i < LT; ++i) | ||||||
| 			bnl[i] = alg.zero(); | 			bnl[i] = alg.zero(); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	bool bad(TYPE *data, TYPE *parity, int blocks) | 	bool bad(TYPE *data, TYPE *parity, int blocks) | ||||||
| 	{ | 	{ | ||||||
| 		for (int i = 0; i < q; ++i) { | 		for (int i = 0; i < q; ++i) { | ||||||
| @ -107,6 +118,7 @@ class LDPCDecoder | |||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	void update(TYPE *data, TYPE *parity) | 	void update(TYPE *data, TYPE *parity) | ||||||
| 	{ | 	{ | ||||||
| 		TYPE *bl = bnl; | 		TYPE *bl = bnl; | ||||||
| @ -135,10 +147,12 @@ class LDPCDecoder | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| public: | public: | ||||||
| 	LDPCDecoder() : initialized(false) | 	LDPCDecoder() | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	void init(LDPCInterface *it) | 	void init(LDPCInterface *it) | ||||||
| 	{ | 	{ | ||||||
| 		if (initialized) { | 		if (initialized) { | ||||||
|  | |||||||
| @ -124,16 +124,18 @@ int main(int argc, char **argv) | |||||||
| 
 | 
 | ||||||
| 	// DVB-S2 MODCOD definitions
 | 	// DVB-S2 MODCOD definitions
 | ||||||
| 	static const char *mc_tabnames[2][32] = { // [shortframes][modcod]
 | 	static const char *mc_tabnames[2][32] = { // [shortframes][modcod]
 | ||||||
| 											 {// Normal frames
 |         {// Normal frames
 | ||||||
| 											  0, "B1", "B2", "B3", "B4", "B5", "B6", "B7", |             nullptr, "B1", "B2", "B3", "B4", "B5", "B6", "B7", | ||||||
| 											  "B8", "B9", "B10", "B11", "B5", "B6", "B7", "B9", |             "B8", "B9", "B10", "B11", "B5", "B6", "B7", "B9", | ||||||
| 											  "B10", "B11", "B6", "B7", "B8", "B9", "B10", "B11", |             "B10", "B11", "B6", "B7", "B8", "B9", "B10", "B11", | ||||||
| 											  "B7", "B8", "B8", "B10", "B11", 0, 0, 0}, |             "B7", "B8", "B8", "B10", "B11", nullptr, nullptr, nullptr | ||||||
| 											 {// Short frames
 |         }, | ||||||
| 											  0, "C1", "C2", "C3", "C4", "C5", "C6", "C7", |         {// Short frames
 | ||||||
| 											  "C8", "C9", "C10", 0, "C5", "C6", "C7", "C9", |             nullptr, "C1", "C2", "C3", "C4", "C5", "C6", "C7", | ||||||
| 											  "C10", 0, "C6", "C7", "C8", "C9", "C10", 0, |             "C8", "C9", "C10", nullptr, "C5", "C6", "C7", "C9", | ||||||
| 											  "C7", "C8", "C8", "C10", 0, 0, 0, 0}}; |             "C10", nullptr, "C6", "C7", "C8", "C9", "C10", nullptr, | ||||||
|  |             "C7", "C8", "C8", "C10", nullptr, nullptr, nullptr, nullptr | ||||||
|  |     }}; | ||||||
| 
 | 
 | ||||||
| 	const char *tabname = mc_tabnames[shortframes][modcod]; | 	const char *tabname = mc_tabnames[shortframes][modcod]; | ||||||
| 	if (!tabname) | 	if (!tabname) | ||||||
| @ -188,8 +190,16 @@ int main(int argc, char **argv) | |||||||
| 			int blocks = j + ldpctool::SIMD_WIDTH > BLOCKS ? BLOCKS - j : ldpctool::SIMD_WIDTH; | 			int blocks = j + ldpctool::SIMD_WIDTH > BLOCKS ? BLOCKS - j : ldpctool::SIMD_WIDTH; | ||||||
| 
 | 
 | ||||||
| 			for (int n = 0; n < blocks; ++n) | 			for (int n = 0; n < blocks; ++n) | ||||||
|  |             { | ||||||
| 				for (int i = 0; i < CODE_LEN; ++i) | 				for (int i = 0; i < CODE_LEN; ++i) | ||||||
|  |                 { | ||||||
|  |                     if (((j + n) * CODE_LEN + i) >= BLOCKS * CODE_LEN) { | ||||||
|  |                         break; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
| 					reinterpret_cast<ldpctool::code_type *>(simd + i)[n] = code[(j + n) * CODE_LEN + i]; | 					reinterpret_cast<ldpctool::code_type *>(simd + i)[n] = code[(j + n) * CODE_LEN + i]; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
| 			int count = decode(simd, simd + DATA_LEN, max_trials, blocks); | 			int count = decode(simd, simd + DATA_LEN, max_trials, blocks); | ||||||
| 			num_decodes++; | 			num_decodes++; | ||||||
|  | |||||||
| @ -155,14 +155,12 @@ RadioAstronomy::~RadioAstronomy() | |||||||
|     m_deviceAPI->removeChannelSinkAPI(this); |     m_deviceAPI->removeChannelSinkAPI(this); | ||||||
|     m_deviceAPI->removeChannelSink(this); |     m_deviceAPI->removeChannelSink(this); | ||||||
| 
 | 
 | ||||||
|     if (m_basebandSink->isRunning()) { |     if ((m_basebandSink->isRunning()) || (m_worker->isRunning())) { | ||||||
|         stop(); |         stop(); | ||||||
|     } |     } | ||||||
|     delete m_basebandSink; | 
 | ||||||
|     if (m_worker->isRunning()) { |     m_worker->deleteLater(); | ||||||
|         stop(); |     m_basebandSink->deleteLater(); | ||||||
|     } |  | ||||||
|     delete m_worker; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RadioAstronomy::setDeviceAPI(DeviceAPI *deviceAPI) | void RadioAstronomy::setDeviceAPI(DeviceAPI *deviceAPI) | ||||||
|  | |||||||
| @ -50,10 +50,10 @@ struct IEEE_802_15_4_MacFrame | |||||||
|     uint16_t m_frameControl; |     uint16_t m_frameControl; | ||||||
|     uint8_t m_sequenceNumber; |     uint8_t m_sequenceNumber; | ||||||
|     uint16_t m_destPANID; |     uint16_t m_destPANID; | ||||||
|     uint16_t m_destShortAddress; |     uint16_t m_destShortAddress = 0; | ||||||
|     ieee_802_15_4_address m_destAddress; |     ieee_802_15_4_address m_destAddress; | ||||||
|     uint16_t m_sourcePANID; |     uint16_t m_sourcePANID; | ||||||
|     uint16_t m_sourceShortAddress; |     uint16_t m_sourceShortAddress = 0; | ||||||
|     ieee_802_15_4_address m_sourceAddress; |     ieee_802_15_4_address m_sourceAddress; | ||||||
|     uint8_t m_payload[IEEE_802_15_4_MAC_PAYLOAD_MAX_LENGTH]; |     uint8_t m_payload[IEEE_802_15_4_MAC_PAYLOAD_MAX_LENGTH]; | ||||||
|     uint8_t m_payloadLength; |     uint8_t m_payloadLength; | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ except ImportError: | |||||||
|     import _thread as thread |     import _thread as thread | ||||||
| import time | import time | ||||||
| 
 | 
 | ||||||
| from datetime import datetime | from datetime import datetime, timezone | ||||||
| from optparse import OptionParser | from optparse import OptionParser | ||||||
| 
 | 
 | ||||||
| import sdrangel | import sdrangel | ||||||
| @ -50,7 +50,7 @@ class SuperScannerAPIError(SuperScannerError): | |||||||
| 
 | 
 | ||||||
| # ====================================================================== | # ====================================================================== | ||||||
| def log_with_timestamp(message): | def log_with_timestamp(message): | ||||||
|     t = datetime.utcnow() |     t = datetime.now(timezone.utc) | ||||||
|     print(f'{t.isoformat()} {message}') |     print(f'{t.isoformat()} {message}') | ||||||
| 
 | 
 | ||||||
| # ====================================================================== | # ====================================================================== | ||||||
|  | |||||||
| @ -218,7 +218,7 @@ bool SigMFFileRecord::stopRecording() | |||||||
| { | { | ||||||
|     if (m_recordOn) |     if (m_recordOn) | ||||||
|     { |     { | ||||||
|       	qDebug("SigMFFileRecord::stopRecording: file previous capture"); |         qDebug("SigMFFileRecord::stopRecording: file previous capture"); | ||||||
|         makeCapture(); |         makeCapture(); | ||||||
|         m_recordOn = false; |         m_recordOn = false; | ||||||
|         if (m_sampleFile.error()) |         if (m_sampleFile.error()) | ||||||
|  | |||||||
| @ -370,7 +370,13 @@ void WFIR::WindowData(double *Data, int N, TWindowType WindowType, double Alpha, | |||||||
|     if (WindowType != wtKAISER && WindowType != wtFLATTOP) |     if (WindowType != wtKAISER && WindowType != wtFLATTOP) | ||||||
|     { |     { | ||||||
|         for (j = M / 2; j < N - M / 2; j++) |         for (j = M / 2; j < N - M / 2; j++) | ||||||
|  |         { | ||||||
|  |             if (j >= N + 2) { | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             WinCoeff[j] = 1.0; |             WinCoeff[j] = 1.0; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // This will set the gain of the window to 1. Only the Flattop window has unity gain by design.
 |     // This will set the gain of the window to 1. Only the Flattop window has unity gain by design.
 | ||||||
|  | |||||||
| @ -117,7 +117,6 @@ void CFCOMP::calc_comp (CFCOMP *a) | |||||||
|         a->G[i] = sary[3 * i + 1]; |         a->G[i] = sary[3 * i + 1]; | ||||||
|         a->E[i] = sary[3 * i + 2]; |         a->E[i] = sary[3 * i + 2]; | ||||||
|     } |     } | ||||||
|     delete[] (sary); |  | ||||||
|     a->fp[0] = 0.0; |     a->fp[0] = 0.0; | ||||||
|     a->fp[a->nfreqs + 1] = fmax; |     a->fp[a->nfreqs + 1] = fmax; | ||||||
|     a->gp[0] = a->G[0]; |     a->gp[0] = a->G[0]; | ||||||
|  | |||||||
| @ -230,7 +230,7 @@ void EMNR::interpM (double* res, double x, int nvals, double* xvals, double* yva | |||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         int idx = 0; |         int idx = 1; | ||||||
|         double xllow, xlhigh, frac; |         double xllow, xlhigh, frac; | ||||||
| 
 | 
 | ||||||
|         while ((x >= xvals[idx]) && (idx < nvals - 1)) |         while ((x >= xvals[idx]) && (idx < nvals - 1)) | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								wdsp/fir.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								wdsp/fir.cpp
									
									
									
									
									
								
							| @ -317,10 +317,15 @@ float *FIR::fir_read (int N, const char *filename, int rtype, float scale) | |||||||
| 
 | 
 | ||||||
| void FIR::analytic (int N, float* in, float* out) | void FIR::analytic (int N, float* in, float* out) | ||||||
| { | { | ||||||
|  |     if (N < 1) { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     int i; |     int i; | ||||||
|     double inv_N = 1.0 / (double) N; |     double inv_N = 1.0 / (double) N; | ||||||
|     double two_inv_N = 2.0 * inv_N; |     double two_inv_N = 2.0 * inv_N; | ||||||
|     float* x = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
 |     float* x = new float[N * 2]; // (float *) malloc0 (N * sizeof (complex));
 | ||||||
|  | 
 | ||||||
|     fftwf_plan pfor = fftwf_plan_dft_1d ( |     fftwf_plan pfor = fftwf_plan_dft_1d ( | ||||||
|         N, |         N, | ||||||
|         (fftwf_complex *) in, |         (fftwf_complex *) in, | ||||||
| @ -328,6 +333,7 @@ void FIR::analytic (int N, float* in, float* out) | |||||||
|         FFTW_FORWARD, |         FFTW_FORWARD, | ||||||
|         FFTW_PATIENT |         FFTW_PATIENT | ||||||
|     ); |     ); | ||||||
|  | 
 | ||||||
|     fftwf_plan prev = fftwf_plan_dft_1d ( |     fftwf_plan prev = fftwf_plan_dft_1d ( | ||||||
|         N, |         N, | ||||||
|         (fftwf_complex *) x, |         (fftwf_complex *) x, | ||||||
| @ -335,20 +341,24 @@ void FIR::analytic (int N, float* in, float* out) | |||||||
|         FFTW_BACKWARD, |         FFTW_BACKWARD, | ||||||
|         FFTW_PATIENT |         FFTW_PATIENT | ||||||
|     ); |     ); | ||||||
|  | 
 | ||||||
|     fftwf_execute (pfor); |     fftwf_execute (pfor); | ||||||
|     x[0] *= inv_N; |     x[0] *= inv_N; | ||||||
|     x[1] *= inv_N; |     x[1] *= inv_N; | ||||||
|  | 
 | ||||||
|     for (i = 1; i < N / 2; i++) |     for (i = 1; i < N / 2; i++) | ||||||
|     { |     { | ||||||
|         x[2 * i + 0] *= two_inv_N; |         x[2 * i + 0] *= two_inv_N; | ||||||
|         x[2 * i + 1] *= two_inv_N; |         x[2 * i + 1] *= two_inv_N; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     x[N + 0] *= inv_N; |     x[N + 0] *= inv_N; | ||||||
|     x[N + 1] *= inv_N; |     x[N + 1] *= inv_N; | ||||||
|     memset (&x[N + 2], 0, (N - 2) * sizeof (float)); |     memset (&x[N + 2], 0, (N - 2) * sizeof (float)); | ||||||
|     fftwf_execute (prev); |     fftwf_execute (prev); | ||||||
|     fftwf_destroy_plan (prev); |     fftwf_destroy_plan (prev); | ||||||
|     fftwf_destroy_plan (pfor); |     fftwf_destroy_plan (pfor); | ||||||
|  | 
 | ||||||
|     delete[] x; |     delete[] x; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -60,8 +60,8 @@ void RESAMPLE::calc_resample (RESAMPLE *a) | |||||||
|     a->L = a->out_rate / x; |     a->L = a->out_rate / x; | ||||||
|     a->M = a->in_rate / x; |     a->M = a->in_rate / x; | ||||||
| 
 | 
 | ||||||
|     a->L <= 0 ? 1 : a->L; |     a->L = a->L <= 0 ? 1 : a->L; | ||||||
|     a->M <= 0 ? 1 : a->M; |     a->M = a->M <= 0 ? 1 : a->M; | ||||||
| 
 | 
 | ||||||
|     if (a->in_rate < a->out_rate) |     if (a->in_rate < a->out_rate) | ||||||
|         min_rate = a->in_rate; |         min_rate = a->in_rate; | ||||||
|  | |||||||
| @ -64,8 +64,8 @@ RESAMPLEF* RESAMPLEF::create_resampleF ( int run, int size, float* in, float* ou | |||||||
|     a->L = out_rate / x; |     a->L = out_rate / x; | ||||||
|     a->M = in_rate / x; |     a->M = in_rate / x; | ||||||
| 
 | 
 | ||||||
|     a->L <= 0 ? 1 : a->L; |     a->L = a->L <= 0 ? 1 : a->L; | ||||||
|     a->M <= 0 ? 1 : a->M; |     a->M = a->M <= 0 ? 1 : a->M; | ||||||
| 
 | 
 | ||||||
|     if (in_rate < out_rate) |     if (in_rate < out_rate) | ||||||
|         min_rate = in_rate; |         min_rate = in_rate; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user