ITASampleBuffer.h 11 KB
Newer Older
Jonas Stienen's avatar
Jonas Stienen committed
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 * ----------------------------------------------------------------
 *
 *		ITA core libs
 *		(c) Copyright Institute of Technical Acoustics (ITA)
 *		RWTH Aachen University, Germany, 2015-2016
 *
 * ----------------------------------------------------------------
 *				    ____  __________  _______
 *				   //  / //__   ___/ //  _   |
 *				  //  /    //  /    //  /_|  |
 *				 //  /    //  /    //  ___   |
 *				//__/    //__/    //__/   |__|
 *
 * ----------------------------------------------------------------
 *
 */
Jonas Stienen's avatar
Jonas Stienen committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

#ifndef INCLUDE_WATCHER_ITA_SAMPLE_BUFFER
#define INCLUDE_WATCHER_ITA_SAMPLE_BUFFER

// ITABase
#include <ITABaseDefinitions.h>

// STL
#include <string>

// Forwards
class ITASampleFrame;

//! Buffer for a field of audio samples of type 32-bit floating point
/**
  *
  */
class ITA_BASE_API ITASampleBuffer
{
public:
	ITASampleBuffer();

	//! Create sample buffer of certain size
	/**
	  * \param iLength	Length (size) of buffer in samples
	  */
44
	explicit ITASampleBuffer( int iLength, bool bZeroInit = true );
Jonas Stienen's avatar
Jonas Stienen committed
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

	//! Copy constructor as pointer
	/**
	 * \param pSource Pointer to source buffer
	 */
	ITASampleBuffer( const ITASampleBuffer* pSource );

	//! Copy constructor as reference
	/**
	* \param pbSource Reference to source buffer
	*/
	ITASampleBuffer( const ITASampleBuffer& sbSource );

	virtual ~ITASampleBuffer();

	bool IsEmpty() const;

	//! Deprecated
63 64 65 66
	inline int length()
	{ 
		return GetLength();
	};
Jonas Stienen's avatar
Jonas Stienen committed
67 68 69 70 71

	//! Length (size) of buffer (number of samples)
	int GetLength() const;

	//! Deprecated
72 73 74 75 76 77 78 79 80
	inline const float* data() const
	{
		return GetData();
	};

	inline float* data()
	{
		return GetData();
	};
Jonas Stienen's avatar
Jonas Stienen committed
81 82 83 84 85 86 87 88 89 90

	//! Data pointer read-only
	const float* GetData() const;

	//! Data pointer
	float* GetData();

	//! Initialize
	/**
	 * (Re-)Initialize a sample buffer
91 92 93
	 *
	 * \param iLength	   Number of new samples
	 * \param bZeroInit	   Init with zeros
Jonas Stienen's avatar
Jonas Stienen committed
94
	 */
95
	void Init( int iLength, bool bZeroInit = true );
Jonas Stienen's avatar
Jonas Stienen committed
96 97 98 99 100 101 102 103 104 105 106 107 108

	//! Free allocated samples
	void Free();

	//! Sets all buffer samples to given value
	void Fill( float fValue );

	//! Sets defined samples to given value
	/**
	 * \param iOffset Startindex
	 * \param iCount  Anzahl Samples
	 * \param fFloat  Wert
	 */
109
	void Fill( int iOffset, int iCount, float fValue );
Jonas Stienen's avatar
Jonas Stienen committed
110 111 112 113 114

	//! Sets all samples to zero
	void Zero();

	//! Sets given samples to zero
115
	void Zero( int iOffset, int iCount );
Jonas Stienen's avatar
Jonas Stienen committed
116 117 118 119 120 121 122 123

	//! Sets a Cronecker-Delta function (diskrete Dirac impulse)
	void Identity();

	//! Fade ind or fade out
	/**
	 * Fades in sample region [iOffset, iOffset+iCount] using given fading function
	 */
124
	void Fade( int iOffset, int iCount, int iFadeDirection, int iFadeFunction );
Jonas Stienen's avatar
Jonas Stienen committed
125 126 127 128 129 130 131 132 133 134 135

