ITAStreamFunctionGenerator.cpp 5.61 KB
Newer Older
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
1
 #include "ITAStreamFunctionGenerator.h"
Jonas Stienen's avatar
Jonas Stienen committed
2 3 4 5 6 7 8 9 10 11 12 13 14 15

#include <ITAConstants.h>
#include <ITADataSourceRealization.h>
#include <ITANumericUtils.h>
#include <ITAFastMath.h>
#include <cmath>
#include <cassert>
#include <string>
#include <cstdlib>

#ifndef WIN32
#include <memory.h>
#endif

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29
ITAStreamFunctionGenerator::ITAStreamFunctionGenerator( unsigned int uiChannels, double dSamplerate, unsigned int uiBlocklength, int iSignalFunction, double dFrequency, float fAmplitude, bool bPeriodic )
	: ITADatasourceRealization( uiChannels, dSamplerate, uiBlocklength ),
	m_iFunction( iSignalFunction ),
	m_bPeriodic( bPeriodic ),
	m_bMuted( false ),
	m_fAmplitude( fAmplitude ),
	m_iSampleCount( 0 ),
	m_fPhase( 0.0f )
{
	assert( uiChannels > 0 );
	assert( dSamplerate > 0 );
	assert( uiBlocklength > 0 );

	SetFrequency( dFrequency );
Jonas Stienen's avatar
Jonas Stienen committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43
	Reset();
}

void ITAStreamFunctionGenerator::Reset()
{
	m_iSampleCount = 0;
	m_fPhase = 0.0f;
}

