#include "ITANUPCInputBuffer1.h" #include "ITANUPCHelpers.h" #include "ITANUPCUtils.h" #include #include #include CInputBuffer1::CInputBuffer1( unsigned int m_uiBlocklength, unsigned int m_uiSize ) : m_uiBlocklength( m_uiBlocklength ), m_uiSize( m_uiSize ), m_pfData( nullptr ) { // WICHTIG: Größe muss Vielfaches der Blocklänge sein assert( ( m_uiSize % m_uiBlocklength ) == 0 ); /* Hinweis: Das erste Cursor-Inkrement geschieht bereits beim ersten Eintritt in GetBlockPointer, dann wenn noch gar keine Daten gelesen wurden. Würde der Cursor mit 0 initialisiert, so würden die ersten Eingabedaten an den Offset Blocklänge geschrieben werden. Damit möglich wenig zweiteilige Kopieraktionen nötig sind, wir der Cursor daher mit m_uiSize - m_uiBlocklength initialisiert, so dass die ersten Eingangsdaten am Offset 0 zu finden sind. */ uiCursor = m_uiSize - m_uiBlocklength; m_pfData = fm_falloc( m_uiSize, true ); m_vbSilence.resize( m_uiSize / m_uiBlocklength, true ); } CInputBuffer1::~CInputBuffer1() { fm_free( m_pfData ); } void CInputBuffer1::reset() { fm_zero( m_pfData, m_uiSize ); for( unsigned int i = 0; i < ( m_uiSize / m_uiBlocklength ); i++ ) m_vbSilence[ i ] = true; uiCursor = m_uiSize - m_uiBlocklength; } bool CInputBuffer1::get( float* pfDest, unsigned int uiOffset, unsigned int uiLength ) { #ifdef _INPUTBUFFER_DEBUG_MESSAGES printf("[InputBuffer1::get] Offset = %d, Length = %d\n", uiOffset, uiLength); #endif assert( uiOffset < m_uiSize ); // Zunächst prüfen, ob die angeforderten Daten Stille sind: bool bSilence = true; unsigned int c = uiOffset; for( unsigned int i = 0; i < uiLength / m_uiBlocklength; i++ ) { c %= m_uiSize; if( !m_vbSilence[ c / m_uiBlocklength ] ) { bSilence = false; break; } c += m_uiBlocklength; } // Stille? Dann nichts kopieren... Sondern direkt mit Nullen initialisieren if( bSilence ) { fm_zero( pfDest, uiLength ); return false; } unsigned int r = m_uiSize - uiOffset; if( uiLength <= r ) // Kopieren in einem Schritt fm_copy( pfDest, m_pfData + uiOffset, uiLength ); else { // Buffer-wrapping: Kopieren in zwei Schritten fm_copy( pfDest, m_pfData + uiOffset, r ); fm_copy( pfDest + r, m_pfData, uiLength - r ); } return true; } void CInputBuffer1::put( const float* pfSource, float fGain ) { #ifdef _INPUTBUFFER_DEBUG_MESSAGES printf("[InputBuffer1::put] Cursor = %d\n", uiCursor); #endif // Nullzeiger = Stille if( pfSource && ( fGain != 0 ) ) { /* fwe: Bugfix. Früher mittels fm_copy kopiert. Allerdings muß pfSource nicht SIMD-Aligned sein und die Spezifikation von FastMath legt nicht exakt fest, ob dies erfüllt sein muss. */ if( fGain == 1.0 ) memcpy( m_pfData + uiCursor, pfSource, m_uiBlocklength * sizeof( float ) ); else for( unsigned int i = 0; i < m_uiBlocklength; i++ ) m_pfData[ uiCursor + i ] = pfSource[ i ] * fGain; // Auf Stille testen m_vbSilence[ uiCursor / m_uiBlocklength ] = ITANUPCFCheckZero( m_pfData + uiCursor, m_uiBlocklength ); } else { fm_zero( m_pfData + uiCursor, m_uiBlocklength ); m_vbSilence[ uiCursor / m_uiBlocklength ] = true; } // DEBUG: if (m_vbSilence[uiCursor/m_uiBlocklength]) printf("Silence!\n"); } void CInputBuffer1::mix( const float* pfSource, float fGain ) { #ifdef _INPUTBUFFER_DEBUG_MESSAGES printf("[InputBuffer1::mix] Cursor = %d\n", uiCursor); #endif // Nullzeiger = Stille if( pfSource && ( fGain != 0 ) ) { // fwe: Bugfix. Früher mittels fm_add gemischt. Allerdings muß pfSource nicht SIMD-Aligned sein! if( fGain == 1.0 ) for( unsigned int i = 0; i < m_uiBlocklength; i++ ) m_pfData[ uiCursor + i ] += pfSource[ i ]; else for( unsigned int i = 0; i < m_uiBlocklength; i++ ) m_pfData[ uiCursor + i ] += pfSource[ i ] * fGain; // Durch das Einmischen kann vorhandene Stille aufgehoben wurden sein: if( m_vbSilence[ uiCursor / m_uiBlocklength ] ) { // Erneut auf Stille testen: for( unsigned int i = 0; i < m_uiBlocklength; i++ ) { if( m_pfData[ uiCursor + i ] != 0 ) { m_vbSilence[ uiCursor / m_uiBlocklength ] = false; return; } } } } } void CInputBuffer1::incrementCursor() { uiCursor += m_uiBlocklength; uiCursor %= m_uiSize; #ifdef _INPUTBUFFER_DEBUG_MESSAGES printf("[InputBuffer1::incrementCursor] Cursor = %d\n", uiCursor); #endif } unsigned int CInputBuffer1::getOffset( unsigned int uiLength ) { return ( m_uiSize + uiCursor - uiLength + m_uiBlocklength ) % m_uiSize; }