	//! Crossfade
	/**
	 * Fhrt eine Kreuzblende von angebenen Puffer in diesen Puffer durch.
	 *
	 * Fr den Modus CROSSFADE_FROM gilt:
	 *
	 * Zunchst werden iOffset Samples vom angebenen Puffer kopiert.
	 * Danach werden iCount Samples zwischen den beiden Puffern kreuzgeblendet.
	 * Dahinter folgen nur noch Samples dieses Puffers.
	 */
136 137
	void Crossfade( const ITASampleBuffer* psbSrc, int iOffset, int iCount, int iFadeDirection, int iFadeFunction );
	void Crossfade( const ITASampleBuffer& sbSrc, int iOffset, int iCount, int iFadeDirection, int iFadeFunction );
Jonas Stienen's avatar
Jonas Stienen committed
138 139 140 141

	//! Envelope
	/**
	/* Wendet eine lineare Einhllende (envelope) auf den Puffer an.
142 143 144 145 146
	*
	* \param fGain0	Startwert [0..1]
	* \param fGain1	Endwert [0..1]
	*/
	void Envelope( float fGain0, float fGain1 );
Jonas Stienen's avatar
Jonas Stienen committed
147 148 149 150 151 152 153 154 155 156 157 158 159

	//! Samples in ein Array kopieren
	/**
	 * Kopiert iCount Samples aus dem Block beginnend bei Leseposition iOffset
	 * in den angegebenen Zielpuffer, dort beginnend ab Schreibposition 0.
	 *
	 * \param pfDest		Zielarray
	 * \param iCount		Anzahl zu kopierender Samples
	 * \param iSrcOffset	Leseposition in diesem Puffer (SampleBuffer)
	 *
	 * TODO: Memory alignment fr SSE?
	 * \note Kein Lesen ber das Pufferende hinaus!
	 */
160
	void read( float* pfDest, int iCount, int iSrcOffset = 0 ) const;
Jonas Stienen's avatar
Jonas Stienen committed
161 162 163 164

	//! Samples aus einem Array in den Puffer kopieren
	/**
	 * Kopiert iCount Samples aus angegebenen Array beginnend bei Leseposition 0
165
	 * in den Puffer (SampleBuffer), dort beginnend ab Schreibposition iDestOffset.
Jonas Stienen's avatar
Jonas Stienen committed
166 167 168 169 170 171 172
	 *
	 * \param pfSrc			Quellarray
	 * \param iCount		Anzahl zu kopierender Samples
	 * \param iDestOffset	Schreibposition in diesem Puffer (SampleBuffer)
	 *
	 * \note Kein Schreiben ber das Pufferende hinaus!
	 */
173
	void write( const float* pfSrc, int iCount, int iDestOffset = 0 );
Jonas Stienen's avatar
Jonas Stienen committed
174 175 176 177