int ITAStreamFunctionGenerator::GetFunction() const
{
	return m_iFunction;
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
44
void ITAStreamFunctionGenerator::SetFunction( int iFunction )
Jonas Stienen's avatar
Jonas Stienen committed
45 46 47 48 49 50
{
	m_iFunction = iFunction;
}

double ITAStreamFunctionGenerator::GetFrequency() const
{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
51
	return m_dSampleRate / ( double ) m_iPeriodLengthSamples;
Jonas Stienen's avatar
Jonas Stienen committed
52 53
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
54
void ITAStreamFunctionGenerator::SetFrequency( double dFrequency )
Jonas Stienen's avatar
Jonas Stienen committed
55 56
{
	assert( dFrequency >= 0 );
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
57
	m_iPeriodLengthSamples = ( int ) round( m_dSampleRate / dFrequency );
Jonas Stienen's avatar
Jonas Stienen committed
58 59 60 61 62 63 64
}

int ITAStreamFunctionGenerator::GetPeriodAsSamples() const
{
	return m_iPeriodLengthSamples;
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
65
void ITAStreamFunctionGenerator::SetPeriodAsSamples( int iNumSamples )
Jonas Stienen's avatar
Jonas Stienen committed
66 67 68 69 70 71 72
{
	assert( iNumSamples >= 0 );
	m_iPeriodLengthSamples = iNumSamples;
}

double ITAStreamFunctionGenerator::GetPeriodAsTime() const
{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
73
	return ( double ) m_iPeriodLengthSamples / m_dSampleRate;
Jonas Stienen's avatar
Jonas Stienen committed
74 75
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
76
void ITAStreamFunctionGenerator::SetPeriodAsTime( double dPeriodLength )
Jonas Stienen's avatar
Jonas Stienen committed
77
{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
78
	m_iPeriodLengthSamples = ( int ) round( dPeriodLength * m_dSampleRate );
Jonas Stienen's avatar
Jonas Stienen committed
79 80 81 82 83 84 85
}

bool ITAStreamFunctionGenerator::IsPeriodic() const
{
	return m_bPeriodic;
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
86
void ITAStreamFunctionGenerator::SetPeriodic( bool bPeriodic )
Jonas Stienen's avatar
Jonas Stienen committed
87 88 89 90 91 92 93 94 95
{
	m_bPeriodic = bPeriodic;
}

bool ITAStreamFunctionGenerator::IsMuted() const
{
	return m_bMuted;
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
96
void ITAStreamFunctionGenerator::SetMuted( bool bMuted )
Jonas Stienen's avatar
Jonas Stienen committed
97 98 99 100 101 102 103 104 105
{
	m_bMuted = bMuted;
}

float ITAStreamFunctionGenerator::GetAmplitude() const
{
	return m_fAmplitude;
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
106
void ITAStreamFunctionGenerator::SetAmplitude( float fAmplitude )
Jonas Stienen's avatar
Jonas Stienen committed
107
{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
108
	m_fAmplitude = ( float ) fAmplitude;
Jonas Stienen's avatar
Jonas Stienen committed
109 110
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
111
void ITAStreamFunctionGenerator::ProcessStream( const ITAStreamInfo* )
Jonas Stienen's avatar
Jonas Stienen committed
112 113
{
	// Generate the next output samples
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
114 115
	float* pfOutputData = GetWritePointer( 0 );
	fm_zero( pfOutputData, m_uiBlocklength );
Jonas Stienen's avatar
Jonas Stienen committed
116 117 118 119

	// Variables
	int N = m_iPeriodLengthSamples;
	float a = m_fAmplitude;
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
120

Jonas Stienen's avatar
Jonas Stienen committed
121
	float omega;
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
122
	float gradient = a / ( float ) ( N - 1 );	// Steigung der Sgezahn und Dreieck
Jonas Stienen's avatar
Jonas Stienen committed
123 124
	int iZero;							// Offset bergang 1=>0 bei Rechteck
	int iNumSamples;					// Anzahl zu erzeugender Samples
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
125 126

	switch( m_iFunction ) {
Jonas Stienen's avatar
Jonas Stienen committed
127 128 129

	case SINE:

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
130 131 132
		omega = ITAConstants::TWO_PI_F / ( float ) N; // 2*pi/T

		iNumSamples = m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount );
Jonas Stienen's avatar
Jonas Stienen committed
133

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
134 135
		for( int i = 0; i < iNumSamples; i++ ) {
			pfOutputData[ i ] = a * sin( omega*i + m_fPhase );
Jonas Stienen's avatar
Jonas Stienen committed
136 137 138 139 140
		}

		m_fPhase = fmodf( iNumSamples*omega + m_fPhase, ITAConstants::TWO_PI_F );

		m_iSampleCount += iNumSamples;
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
141

Jonas Stienen's avatar
Jonas Stienen committed
142 143 144 145
		break;

	case TRIANGLE:

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
146
		iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
Jonas Stienen's avatar
Jonas Stienen committed
147

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
148 149 150
		for( int i = 0; i < iNumSamples; i++ )
		{
			float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
Jonas Stienen's avatar
Jonas Stienen committed
151

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
152
			pfOutputData[ i ] = x < N / 2 ? 2 * ( x*gradient ) : 2 * ( ( -x*gradient ) + a );
Jonas Stienen's avatar
Jonas Stienen committed
153 154 155
		}

		break;
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
156

Jonas Stienen's avatar
Jonas Stienen committed
157 158
	case SAWTOOTH:  // Sgezahn

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
159
		iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
Jonas Stienen's avatar
Jonas Stienen committed
160

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
161 162 163 164
		for( int i = 0; i < iNumSamples; i++ ) {

			float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
			pfOutputData[ i ] = a * ( x*gradient );
Jonas Stienen's avatar
Jonas Stienen committed
165 166 167
		}

		break;
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
168

Jonas Stienen's avatar
Jonas Stienen committed
169 170
	case RECTANGLE:

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
171 172 173
		// Position des Wechsels von 1 zu 0 innerhalb einer Periode
		iZero = ( int ) ( m_iPeriodLengthSamples / 2 );
		iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );
Jonas Stienen's avatar
Jonas Stienen committed
174

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
175 176 177 178 179 180 181
		for( int i = 0; i < iNumSamples; i++ )
		{
			// Position innerhalb einer Periodenlnge
			float x = fmodf( ( float ) m_iSampleCount++, ( float ) m_iPeriodLengthSamples );
			int iOffset = ( int ) roundf( x );
			pfOutputData[ i ] = ( iOffset < iZero ? a : 0 );
		}
Jonas Stienen's avatar
Jonas Stienen committed
182

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
183
		break;
Jonas Stienen's avatar
Jonas Stienen committed
184 185

	case DIRAC:
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
186 187 188 189 190 191 192 193 194 195 196

		iNumSamples = ( m_bPeriodic ? ( int ) m_uiBlocklength : ( std::min )( ( int ) m_uiBlocklength, m_iPeriodLengthSamples - m_iSampleCount ) );

		if( m_bPeriodic )
		{

			for( int i = 0; i < iNumSamples; i++ ) pfOutputData[ i ] = ( m_iSampleCount++ % N ? 0 : a );
		}
		else {
			pfOutputData[ 0 ] = ( m_iSampleCount == 0 ? a : 0 );
			for( int i = 1; i < iNumSamples; i++ ) pfOutputData[ i ] = 0;
Jonas Stienen's avatar
Jonas Stienen committed
197 198 199 200 201
			m_iSampleCount += iNumSamples;
		}

		break;

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
202 203 204 205 206
	case WHITE_NOISE:

		srand( 100 );
		for( unsigned int i = 0; i < m_uiBlocklength; i++ )
			pfOutputData[ i ] = a * ( float ) rand() / RAND_MAX;
Jonas Stienen's avatar
Jonas Stienen committed
207

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
208 209
		break;
		// ...
Jonas Stienen's avatar
Jonas Stienen committed
210 211 212

	default:
		// Case: Invalid signal function => Generate zeros
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
213 214
		for( unsigned int i = 0; i < m_uiBlocklength; i++ )
			pfOutputData[ i ] = 0;
Jonas Stienen's avatar
Jonas Stienen committed
215 216 217 218 219 220 221 222
	}

	/*
	 *  Since all output channels share the same data,
	 *  we calculate it just for the first channel and
	 *  then copy the data into all further channels.
	 */

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
223 224 225
	for( unsigned int c = 1; c < m_uiChannels; c++ )
		memcpy( GetWritePointer( c ), pfOutputData, m_uiBlocklength * sizeof( float ) );

Jonas Stienen's avatar
Jonas Stienen committed
226 227 228
	IncrementWritePointer();
}