📄 block.cpp
字号:
/*************************************************************************** block.cpp - The definition for the block ------------------- begin : 2002 authors : Linus Gasser emails : linus.gasser@epfl.ch***************************************************************************//*************************************************************************** Changes ------- date - name - description 02-12-19 - ineiti - begin **************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************//** * @short Holds the definition of a block */#include <qapplication.h>#include <qregexp.h>#include <iostream>#include <stdlib.h>#include <unistd.h>#include <math.h>#include "block.h"#include "swr_types.h"#define min(a,b) (a)<(b)?(a):(b)#define max(a,b) (a)>(b)?(a):(b)// this is the standard C++-way of using cout <<using namespace std;void Block::getSample( void *data, int i, double &re, double &im ){ switch ( sig_type ) { case SIG_U8: im = ( double ) ( ( U8* ) data ) [ i ]; break; case SIG_SYMBOL_S16: im = ( double ) ( ( SYMBOL_S16* ) data ) [ i ]; break; case SIG_DOUBLE: im = ( ( double* ) data ) [ i ]; break; case SIG_DOUBLE_COMPLEX: re = ( ( double_complex* ) data ) [ i ].real; im = ( ( double_complex* ) data ) [ i ].imag; break; case SIG_SYMBOL_COMPLEX: re = ( double ) ( ( SYMBOL_COMPLEX* ) data ) [ i ].real; im = ( double ) ( ( SYMBOL_COMPLEX* ) data ) [ i ].imag; break; case SIG_SYMBOL_COMPLEX_S32: re = ( double ) ( ( SYMBOL_COMPLEX_S32* ) data ) [ i ].real; im = ( double ) ( ( SYMBOL_COMPLEX_S32* ) data ) [ i ].imag; break; case SIG_QUAD_SYMBOL_ICS_AD: // To get the even channel, set this to 1.#define CHANNEL_EVEN 0 // The QUAD_SYMBOL_ICS_AD has 4 samples of the odd channel, then // 4 of the even, and so on. The following formula gives: // 0 1 2 3 8 9 10 11 16 17 18 19 // for CHANNEL_EVEN = 0, which corresponds to the odd samples of the // ICS-554-AD converters... i += i - ( i % 4 ) + CHANNEL_EVEN * 4; re = ( double ) ( ( SYMBOL_COMPLEX_S32* ) data ) [ i ].real; im = ( double ) ( ( SYMBOL_COMPLEX_S32* ) data ) [ i ].imag; break; case SIG_SYMBOL_MMX: re = ( double ) ( ( SYMBOL_MMX* ) data ) [ i ].w[ 0 ]; im = ( double ) ( ( SYMBOL_MMX* ) data ) [ i ].w[ 1 ]; break; case SIG_SAMPLE_S12: im = ( double ) ( ( SAMPLE_S12* ) data ) [ i ]; break; case SIG_S32: im = ( double ) ( ( S32* ) data ) [ i ]; break; default: im = 0; }}/** * The general way of making two vectors - x and y - and * initialising them with the data found in this block. * In order to have less points on the display and thus display * faster, "samples" may be smaller than "length". In this case, * "s" will be calculated so as to provide a 'smooth' interpolation * of the whole data-area. */int Block::Data( double **x_ret, double **y_ret, int samples, enum showType_e s_type ) { QByteArray d; void *data; int i; double step; double *x, *y; d = getData(); if ( !d ) { cout << "strange, couldn't get Data\n" << length << endl; return 0; } data = d.data(); // cout << "Got a length of " << d.size() << " expecting " << length << endl; if ( samples ){ samples = max( 0, ( int ) min( samples, ( int ) getNumOfSamples() ) ); } else { samples = getNumOfSamples(); } *x_ret = x = (double*) malloc( samples * sizeof( double ) ); *y_ret = y = (double*) malloc( samples * sizeof( double ) ); step = (double)getNumOfSamples() / samples; if ( step == 1. ){ // For fully resolution plot: for ( i = 0; i < samples; i++ ) { x[ i ] = i; getSample( data, i, x[ i ], y[ i ] ); } } else { /** * For interpolated plot two versions of interpolation exist: * - pick one sample every n * - calculate the mean of n samples * The first method is good for Complex plotting while the second is * better at anything else. * For the "pick one sample every n": * take 2 * step samples, calculate the max and min, and first put the max, * then the min. */ switch ( s_type ) { case show_real: case show_abs: case show_plot: case show_imag: for ( i = 0; i < samples; i+=2 ) { double re = i * step, im = 0., re_max = -1e100, re_min = 1e100, im_max = -1e100, im_min = 1e100; int s; // average over all s for ( s=(int)(i*step); s<(int)((i+2.)*step); s++ ){ getSample( data, s, re, im ); re_max = max( re_max, re ); im_max = max( im_max, im ); re_min = min( re_min, re ); im_min = min( im_min, im ); } x[ i ] = re_min; y[ i ] = im_min; x[i+1] = re_max; y[i+1] = im_max; } break; case show_complex: for ( i = 0; i < samples; i++ ) { x[ i ] = i * step; getSample( data, (int)x[ i ], x[ i ], y[ i ] ); } break; case show_fft: cout << "You shouldn't undersample an FFT\n"; for ( i = 0; i < samples; i++ ) { x[ i ] = i; getSample( data, (int)x[ i ], x[ i ], y[ i ] ); } break; } } return samples;}/** * returns this size */int Block::TypeSize() { return TypeSize( sig_type );}/** * more general function to return a certain type-size in bytes */int Block::TypeSize( swr_signal_type_t t ) { switch ( t ) { case SIG_U8: return 1; case SIG_SYMBOL_S16: return 2; case SIG_SYMBOL_COMPLEX: return 4; case SIG_SYMBOL_COMPLEX_S32: return 8; case SIG_QUAD_SYMBOL_ICS_AD: return 8 * 4 * 2; case SIG_SYMBOL_MMX: return 8; case SIG_SAMPLE_S12: return 2; case SIG_S32: return 4; case SIG_DOUBLE: return sizeof( double ); case SIG_DOUBLE_COMPLEX: return sizeof( double_complex ); default: return -1; }}int Block::getNumOfSamples(){ switch ( sig_type ){ case SIG_QUAD_SYMBOL_ICS_AD: // There are 4 samples in one QUAD_SYMBOL_ICS_AD return length * 4; default: return length; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -