experimental support for MMX/SSE/SSE2 instructions
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1832 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -121,31 +121,22 @@ public:
|
||||
protected:
|
||||
// subclasses can re-implement this for being used in conjunction with
|
||||
// processNextBuffer()
|
||||
virtual void writeBuffer( const surroundSampleFrame * /* _buf*/,
|
||||
virtual void writeBuffer( const sampleFrameA * /* _buf*/,
|
||||
const fpp_t /*_frames*/,
|
||||
const float /*_master_gain*/ )
|
||||
{
|
||||
}
|
||||
|
||||
// called by according driver for fetching new sound-data
|
||||
fpp_t getNextBuffer( surroundSampleFrame * _ab );
|
||||
|
||||
// convert a given audio-buffer to a buffer in signed 16-bit samples
|
||||
// returns num of bytes in outbuf
|
||||
Uint32 convertToS16( const surroundSampleFrame * _ab,
|
||||
const fpp_t _frames,
|
||||
const float _master_gain,
|
||||
int_sample_t * _output_buffer,
|
||||
const bool _convert_endian = FALSE );
|
||||
fpp_t getNextBuffer( sampleFrameA * _ab );
|
||||
|
||||
// clear given signed-int-16-buffer
|
||||
void clearS16Buffer( int_sample_t * _outbuf,
|
||||
const fpp_t _frames );
|
||||
void clearS16Buffer( intSampleFrameA * _outbuf, const fpp_t _frames );
|
||||
|
||||
// resample given buffer from samplerate _src_sr to samplerate _dst_sr
|
||||
void resample( const surroundSampleFrame * _src,
|
||||
void resample( const sampleFrameA * _src,
|
||||
const fpp_t _frames,
|
||||
surroundSampleFrame * _dst,
|
||||
sampleFrameA * _dst,
|
||||
const sample_rate_t _src_sr,
|
||||
const sample_rate_t _dst_sr );
|
||||
|
||||
@@ -161,9 +152,11 @@ protected:
|
||||
|
||||
bool hqAudio( void ) const;
|
||||
|
||||
|
||||
protected:
|
||||
bool m_supportsCapture;
|
||||
|
||||
|
||||
private:
|
||||
sample_rate_t m_sampleRate;
|
||||
ch_cnt_t m_channels;
|
||||
@@ -175,7 +168,7 @@ private:
|
||||
SRC_DATA m_srcData;
|
||||
SRC_STATE * m_srcState;
|
||||
|
||||
surroundSampleFrame * m_buffer;
|
||||
sampleFrameA * m_buffer;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#define _AUDIO_DUMMY_H
|
||||
|
||||
#include "audio_device.h"
|
||||
#include "basic_ops.h"
|
||||
#include "micro_timer.h"
|
||||
|
||||
|
||||
@@ -94,16 +95,16 @@ private:
|
||||
virtual void run( void )
|
||||
{
|
||||
microTimer timer;
|
||||
while( TRUE )
|
||||
while( true )
|
||||
{
|
||||
timer.reset();
|
||||
const surroundSampleFrame * b =
|
||||
surroundSampleFrame * b =
|
||||
getMixer()->nextBuffer();
|
||||
if( !b )
|
||||
{
|
||||
break;
|
||||
}
|
||||
delete[] b;
|
||||
alignedFreeFrames( b );
|
||||
|
||||
const Sint32 microseconds = static_cast<Sint32>(
|
||||
getMixer()->framesPerPeriod() *
|
||||
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
QSemaphore m_stop_semaphore;
|
||||
|
||||
QVector<jack_port_t *> m_outputPorts;
|
||||
surroundSampleFrame * m_outBuf;
|
||||
sampleFrameA * m_outBuf;
|
||||
|
||||
|
||||
f_cnt_t m_framesDoneInCurBuf;
|
||||
|
||||
@@ -40,14 +40,14 @@ public:
|
||||
audioPort( const QString & _name, bool _has_effect_chain = true );
|
||||
~audioPort();
|
||||
|
||||
inline sampleFrame * firstBuffer( void )
|
||||
inline sampleFrameA * firstBuffer( void )
|
||||
{
|
||||
return( m_firstBuffer );
|
||||
return m_firstBuffer;
|
||||
}
|
||||
|
||||
inline sampleFrame * secondBuffer( void )
|
||||
inline sampleFrameA * secondBuffer( void )
|
||||
{
|
||||
return( m_secondBuffer );
|
||||
return m_secondBuffer;
|
||||
}
|
||||
|
||||
inline void lockFirstBuffer( void )
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
// indicate whether JACK & Co should provide output-buffer at ext. port
|
||||
inline bool extOutputEnabled( void ) const
|
||||
{
|
||||
return( m_extOutputEnabled );
|
||||
return m_extOutputEnabled;
|
||||
}
|
||||
|
||||
void setExtOutputEnabled( bool _enabled );
|
||||
@@ -86,12 +86,12 @@ public:
|
||||
// (-1 = none 0 = master)
|
||||
inline fx_ch_t nextFxChannel( void ) const
|
||||
{
|
||||
return( m_nextFxChannel );
|
||||
return m_nextFxChannel;
|
||||
}
|
||||
|
||||
inline effectChain * getEffects( void )
|
||||
{
|
||||
return( m_effects );
|
||||
return m_effects;
|
||||
}
|
||||
|
||||
void setNextFxChannel( const fx_ch_t _chnl )
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
|
||||
const QString & name( void ) const
|
||||
{
|
||||
return( m_name );
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void setName( const QString & _new_name );
|
||||
@@ -122,8 +122,8 @@ public:
|
||||
private:
|
||||
volatile bufferUsages m_bufferUsage;
|
||||
|
||||
sampleFrame * m_firstBuffer;
|
||||
sampleFrame * m_secondBuffer;
|
||||
sampleFrameA * m_firstBuffer;
|
||||
sampleFrameA * m_secondBuffer;
|
||||
QMutex m_firstBufferLock;
|
||||
QMutex m_secondBufferLock;
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ private:
|
||||
|
||||
bool m_wasPAInitError;
|
||||
|
||||
surroundSampleFrame * m_outBuf;
|
||||
sampleFrameA * m_outBuf;
|
||||
int m_outBufPos;
|
||||
int m_outBufSize;
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ private:
|
||||
|
||||
SDL_AudioSpec m_audioHandle;
|
||||
|
||||
surroundSampleFrame * m_outBuf;
|
||||
Uint8 * m_convertedBuf;
|
||||
sampleFrameA * m_outBuf;
|
||||
intSampleFrameA * m_convertedBuf;
|
||||
int m_convertedBufPos;
|
||||
int m_convertedBufSize;
|
||||
|
||||
|
||||
94
include/basic_ops.h
Normal file
94
include/basic_ops.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* basic_ops.h - basic memory operations
|
||||
*
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _BASIC_OPS_H
|
||||
#define _BASIC_OPS_H
|
||||
|
||||
#include "lmms_basics.h"
|
||||
|
||||
#ifdef LMMS_HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
void initBasicOps( void );
|
||||
|
||||
void * alignedMalloc( int _bytes );
|
||||
void alignedFree( void * _buf );
|
||||
|
||||
sampleFrameA * alignedAllocFrames( int _frames );
|
||||
void alignedFreeFrames( sampleFrameA * _buf );
|
||||
|
||||
|
||||
// all aligned* functions assume data to be 16 byte aligned and size to be
|
||||
// multiples of 64
|
||||
typedef void (*alignedMemCpyFunc)( void * RP _dst, const void * RP _src,
|
||||
int _size );
|
||||
typedef void (*alignedMemClearFunc)( void * RP _dst, int _size );
|
||||
typedef void (*alignedBufApplyGainFunc)( sampleFrameA * RP _dst,
|
||||
float _gain, int _frames );
|
||||
typedef void (*alignedBufMixFunc)( sampleFrameA * RP _dst,
|
||||
const sampleFrameA * RP _src,
|
||||
int _frames );
|
||||
typedef void (*alignedBufMixLRCoeffFunc)( sampleFrameA * RP _dst,
|
||||
const sampleFrameA * RP _src,
|
||||
float _left, float _right,
|
||||
int _frames );
|
||||
typedef void (*unalignedBufMixLRCoeffFunc)( sampleFrame * RP _dst,
|
||||
const sampleFrame * RP _src,
|
||||
float _left, float _right,
|
||||
int _frames );
|
||||
typedef void (*alignedBufWetDryMixFunc)( sampleFrameA * RP _dst,
|
||||
const sampleFrameA * RP _src,
|
||||
float _wet, float _dry, int _frames );
|
||||
typedef void (*alignedBufWetDryMixSplittedFunc)( sampleFrameA * RP _dst,
|
||||
const float * RP _left,
|
||||
const float * RP _right,
|
||||
float _wet, float _dry, int _frames );
|
||||
typedef int (*alignedConvertToS16Func)( const sampleFrameA * RP _src,
|
||||
intSampleFrameA * RP _dst,
|
||||
const fpp_t _frames,
|
||||
const float _master_gain,
|
||||
const bool _convert_endian );
|
||||
|
||||
extern alignedMemCpyFunc alignedMemCpy;
|
||||
extern alignedMemClearFunc alignedMemClear;
|
||||
extern alignedBufApplyGainFunc alignedBufApplyGain;
|
||||
extern alignedBufMixFunc alignedBufMix;
|
||||
extern alignedBufMixLRCoeffFunc alignedBufMixLRCoeff;
|
||||
extern unalignedBufMixLRCoeffFunc unalignedBufMixLRCoeff;
|
||||
extern alignedBufWetDryMixFunc alignedBufWetDryMix;
|
||||
extern alignedBufWetDryMixSplittedFunc alignedBufWetDryMixSplitted;
|
||||
extern alignedConvertToS16Func alignedConvertToS16;
|
||||
|
||||
|
||||
#ifdef LMMS_HOST_X86
|
||||
#define X86_OPTIMIZATIONS
|
||||
#endif
|
||||
#ifdef LMMS_HOST_X86_64
|
||||
#define X86_OPTIMIZATIONS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* fifo_buffer.h - FIFO fixed-size buffer
|
||||
*
|
||||
* Copyright (c) 2007 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -33,50 +34,50 @@ class fifoBuffer
|
||||
{
|
||||
public:
|
||||
fifoBuffer( int _size ) :
|
||||
m_reader_sem( _size ),
|
||||
m_writer_sem( _size ),
|
||||
m_reader_index( 0 ),
|
||||
m_writer_index( 0 ),
|
||||
m_readerSem( _size ),
|
||||
m_writerSem( _size ),
|
||||
m_readerIndex( 0 ),
|
||||
m_writerIndex( 0 ),
|
||||
m_size( _size )
|
||||
{
|
||||
m_buffer = new T[_size];
|
||||
m_reader_sem.acquire( _size );
|
||||
m_readerSem.acquire( _size );
|
||||
}
|
||||
|
||||
~fifoBuffer()
|
||||
{
|
||||
delete[] m_buffer;
|
||||
m_reader_sem.release( m_size );
|
||||
m_readerSem.release( m_size );
|
||||
}
|
||||
|
||||
void write( T _element )
|
||||
{
|
||||
m_writer_sem.acquire();
|
||||
m_buffer[m_writer_index++] = _element;
|
||||
m_writer_index %= m_size;
|
||||
m_reader_sem.release();
|
||||
m_writerSem.acquire();
|
||||
m_buffer[m_writerIndex++] = _element;
|
||||
m_writerIndex %= m_size;
|
||||
m_readerSem.release();
|
||||
}
|
||||
|
||||
T read( void )
|
||||
{
|
||||
m_reader_sem.acquire();
|
||||
T element = m_buffer[m_reader_index++];
|
||||
m_reader_index %= m_size;
|
||||
m_writer_sem.release();
|
||||
return( element );
|
||||
m_readerSem.acquire();
|
||||
T element = m_buffer[m_readerIndex++];
|
||||
m_readerIndex %= m_size;
|
||||
m_writerSem.release();
|
||||
return element;
|
||||
}
|
||||
|
||||
bool available( void )
|
||||
{
|
||||
return( m_reader_sem.available() );
|
||||
return m_readerSem.available();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
QSemaphore m_reader_sem;
|
||||
QSemaphore m_writer_sem;
|
||||
int m_reader_index;
|
||||
int m_writer_index;
|
||||
QSemaphore m_readerSem;
|
||||
QSemaphore m_writerSem;
|
||||
int m_readerIndex;
|
||||
int m_writerIndex;
|
||||
int m_size;
|
||||
T * m_buffer;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* types.h - typedefs for common types that are used in the whole app
|
||||
* lmms_basics.h - common basics for the whole App
|
||||
*
|
||||
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
@@ -23,10 +23,8 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _TYPES_H
|
||||
#define _TYPES_H
|
||||
|
||||
#include <limits>
|
||||
#ifndef _LMMS_BASICS_H
|
||||
#define _LMMS_BASICS_H
|
||||
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
@@ -68,6 +66,9 @@ typedef Uint32 jo_id_t; // (unique) ID of a journalling object
|
||||
#define likely(x) __builtin_expect((x),1)
|
||||
#define unlikely(x) __builtin_expect((x),0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <limits>
|
||||
|
||||
template<typename T>
|
||||
struct typeInfo
|
||||
@@ -115,25 +116,50 @@ inline bool typeInfo<float>::isEqual( float _x, float _y )
|
||||
return absVal( _x - _y ) < minEps();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
const ch_cnt_t DEFAULT_CHANNELS = 2;
|
||||
|
||||
const ch_cnt_t SURROUND_CHANNELS =
|
||||
#define DEFAULT_CHANNELS 2
|
||||
#define LMMS_DISABLE_SURROUND
|
||||
#ifndef LMMS_DISABLE_SURROUND
|
||||
4;
|
||||
#ifdef LMMS_DISABLE_SURROUND
|
||||
#define SURROUND_CHANNELS 2
|
||||
#else
|
||||
2;
|
||||
#define SURROUND_CHANNELS 4
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef sample_t sampleFrame[DEFAULT_CHANNELS];
|
||||
typedef sample_t surroundSampleFrame[SURROUND_CHANNELS];
|
||||
|
||||
#define ALIGN_SIZE 16
|
||||
|
||||
#if __GNUC__
|
||||
|
||||
typedef sample_t sampleFrameA[DEFAULT_CHANNELS] __attribute__((__aligned__(ALIGN_SIZE)));
|
||||
typedef int_sample_t intSampleFrameA[DEFAULT_CHANNELS] __attribute__((__aligned__(ALIGN_SIZE)));
|
||||
#define RP __restrict__
|
||||
|
||||
#else
|
||||
|
||||
#define RP
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
const int BYTES_PER_SAMPLE = sizeof( sample_t );
|
||||
const int BYTES_PER_INT_SAMPLE = sizeof( int_sample_t );
|
||||
const int BYTES_PER_FRAME = sizeof( sampleFrame );
|
||||
const int BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame );
|
||||
|
||||
const float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
|
||||
#else
|
||||
#define BYTES_PER_SAMPLE sizeof( sample_t )
|
||||
#define BYTES_PER_INT_SAMPLE sizeof( int_sample_t )
|
||||
#define BYTES_PER_FRAME sizeof( sampleFrame )
|
||||
#define BYTES_PER_SURROUND_FRAME sizeof( surroundSampleFrame )
|
||||
#define OUTPUT_SAMPLE_MULTIPLIER 32767.0f
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -57,13 +57,6 @@ class audioPort;
|
||||
|
||||
const fpp_t DEFAULT_BUFFER_SIZE = 256;
|
||||
|
||||
const int BYTES_PER_SAMPLE = sizeof( sample_t );
|
||||
const int BYTES_PER_INT_SAMPLE = sizeof( int_sample_t );
|
||||
const int BYTES_PER_FRAME = sizeof( sampleFrame );
|
||||
const int BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame );
|
||||
|
||||
const float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
|
||||
|
||||
|
||||
const float BaseFreq = 440.0f;
|
||||
const Keys BaseKey = Key_A;
|
||||
@@ -361,7 +354,7 @@ public:
|
||||
return m_inputBufferFrames[ m_inputBufferRead ];
|
||||
}
|
||||
|
||||
inline const surroundSampleFrame * nextBuffer( void )
|
||||
inline surroundSampleFrame * nextBuffer( void )
|
||||
{
|
||||
return hasFifoWriter() ? m_fifo->read() : renderNextBuffer();
|
||||
}
|
||||
@@ -407,7 +400,7 @@ private:
|
||||
midiClient * tryMidiClients( void );
|
||||
|
||||
|
||||
const surroundSampleFrame * renderNextBuffer( void );
|
||||
surroundSampleFrame * renderNextBuffer( void );
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user