	//! Samples aus einem anderen Puffer in den Puffer kopieren
	/**
	 * Kopiert iCount Samples aus angegebenen Puffer beginnend bei Leseposition iSrcOffset
178
	 * in disen Puffer, dort beginnend ab Schreibposition iDestOffset.
Jonas Stienen's avatar
Jonas Stienen committed
179 180 181 182 183 184 185 186
	 *
	 * \param psbSrc		Quellpuffer
	 * \param iCount		Anzahl zu kopierender Samples
	 * \param iSrcOffset	Leseposition im Quellpuffer
	 * \param iDestOffset	Schreibposition in diesem Puffer
	 *
	 * \note Kein Schreiben ber das Pufferende hinaus!
	 */
187 188
	void write( const ITASampleBuffer* psbSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
	void write( const ITASampleBuffer& sbSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
Jonas Stienen's avatar
Jonas Stienen committed
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203

	//! Zyklisches Lesen
	/**
	 * Diese Methode erlaubt das zylische Lesen von Samples aus dem Puffer.
	 * Wenn die Leseanforderung das Ende der Puffers berschreitet wird das
	 * Lesen einfach am Anfang des Puffers fortgesetzt. Ntzlich ist diese
	 * Funktionalitt vorallem fr das Implementieren von Ringpuffern.
	 * Semantik ansonsten wie read().
	 *
	 * \param pfDest		Zielarray
	 * \param iCount		Anzahl zu kopierender Samples
	 * \param iSrcOffset	Leseposition in diesem Puffer (SampleBuffer)
	 *
	 * TODO: Memory alignment fr SSE?
	 */
204
	void cyclic_read( float* pfDest, int iCount, int iSrcOffset = 0 ) const;
Jonas Stienen's avatar
Jonas Stienen committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219

	//! Zyklisches Schreiben
	/**
	 * Diese Methode erlaubt das zylische Lesen von Samples aus dem Puffer.
	 * Wenn die Leseanforderung das Ende der Puffers berschreitet wird das
	 * Lesen einfach am Anfang des Puffers fortgesetzt. Ntzlich ist diese
	 * Funktionalitt vorallem fr das Implementieren von Ringpuffern.
	 * Semantik ansonsten wie read().
	 *
	 * \param pfSrc			Quellarray
	 * \param iCount		Anzahl zu kopierender Samples
	 * \param iDestOffset	Schreibposition in diesem Puffer (SampleBuffer)
	 *
	 * TODO: Memory alignment fr SSE?
	 */
220
	void cyclic_write( const float* pfSrc, int iCount, int iDestOffset = 0 );
Jonas Stienen's avatar
Jonas Stienen committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236

	//! Zyklisches Schreiben
	/**
	 * Diese Methode erlaubt das zylische Lesen von Samples aus dem Puffer.
	 * Wenn die Leseanforderung das Ende der Puffers berschreitet wird das
	 * Lesen einfach am Anfang des Puffers fortgesetzt. Ntzlich ist diese
	 * Funktionalitt vorallem fr das Implementieren von Ringpuffern.
	 * Semantik ansonsten wie read().
	 *
	 * \param psbSrc		Quellpuffer
	 * \param iCount		Anzahl zu kopierender Samples
	 * \param iSrcOffset	Leseposition im Quellpuffer
	 * \param iDestOffset	Schreibposition in diesem Puffer
	 *
	 * TODO: Memory alignment fr SSE?
	 */
237 238
	void cyclic_write( const ITASampleBuffer* psbSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
	void cyclic_write( const ITASampleBuffer& sbSrc, int iCount, int iSrcOffset = 0, int iDestOffset = 0 );
Jonas Stienen's avatar
Jonas Stienen committed
239 240 241 242 243

	//! Cyclic shifting of samples
	/**
	 * @param [in] iCount Shifts the samples in buffer by given count
	 */
244
	void CyclicShift( int iCount );
Jonas Stienen's avatar
Jonas Stienen committed
245 246

	//! In-place Addition: Jedem Sample einen konstanten Wert addieren
247
	void add_scalar( float fValue );
Jonas Stienen's avatar
Jonas Stienen committed
248 249

	//! In-place Subtraktion: Jedem Sample einen konstanten Wert subtrahieren
250
	void sub_scalar( float fValue );
Jonas Stienen's avatar
Jonas Stienen committed
251 252

	//! In-place Multiplikation: Jedes Sample mit einem konstanten Wert multiplizieren
253
	void mul_scalar( float fValue );
Jonas Stienen's avatar
Jonas Stienen committed
254 255

	//! In-place Division: Jedes Sample durch einen konstanten Wert dividieren
256
	void div_scalar( float fValue );
Jonas Stienen's avatar
Jonas Stienen committed
257 258 259 260 261 262 263

	// TODO: Bereiche Addieren usw.

	//! Paarweise alle Samples des gegebenen Puffers zu den Samples diesem addieren
	/*
	 * - Mssen gleiche Lngen haben!
	 */
264 265 266 267 268
	void add_buf( const ITASampleBuffer* pSource, int iCount );
	void add_buf( const ITASampleBuffer* pSource );
	void sub_buf( const ITASampleBuffer* pSource );
	void mul_buf( const ITASampleBuffer* pSource );
	void div_buf( const ITASampleBuffer* pSource );
Jonas Stienen's avatar
Jonas Stienen committed
269

270 271
	void add_buf_pos( const ITASampleBuffer* pSource, int iPos );
	void add_buf_pos( float* fSource, int iSize, int iPos );
Jonas Stienen's avatar
Jonas Stienen committed
272 273

	// Implementierung mittels Referenzen
274 275 276 277 278
	void add_buf( const ITASampleBuffer& sbSource, int iCount );
	void add_buf( const ITASampleBuffer& sbSource );
	void sub_buf( const ITASampleBuffer& sbSource );
	void mul_buf( const ITASampleBuffer& sbSource );
	void div_buf( const ITASampleBuffer& sbSource );
Jonas Stienen's avatar
Jonas Stienen committed
279 280 281 282 283 284 285 286 287 288 289

	// Spezial-Operatoren

	// Werte eines anderen Puffers mit einer Konstante multiplizieren und dann hierauf addieren
	// Semantik: 
	// for i from 0 to iCount-1 do
	//   this[dest_offset + i] += (scalar * source[src_offset + i])
	//
	// iSrcOffset = Leseposition im Quellpuffer
	// iDestOffset = Schreibposition in diesem Puffer
	// iCount = Anzahl Samples
290 291
	void MulAdd( const ITASampleBuffer* pSource, float fScalar, int iSrcOffset, int iDestOffset, int iCount );
	void MulAdd( const ITASampleBuffer& sbSource, float fScalar, int iSrcOffset, int iDestOffset, int iCount );
Jonas Stienen's avatar
Jonas Stienen committed
292 293 294 295 296 297 298

	//! Spitzenwert suchen
	/**
	 * Sucht den betragsgrten Wert im Puffer und gibt dessen Betragswert zurck.
	 * Auf Wunsch wird auch der Index der ersten Samples zurckgegeben, das diesen
	 * Spitzenwert erreichte (erste Fundstelle).
	 */
299
	float FindPeak( int* piPeakIndex = NULL );
Jonas Stienen's avatar
Jonas Stienen committed
300 301 302 303

	//! Negieren (Multiplikation mit -1 bzw. Phasendrehungum 180)
	void Negate();

304 305 306
	//! Normalize data
	void Normalize();

Jonas Stienen's avatar
Jonas Stienen committed
307
	//! Read/Write Indizierungsoperator
308
	float& operator[]( int iSample );
Jonas Stienen's avatar
Jonas Stienen committed
309 310

	//! Read-only Indizierungsoperator
311
	const float& operator[]( int iSample ) const;
Jonas Stienen's avatar
Jonas Stienen committed
312 313 314 315 316 317 318

	//! Zuweisungsoperator
	/**
	 * Dieser Operator weist dem Puffer alle Samples eines anderen Quellpuffers zu.
	 * Hierzu wird zunchst die Lnge des Puffer der des Quellpuffers angepasst.
	 * Anschlieend werden alle Samples kopiert.
	 */
319
	ITASampleBuffer& operator=( const ITASampleBuffer& rhs );
Jonas Stienen's avatar
Jonas Stienen committed
320 321

	//! Arithemtische Operatoren (Aliase fr arithmetische Methoden - siehe oben)
322 323 324 325 326 327 328 329
	ITASampleBuffer& operator+=( float rhs );
	ITASampleBuffer& operator-=( float rhs );
	ITASampleBuffer& operator*=( float rhs );
	ITASampleBuffer& operator/=( float rhs );
	ITASampleBuffer& operator+=( const ITASampleBuffer& rhs );
	ITASampleBuffer& operator-=( const ITASampleBuffer& rhs );
	ITASampleBuffer& operator*=( const ITASampleBuffer& rhs );
	ITASampleBuffer& operator/=( const ITASampleBuffer& rhs );
Jonas Stienen's avatar
Jonas Stienen committed
330 331 332 333 334 335 336 337

	//! Informationen ber den Puffer als Zeichenkette zurckgeben
	std::string toString() const;

	//! Werte als Zeichenkette zurckgeben
	std::string valuesToString() const;

	//! berblendfunktionen
338 339
	enum
	{
Jonas Stienen's avatar
Jonas Stienen committed
340 341 342 343 344
		LINEAR = 0,			//!< Lineare berblendung aka. Rampe
		COSINE_SQUARE = 1	//!< Cosinus-Quadrat berblendung (aka Hanning-Fenster)
	};

	//! berblendrichtungen
345 346
	enum
	{
Jonas Stienen's avatar
Jonas Stienen committed
347 348 349 350
		FADE_IN = 0,	//!< Einblenden
		FADE_OUT = 1	//!< Ausblenden
	};

351 352
	enum
	{
Jonas Stienen's avatar
Jonas Stienen committed
353 354 355 356 357 358 359 360 361 362 363 364 365
		CROSSFADE_TO_SOURCE = 0,	//!< Kreuzblende hin zum Quellsignal
		CROSSFADE_FROM_SOURCE = 1	//!< Kreuzblende weg vom Quellsignal
	};

private:
	int m_iLength;
	float* m_pfData;
	ITASampleFrame* m_pParent;

	friend class ITASampleFrame;
};

#endif // INCLUDE_WATCHER_ITA_SAMPLE_BUFFER