better VST support and bugfixes

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@77 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2006-02-06 12:52:58 +00:00
parent af3d57b67f
commit de00678815
43 changed files with 966 additions and 668 deletions

View File

@@ -1,3 +1,43 @@
2006-02-05 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* include/basic_filters.h:
small optimizations: do not divide by 2.0, instead multiply with 0.5
* src/core/main.cpp:
set SCHED_FIFO-priority for LMMS if possible
* plugins/vestige/communication.h:
* plugins/vestige/lvsl_client.cpp:
* plugins/vestige/lvsl_server.c:
- set SCHED_FIFO-priority for VST-server if possible
- no X-calls needed anymore
- more complete host-callback-implementation
- support for geometry-changes of plugin
- use std::list instead of std::vector for enqueing MIDI-events (faster)
- support for telling plugin system's language
* configure.in:
when checking for VST-SDK-headers, use C++ compiler instead of
C-compilers as headers fail to compile with it
2006-02-04 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* include/types.h:
* most files:
more strict typing -> types for samplerate, bpm, frame-count,
channel-count etc.
* src/core/track.cpp:
when creating a track, pause mixer for not causing any trouble because
of incompletely initialized track etc. - fixes several crashes when
adding track while playing
* include/mixer.h:
* src/core/mixer.cpp:
more "intelligent" mix-mutex-management for allow multiple pause()-
calls without ending in deadlock or crash because of mutex being
unlocked to early
2006-02-02 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* configure.in:

2
TODO
View File

@@ -1,5 +1,7 @@
to be done as soon as possible:
- fix qtimer-problem /channel-activity-LEDs
- make color-scheme switchable: LMMS / user
- autosave every 30s (configurable!) and offer recovery at startup after crash
- make piano-roll use rubberband instead of implementing a simple one on it's own
- level-meters in output-graph and channel-track

View File

@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(lmms, 0.1.4, tobydox/at/users/dot/sourceforge/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.1.4)
AC_INIT(lmms, 0.1.4-cvs20060205, tobydox/at/users/dot/sourceforge/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.1.4-cvs20060205)
AM_CONFIG_HEADER(config.h)
@@ -22,7 +22,7 @@ gw_CHECK_QT
# checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([fcntl.h memory.h string.h sys/ioctl.h unistd.h stdlib.h pthread.h sys/ipc.h sys/shm.h sys/time.h sys/select.h sys/types.h stdarg.h signal.h])
AC_CHECK_HEADERS([fcntl.h memory.h string.h sys/ioctl.h unistd.h stdlib.h pthread.h sys/ipc.h sys/shm.h sys/time.h sys/select.h sys/types.h stdarg.h signal.h sched.h])
# checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
@@ -167,6 +167,8 @@ if test "x$with_vst" = "xyes" ; then
ORIG_CPPFLAGS=$CPPFLAGS
CFLAGS="$CLFAGS -I./include"
CPPFLAGS="$CPPFLAGS -I./include"
ORIG_CC="$CC"
CC="$CXX"
AC_CHECK_HEADER(aeffectx.h, HAVE_VST_AEFFECTX_H="true")
CFLAGS="$ORIG_CFLAGS"
CPPFLAGS="$ORIG_CPPFLAGS"
@@ -181,6 +183,7 @@ if test "x$with_vst" = "xyes" ; then
WINE_OK_BUT_VST_INCOMPLETE="true"
fi
fi
CC="$ORIG_CC"
fi
AM_CONDITIONAL(VST_SUPPORT, test ! -z "$WINEGCC")

View File

@@ -1,7 +1,7 @@
/*
* audio_alsa.h - device-class that implements ALSA-PCM-output
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -51,7 +51,7 @@ class QLineEdit;
class audioALSA : public audioDevice, public QThread
{
public:
audioALSA( Uint32 _sample_rate, bool & _success_ful );
audioALSA( const sample_rate_t _sample_rate, bool & _success_ful );
~audioALSA();
inline static QString name( void )
@@ -83,7 +83,8 @@ private:
virtual void stopProcessing( void );
virtual void run( void );
int FASTCALL setHWParams( Uint32 _sample_rate, Uint32 _channels,
int FASTCALL setHWParams( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
snd_pcm_access_t _access );
int setSWParams( void );
int FASTCALL handleError( int _err );

View File

@@ -63,7 +63,8 @@ class audioPort;
class audioDevice
{
public:
audioDevice( Uint32 _sample_rate, Uint8 _channels );
audioDevice( const sample_rate_t _sample_rate,
const ch_cnt_t _channels );
virtual ~audioDevice();
inline void lock( void )
@@ -86,12 +87,12 @@ public:
virtual void renamePort( audioPort * _port );
inline Uint32 sampleRate( void ) const
inline sample_rate_t sampleRate( void ) const
{
return( m_sampleRate );
}
Uint8 channels( void ) const
ch_cnt_t channels( void ) const
{
return( m_channels );
}
@@ -127,43 +128,45 @@ public:
protected:
// subclasses can overload this for being used in conjunction with
// subclasses can re-implement this for being used in conjunction with
// processNextBuffer()
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
virtual void FASTCALL writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain )
{
}
// called by according driver for fetching new sound-data
Uint32 FASTCALL getNextBuffer( surroundSampleFrame * _ab );
fpab_t FASTCALL getNextBuffer( surroundSampleFrame * _ab );
// convert a given audio-buffer to a buffer in signed 16-bit samples
// returns num of bytes in outbuf
int FASTCALL convertToS16( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain,
outputSampleType * _output_buffer,
bool _convert_endian = FALSE );
Uint32 FASTCALL convertToS16( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain,
int_sample_t * _output_buffer,
const bool _convert_endian = FALSE );
// clear given signed-int-16-buffer
void FASTCALL clearS16Buffer( outputSampleType * _outbuf,
Uint32 _frames );
void FASTCALL clearS16Buffer( int_sample_t * _outbuf,
const fpab_t _frames );
// resample given buffer from samplerate _src_src to samplerate _dst_src
// resample given buffer from samplerate _src_sr to samplerate _dst_sr
void FASTCALL resample( const surroundSampleFrame * _src,
Uint32 _frames,
const fpab_t _frames,
surroundSampleFrame * _dst,
Uint32 _src_sr, Uint32 _dst_sr );
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr );
inline void setSampleRate( Uint32 _new_sr )
inline void setSampleRate( const sample_rate_t _new_sr )
{
m_sampleRate = _new_sr;
}
private:
Uint32 m_sampleRate;
Uint8 m_channels;
sample_rate_t m_sampleRate;
ch_cnt_t m_channels;
QMutex m_devMutex;
#ifdef HAVE_SAMPLERATE_H

View File

@@ -2,7 +2,7 @@
* audio_file_device.h - base-class for audio-device-classes which write
* their output into a file
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -47,34 +47,40 @@
class audioFileDevice : public audioDevice
{
public:
audioFileDevice( Uint32 _sample_rate, Uint8 _channels,
const QString & _file, bool _use_vbr,
Uint16 _nom_bitrate, Uint16 _min_bitrate,
Uint16 _max_bitrate );
audioFileDevice( const sample_rate_t _sample_rate,
const ch_cnt_t _channels, const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate );
virtual ~audioFileDevice();
protected:
int FASTCALL writeData( const void * _data, int _len );
Sint32 FASTCALL writeData( const void * _data, Sint32 _len );
void seekToBegin( void );
inline bool useVBR( void ) const
{
return( m_useVbr );
}
inline Uint16 nominalBitrate( void ) const
inline bitrate_t nominalBitrate( void ) const
{
return( m_nomBitrate );
}
inline Uint16 minBitrate( void ) const
inline bitrate_t minBitrate( void ) const
{
return( m_minBitrate );
}
inline Uint16 maxBitrate( void ) const
inline bitrate_t maxBitrate( void ) const
{
return( m_maxBitrate );
}
inline bool outputFileOpened( void ) const
{
return( m_outputFile.isOpen() );
@@ -86,9 +92,9 @@ private:
bool m_useVbr;
Uint16 m_nomBitrate;
Uint16 m_minBitrate;
Uint16 m_maxBitrate;
bitrate_t m_nomBitrate;
bitrate_t m_minBitrate;
bitrate_t m_maxBitrate;
} ;

View File

@@ -2,7 +2,7 @@
* audio_file_ogg.h - Audio-device which encodes wave-stream and writes it
* into an OGG-file. This is used for song-export.
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -42,19 +42,24 @@
class audioFileOgg : public audioFileDevice
{
public:
audioFileOgg( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful, const QString & _file,
bool _use_vbr, Uint16 _nom_bitrate,
Uint16 _min_bitrate, Uint16 _max_bitrate );
~audioFileOgg();
audioFileOgg( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate );
virtual ~audioFileOgg();
static audioFileDevice * getInst( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful,
const QString & _file,
bool _use_vbr,
Uint16 _nom_bitrate,
Uint16 _min_bitrate,
Uint16 _max_bitrate )
static audioFileDevice * getInst( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate )
{
return( new audioFileOgg( _sample_rate, _channels, _success_ful,
_file, _use_vbr, _nom_bitrate,
@@ -63,26 +68,24 @@ public:
private:
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
virtual void FASTCALL writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain );
bool startEncoding( void );
void finishEncoding( void );
inline int writePage( void );
inline Sint32 writePage( void );
int m_channels;
long m_rate;
ch_cnt_t m_channels;
sample_rate_t m_rate;
// Various bitrate/quality options
int m_managed;
int m_bitrate;
int m_minBitrate;
int m_maxBitrate;
bitrate_t m_minBitrate;
bitrate_t m_maxBitrate;
unsigned int m_serialNo;
Uint32 m_serialNo;
vorbis_comment * m_comments;

View File

@@ -2,7 +2,7 @@
* audio_file_wave.h - Audio-device which encodes wave-stream and writes it
* into an WAVE-file. This is used for song-export.
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -35,29 +35,35 @@
class audioFileWave : public audioFileDevice
{
public:
audioFileWave( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful, const QString & _file,
bool _use_vbr, Uint16 _nom_bitrate,
Uint16 _min_bitrate, Uint16 _max_bitrate );
audioFileWave( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate );
virtual ~audioFileWave();
static audioFileDevice * getInst( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful,
const QString & _file, bool _use_vbr,
Uint16 _nom_bitrate,
Uint16 _min_bitrate,
Uint16 _max_bitrate )
static audioFileDevice * getInst( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate )
{
return( new audioFileWave( _sample_rate, _channels,
_success_ful, _file, _use_vbr,
_nom_bitrate, _min_bitrate,
_max_bitrate ) );
_max_bitrate ) );
}
private:
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
virtual void FASTCALL writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames,
float _master_gain );
bool startEncoding( void );

View File

@@ -1,7 +1,7 @@
/*
* audio_oss.h - device-class that implements OSS-PCM-output
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -47,8 +47,8 @@ class QLineEdit;
class audioOSS : public audioDevice, public QThread
{
public:
audioOSS( Uint32 _sample_rate, bool & _success_ful );
~audioOSS();
audioOSS( const sample_rate_t _sample_rate, bool & _success_ful );
virtual ~audioOSS();
inline static QString name( void )
{

View File

@@ -1,7 +1,7 @@
/*
* audio_port.h - base-class for objects providing sound at a port
*
* Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -71,15 +71,17 @@ public:
// next effect-channel after this audio-port
// (-1 = none 0 = master)
inline fxChnl nextFxChannel( void ) const
inline fx_ch_t nextFxChannel( void ) const
{
return( m_nextFxChannel );
}
void setNextFxChannel( fxChnl _chnl )
void setNextFxChannel( const fx_ch_t _chnl )
{
m_nextFxChannel = _chnl;
}
const QString & name( void ) const
{
return( m_name );
@@ -87,6 +89,7 @@ public:
void setName( const QString & _new_name );
enum bufferUsages
{
NONE, FIRST, BOTH
@@ -97,7 +100,7 @@ private:
surroundSampleFrame * m_firstBuffer;
surroundSampleFrame * m_secondBuffer;
bool m_extOutputEnabled;
fxChnl m_nextFxChannel;
fx_ch_t m_nextFxChannel;
QString m_name;

View File

@@ -3,7 +3,7 @@
* surround-audio-buffers into RAM, maybe later
* also harddisk
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -33,12 +33,12 @@
#ifdef QT4
#include <QVector>
#include <QList>
#include <QPair>
#else
#include <qvaluevector.h>
#include <qvaluelist.h>
#include <qpair.h>
#endif
@@ -53,21 +53,21 @@ class sampleBuffer;
class audioSampleRecorder : public audioDevice
{
public:
audioSampleRecorder( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful );
~audioSampleRecorder();
audioSampleRecorder( const sample_rate_t _sample_rate,
const ch_cnt_t _channels, bool & _success_ful );
virtual ~audioSampleRecorder();
Uint32 framesRecorded( void ) const;
f_cnt_t framesRecorded( void ) const;
void FASTCALL createSampleBuffer( sampleBuffer * * _sample_buf ) const;
private:
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
virtual void FASTCALL writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain );
typedef vvector<QPair<sampleFrame *, Uint32> > bufferVector;
bufferVector m_buffers;
typedef vlist<QPair<sampleFrame *, fpab_t> > bufferList;
bufferList m_buffers;
} ;

View File

@@ -1,7 +1,7 @@
/*
* audio_sdl.h - device-class that performs PCM-output via SDL
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -51,8 +51,8 @@ class QLineEdit;
class audioSDL : public audioDevice
{
public:
audioSDL( Uint32 _sample_rate, bool & _success_ful );
~audioSDL();
audioSDL( const sample_rate_t _sample_rate, bool & _success_ful );
virtual ~audioSDL();
inline static QString name( void )
{

View File

@@ -2,9 +2,9 @@
* basic_filters.h - simple but powerful filter-class with most used filters
*
* original file by ???
* modified and enhanced by Tobias Doerffel, 2004
* modified and enhanced by Tobias Doerffel
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -39,9 +39,9 @@
#include "mixer.h"
#include "templates.h"
const int MOOG_VOLTAGE = 40000;
//const int MOOG_VOLTAGE = 40000;
template<Uint8 CHANNELS = DEFAULT_CHANNELS>
template<ch_cnt_t CHANNELS = DEFAULT_CHANNELS>
class basicFilters
{
public:
@@ -70,17 +70,17 @@ public:
SIMPLE_FLT_CNT ) );
}
inline basicFilters( const float _sampleRate ) :
inline basicFilters( const sample_rate_t _sample_rate ) :
m_b0a0( 0.0f ),
m_b1a0( 0.0f ),
m_b2a0( 0.0f ),
m_a1a0( 0.0f ),
m_a2a0( 0.0f ),
m_sampleRate( _sampleRate ),
m_sampleRate( 1.0f / _sample_rate ),
m_subFilter( NULL )
{
// reset in/out history
for( Uint8 _chnl = 0; _chnl < CHANNELS; ++_chnl )
for( ch_cnt_t _chnl = 0; _chnl < CHANNELS; ++_chnl )
{
// reset in/out history for simple filters
m_ou1[_chnl] = m_ou2[_chnl] = m_in1[_chnl] =
@@ -97,15 +97,15 @@ public:
delete m_subFilter;
}
inline sampleType update( sampleType _in0, Uint8 _chnl )
inline sample_t update( sample_t _in0, ch_cnt_t _chnl )
{
sampleType out;
sample_t out;
switch( m_type )
{
case MOOG:
case DOUBLE_MOOG:
{
sampleType x = _in0 - m_r*m_y4[_chnl];
sample_t x = _in0 - m_r*m_y4[_chnl];
// four cascaded onepole filters
// (bilinear transform)
@@ -207,10 +207,12 @@ public:
m_ou1[_chnl] = out;
break;
}
if( m_subFilter != NULL )
{
return( m_subFilter->update( out, _chnl ) );
}
// Clipper band limited sigmoid
return( out );
}
@@ -233,7 +235,7 @@ public:
{
m_subFilter =
new basicFilters<CHANNELS>(
m_sampleRate );
static_cast<sample_rate_t>( 1.0f / m_sampleRate ) );
}
m_subFilter->calcFilterCoeffs( MOOG, _freq,
_q );
@@ -242,7 +244,7 @@ public:
case MOOG:
{
// [ 0 - 1 ]
const float f = 2 * _freq / m_sampleRate;
const float f = 2 * _freq * m_sampleRate;
// (Empirical tunning)
m_k = 3.6f*f - 1.6f*f*f - 1;
m_p = (m_k+1)*0.5f;
@@ -256,7 +258,7 @@ public:
{
m_subFilter =
new basicFilters<CHANNELS>(
m_sampleRate );
1.0f / m_sampleRate );
}
m_subFilter->calcFilterCoeffs( MOOG2, _freq,
_q );
@@ -264,8 +266,8 @@ public:
case MOOG2:
{
const float kfc = 2 * _freq / m_sampleRate;
const float kf = _freq / m_sampleRate;
const float kfc = 2 * _freq * m_sampleRate;
const float kf = _freq * m_sampleRate;
const float kfcr = 1.8730 * ( kfc*kfc*kfc ) +
0.4955 * ( kfc*kfc ) +
0.6490 * kfc + 0.9988;
@@ -280,7 +282,7 @@ public:
default:
{
// other filters
const float omega = 2.0f * M_PI * _freq /
const float omega = 2.0f * M_PI * _freq *
m_sampleRate;
const float tsin = sinf( omega );
const float tcos = cosf( omega );
@@ -290,14 +292,14 @@ public:
//alpha = tsin*sinhf(logf(2.0f)/2.0f*q*omega/
// tsin);
//else
const float alpha = tsin / ( 2.0f * _q );
const float alpha = 0.5f * tsin / _q;
const float a0 = 1.0f / ( 1.0f+alpha );
const float a0 = 1.0f / ( 1.0f + alpha );
if( m_type == LOWPASS ||
m_type == DOUBLE_LOWPASS )
{
m_b0a0 = ((1.0f-tcos)/2.0f)*a0;
m_b0a0 = ((1.0f-tcos)*0.5f)*a0;
m_b1a0 = (1.0f-tcos)*a0;
m_b2a0 = m_b0a0;//((1.0f-tcos)/2.0f)*a0;
m_a1a0 = (-2.0f*tcos)*a0;
@@ -306,26 +308,25 @@ public:
if( m_subFilter == NULL )
{
m_subFilter =
new basicFilters<CHANNELS>( m_sampleRate );
new basicFilters<CHANNELS>( static_cast<sample_rate_t>(
1.0f / m_sampleRate ) );
}
m_subFilter->calcFilterCoeffs(
LOWPASS,
_freq,
_q );
LOWPASS, _freq, _q );
}
}
else if( m_type == HIPASS )
{
m_b0a0 = ((1.0f+tcos)/2.0f)*a0;
m_b0a0 = ((1.0f+tcos)*0.5f)*a0;
m_b1a0 = (-1.0f-tcos)*a0;
m_b2a0 = m_b0a0;//((1.0f+tcos)/2.0f)*a0;
m_a1a0 = (-2.0f*tcos)*a0;
}
else if( m_type == BANDPASS_CSG )
{
m_b0a0 = (tsin/2.0f)*a0;
m_b0a0 = tsin*0.5f*a0;
m_b1a0 = 0.0f;
m_b2a0 = (-tsin/2.0f)*a0;
m_b2a0 = -tsin*0.5f*a0;
m_a1a0 = (-2.0f*tcos)*a0;
}
else if( m_type == BANDPASS_CZPG )
@@ -364,7 +365,7 @@ private:
// coeffs for moog-filter
float m_r, m_p, m_k;
typedef sampleType frame[CHANNELS];
typedef sample_t frame[CHANNELS];
// in/out history
frame m_ou1, m_ou2, m_in1, m_in2;

View File

@@ -1,7 +1,7 @@
/*
* effect_board.h - stuff for effect-board
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -22,15 +22,14 @@
*
*/
#ifndef _EFFECT_BOARD_H
#define _EFFECT_BOARD_H
#include "types.h"
const int MIN_EFFECT_CHANNEL = 0;
const int MAX_EFFECT_CHANNEL = 63;
const int DEFAULT_EFFECT_CHANNEL = MIN_EFFECT_CHANNEL;
typedef Sint8 fxChnl;
const fx_ch_t MIN_EFFECT_CHANNEL = 0;
const fx_ch_t MAX_EFFECT_CHANNEL = 63;
const fx_ch_t DEFAULT_EFFECT_CHANNEL = MIN_EFFECT_CHANNEL;
#endif

View File

@@ -1,7 +1,7 @@
/*
* export.h - header which is needed for song-export
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -31,14 +31,14 @@
class audioFileDevice;
typedef audioFileDevice * ( * getDeviceInst)( Uint32 _sample_rate,
Uint32 _channels,
typedef audioFileDevice * ( * getDeviceInst)( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
bool _use_vbr,
Uint16 _nom_bitrate,
Uint16 _min_bitrate,
Uint16 _max_bitrate );
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate );
enum fileTypes

View File

@@ -61,26 +61,31 @@ class plugin;
class audioPort;
const int DEFAULT_BUFFER_SIZE = 512;
const fpab_t DEFAULT_BUFFER_SIZE = 512;
const Uint8 DEFAULT_CHANNELS = 2;
const ch_cnt_t DEFAULT_CHANNELS = 2;
const Uint8 SURROUND_CHANNELS =
const ch_cnt_t SURROUND_CHANNELS =
#ifndef DISABLE_SURROUND
4;
#else
2;
#endif
const Uint8 QUALITY_LEVELS = 2;
const Uint32 DEFAULT_QUALITY_LEVEL = 0;
const Uint32 HIGH_QUALITY_LEVEL = DEFAULT_QUALITY_LEVEL+1;
extern Uint32 SAMPLE_RATES[QUALITY_LEVELS];
const Uint32 DEFAULT_SAMPLE_RATE = 44100;
enum qualityLevels
{
DEFAULT_QUALITY_LEVEL,
HIGH_QUALITY_LEVEL,
QUALITY_LEVELS
} ;
extern sample_rate_t SAMPLE_RATES[QUALITY_LEVELS];
const sample_rate_t DEFAULT_SAMPLE_RATE = 44100;
typedef sampleType sampleFrame[DEFAULT_CHANNELS];
typedef sampleType surroundSampleFrame[SURROUND_CHANNELS];
typedef sample_t sampleFrame[DEFAULT_CHANNELS];
typedef sample_t surroundSampleFrame[SURROUND_CHANNELS];
typedef struct
{
@@ -88,10 +93,10 @@ typedef struct
} volumeVector;
const Uint32 BYTES_PER_SAMPLE = sizeof( sampleType );
const Uint32 BYTES_PER_FRAME = sizeof( sampleFrame );
const Uint32 BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame );
const Uint32 BYTES_PER_OUTPUT_SAMPLE = sizeof( outputSampleType );
const Uint8 BYTES_PER_SAMPLE = sizeof( sample_t );
const Uint8 BYTES_PER_INT_SAMPLE = sizeof( int_sample_t );
const Uint8 BYTES_PER_FRAME = sizeof( sampleFrame );
const Uint8 BYTES_PER_SURROUND_FRAME = sizeof( surroundSampleFrame );
const float OUTPUT_SAMPLE_MULTIPLIER = 32767.0f;
@@ -116,11 +121,13 @@ public:
}
void FASTCALL bufferToPort( sampleFrame * _buf, Uint32 _frames,
Uint32 _framesAhead,
volumeVector & _volumeVector,
audioPort * _port );
inline Uint32 framesPerAudioBuffer( void ) const
void FASTCALL bufferToPort( const sampleFrame * _buf,
const fpab_t _frames,
const fpab_t _framesAhead,
const volumeVector & _volumeVector,
audioPort * _port );
inline fpab_t framesPerAudioBuffer( void ) const
{
return( m_framesPerAudioBuffer );
}
@@ -205,7 +212,7 @@ public:
inline Uint32 sampleRate( void )
inline sample_rate_t sampleRate( void )
{
return( SAMPLE_RATES[m_qualityLevel] );
}
@@ -222,7 +229,7 @@ public:
}
static inline sampleType clip( sampleType _s )
static inline sample_t clip( const sample_t _s )
{
if( _s > 1.0f )
{
@@ -238,22 +245,31 @@ public:
void pause( void )
{
m_mixMutex.lock();
if( m_mixMutexLockLevel == 0 )
{
m_mixMutex.lock();
}
++m_mixMutexLockLevel;
}
void play( void )
{
m_mixMutex.unlock();
if( m_mixMutexLockLevel == 1 )
{
m_mixMutex.unlock();
}
--m_mixMutexLockLevel;
}
void FASTCALL clear( bool _everything = FALSE );
void FASTCALL clear( const bool _everything = FALSE );
void FASTCALL clearAudioBuffer( sampleFrame * _ab, Uint32 _frames );
void FASTCALL clearAudioBuffer( sampleFrame * _ab,
const f_cnt_t _frames );
#ifndef DISABLE_SURROUND
void FASTCALL clearAudioBuffer( surroundSampleFrame * _ab,
Uint32 _frames );
const f_cnt_t _frames );
#endif
inline bool haveNoRunningNotes( void ) const
@@ -264,13 +280,15 @@ public:
const surroundSampleFrame * renderNextBuffer( void );
public slots:
void setHighQuality( bool _hq_on = FALSE );
signals:
void sampleRateChanged( void );
void nextAudioBuffer( const surroundSampleFrame *, Uint32 _frames );
void nextAudioBuffer( const surroundSampleFrame *,
const fpab_t _frames );
private:
@@ -293,13 +311,14 @@ private:
audioDevice * tryAudioDevices( void );
midiClient * tryMIDIClients( void );
void processBuffer( surroundSampleFrame * _buf, fxChnl _fx_chnl );
void processBuffer( const surroundSampleFrame * _buf,
const fx_ch_t _fx_chnl );
vvector<audioPort *> m_audioPorts;
Uint32 m_framesPerAudioBuffer;
fpab_t m_framesPerAudioBuffer;
surroundSampleFrame * m_curBuf;
surroundSampleFrame * m_nextBuf;
@@ -309,7 +328,7 @@ private:
playHandleVector m_playHandles;
playHandleVector m_playHandlesToRemove;
Uint8 m_qualityLevel;
qualityLevels m_qualityLevel;
float m_masterGain;
@@ -323,6 +342,7 @@ private:
QMutex m_mixMutex;
Uint8 m_mixMutexLockLevel;
friend class lmmsMainWin;

View File

@@ -1,7 +1,7 @@
/*
* oscillator.h - header-file for oscillator.cpp, a powerful oscillator-class
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -42,7 +42,8 @@
class oscillator;
typedef void ( oscillator:: * oscFuncPtr )
( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl );
( sampleFrame * _ab, const fpab_t _frames,
const ch_cnt_t _chnl );
const sampleFrame ZERO_FRAME = { 0.0f, 0.0f } ;
@@ -68,14 +69,16 @@ public:
FREQ_MODULATION, AMP_MODULATION, MIX, SYNC
} ;
oscillator( modulationAlgos _modulation_algo, float _freq,
Sint16 _phase_offset, float _volume_factor,
oscillator * _m_subOsc );
inline virtual ~oscillator()
oscillator( const modulationAlgos _modulation_algo, const float _freq,
const Sint16 _phase_offset, const float _volume_factor,
oscillator * _m_subOsc ) FASTCALL;
virtual ~oscillator()
{
delete m_subOsc;
}
inline void setUserWave( const sampleFrame * _data, Uint32 _frames )
inline void setUserWave( const sampleFrame * _data,
const f_cnt_t _frames )
{
if( m_userWaveFrames > 0 )
{
@@ -88,11 +91,14 @@ public:
m_userWaveFrames = 1;
}
}
inline void update( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl )
inline void update( sampleFrame * _ab, const fpab_t _frames,
const ch_cnt_t _chnl )
{
( this->*m_callUpdate )( _ab, _frames, _chnl );
}
inline void setNewFreq( float _new_freq )
inline void setNewFreq( const float _new_freq )
{
// save current state - we need it later for restoring same
// phase (otherwise we'll get clicks in the audio-stream)
@@ -101,9 +107,11 @@ public:
recalcOscCoeff( fraction( v ) );
}
static oscillator * FASTCALL createOsc( waveShapes _wave_shape,
modulationAlgos _modulation_algo, float _freq,
Sint16 _phase_offset, float _volume_factor,
static oscillator * FASTCALL createOsc( const waveShapes _wave_shape,
const modulationAlgos _modulation_algo,
const float _freq,
const Sint16 _phase_offset,
const float _volume_factor,
oscillator * _m_subOsc = NULL );
inline bool syncOk( void )
{
@@ -126,13 +134,12 @@ public:
// now follow the wave-shape-routines...
static inline sampleType sinSample( float _sample )
static inline sample_t sinSample( const float _sample )
{
return( sinf( _sample * static_cast<sampleType>( 2.0f * M_PI
) ) );
return( sinf( _sample * 2.0f * M_PI ) );
}
static inline sampleType triangleSample( float _sample )
static inline sample_t triangleSample( const float _sample )
{
const float ph = fraction( _sample );
if( ph <= 0.25f )
@@ -146,17 +153,17 @@ public:
return( ph * 4.0f - 4.0f );
}
static inline sampleType sawSample( float _sample )
static inline sample_t sawSample( const float _sample )
{
return( -1.0f + fraction( _sample ) * 2.0f );
}
static inline sampleType squareSample( float _sample )
static inline sample_t squareSample( const float _sample )
{
return( ( fraction( _sample ) > 0.5f ) ? -1.0f : 1.0f );
}
static inline sampleType moogSawSample( float _sample )
static inline sample_t moogSawSample( const float _sample )
{
const float ph = fraction( _sample );
if( ph < 0.5f )
@@ -166,7 +173,7 @@ public:
return( 1.0f - 2.0f * ph );
}
static inline sampleType expSample( float _sample )
static inline sample_t expSample( const float _sample )
{
float ph = fraction( _sample );
if( ph > 0.5f )
@@ -176,22 +183,25 @@ public:
return( -1.0f + 8.0f * ph * ph );
}
static inline sampleType noiseSample( float )
static inline sample_t noiseSample( const float )
{
return( 1.0f - 2.0f * ( ( float )rand() * ( 1.0f /
RAND_MAX ) ) );
}
static inline sampleType userWaveSample( float _sample,
const sampleFrame * _user_wave, Uint32 _user_wave_frames )
static inline sample_t userWaveSample( const float _sample,
const sampleFrame * _user_wave,
const f_cnt_t _user_wave_frames )
{
const float frame = fraction( _sample ) * _user_wave_frames;
const Uint32 f1 = static_cast<Uint32>( frame );
const Uint32 f2 = ( f1 + 1 ) % _user_wave_frames;
const f_cnt_t f1 = static_cast<f_cnt_t>( frame );
const f_cnt_t f2 = ( f1 + 1 ) % _user_wave_frames;
return( linearInterpolate( _user_wave[f1][0],
_user_wave[f2][0],
fraction( frame ) ) );
}
inline sampleType userWaveSample( float _sample )
inline sample_t userWaveSample( const float _sample )
{
return( userWaveSample( _sample, m_userWaveData,
m_userWaveFrames ) );
@@ -203,28 +213,34 @@ protected:
float m_volumeFactor;
Sint16 m_phaseOffset;
oscillator * m_subOsc;
Uint32 m_sample;
f_cnt_t m_sample;
float m_oscCoeff;
sampleFrame const * m_userWaveData;
Uint32 m_userWaveFrames;
f_cnt_t m_userWaveFrames;
oscFuncPtr m_callUpdate;
virtual void FASTCALL updateNoSub( sampleFrame * _ab, Uint32 _frames,
Uint8 _chnl ) = 0;
virtual void FASTCALL updateFM( sampleFrame * _ab, Uint32 _frames,
Uint8 _chnl ) = 0;
virtual void FASTCALL updateAM( sampleFrame * _ab, Uint32 _frames,
Uint8 _chnl ) = 0;
virtual void FASTCALL updateMix( sampleFrame * _ab, Uint32 _frames,
Uint8 _chnl ) = 0;
virtual void FASTCALL updateSync( sampleFrame * _ab, Uint32 _frames,
Uint8 _chnl ) = 0;
virtual void FASTCALL updateNoSub( sampleFrame * _ab,
const fpab_t _frames,
const ch_cnt_t _chnl ) = 0;
virtual void FASTCALL updateFM( sampleFrame * _ab,
const fpab_t _frames,
const ch_cnt_t _chnl ) = 0;
virtual void FASTCALL updateAM( sampleFrame * _ab,
const fpab_t _frames,
const ch_cnt_t _chnl ) = 0;
virtual void FASTCALL updateMix( sampleFrame * _ab,
const fpab_t _frames,
const ch_cnt_t _chnl ) = 0;
virtual void FASTCALL updateSync( sampleFrame * _ab,
const fpab_t _frames,
const ch_cnt_t _chnl ) = 0;
inline void sync( void )
{
m_sample = 0;
}
void FASTCALL recalcOscCoeff( const float _additional_phase_offset =
0.0 );

View File

@@ -71,15 +71,16 @@ public:
// base64-data out of string
sampleBuffer( const QString & _audio_file = "",
bool _is_base64_data = FALSE );
sampleBuffer( const sampleFrame * _data, Uint32 _frames );
sampleBuffer( Uint32 _frames );
sampleBuffer( const sampleFrame * _data, const f_cnt_t _frames );
sampleBuffer( const f_cnt_t _frames );
~sampleBuffer();
bool FASTCALL play( sampleFrame * _ab, Uint32 _start_frame,
Uint32 _frames =
bool FASTCALL play( sampleFrame * _ab, const f_cnt_t _start_frame,
const fpab_t _frames =
mixer::inst()->framesPerAudioBuffer(),
float _freq = BASE_FREQ, bool _looped = FALSE,
const float _freq = BASE_FREQ,
const bool _looped = FALSE,
void * * _resampling_data = NULL );
void FASTCALL drawWaves( QPainter & _p, QRect _dr,
@@ -90,17 +91,17 @@ public:
return( m_audioFile );
}
inline Uint32 startFrame( void ) const
inline f_cnt_t startFrame( void ) const
{
return( m_startFrame );
}
inline Uint32 endFrame( void ) const
inline f_cnt_t endFrame( void ) const
{
return( m_endFrame );
}
inline Uint32 frames( void ) const
inline f_cnt_t frames( void ) const
{
return( m_frames );
}
@@ -128,14 +129,14 @@ public:
static sampleBuffer * FASTCALL resample( sampleFrame * _data,
const Uint32 _frames,
const Uint32 _src_sr,
const Uint32 _dst_sr );
const f_cnt_t _frames,
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr );
static inline sampleBuffer * FASTCALL resample(
sampleBuffer * _buf,
const Uint32 _src_sr,
const Uint32 _dst_sr )
const sampleBuffer * _buf,
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
{
return( resample( _buf->m_data, _buf->m_frames, _src_sr,
_dst_sr ) );
@@ -145,8 +146,8 @@ public:
public slots:
void setAudioFile( const QString & _audio_file );
void loadFromBase64( const QString & _data );
void setStartFrame( Uint32 _s );
void setEndFrame( Uint32 _e );
void setStartFrame( const f_cnt_t _s );
void setEndFrame( const f_cnt_t _e );
void setAmplification( float _a );
void setReversed( bool _on );
@@ -155,28 +156,31 @@ private:
void FASTCALL update( bool _keep_settings = FALSE );
#ifdef SDL_SDL_SOUND_H
Uint32 FASTCALL decodeSampleSDL( const char * _f, Sint16 * & _buf,
Uint8 & _channels,
Uint32 & _sample_rate );
f_cnt_t FASTCALL decodeSampleSDL( const char * _f,
int_sample_t * & _buf,
ch_cnt_t & _channels,
sample_rate_t & _sample_rate );
#endif
#ifdef HAVE_SNDFILE_H
Uint32 FASTCALL decodeSampleSF( const char * _f, Sint16 * & _buf,
Uint8 & _channels,
Uint32 & _sample_rate );
f_cnt_t FASTCALL decodeSampleSF( const char * _f,
int_sample_t * & _buf,
ch_cnt_t & _channels,
sample_rate_t & _sample_rate );
#endif
#ifdef HAVE_VORBIS_VORBISFILE_H
Uint32 FASTCALL decodeSampleOGGVorbis( const char * _f, Sint16 * & _buf,
Uint8 & _channels,
Uint32 & _sample_rate );
f_cnt_t FASTCALL decodeSampleOGGVorbis( const char * _f,
int_sample_t * & _buf,
ch_cnt_t & _channels,
sample_rate_t & _sample_rate );
#endif
QString m_audioFile;
sampleFrame * m_origData;
Uint32 m_origFrames;
f_cnt_t m_origFrames;
sampleFrame * m_data;
Uint32 m_frames;
Uint32 m_startFrame;
Uint32 m_endFrame;
f_cnt_t m_frames;
f_cnt_t m_startFrame;
f_cnt_t m_endFrame;
float m_amplification;
bool m_reversed;
QMutex m_dataMutex;

View File

@@ -1,7 +1,7 @@
/*
* types.h - typedefs for common types that are used in the whole app
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -22,10 +22,10 @@
*
*/
#ifndef _TYPES_H
#define _TYPES_H
typedef unsigned char Uint8;
typedef signed char Sint8;
typedef unsigned short Uint16;
@@ -42,8 +42,16 @@ typedef Uint8 volume;
typedef Sint8 panning;
typedef float sampleType;
typedef Sint16 outputSampleType;
typedef float sample_t; // standard sample-type
typedef Sint16 int_sample_t; // 16-bit-int-sample
typedef Uint32 sample_rate_t; // sample-rate
typedef Uint16 fpab_t; // frames per audio-buffer (0-16384)
typedef Uint32 f_cnt_t; // standard frame-count
typedef Uint8 ch_cnt_t; // channel-count (0-SURROUND_CHANNELS)
typedef Uint16 bpm_t; // tempo (MIN_BPM to MAX_BPM)
typedef Uint16 bitrate_t; // bitrate in kbps
typedef Sint8 fx_ch_t; // FX-channel (0 to MAX_EFFECT_CHANNEL)
#endif

View File

@@ -65,7 +65,7 @@ protected:
protected slots:
void setAudioBuffer( const surroundSampleFrame * _ab, Uint32 _frames );
void setAudioBuffer( const surroundSampleFrame * _ab, const fpab_t _frames );
private:
@@ -73,7 +73,6 @@ private:
bool m_enabled;
surroundSampleFrame * m_buffer;
Uint32 m_frames;
QTimer * m_updateTimer;

View File

@@ -126,7 +126,7 @@ bSynth::~bSynth()
delete[] sample_shape;
}
sampleType bSynth::nextStringSample( void )
sample_t bSynth::nextStringSample( void )
{
@@ -135,7 +135,7 @@ sampleType bSynth::nextStringSample( void )
sample_realindex -= sample_length;
}
sampleType sample;
sample_t sample;
if (interpolation) {
@@ -705,7 +705,7 @@ void bitInvader::playNote( notePlayHandle * _n )
bSynth * ps = static_cast<bSynth *>( _n->m_pluginData );
for( Uint32 frame = 0; frame < frames; ++frame )
{
const sampleType cur = ps->nextStringSample();
const sample_t cur = ps->nextStringSample();
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
buf[frame][chnl] = cur;

View File

@@ -56,7 +56,7 @@ public:
bSynth(float* sample, int length, float _pitch, bool _interpolation, float factor);
virtual ~bSynth();
sampleType nextStringSample();
sample_t nextStringSample();
private:

View File

@@ -148,7 +148,7 @@ void pluckedStringSynth::playNote( notePlayHandle * _n )
pluckSynth * ps = static_cast<pluckSynth *>( _n->m_pluginData );
for( Uint32 frame = 0; frame < frames; ++frame )
{
const sampleType cur = ps->nextStringSample();
const sample_t cur = ps->nextStringSample();
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
buf[frame][chnl] = cur;
@@ -178,7 +178,7 @@ pluckSynth::delayLine * FASTCALL pluckSynth::initDelayLine( int _len )
dl->length = _len;
if( _len > 0 )
{
dl->data = new sampleType[_len];
dl->data = new sample_t[_len];
}
else
{

View File

@@ -46,16 +46,16 @@ public:
pluckSynth::freeDelayLine( m_lowerRail );
}
inline sampleType nextStringSample( void )
inline sample_t nextStringSample( void )
{
// Output at pickup position
sampleType outsamp = rgDlAccess( m_upperRail, m_pickupLoc );
sample_t outsamp = rgDlAccess( m_upperRail, m_pickupLoc );
outsamp += lgDlAccess( m_lowerRail, m_pickupLoc );
// Sample traveling into "bridge"
sampleType ym0 = lgDlAccess( m_lowerRail, 1 );
sample_t ym0 = lgDlAccess( m_lowerRail, 1 );
// Sample to "nut"
sampleType ypM = rgDlAccess( m_upperRail,
sample_t ypM = rgDlAccess( m_upperRail,
m_upperRail->length - 2 );
// String state update
@@ -72,10 +72,10 @@ public:
private:
struct delayLine
{
sampleType * data;
sample_t * data;
int length;
sampleType * pointer;
sampleType * end;
sample_t * pointer;
sample_t * end;
} ;
delayLine * m_upperRail;
@@ -100,9 +100,9 @@ private:
* wave travels one sample to the left), turning the previous
* position into an "effective" x = L position for the next
* iteration. */
static inline void lgDlUpdate( delayLine * _dl, sampleType _insamp )
static inline void lgDlUpdate( delayLine * _dl, sample_t _insamp )
{
register sampleType * ptr = _dl->pointer;
register sample_t * ptr = _dl->pointer;
*ptr = _insamp;
++ptr;
if( ptr > _dl->end )
@@ -118,9 +118,9 @@ private:
* "effective" x = 0 position for the next iteration. The
* "bridge-reflected" sample from lower delay-line is then placed
* into this position. */
static inline void rgDlUpdate( delayLine * _dl, sampleType _insamp )
static inline void rgDlUpdate( delayLine * _dl, sample_t _insamp )
{
register sampleType * ptr = _dl->pointer;
register sample_t * ptr = _dl->pointer;
--ptr;
if( ptr < _dl->data )
{
@@ -133,9 +133,9 @@ private:
/* dlAccess(dl, position);
* Returns sample "position" samples into delay-line's past.
* Position "0" points to the most recently inserted sample. */
static inline sampleType dlAccess( delayLine * _dl, int _position )
static inline sample_t dlAccess( delayLine * _dl, int _position )
{
sampleType * outpos = _dl->pointer + _position;
sample_t * outpos = _dl->pointer + _position;
while( outpos < _dl->data )
{
outpos += _dl->length;
@@ -163,7 +163,7 @@ private:
* is equal to the current upper delay-line pointer position (x = 0).
* In a right-going delay-line, position increases to the right, and
* delay increases to the right => left = past and right = future. */
static inline sampleType rgDlAccess( delayLine * _dl, int _position )
static inline sample_t rgDlAccess( delayLine * _dl, int _position )
{
return( dlAccess( _dl, _position ) );
}
@@ -173,14 +173,14 @@ private:
* is equal to the current lower delay-line pointer position (x = 0).
* In a left-going delay-line, position increases to the right, and
* delay DEcreases to the right => left = future and right = past. */
static inline sampleType lgDlAccess( delayLine * _dl, int _position )
static inline sample_t lgDlAccess( delayLine * _dl, int _position )
{
return( dlAccess( _dl, _position ) );
}
static inline sampleType bridgeReflection( sampleType _insamp )
static inline sample_t bridgeReflection( sample_t _insamp )
{
static sampleType state = 0.0f; // filter memory
static sample_t state = 0.0f; // filter memory
// Implement a one-pole lowpass with feedback coefficient = 0.5
return( state = state*0.5f + _insamp*0.5f );
}

View File

@@ -1,3 +1,29 @@
/*
* communication.h - header file defining stuff concerning communication between
* LVSL-server and -client
*
* Copyright (c) 2005-2006 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#ifndef _COMMUNICATION_H
#define _COMMUNICATION_H
@@ -79,6 +105,18 @@ struct vstParamProperties
} ;
enum hostLanguages
{
LVSL_LANG_ENGLISH = 1,
LVSL_LANG_GERMAN,
LVSL_LANG_FRENCH,
LVSL_LANG_ITALIAN,
LVSL_LANG_SPANISH,
LVSL_LANG_JAPANESE
} ;
enum vstRemoteCommands
{
// client -> server
@@ -90,6 +128,7 @@ enum vstRemoteCommands
VST_SAMPLE_RATE,
VST_BUFFER_SIZE,
VST_BPM,
VST_LANGUAGE,
VST_GET_PARAMETER_COUNT = 20,
VST_GET_PARAMETER_DUMP,
VST_SET_PARAMETER_DUMP,
@@ -103,6 +142,7 @@ enum vstRemoteCommands
VST_INPUT_COUNT,
VST_OUTPUT_COUNT,
VST_PLUGIN_XID,
VST_PLUGIN_EDITOR_GEOMETRY,
VST_PROCESS_DONE,
VST_PLUGIN_NAME,
VST_PLUGIN_VERSION,

View File

@@ -35,6 +35,8 @@
#else
#include <qapplication.h>
#include <qlocale.h>
#include "qxembed.h"
#define QX11EmbedWidget QXEmbed
@@ -80,11 +82,12 @@
remoteVSTPlugin::remoteVSTPlugin( const QString & _plugin ) :
m_failed( TRUE ),
m_plugin( _plugin ),
m_pluginWidget( NULL ),
m_pluginWID( 0 ),
m_pluginXID( 0 ),
m_pluginPID( -1 ),
m_serverInFD( -1 ),
m_serverOutFD( -1 ),
@@ -132,6 +135,20 @@ remoteVSTPlugin::remoteVSTPlugin( const QString & _plugin ) :
m_serverOutFD = m_pipes[0][1];
lock();
writeValueS<Sint16>( VST_LANGUAGE );
hostLanguages hlang = LVSL_LANG_ENGLISH;
switch( QLocale::system().language() )
{
case QLocale::German: hlang = LVSL_LANG_GERMAN; break;
case QLocale::French: hlang = LVSL_LANG_FRENCH; break;
case QLocale::Italian: hlang = LVSL_LANG_ITALIAN; break;
case QLocale::Spanish: hlang = LVSL_LANG_SPANISH; break;
case QLocale::Japanese: hlang = LVSL_LANG_JAPANESE; break;
default: break;
}
writeValueS<hostLanguages>( hlang );
writeValueS<Sint16>( VST_LOAD_PLUGIN );
writeStringS( m_plugin.
#ifdef QT4
@@ -210,8 +227,6 @@ remoteVSTPlugin::~remoteVSTPlugin()
#include <X11/Xlib.h>
void remoteVSTPlugin::showEditor( void )
{
@@ -220,29 +235,21 @@ void remoteVSTPlugin::showEditor( void )
m_pluginWidget->show();
return;
}
if( m_pluginWID == 0 )
if( m_pluginXID == 0 )
{
return;
}
XWindowAttributes attr;
XGetWindowAttributes(
#ifdef QT4
QX11Info::display(),
#else
qt_xdisplay(),
#endif
m_pluginWID, &attr );
m_pluginWidget = new QWidget( lmmsMainWin::inst()->workspace() );
m_pluginWidget->setFixedSize( attr.width, attr.height );
m_pluginWidget->setFixedSize( m_pluginGeometry );
m_pluginWidget->setWindowTitle( name() );
m_pluginWidget->show();
QX11EmbedWidget * xe = new QX11EmbedWidget( m_pluginWidget );
xe->embedInto( m_pluginWID );
xe->setFixedSize( attr.width, attr.height );
xe->embedInto( m_pluginXID );
xe->setFixedSize( m_pluginGeometry );
//xe->setAutoDelete( FALSE );
m_pluginWidget->show();
xe->show();
lock();
@@ -267,14 +274,14 @@ void remoteVSTPlugin::hideEditor( void )
void remoteVSTPlugin::process( const sampleFrame * _in_buf,
sampleFrame * _out_buf )
{
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
const fpab_t frames = mixer::inst()->framesPerAudioBuffer();
if( m_shm == NULL )
{
// m_shm being zero means we didn't initialize everything so
// far so process one message each time (and hope we get
// information like SHM-key etc.) until we process
// messages in later stage of this procedure
// information like SHM-key etc.) until we process messages
// in a later stage of this procedure
if( m_shmSize == 0 && messagesLeft() == TRUE )
{
(void) processNextMessage();
@@ -285,15 +292,15 @@ void remoteVSTPlugin::process( const sampleFrame * _in_buf,
memset( m_shm, 0, m_shmSize );
Uint8 inputs = tMax<Uint8>( m_inputCount, DEFAULT_CHANNELS );
ch_cnt_t inputs = tMax<ch_cnt_t>( m_inputCount, DEFAULT_CHANNELS );
if( _in_buf != NULL && inputs > 0 )
{
for( Uint8 ch = 0; ch < inputs; ++ch )
for( ch_cnt_t ch = 0; ch < inputs; ++ch )
{
for( Uint32 frame = 0; frame < frames; ++frame )
for( fpab_t frame = 0; frame < frames; ++frame )
{
m_shm[ch*frames+frame] = _in_buf[frame][ch];
m_shm[ch * frames + frame] = _in_buf[frame][ch];
}
}
}
@@ -307,19 +314,21 @@ void remoteVSTPlugin::process( const sampleFrame * _in_buf,
// wait until server signals that process()ing is done
while( processNextMessage() != VST_PROCESS_DONE )
{
// allow better scheduling (we're just waiting)
// hopefully scheduler gives process-time to plugin...
usleep( 10 );
}
Uint8 outputs = tMax<Uint8>( m_outputCount, DEFAULT_CHANNELS );
ch_cnt_t outputs = tMax<ch_cnt_t>( m_outputCount,
DEFAULT_CHANNELS );
if( outputs != DEFAULT_CHANNELS )
{
// clear buffer, if plugin doesn't fill up both channels
// clear buffer, if plugin didn't fill up both channels
mixer::inst()->clearAudioBuffer( _out_buf, frames );
}
for( Uint8 ch = 0; ch < outputs; ++ch )
for( ch_cnt_t ch = 0; ch < outputs; ++ch )
{
for( Uint32 frame = 0; frame < frames; ++frame )
for( fpab_t frame = 0; frame < frames; ++frame )
{
_out_buf[frame][ch] = m_shm[(m_inputCount+ch)*
frames+frame];
@@ -376,7 +385,7 @@ void remoteVSTPlugin::setParameterDump( const QMap<QString, QString> & _pdump )
for( QMap<QString, QString>::const_iterator it = _pdump.begin();
it != _pdump.end(); ++it )
{
vstParameterDumpItem dump_item =
const vstParameterDumpItem dump_item =
{
( *it ).section( ':', 0, 0 ).toInt(),
"",
@@ -397,6 +406,7 @@ void remoteVSTPlugin::setShmKeyAndSize( Uint16 _key, size_t _size )
m_shm = NULL;
m_shmSize = 0;
}
// only called for detaching SHM?
if( _size == 0 )
{
@@ -418,14 +428,6 @@ void remoteVSTPlugin::setShmKeyAndSize( Uint16 _key, size_t _size )
void remoteVSTPlugin::setPluginXID( const Sint32 _plugin_xid )
{
m_pluginWID = _plugin_xid;
}
bool remoteVSTPlugin::messagesLeft( void ) const
{
fd_set rfds;
@@ -462,13 +464,14 @@ Sint16 remoteVSTPlugin::processNextMessage( void )
case VST_GET_SAMPLE_RATE:
writeValueS<Sint16>( VST_SAMPLE_RATE );
// handle is the same
writeValueS<Sint32>( mixer::inst()->sampleRate() );
writeValueS<sample_rate_t>(
mixer::inst()->sampleRate() );
break;
case VST_GET_BUFFER_SIZE:
writeValueS<Sint16>( VST_BUFFER_SIZE );
// handle is the same
writeValueS<Uint32>(
writeValueS<fpab_t>(
mixer::inst()->framesPerAudioBuffer() );
break;
@@ -481,17 +484,36 @@ Sint16 remoteVSTPlugin::processNextMessage( void )
}
case VST_INPUT_COUNT:
m_inputCount = readValueS<Uint8>();
m_inputCount = readValueS<ch_cnt_t>();
break;
case VST_OUTPUT_COUNT:
m_outputCount = readValueS<Uint8>();
m_outputCount = readValueS<ch_cnt_t>();
break;
case VST_PLUGIN_XID:
setPluginXID( readValueS<Sint32>() );
m_pluginXID = readValueS<Sint32>();
break;
case VST_PLUGIN_EDITOR_GEOMETRY:
{
const Sint16 w = readValueS<Sint16>();
const Sint16 h = readValueS<Sint16>();
m_pluginGeometry = QSize( w, h );
if( m_pluginWidget != NULL )
{
m_pluginWidget->setFixedSize(
m_pluginGeometry );
if( m_pluginWidget->childAt( 0, 0 ) != NULL )
{
m_pluginWidget->childAt( 0, 0
)->setFixedSize(
m_pluginGeometry );
}
}
break;
}
case VST_PLUGIN_NAME:
m_name = readStringS().c_str();
break;

View File

@@ -144,14 +144,13 @@ private:
Sint16 processNextMessage( void );
void FASTCALL setShmKeyAndSize( const Uint16 _key, const size_t _size );
void FASTCALL setPluginXID( const Sint32 _plugin_xid );
bool m_failed;
QString m_plugin;
QWidget * m_pluginWidget;
Sint32 m_pluginWID;
Sint32 m_pluginXID;
QSize m_pluginGeometry;
int m_pluginPID;
int m_pipes[2][2];

View File

@@ -56,19 +56,19 @@
#include <signal.h>
#endif
#ifdef HAVE_SCHED_H
#include <sched.h>
#endif
#include <windows.h>
#include <wine/exception.h>
#include <vector>
#include <list>
#include <string>
#include "types.h"
#include "midi.h"
#include "communication.h"
#include <aeffectx.h>
#if kVstVersion < 2400
@@ -89,6 +89,11 @@ struct ERect
#endif
#include "types.h"
#include "midi.h"
#include "communication.h"
#ifdef HAVE_TLS
static __thread int ejmpbuf_valid = false;
static __thread jmp_buf ejmpbuf;
@@ -98,6 +103,9 @@ static pthread_key_t ejmpbuf_key;
#endif
static hostLanguages hlang = LVSL_LANG_ENGLISH;
class VSTPlugin;
VSTPlugin * plugin = NULL;
@@ -140,20 +148,21 @@ public:
// enqueue given MIDI-event to be processed the next time process() is
// called
void enqueueMidiEvent( const midiEvent & _event,
const Uint32 _frames_ahead );
const f_cnt_t _frames_ahead );
// set given sample-rate for plugin
void setSampleRate( const Sint32 _rate )
void setSampleRate( const sample_rate_t _rate )
{
m_plugin->dispatcher( m_plugin, effSetSampleRate, 0, 0, NULL,
(float) _rate );
m_sampleRate = _rate;
}
// set given block-size for plugin
void setBlockSize( const Uint32 _bsize );
void setBlockSize( const fpab_t _bsize );
// set given tempo
void setBPM( const Uint16 _bpm )
void setBPM( const bpm_t _bpm )
{
m_bpm = _bpm;
}
@@ -184,13 +193,13 @@ public:
void getParameterProperties( const Sint32 _idx );
// number of inputs
Uint8 inputCount( void ) const
ch_cnt_t inputCount( void ) const
{
return( m_plugin->numInputs );
}
// number of outputs
Uint8 outputCount( void ) const
ch_cnt_t outputCount( void ) const
{
return( m_plugin->numOutputs );
}
@@ -224,22 +233,26 @@ private:
AEffect * m_plugin;
HWND m_window;
int m_windowXID;
Sint32 m_windowXID;
Sint16 m_windowWidth;
Sint16 m_windowHeight;
pthread_mutex_t m_lock;
pthread_cond_t m_windowStatusChange;
DWORD m_guiThreadID;
Uint32 m_blockSize;
fpab_t m_blockSize;
float * m_shm;
float * * m_inputs;
float * * m_outputs;
std::vector<VstMidiEvent> m_midiEvents;
std::list<VstMidiEvent> m_midiEvents;
Uint16 m_bpm;
bpm_t m_bpm;
sample_rate_t m_sampleRate;
double m_currentSamplePos;
} ;
@@ -252,6 +265,8 @@ VSTPlugin::VSTPlugin( const std::string & _plugin_file ) :
m_plugin( NULL ),
m_window( NULL ),
m_windowXID( 0 ),
m_windowWidth( 0 ),
m_windowHeight( 0 ),
m_lock(),
m_windowStatusChange(),
m_guiThreadID( 0 ),
@@ -260,7 +275,9 @@ VSTPlugin::VSTPlugin( const std::string & _plugin_file ) :
m_inputs( NULL ),
m_outputs( NULL ),
m_midiEvents(),
m_bpm( 0 )
m_bpm( 0 ),
m_sampleRate( 44100 ),
m_currentSamplePos( 0 )
{
if( load( _plugin_file ) == false )
{
@@ -293,6 +310,13 @@ VSTPlugin::VSTPlugin( const std::string & _plugin_file ) :
writeValue<Sint16>( VST_PLUGIN_XID );
writeValue<Sint32>( m_windowXID );
if( m_windowXID != 0 )
{
writeValue<Sint16>( VST_PLUGIN_EDITOR_GEOMETRY );
writeValue<Sint16>( m_windowWidth );
writeValue<Sint16>( m_windowHeight );
}
writeValue<Sint16>( VST_PLUGIN_NAME );
writeString( pluginName() );
@@ -364,9 +388,9 @@ bool VSTPlugin::load( const std::string & _plugin_file )
m_shortName = basename( tmp );
free( tmp );
typedef AEffect * ( * mainEntry )( audioMasterCallback );
typedef AEffect * ( __stdcall * mainEntry )( audioMasterCallback );
mainEntry main_entry = (mainEntry) GetProcAddress( m_libInst,
"main" );
"main" );
if( main_entry == NULL )
{
return( false );
@@ -402,19 +426,22 @@ void VSTPlugin::process( void )
// dispatcher-call, so we create static copies of the
// data and post them
#define MIDI_EVENT_BUFFER_COUNT 1024
static char event_buf[sizeof(VstMidiEvent * ) *
static char event_buf[sizeof( VstMidiEvent * ) *
MIDI_EVENT_BUFFER_COUNT +
sizeof( VstEvents )];
static VstMidiEvent vme[MIDI_EVENT_BUFFER_COUNT];
VstEvents * events = (VstEvents *) event_buf;
events->reserved = 0;
events->numEvents = m_midiEvents.size();
for( unsigned int i = 0; i < m_midiEvents.size(); ++i )
Sint16 idx = 0;
for( std::list<VstMidiEvent>::iterator it =
m_midiEvents.begin();
it != m_midiEvents.end(); ++it, ++idx )
{
memcpy( &vme[i], &m_midiEvents[i],
sizeof( VstMidiEvent ) );
events->events[i] = (VstEvent *) &vme[i];
memcpy( &vme[idx], &*it, sizeof( VstMidiEvent ) );
events->events[idx] = (VstEvent *) &vme[idx];
}
m_midiEvents.clear();
m_plugin->dispatcher( m_plugin, effProcessEvents, 0, 0, events,
0.0f );
@@ -422,15 +449,14 @@ void VSTPlugin::process( void )
// now we're ready to fetch sound from VST-plugin
for( int i = 0; i < inputCount(); ++i )
for( ch_cnt_t i = 0; i < inputCount(); ++i )
{
m_inputs[i] = &m_shm[i * m_blockSize];
}
for( int i = 0; i < outputCount(); ++i )
for( ch_cnt_t i = 0; i < outputCount(); ++i )
{
m_outputs[i] = &m_shm[( i + inputCount() ) *
m_blockSize];
m_outputs[i] = &m_shm[( i + inputCount() ) * m_blockSize];
}
#ifdef OLD_VST_SDK
@@ -449,6 +475,8 @@ void VSTPlugin::process( void )
}
#endif
m_currentSamplePos += m_blockSize;
writeValue<Sint16>( VST_PROCESS_DONE );
// give plugin some idle-time for GUI-update and so on...
@@ -460,7 +488,7 @@ void VSTPlugin::process( void )
void VSTPlugin::enqueueMidiEvent( const midiEvent & _event,
const Uint32 _frames_ahead )
const f_cnt_t _frames_ahead )
{
VstMidiEvent event;
@@ -484,12 +512,13 @@ void VSTPlugin::enqueueMidiEvent( const midiEvent & _event,
void VSTPlugin::setBlockSize( const Uint32 _bsize )
void VSTPlugin::setBlockSize( const Uint16 _bsize )
{
if( _bsize == m_blockSize )
{
return;
}
m_blockSize = _bsize;
resizeSharedMemory();
m_plugin->dispatcher( m_plugin, effSetBlockSize, 0, _bsize, NULL,
@@ -612,7 +641,7 @@ void VSTPlugin::resizeSharedMemory( void )
int shm_id;
Uint16 shm_key = 0;
while( ( shm_id = shmget( ++shm_key, s, IPC_CREAT | IPC_EXCL |
0666 ) ) == -1 )
0666 ) ) == -1 )
{
}
@@ -628,10 +657,10 @@ void VSTPlugin::resizeSharedMemory( void )
}
writeValue<Sint16>( VST_INPUT_COUNT );
writeValue<Uint8>( inputCount() );
writeValue<ch_cnt_t>( inputCount() );
writeValue<Sint16>( VST_OUTPUT_COUNT );
writeValue<Uint8>( outputCount() );
writeValue<ch_cnt_t>( outputCount() );
writeValue<Sint16>( VST_SHM_KEY_AND_SIZE );
writeValue<Uint16>( shm_key );
@@ -648,6 +677,13 @@ void VSTPlugin::resizeSharedMemory( void )
#endif
/* TODO:
* - complete audioMasterGetTime-handling (bars etc.)
* - implement audioMasterProcessEvents
* - audioMasterGetVendorVersion: return LMMS-version (config.h!)
* - audioMasterGetDirectory: return either VST-plugin-dir or LMMS-workingdir
* - audioMasterOpenFileSelector: show QFileDialog?
*/
VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
VstInt32 _index, VstIntPtr _value,
void * _ptr, float _opt )
@@ -664,8 +700,7 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
case audioMasterVersion:
//SHOW_CALLBACK( "amc: audioMasterVersion\n" );
// vst version, currently 2 (0 for older)
return( 2 );
return( 2300 );
case audioMasterCurrentId:
SHOW_CALLBACK( "amc: audioMasterCurrentId\n" );
@@ -682,7 +717,7 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
return( 0 );
case audioMasterPinConnected:
SHOW_CALLBACK( "amc: audioMasterPinConnected\n" );
//SHOW_CALLBACK( "amc: audioMasterPinConnected\n" );
// inquire if an input or output is beeing connected;
// index enumerates input or output counting from zero:
// value is 0 for input and != 0 otherwise. note: the
@@ -699,8 +734,8 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
_timeInfo.samplePos = 0;
// TODO: _timeInfo.sampleRate = mixer::inst()->sampleRate();
_timeInfo.samplePos = plugin->m_currentSamplePos;
_timeInfo.sampleRate = plugin->m_sampleRate;
_timeInfo.flags = 0;
_timeInfo.tempo = plugin->m_bpm;
_timeInfo.timeSigNumerator = 4;
@@ -717,7 +752,7 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
case audioMasterIOChanged:
plugin->resizeSharedMemory();
SHOW_CALLBACK( "amc: audioMasterIOChanged\n" );
//SHOW_CALLBACK( "amc: audioMasterIOChanged\n" );
// numInputs and/or numOutputs has changed
return( 0 );
@@ -725,21 +760,22 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
case audioMasterWantMidi:
//SHOW_CALLBACK( "amc: audioMasterWantMidi\n" );
// <value> is a filter which is currently ignored
return( 0 );
return( 1 );
case audioMasterSetTime:
SHOW_CALLBACK( "amc: audioMasterSetTime\n" );
// VstTimenfo* in <ptr>, filter in <value>, not
// supported
return( 0 );
case audioMasterTempoAt:
SHOW_CALLBACK( "amc: audioMasterTempoAt\n" );
//SHOW_CALLBACK( "amc: audioMasterTempoAt\n" );
return( plugin->m_bpm * 10000 );
case audioMasterGetNumAutomatableParameters:
SHOW_CALLBACK( "amc: audioMasterGetNumAutomatable"
"Parameters\n" );
return( 0 );
return( 5000 );
case audioMasterGetParameterQuantization:
SHOW_CALLBACK( "amc: audioMasterGetParameter\n"
@@ -748,12 +784,12 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
// or 1 if full single float precision is maintained
// in automation. parameter index in <value> (-1: all,
// any)
return( 0 );
return( 1 );
case audioMasterNeedIdle:
//SHOW_CALLBACK( "amc: audioMasterNeedIdle\n" );
// plug needs idle calls (outside its editor window)
return( 0 );
return( 1 );
case audioMasterGetPreviousPlug:
SHOW_CALLBACK( "amc: audioMasterGetPreviousPlug\n" );
@@ -805,30 +841,37 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
#endif
case audioMasterSizeWindow:
// TODO using lmms-main-window-size
SHOW_CALLBACK( "amc: audioMasterSizeWindow\n" );
// index: width, value: height
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterSizeWindow\n" );
if( plugin->m_window == 0 )
{
return( 0 );
}
plugin->m_windowWidth = _index;
plugin->m_windowHeight = _value;
SetWindowPos( plugin->m_window, 0, 0, 0,
_index + 8, _value + 26,
SWP_NOACTIVATE | SWP_NOMOVE |
SWP_NOOWNERZORDER | SWP_NOZORDER );
writeValue<Sint16>( VST_PLUGIN_EDITOR_GEOMETRY );
writeValue<Sint16>( plugin->m_windowWidth );
writeValue<Sint16>( plugin->m_windowHeight );
return( 1 );
case audioMasterGetSampleRate:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetSampleRate\n" );
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterGetSampleRate\n" );
return( plugin->m_sampleRate );
case audioMasterGetBlockSize:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetBlockSize\n" );
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterGetBlockSize\n" );
return( plugin->m_blockSize );
case audioMasterGetInputLatency:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetInputLatency\n" );
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterGetInputLatency\n" );
return( plugin->m_blockSize );
case audioMasterGetOutputLatency:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetOutputLatency\n" );
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterGetOutputLatency\n" );
return( plugin->m_blockSize );
case audioMasterGetCurrentProcessLevel:
SHOW_CALLBACK( "amc: audioMasterGetCurrentProcess"
@@ -876,22 +919,22 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
return( 0 );
case audioMasterGetVendorString:
SHOW_CALLBACK( "amc: audioMasterGetVendorString\n" );
//SHOW_CALLBACK( "amc: audioMasterGetVendorString\n" );
// fills <ptr> with a string identifying the vendor
// (max 64 char)
strcpy( (char *) _ptr, "LAD");
return( 0 );
strcpy( (char *) _ptr, "Tobias Doerffel & others");
return( 1 );
case audioMasterGetProductString:
SHOW_CALLBACK( "amc: audioMasterGetProductString\n" );
//SHOW_CALLBACK( "amc: audioMasterGetProductString\n" );
// fills <ptr> with a string with product name
// (max 64 char)
strcpy( (char *) _ptr, "XFST-Server" );
return( 0 );
strcpy( (char *) _ptr,
"LMMS VST Support Layer (LVSL)" );
return( 1 );
case audioMasterGetVendorVersion:
SHOW_CALLBACK( "amc: audioMasterGetVendorVersion\n" );
// TODO
// returns vendor-specific version
return( 1000 );
@@ -901,19 +944,18 @@ VstIntPtr VSTPlugin::hostCallback( AEffect * _effect, VstInt32 _opcode,
return( 0 );
case audioMasterCanDo:
SHOW_CALLBACK( "amc: audioMasterCanDo\n" );
// string in ptr, see below
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterCanDo\n" );
return( !strcmp( (char *) _ptr, "sendVstEvents" ) ||
!strcmp( (char *) _ptr, "sendVstMidiEvent" ) ||
!strcmp( (char *) _ptr, "sendVstTimeInfo" ) ||
!strcmp( (char *) _ptr, "sizeWindow" ) );
case audioMasterGetLanguage:
SHOW_CALLBACK( "amc: audioMasterGetLanguage\n" );
// TODO
// see enum
return( 0 );
//SHOW_CALLBACK( "amc: audioMasterGetLanguage\n" );
return( hlang );
case audioMasterGetDirectory:
SHOW_CALLBACK( "amc: audioMasterGetDirectory\n" );
// TODO
// get plug directory, FSSpec on MAC, else char*
return( 0 );
@@ -1015,7 +1057,7 @@ DWORD WINAPI VSTPlugin::guiEventLoop( LPVOID _param )
return( 1 );
}
_this->m_windowXID = (int) GetPropA( _this->m_window,
_this->m_windowXID = (Sint32) GetPropA( _this->m_window,
"__wine_x11_whole_window" );
@@ -1026,13 +1068,18 @@ DWORD WINAPI VSTPlugin::guiEventLoop( LPVOID _param )
_this->m_plugin->dispatcher( _this->m_plugin, effEditGetRect, 0, 0,
&er, 0 );
/* const int width = er->right - er->left;
const int height = er->bottom - er->top;*/
_this->m_windowWidth = er->right - er->left;
_this->m_windowHeight = er->bottom - er->top;
SetWindowPos( _this->m_window, 0, 0, 0, er->right - er->left + 8,
er->bottom-er->top + 26, SWP_NOACTIVATE | SWP_NOREDRAW |
SWP_NOMOVE | SWP_NOZORDER );
SetWindowPos( _this->m_window, 0, 0, 0, _this->m_windowWidth + 8,
_this->m_windowHeight + 26,
SWP_NOACTIVATE /*| SWP_NOREDRAW*/ | SWP_NOMOVE |
SWP_NOOWNERZORDER | SWP_NOZORDER );
#ifdef HAVE_TLS
ejmpbuf_valid = false;
#else
*ejmpbuf_valid = false;
#endif
pthread_cond_signal( &_this->m_windowStatusChange );
@@ -1050,7 +1097,9 @@ DWORD WINAPI VSTPlugin::guiEventLoop( LPVOID _param )
switch( msg.wParam )
{
case SHOW_EDITOR:
ShowWindow( _this->m_window, SW_SHOW );
ShowWindow( _this->m_window,
SW_SHOWNORMAL );
UpdateWindow( _this->m_window );
break;
case CLOSE_PLUGIN:
@@ -1098,6 +1147,17 @@ int main( void )
return( -1 );
}
#ifdef HAVE_SCHED_H
// try to set realtime-priority
struct sched_param sparam;
sparam.sched_priority = ( sched_get_priority_max( SCHED_FIFO ) +
sched_get_priority_min( SCHED_FIFO ) ) / 2;
if( sched_setscheduler( 0, SCHED_FIFO, &sparam ) == -1 )
{
lvsMessage( "could not set realtime priority for VST-server" );
}
#endif
Sint16 cmd;
while( ( cmd = readValue<Sint16>() ) != VST_CLOSE_PLUGIN )
{
@@ -1118,22 +1178,27 @@ int main( void )
case VST_ENQUEUE_MIDI_EVENT:
{
const midiEvent ev = readValue<midiEvent>();
const Uint32 fr_ahead = readValue<Uint32>();
const f_cnt_t fr_ahead = readValue<f_cnt_t>();
plugin->enqueueMidiEvent( ev, fr_ahead );
break;
}
case VST_SAMPLE_RATE:
plugin->setSampleRate( readValue<Sint32>() );
plugin->setSampleRate(
readValue<sample_rate_t>() );
break;
case VST_BUFFER_SIZE:
plugin->setBlockSize( readValue<Uint32>() );
plugin->setBlockSize( readValue<fpab_t>() );
break;
case VST_BPM:
plugin->setBPM( readValue<Uint16>() );
plugin->setBPM( readValue<bpm_t>() );
break;
case VST_LANGUAGE:
hlang = readValue<hostLanguages>();
break;
case VST_GET_PARAMETER_DUMP:

View File

@@ -54,9 +54,9 @@
audioALSA::audioALSA( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<int>( configManager::inst()->value(
"audioalsa", "channels" ).toInt(),
audioALSA::audioALSA( const sample_rate_t _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<ch_cnt_t>(
configManager::inst()->value( "audioalsa", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ) ),
m_handle( NULL ),
m_hwParams( NULL ),
@@ -214,21 +214,20 @@ void audioALSA::run( void )
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() );
outputSampleType * outbuf =
bufferAllocator::alloc<outputSampleType>(
int_sample_t * outbuf = bufferAllocator::alloc<int_sample_t>(
mixer::inst()->framesPerAudioBuffer() *
channels() );
m_quit = FALSE;
while( m_quit == FALSE )
{
const Uint32 frames = getNextBuffer( temp );
const f_cnt_t frames = getNextBuffer( temp );
convertToS16( temp, frames, mixer::inst()->masterGain(), outbuf,
m_littleEndian != isLittleEndian() );
Uint32 frame = 0;
outputSampleType * ptr = outbuf;
f_cnt_t frame = 0;
int_sample_t * ptr = outbuf;
while( frame < frames )
{
@@ -261,7 +260,8 @@ void audioALSA::run( void )
int audioALSA::setHWParams( Uint32 _sample_rate, Uint32 _channels,
int audioALSA::setHWParams( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
snd_pcm_access_t _access )
{
int err, dir;

View File

@@ -1,7 +1,7 @@
/*
* audio_device.cpp - base-class for audio-devices used by LMMS-mixer
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -36,7 +36,8 @@
audioDevice::audioDevice( Uint32 _sample_rate, Uint8 _channels ) :
audioDevice::audioDevice( const sample_rate_t _sample_rate,
const ch_cnt_t _channels ) :
m_sampleRate( _sample_rate ),
m_channels( _channels ),
m_buffer( bufferAllocator::alloc<surroundSampleFrame>(
@@ -75,16 +76,16 @@ audioDevice::~audioDevice()
void audioDevice::processNextBuffer( void )
{
const Uint32 frames = getNextBuffer( m_buffer );
const fpab_t frames = getNextBuffer( m_buffer );
writeBuffer( m_buffer, frames, mixer::inst()->masterGain() );
}
Uint32 audioDevice::getNextBuffer( surroundSampleFrame * _ab )
fpab_t audioDevice::getNextBuffer( surroundSampleFrame * _ab )
{
Uint32 frames = mixer::inst()->framesPerAudioBuffer();
fpab_t frames = mixer::inst()->framesPerAudioBuffer();
const surroundSampleFrame * b = mixer::inst()->renderNextBuffer();
// make sure, no other thread is accessing device
@@ -165,9 +166,10 @@ const float LP_FILTER_COEFFS[LP_FILTER_TAPS] =
void FASTCALL audioDevice::resample( const surroundSampleFrame * _src,
Uint32 _frames,
const fpab_t _frames,
surroundSampleFrame * _dst,
Uint32 _src_sr, Uint32 _dst_sr )
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
{
#ifdef HAVE_SAMPLERATE_H
if( m_srcState == NULL )
@@ -247,18 +249,20 @@ void FASTCALL audioDevice::resample( const surroundSampleFrame * _src,
} ;
static Uint8 oldest = 0;
for( Uint32 frame = 0; frame < _frames; ++frame )
for( fpab_t frame = 0; frame < _frames; ++frame )
{
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < SURROUND_CHANNELS;
++chnl )
{
lp_hist[oldest][chnl] = _src[frame][chnl];
if( frame % 2==0 )
if( frame % 2 == 0 )
{
_dst[frame/2][chnl] = 0.0f;
const fpab_t f = frame / 2;
_dst[f][chnl] = 0.0f;
for( Uint8 tap = 0;
tap < LP_FILTER_TAPS; ++tap )
{
_dst[frame / 2][chnl] +=
_dst[f][chnl] +=
LP_FILTER_COEFFS[tap] * lp_hist[( oldest + tap ) % LP_FILTER_TAPS][chnl];
}
}
@@ -278,17 +282,18 @@ LP_FILTER_COEFFS[tap] * lp_hist[( oldest + tap ) % LP_FILTER_TAPS][chnl];
int FASTCALL audioDevice::convertToS16( surroundSampleFrame * _ab,
Uint32 _frames, float _master_gain,
outputSampleType * _output_buffer,
bool _convert_endian )
Uint32 FASTCALL audioDevice::convertToS16( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain,
int_sample_t * _output_buffer,
const bool _convert_endian )
{
for( Uint32 frame = 0; frame < _frames; ++frame )
for( fpab_t frame = 0; frame < _frames; ++frame )
{
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
for( ch_cnt_t chnl = 0; chnl < channels(); ++chnl )
{
( _output_buffer + frame * channels() )[chnl] =
static_cast<outputSampleType>(
static_cast<int_sample_t>(
mixer::clip( _ab[frame][chnl] *
_master_gain ) *
OUTPUT_SAMPLE_MULTIPLIER );
@@ -296,34 +301,34 @@ int FASTCALL audioDevice::convertToS16( surroundSampleFrame * _ab,
}
if( _convert_endian )
{
for( Uint32 frame = 0; frame < _frames; ++frame )
for( fpab_t frame = 0; frame < _frames; ++frame )
{
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
for( ch_cnt_t chnl = 0; chnl < channels(); ++chnl )
{
Sint8 * ptr = reinterpret_cast<Sint8 *>(
_output_buffer +
frame * channels() +
chnl );
*(outputSampleType *)ptr =
( ( outputSampleType )*ptr << 8
*(int_sample_t *)ptr =
( ( int_sample_t )*ptr << 8
) |
( ( outputSampleType ) *
( ( int_sample_t ) *
( ptr+1 ) );
}
}
}
return( _frames * channels() * BYTES_PER_OUTPUT_SAMPLE );
return( _frames * channels() * BYTES_PER_INT_SAMPLE );
}
void FASTCALL audioDevice::clearS16Buffer( outputSampleType * _outbuf,
Uint32 _frames )
void FASTCALL audioDevice::clearS16Buffer( int_sample_t * _outbuf,
const fpab_t _frames )
{
#ifdef LMMS_DEBUG
assert( _outbuf != NULL );
#endif
memset( _outbuf, 0, _frames * channels() * BYTES_PER_OUTPUT_SAMPLE );
memset( _outbuf, 0, _frames * channels() * BYTES_PER_INT_SAMPLE );
}

View File

@@ -2,7 +2,7 @@
* audio_file_device.cpp - base-class for audio-device-classes which write
* their output into a file
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -42,12 +42,13 @@
#include "buffer_allocator.h"
audioFileDevice::audioFileDevice( Uint32 _sample_rate, Uint8 _channels,
const QString & _file,
bool _use_vbr,
Uint16 _nom_bitrate,
Uint16 _min_bitrate,
Uint16 _max_bitrate ) :
audioFileDevice::audioFileDevice( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate ) :
audioDevice( _sample_rate, _channels),
m_outputFile( _file ),
m_useVbr( _use_vbr ),
@@ -86,12 +87,12 @@ audioFileDevice::~audioFileDevice()
int audioFileDevice::writeData( const void * _data, int _len )
Sint32 audioFileDevice::writeData( const void * _data, Sint32 _len )
{
#ifdef QT4
return( m_outputFile.write( (const char *)_data, _len ) );
return( m_outputFile.write( (const char *) _data, _len ) );
#else
return( m_outputFile.writeBlock( (const char *)_data, _len ) );
return( m_outputFile.writeBlock( (const char *) _data, _len ) );
#endif
}

View File

@@ -5,7 +5,7 @@
* This file is based on encode.c from vorbis-tools-source, for more information
* see below.
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -39,10 +39,14 @@
#include <cstring>
audioFileOgg::audioFileOgg( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful, const QString & _file,
bool _use_vbr, Uint16 _nom_bitrate,
Uint16 _min_bitrate, Uint16 _max_bitrate ) :
audioFileOgg::audioFileOgg( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate ) :
audioFileDevice( _sample_rate, _channels, _file, _use_vbr,
_nom_bitrate, _min_bitrate, _max_bitrate )
{
@@ -60,9 +64,9 @@ audioFileOgg::~audioFileOgg()
inline int audioFileOgg::writePage( void )
inline Sint32 audioFileOgg::writePage( void )
{
int written = writeData( m_og.header, m_og.header_len );
Sint32 written = writeData( m_og.header, m_og.header_len );
written += writeData( m_og.body, m_og.body_len );
return( written );
}
@@ -75,7 +79,7 @@ bool audioFileOgg::startEncoding( void )
vorbis_comment vc;
char * comments = "Cool=This song has been made using Linux "
"MultiMedia Studio";
int comment_length = strlen( comments );
Sint32 comment_length = strlen( comments );
vc.user_comments = &comments;
vc.comment_lengths = &comment_length;
@@ -86,18 +90,15 @@ bool audioFileOgg::startEncoding( void )
// vbr enabled?
if( useVBR() == 0 )
{
m_managed = -1; // we don't want vbr
m_minBitrate = nominalBitrate(); // min for vbr
m_maxBitrate = nominalBitrate(); // max for vbr
}
else
{
m_managed = 0; // let's use vbr
m_minBitrate = minBitrate(); // min for vbr
m_maxBitrate = maxBitrate(); // max for vbr
}
m_bitrate = nominalBitrate(); // nominal bitrate
m_rate = sampleRate(); // default-samplerate
m_serialNo = 0; // track-num?
m_comments = &vc; // comments for ogg-file
@@ -107,7 +108,7 @@ bool audioFileOgg::startEncoding( void )
if( vorbis_encode_setup_managed( &m_vi, m_channels, m_rate,
( m_maxBitrate > 0 )? m_maxBitrate * 1000 : -1,
m_bitrate * 1000,
nominalBitrate() * 1000,
( m_minBitrate > 0 )? m_minBitrate * 1000 : -1 ) )
{
printf( "Mode initialization failed: invalid parameters for "
@@ -116,11 +117,11 @@ bool audioFileOgg::startEncoding( void )
return( FALSE );
}
if( m_managed && m_bitrate < 0 )
if( useVBR() == FALSE )
{
vorbis_encode_ctl( &m_vi, OV_ECTL_RATEMANAGE_AVG, NULL );
}
else if( !m_managed )
else if( useVBR() == TRUE )
{
// Turn off management entirely (if it was turned on).
vorbis_encode_ctl( &m_vi, OV_ECTL_RATEMANAGE_SET, NULL );
@@ -159,7 +160,7 @@ bool audioFileOgg::startEncoding( void )
{
break;
}
int ret = writePage();
Sint32 ret = writePage();
if( ret != m_og.header_len + m_og.body_len )
{
// clean up
@@ -174,18 +175,18 @@ bool audioFileOgg::startEncoding( void )
void FASTCALL audioFileOgg::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
void FASTCALL audioFileOgg::writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain )
{
int eos = 0;
float * * buffer = vorbis_analysis_buffer( &m_vd, _frames *
BYTES_PER_SAMPLE *
channels() );
for( Uint32 frame = 0; frame < _frames; ++frame )
for( fpab_t frame = 0; frame < _frames; ++frame )
{
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
for( ch_cnt_t chnl = 0; chnl < channels(); ++chnl )
{
buffer[chnl][frame] = _ab[frame][chnl] * _master_gain;
}

View File

@@ -2,7 +2,7 @@
* audio_file_wave.cpp - audio-device which encodes wave-stream and writes it
* into a WAVE-file. This is used for song-export.
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -32,10 +32,13 @@
#include <cstring>
audioFileWave::audioFileWave( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful, const QString & _file,
bool _use_vbr, Uint16 _nom_bitrate,
Uint16 _min_bitrate, Uint16 _max_bitrate ) :
audioFileWave::audioFileWave( const sample_rate_t _sample_rate,
const ch_cnt_t _channels, bool & _success_ful,
const QString & _file,
const bool _use_vbr,
const bitrate_t _nom_bitrate,
const bitrate_t _min_bitrate,
const bitrate_t _max_bitrate ) :
audioFileDevice( _sample_rate, _channels, _file, _use_vbr,
_nom_bitrate, _min_bitrate, _max_bitrate )
{
@@ -67,14 +70,13 @@ bool audioFileWave::startEncoding( void )
memcpy( m_waveFileHeader.wave_fmt_str, "WAVEfmt ", 8 );
m_waveFileHeader.bitrate_1 =
m_waveFileHeader.bitrate_2 =
swap16IfBE( BYTES_PER_OUTPUT_SAMPLE * 8 );
swap16IfBE( BYTES_PER_INT_SAMPLE * 8 );
m_waveFileHeader.uncompressed = swap16IfBE( 1 );
m_waveFileHeader.channels = swap16IfBE( channels() );
m_waveFileHeader.sample_rate = swap32IfBE( sampleRate() );
m_waveFileHeader.bytes_per_second = swap32IfBE( sampleRate() *
BYTES_PER_OUTPUT_SAMPLE *
channels() );
m_waveFileHeader.block_alignment = swap16IfBE( BYTES_PER_OUTPUT_SAMPLE *
BYTES_PER_INT_SAMPLE * channels() );
m_waveFileHeader.block_alignment = swap16IfBE( BYTES_PER_INT_SAMPLE *
channels() );
memcpy ( m_waveFileHeader.data_chunk_id, "data", 4 );
m_waveFileHeader.data_bytes = swap32IfBE( 0 );
@@ -87,13 +89,13 @@ bool audioFileWave::startEncoding( void )
void FASTCALL audioFileWave::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
void FASTCALL audioFileWave::writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames,
const float _master_gain )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
int_sample_t * outbuf = bufferAllocator::alloc<int_sample_t>(
_frames * channels() );
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
Uint32 bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
!isLittleEndian() );
writeData( outbuf, bytes );

View File

@@ -91,9 +91,9 @@
audioOSS::audioOSS( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<int>( configManager::inst()->value(
"audiooss", "channels" ).toInt(),
audioOSS::audioOSS( const sample_rate_t _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<ch_cnt_t>(
configManager::inst()->value( "audiooss", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ) ),
m_convertEndian( FALSE ),
m_quit( FALSE )
@@ -124,9 +124,9 @@ audioOSS::audioOSS( Uint32 _sample_rate, bool & _success_ful ) :
}
int frag_spec;
for( frag_spec = 0; static_cast<unsigned int>( 0x01 << frag_spec ) <
for( frag_spec = 0; static_cast<int>( 0x01 << frag_spec ) <
mixer::inst()->framesPerAudioBuffer() * channels() *
BYTES_PER_OUTPUT_SAMPLE;
BYTES_PER_INT_SAMPLE;
++frag_spec )
{
}
@@ -317,8 +317,7 @@ void audioOSS::run( void )
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() );
outputSampleType * outbuf =
bufferAllocator::alloc<outputSampleType>(
int_sample_t * outbuf = bufferAllocator::alloc<int_sample_t>(
mixer::inst()->framesPerAudioBuffer() *
channels() );
m_quit = FALSE;

View File

@@ -3,7 +3,7 @@
* surround-audio-buffers into RAM, maybe later
* also harddisk
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -33,7 +33,8 @@
audioSampleRecorder::audioSampleRecorder( Uint32 _sample_rate, Uint32 _channels,
audioSampleRecorder::audioSampleRecorder( const sample_rate_t _sample_rate,
const ch_cnt_t _channels,
bool & _success_ful ) :
audioDevice( _sample_rate, _channels ),
m_buffers()
@@ -59,10 +60,10 @@ audioSampleRecorder::~audioSampleRecorder()
Uint32 audioSampleRecorder::framesRecorded( void ) const
{
Uint32 frames = 0;
for( bufferVector::const_iterator it = m_buffers.begin();
for( bufferList::const_iterator it = m_buffers.begin();
it != m_buffers.end(); ++it )
{
frames += it->second;
frames += ( *it ).second;
}
return( frames );
}
@@ -73,7 +74,7 @@ Uint32 audioSampleRecorder::framesRecorded( void ) const
void audioSampleRecorder::createSampleBuffer( sampleBuffer * * _sample_buf )
const
{
Uint32 frames = framesRecorded();
f_cnt_t frames = framesRecorded();
// create buffer to store all recorded buffers in
sampleFrame * data = bufferAllocator::alloc<sampleFrame>( frames );
// make sure buffer is cleaned up properly at the end...
@@ -83,11 +84,12 @@ void audioSampleRecorder::createSampleBuffer( sampleBuffer * * _sample_buf )
assert( data != NULL );
#endif
// now copy all buffers into big buffer
for( bufferVector::const_iterator it = m_buffers.begin();
for( bufferList::const_iterator it = m_buffers.begin();
it != m_buffers.end(); ++it )
{
memcpy( data, it->first, it->second * sizeof( sampleFrame ) );
data += it->second;
memcpy( data, ( *it ).first, ( *it ).second *
sizeof( sampleFrame ) );
data += ( *it ).second;
}
// create according sample-buffer out of big buffer
*_sample_buf = new sampleBuffer( ac.ptr(), frames );
@@ -96,13 +98,13 @@ void audioSampleRecorder::createSampleBuffer( sampleBuffer * * _sample_buf )
void audioSampleRecorder::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames, float )
void audioSampleRecorder::writeBuffer( const surroundSampleFrame * _ab,
const fpab_t _frames, const float )
{
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( _frames );
for( Uint32 frame = 0; frame < _frames; ++frame )
for( fpab_t frame = 0; frame < _frames; ++frame )
{
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
buf[frame][chnl] = _ab[frame][chnl];
}

View File

@@ -48,7 +48,7 @@
audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
audioSDL::audioSDL( const sample_rate_t _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, DEFAULT_CHANNELS ),
m_outBuf( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
@@ -142,11 +142,11 @@ void audioSDL::sdlAudioCallback( void * _udata, Uint8 * _buf, int _len )
assert( _this != NULL );
#endif
const Uint32 frames = _this->getNextBuffer( _this->m_outBuf );
const fpab_t frames = _this->getNextBuffer( _this->m_outBuf );
_this->convertToS16( _this->m_outBuf, frames,
mixer::inst()->masterGain(),
(outputSampleType *)( _buf ),
(int_sample_t *)( _buf ),
_this->m_convertEndian );
}

View File

@@ -41,6 +41,11 @@
#endif
#ifdef HAVE_SCHED_H
#include <sched.h>
#endif
#include "lmms_main_win.h"
#include "embed.h"
#include "config_mgr.h"
@@ -224,6 +229,17 @@ int main( int argc, char * * argv )
e->exportBtnClicked();
}
#ifdef HAVE_SCHED_H
struct sched_param sparam;
sparam.sched_priority = ( sched_get_priority_max( SCHED_FIFO ) +
sched_get_priority_min( SCHED_FIFO ) ) / 2;
if( sched_setscheduler( 0, SCHED_FIFO, &sparam ) == -1 )
{
printf( "could not set realtime priority.\n" );
}
#endif
return( app.exec() );
}

View File

@@ -1,7 +1,7 @@
/*
* mixer.cpp - audio-device-independent mixer for LMMS
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -54,7 +54,7 @@
Uint32 SAMPLE_RATES[QUALITY_LEVELS] = { 44100, 88200 } ;
sample_rate_t SAMPLE_RATES[QUALITY_LEVELS] = { 44100, 88200 } ;
mixer * mixer::s_instanceOfMe = NULL;
@@ -69,7 +69,9 @@ mixer::mixer() :
m_qualityLevel( DEFAULT_QUALITY_LEVEL ),
m_masterGain( 1.0f ),
m_audioDev( NULL ),
m_oldAudioDev( NULL )
m_oldAudioDev( NULL ),
m_mixMutex(),
m_mixMutexLockLevel( 0 )
{
// small hack because code calling mixer::inst() is called out of ctor
s_instanceOfMe = this;
@@ -252,7 +254,8 @@ void mixer::clear( bool _everything )
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab, Uint32 _frames )
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab,
const f_cnt_t _frames )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
}
@@ -261,7 +264,7 @@ void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab, Uint32 _frames )
#ifndef DISABLE_SURROUND
void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
Uint32 _frames )
const f_cnt_t _frames )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
}
@@ -269,18 +272,19 @@ void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
void FASTCALL mixer::bufferToPort( sampleFrame * _buf, Uint32 _frames,
Uint32 _frames_ahead,
volumeVector & _volume_vector,
void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
const fpab_t _frames,
const fpab_t _frames_ahead,
const volumeVector & _volume_vector,
audioPort * _port )
{
const Uint32 start_frame = _frames_ahead % m_framesPerAudioBuffer;
Uint32 end_frame = start_frame + _frames;
const Uint32 loop1_frame = tMin( end_frame, m_framesPerAudioBuffer );
const fpab_t start_frame = _frames_ahead % m_framesPerAudioBuffer;
fpab_t end_frame = start_frame + _frames;
const fpab_t loop1_frame = tMin( end_frame, m_framesPerAudioBuffer );
for( Uint32 frame = start_frame; frame < loop1_frame; ++frame )
for( fpab_t frame = start_frame; frame < loop1_frame; ++frame )
{
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
{
_port->firstBuffer()[frame][chnl] +=
_buf[frame - start_frame][chnl %
@@ -291,12 +295,13 @@ void FASTCALL mixer::bufferToPort( sampleFrame * _buf, Uint32 _frames,
if( end_frame > m_framesPerAudioBuffer )
{
Uint32 frames_done = m_framesPerAudioBuffer - start_frame;
fpab_t frames_done = m_framesPerAudioBuffer - start_frame;
end_frame = tMin( end_frame -= m_framesPerAudioBuffer,
m_framesPerAudioBuffer );
for( Uint32 frame = 0; frame < end_frame; ++frame )
for( fpab_t frame = 0; frame < end_frame; ++frame )
{
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < SURROUND_CHANNELS;
++chnl )
{
_port->secondBuffer()[frame][chnl] +=
_buf[frames_done + frame][chnl %
@@ -361,7 +366,7 @@ void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
m_audioDev = _dev;
}
m_qualityLevel = _hq ? 1 : 0;
m_qualityLevel = _hq ? HIGH_QUALITY_LEVEL : DEFAULT_QUALITY_LEVEL;
emit sampleRateChanged();
}
@@ -375,11 +380,13 @@ void mixer::restoreAudioDevice( void )
delete m_audioDev; // dtor automatically calls
// stopProcessing()
m_audioDev = m_oldAudioDev;
for( Uint8 qli = 0; qli < QUALITY_LEVELS; ++qli )
for( Uint8 qli = DEFAULT_QUALITY_LEVEL;
qli < QUALITY_LEVELS; ++qli )
{
if( SAMPLE_RATES[qli] == m_audioDev->sampleRate() )
{
m_qualityLevel = qli;
m_qualityLevel =
static_cast<qualityLevels>( qli );
emit sampleRateChanged();
break;
}
@@ -544,12 +551,13 @@ midiClient * mixer::tryMIDIClients( void )
void mixer::processBuffer( surroundSampleFrame * _buf, fxChnl/* _fx_chnl */ )
void mixer::processBuffer( const surroundSampleFrame * _buf,
fx_ch_t/* _fx_chnl */ )
{
// TODO: effect-implementation
for( Uint32 frame = 0; frame < m_framesPerAudioBuffer; ++frame )
for( fpab_t frame = 0; frame < m_framesPerAudioBuffer; ++frame )
{
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
{
m_curBuf[frame][chnl] += _buf[frame][chnl];
}

View File

@@ -522,7 +522,7 @@ trackContentObject * FASTCALL trackContentWidget::getTCO( csize _tco_num )
return( m_trackContentObjects[_tco_num] );
}
printf( "called trackContentWidget::getTCO( %d, TRUE ), "
" but TCO %d doesn't exist\n", _tco_num, _tco_num );
"but TCO %d doesn't exist\n", _tco_num, _tco_num );
return( getTrack()->addTCO( getTrack()->createTCO( _tco_num * 64 ) ) );
// return( NULL );
}
@@ -1264,18 +1264,28 @@ track::~track()
track * FASTCALL track::create( trackTypes _tt, trackContainer * _tc )
{
// while adding track, pause mixer for not getting into any trouble
// because of track being not created completely so far
mixer::inst()->pause();
track * t = NULL;
switch( _tt )
{
case CHANNEL_TRACK: return( new channelTrack( _tc ) );
case BB_TRACK: return( new bbTrack( _tc ) );
case SAMPLE_TRACK: return( new sampleTrack( _tc ) );
case CHANNEL_TRACK: t = new channelTrack( _tc ); break;
case BB_TRACK: t = new bbTrack( _tc ); break;
case SAMPLE_TRACK: t = new sampleTrack( _tc ); break;
// case EVENT_TRACK:
// case VIDEO_TRACK:
default: break;
}
qFatal( "Attempt to create track with invalid type %d!",
static_cast<int>( _tt ) );
return( NULL );
assert( t != NULL );
// allow mixer to continue
mixer::inst()->play();
return( t );
}
@@ -1286,9 +1296,6 @@ track * FASTCALL track::create( const QDomElement & _this,
{
track * t = create( static_cast<trackTypes>( _this.attribute(
"type" ).toInt() ), _tc );
#ifdef LMMS_DEBUG
assert( t != NULL );
#endif
t->loadSettings( _this );
return( t );
}

View File

@@ -1,7 +1,7 @@
/*
* oscillator.cpp - implementation of powerful oscillator-class
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2004-2006 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
@@ -27,17 +27,16 @@
oscillator::oscillator( modulationAlgos _modulation_algo, float _freq,
Sint16 _phase_offset, float _volume_factor,
oscillator * _sub_osc ) :
m_freq(_freq),
m_volumeFactor(_volume_factor),
m_phaseOffset(_phase_offset),
m_subOsc(_sub_osc),
oscillator::oscillator( const modulationAlgos _modulation_algo,
const float _freq, const Sint16 _phase_offset,
const float _volume_factor, oscillator * _sub_osc ) :
m_freq( _freq ),
m_volumeFactor( _volume_factor ),
m_phaseOffset( _phase_offset ),
m_subOsc( _sub_osc ),
m_userWaveData( &ZERO_FRAME ),
m_userWaveFrames( 1 )
{
if( m_subOsc != NULL )
{
switch( _modulation_algo )
@@ -70,9 +69,10 @@ oscillator::oscillator( modulationAlgos _modulation_algo, float _freq,
// if we have no sub-osc, we can't do any modulation... just get our samples
#define defineNoSubUpdateFor(x,getSampleFunction) \
void x::updateNoSub( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
void x::updateNoSub( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ) \
{ \
for( Uint16 frame = 0; frame < _frames; ++frame ) \
for( fpab_t frame = 0; frame < _frames; ++frame ) \
{ \
_ab[frame][_chnl] = getSampleFunction( ++m_sample * \
m_oscCoeff ) * m_volumeFactor; \
@@ -82,10 +82,11 @@ void x::updateNoSub( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
// do fm by using sub-osc as modulator
#define defineFMUpdateFor(x,getSampleFunction) \
void x::updateFM( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
void x::updateFM( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ) \
{ \
m_subOsc->update( _ab, _frames, _chnl ); \
for( Uint16 frame = 0; frame < _frames; ++frame ) \
for( fpab_t frame = 0; frame < _frames; ++frame ) \
{ \
_ab[frame][_chnl] = getSampleFunction( ++m_sample * \
m_oscCoeff + \
@@ -103,10 +104,11 @@ void x::updateFM( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
// do am by using sub-osc as modulator
#define defineAMUpdateFor(x,getSampleFunction) \
void x::updateAM( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
void x::updateAM( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ) \
{ \
m_subOsc->update( _ab, _frames, _chnl ); \
for( Uint16 frame = 0; frame < _frames; ++frame ) \
for( fpab_t frame = 0; frame < _frames; ++frame ) \
{ \
_ab[frame][_chnl] *= getSampleFunction( ++m_sample * \
m_oscCoeff ) * m_volumeFactor; \
@@ -116,10 +118,11 @@ void x::updateAM( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
// do mix by using sub-osc as mix-sample
#define defineMixUpdateFor(x,getSampleFunction) \
void x::updateMix( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
void x::updateMix( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ) \
{ \
m_subOsc->update( _ab, _frames, _chnl ); \
for( Uint16 frame = 0; frame < _frames; ++frame ) \
for( fpab_t frame = 0; frame < _frames; ++frame ) \
{ \
_ab[frame][_chnl] += getSampleFunction( ++m_sample * \
m_oscCoeff ) * m_volumeFactor; \
@@ -130,9 +133,10 @@ void x::updateMix( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
// sync with sub-osc (every time sub-osc starts new period, we also start new
// period)
#define defineSyncUpdateFor(x,getSampleFunction) \
void x::updateSync( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
void x::updateSync( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ) \
{ \
for( Uint16 frame = 0; frame < _frames ; ++frame ) \
for( fpab_t frame = 0; frame < _frames ; ++frame ) \
{ \
if( m_subOsc->syncOk() ) \
{ \
@@ -149,24 +153,28 @@ void x::updateSync( sampleFrame * _ab, Uint32 _frames, Uint8 _chnl ) \
class x : public oscillator \
{ \
public: \
x( modulationAlgos modulation_algo, float _freq, Sint16 _phase_offset, \
float _volume_factor, oscillator * _sub_osc) : \
oscillator (modulation_algo, _freq, _phase_offset, _volume_factor, \
_sub_osc ) \
x( const modulationAlgos modulation_algo, const float _freq, \
const Sint16 _phase_offset, const float _volume_factor, \
oscillator * _sub_osc ) FASTCALL : \
oscillator( modulation_algo, _freq, _phase_offset, \
_volume_factor, _sub_osc ) \
{ \
} \
virtual ~x() \
{ \
} \
\
protected: \
void updateNoSub( sampleFrame * _ab, Uint32 _frames, \
Uint8 _chnl ); \
void updateFM( sampleFrame * _ab, Uint32 _frames, \
Uint8 _chnl ); \
void updateAM( sampleFrame * _ab, Uint32 _frames, \
Uint8 _chnl ); \
void updateMix( sampleFrame * _ab, Uint32 _frames, \
Uint8 _chnl ); \
void updateSync( sampleFrame * _ab, Uint32 _frames, \
Uint8 _chnl ); \
void updateNoSub( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ); \
void updateFM( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ); \
void updateAM( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ); \
void updateMix( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ); \
void updateSync( sampleFrame * _ab, const fpab_t _frames, \
const ch_cnt_t _chnl ); \
\
} ; \
\
@@ -188,10 +196,11 @@ generateOscillatorCodeFor( userWaveOsc, userWaveSample );
oscillator * oscillator::createOsc( waveShapes _wave_shape,
modulationAlgos _modulation_algo,
float _freq, Sint16 _phase_offset,
float _volume_factor,
oscillator * oscillator::createOsc( const waveShapes _wave_shape,
const modulationAlgos _modulation_algo,
const float _freq,
const Sint16 _phase_offset,
const float _volume_factor,
oscillator * _sub_osc )
{
switch( _wave_shape )
@@ -244,7 +253,7 @@ void oscillator::recalcOscCoeff( const float additional_phase_offset )
{
m_oscCoeff = m_freq / static_cast<float>( mixer::inst()->sampleRate() );
m_sample = static_cast<Uint32>( ( m_phaseOffset * ( 1.0f / 360.0f ) +
m_sample = static_cast<f_cnt_t>( ( m_phaseOffset * ( 1.0f / 360.0f ) +
additional_phase_offset ) *
( mixer::inst()->sampleRate() /
m_freq ) );

View File

@@ -131,7 +131,7 @@ sampleBuffer::sampleBuffer( const QString & _audio_file,
sampleBuffer::sampleBuffer( const sampleFrame * _data, Uint32 _frames ) :
sampleBuffer::sampleBuffer( const sampleFrame * _data, const f_cnt_t _frames ) :
QObject(),
m_audioFile( "" ),
m_origData( NULL ),
@@ -160,7 +160,7 @@ sampleBuffer::sampleBuffer( const sampleFrame * _data, Uint32 _frames ) :
sampleBuffer::sampleBuffer( Uint32 _frames ) :
sampleBuffer::sampleBuffer( const f_cnt_t _frames ) :
QObject(),
m_audioFile( "" ),
m_origData( NULL ),
@@ -253,9 +253,9 @@ void sampleBuffer::update( bool _keep_settings )
#else
file.ascii();
#endif
Sint16 * buf = NULL;
Uint8 channels = DEFAULT_CHANNELS;
Uint32 samplerate = SAMPLE_RATES[DEFAULT_QUALITY_LEVEL];
int_sample_t * buf = NULL;
ch_cnt_t channels = DEFAULT_CHANNELS;
sample_rate_t samplerate = SAMPLE_RATES[DEFAULT_QUALITY_LEVEL];
#ifdef HAVE_SNDFILE_H
if( m_frames == 0 )
@@ -290,28 +290,28 @@ void sampleBuffer::update( bool _keep_settings )
// scaling
if( m_reversed )
{
for( Uint32 frame = 0; frame < m_frames;
for( f_cnt_t frame = 0; frame < m_frames;
++frame )
{
for( Uint8 chnl = 0;
for( ch_cnt_t chnl = 0;
chnl < DEFAULT_CHANNELS;
++chnl )
{
const Uint32 idx = ( m_frames - frame ) * channels + ( chnl % channels );
const f_cnt_t idx = ( m_frames - frame ) * channels + ( chnl % channels );
m_data[frame][chnl] = buf[idx] * fac;
}
}
}
else
{
for( Uint32 frame = 0; frame < m_frames;
for( f_cnt_t frame = 0; frame < m_frames;
++frame )
{
for( Uint8 chnl = 0;
for( ch_cnt_t chnl = 0;
chnl < DEFAULT_CHANNELS;
++chnl )
{
const Uint32 idx = frame * channels + ( chnl % channels );
const f_cnt_t idx = frame * channels + ( chnl % channels );
m_data[frame][chnl] = buf[idx] * fac;
}
}
@@ -379,9 +379,10 @@ m_data[frame][chnl] = buf[idx] * fac;
#ifdef SDL_SDL_SOUND_H
Uint32 sampleBuffer::decodeSampleSDL( const char * _f, Sint16 * & _buf,
Uint8 & _channels,
Uint32 & _samplerate )
f_cnt_t sampleBuffer::decodeSampleSDL( const char * _f,
int_sample_t * & _buf,
ch_cnt_t & _channels,
sample_rate_t & _samplerate )
{
Sound_AudioInfo STD_AUDIO_INFO =
{
@@ -389,7 +390,7 @@ Uint32 sampleBuffer::decodeSampleSDL( const char * _f, Sint16 * & _buf,
_channels,
_samplerate,
} ;
Uint32 frames = 0;
f_cnt_t frames = 0;
Sound_Sample * snd_sample = Sound_NewSampleFromFile( _f,
&STD_AUDIO_INFO, 16384 );
@@ -400,9 +401,9 @@ Uint32 sampleBuffer::decodeSampleSDL( const char * _f, Sint16 * & _buf,
( void )Sound_DecodeAll( snd_sample );
_channels = snd_sample->actual.channels;
_samplerate = snd_sample->actual.rate;
frames = snd_sample->buffer_size / ( BYTES_PER_OUTPUT_SAMPLE *
frames = snd_sample->buffer_size / ( BYTES_PER_INT_SAMPLE *
_channels );
_buf = new Sint16[frames * _channels];
_buf = new int_sample_t[frames * _channels];
memcpy( _buf, snd_sample->buffer, snd_sample->buffer_size );
Sound_FreeSample( snd_sample );
@@ -415,13 +416,14 @@ Uint32 sampleBuffer::decodeSampleSDL( const char * _f, Sint16 * & _buf,
#ifdef HAVE_SNDFILE_H
Uint32 sampleBuffer::decodeSampleSF( const char * _f, Sint16 * & _buf,
Uint8 & _channels,
Uint32 & _samplerate )
f_cnt_t sampleBuffer::decodeSampleSF( const char * _f,
int_sample_t * & _buf,
ch_cnt_t & _channels,
sample_rate_t & _samplerate )
{
SNDFILE * snd_file;
SF_INFO sf_info;
Uint32 frames = 0;
f_cnt_t frames = 0;
#ifdef OLD_SNDFILE
if( ( snd_file = sf_open_read( _f, &sf_info ) ) != NULL )
{
@@ -431,7 +433,7 @@ Uint32 sampleBuffer::decodeSampleSF( const char * _f, Sint16 * & _buf,
{
frames = sf_info.frames;
#endif
_buf = new Sint16[sf_info.channels * frames];
_buf = new int_sample_t[sf_info.channels * frames];
frames = sf_read_short( snd_file, _buf, frames );
_channels = sf_info.channels;
_samplerate = sf_info.samplerate;
@@ -458,7 +460,7 @@ Uint32 sampleBuffer::decodeSampleSF( const char * _f, Sint16 * & _buf,
size_t qfileReadCallback( void * _ptr, size_t _size, size_t _n, void * _udata )
{
return( static_cast<QFile *>( _udata )->read( (char*)_ptr,
return( static_cast<QFile *>( _udata )->read( (char*) _ptr,
_size * _n ) );
}
@@ -504,9 +506,10 @@ long qfileTellCallback( void * _udata )
Uint32 sampleBuffer::decodeSampleOGGVorbis( const char * _f, Sint16 * & _buf,
Uint8 & _channels,
Uint32 & _samplerate )
f_cnt_t sampleBuffer::decodeSampleOGGVorbis( const char * _f,
int_sample_t * & _buf,
ch_cnt_t & _channels,
sample_rate_t & _samplerate )
{
static ov_callbacks callbacks =
{
@@ -518,7 +521,7 @@ Uint32 sampleBuffer::decodeSampleOGGVorbis( const char * _f, Sint16 * & _buf,
OggVorbis_File vf;
Uint32 frames = 0;
f_cnt_t frames = 0;
QFile * f = new QFile( _f );
#ifdef QT4
@@ -569,7 +572,7 @@ Uint32 sampleBuffer::decodeSampleOGGVorbis( const char * _f, Sint16 * & _buf,
ogg_int64_t total = ov_pcm_total( &vf, -1 );
_buf = new Sint16[total * _channels];
_buf = new int_sample_t[total * _channels];
int bitstream = 0;
long bytes_read = 0;
@@ -577,14 +580,14 @@ Uint32 sampleBuffer::decodeSampleOGGVorbis( const char * _f, Sint16 * & _buf,
{
bytes_read = ov_read( &vf, (char *) &_buf[frames * _channels],
( total - frames ) * _channels *
sizeof( Sint16 ),
isLittleEndian()? 0 : 1,
sizeof( Sint16 ), 1, &bitstream );
BYTES_PER_INT_SAMPLE,
isLittleEndian() ? 0 : 1,
BYTES_PER_INT_SAMPLE, 1, &bitstream );
if( bytes_read < 0 )
{
break;
}
frames += bytes_read / ( _channels * sizeof( Sint16 ) );
frames += bytes_read / ( _channels * BYTES_PER_INT_SAMPLE );
}
while( bytes_read != 0 && bitstream == 0 );
@@ -642,10 +645,12 @@ void sampleBuffer::destroyResamplingContext( SRC_STATE * _context )
bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
Uint32 _frames, float _freq,
bool _looped,
void * * _resampling_data )
bool FASTCALL sampleBuffer::play( sampleFrame * _ab,
const f_cnt_t _start_frame,
const fpab_t _frames,
const float _freq,
const bool _looped,
void * * _resampling_data )
{
mixer::inst()->clearAudioBuffer( _ab, _frames );
@@ -657,10 +662,10 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
const double freq_factor = (double) _freq / (double) BASE_FREQ;
const Sint16 freq_diff = static_cast<Sint16>( BASE_FREQ - _freq );
Uint32 frames_to_process = _frames;
fpab_t frames_to_process = _frames;
// calculate how many frames we have in requested pitch
const Uint32 total_frames_for_current_pitch = static_cast<Uint32>( (
const f_cnt_t total_frames_for_current_pitch = static_cast<f_cnt_t>( (
m_endFrame - m_startFrame ) /
freq_factor );
if( total_frames_for_current_pitch == 0 )
@@ -676,11 +681,11 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
}
// this holds the number of the first frame to play
const Uint32 play_frame = m_startFrame + ( _start_frame %
const f_cnt_t play_frame = m_startFrame + ( _start_frame %
total_frames_for_current_pitch );
// this holds the number of remaining frames in current loop
Uint32 frames_for_loop = total_frames_for_current_pitch -
f_cnt_t frames_for_loop = total_frames_for_current_pitch -
( play_frame - m_startFrame );
// make sure, data isn't accessed in any other way (e.g. deleting
@@ -691,7 +696,7 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
{
frames_to_process = frames_for_loop;
}
const Uint32 f1 = static_cast<Uint32>( play_frame * freq_factor );
const f_cnt_t f1 = static_cast<f_cnt_t>( play_frame * freq_factor );
/* Uint32 f2 = 0;
while( f2 < f1 )
{
@@ -723,7 +728,7 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
}
m_srcData.data_in = start_frame[0];
m_srcData.data_out = _ab[0];
m_srcData.input_frames = static_cast<Uint32>( frames_for_loop *
m_srcData.input_frames = static_cast<f_cnt_t>( frames_for_loop *
freq_factor );
m_srcData.output_frames = frames_to_process;
m_srcData.src_ratio = 1.0 / freq_factor;
@@ -734,12 +739,12 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
src_strerror( error ) );
}
#else
Uint32 src_frame_base = 0;
f_cnt_t src_frame_base = 0;
// check whether we're in high-quality-mode
if( mixer::inst()->highQuality() == TRUE )
{
// we are, so let's use cubic interpolation...
for( Uint32 frame = 0; frame < frames_to_process;
for( f_cnt_t frame = 0; frame < frames_to_process;
++frame )
{
// current loop done?
@@ -753,10 +758,10 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
}
const float src_frame_idx = frame * freq_factor;
Uint32 frame_num = static_cast<Uint32>(
f_cnt_t frame_num = static_cast<f_cnt_t>(
src_frame_idx) - src_frame_base;
const float frac_pos = src_frame_idx -
static_cast<Uint32>( src_frame_idx );
static_cast<f_cnt_t>( src_frame_idx );
// because of cubic interpolation we have to
// access start_frame[frame_num-1], so make
@@ -766,7 +771,7 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
{
frame_num = 1;
}
for ( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS;
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS;
++chnl )
{
_ab[frame][chnl] = cubicInterpolate(
@@ -782,10 +787,10 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
{
// just normal mode, so we can use linear
// interpolation...
for( Uint32 frame = 0; frame < frames_to_process;
for( f_cnt_t frame = 0; frame < frames_to_process;
++frame )
{
if( _looped && ( frame-src_frame_base ) >
if( _looped && ( frame - src_frame_base ) >
frames_for_loop )
{
start_frame = loop_start;
@@ -794,11 +799,11 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
total_frames_for_current_pitch;
}
const float src_frame_idx = frame * freq_factor;
const Uint32 frame_num = (Uint32)src_frame_idx -
src_frame_base + 0;
const f_cnt_t frame_num =
(f_cnt_t)src_frame_idx-src_frame_base;
const float frac_pos = src_frame_idx -
(Uint32) src_frame_idx;
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS;
(f_cnt_t) src_frame_idx;
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS;
++chnl )
{
_ab[frame][chnl] = linearInterpolate(
@@ -816,7 +821,7 @@ bool FASTCALL sampleBuffer::play( sampleFrame * _ab, Uint32 _start_frame,
// as is into pitched-copy-buffer
if( _looped && frames_for_loop < frames_to_process )
{
Uint32 total_frames_copied = 0;
f_cnt_t total_frames_copied = 0;
while( total_frames_copied < frames_to_process )
{
memcpy( _ab[total_frames_copied], start_frame,
@@ -878,13 +883,14 @@ void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm )
float old_x = _dr.x();
float old_y[DEFAULT_CHANNELS] = { y_base, y_base };
float fpp = tMax<float>( tMin<float>( m_frames / (float)w,
const float fpp = tMax<float>( tMin<float>( m_frames / (float)w,
20.0f ), 1.0f );
for( float frame = 0; frame < m_frames; frame += fpp )
{
const float x = frame*w / m_frames + _dr.x();
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS;
++chnl )
{
const float y = y_base +
m_data[static_cast<int>( frame )][chnl] * y_space;
@@ -898,15 +904,15 @@ void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm )
int old_x = _dr.x();
int old_y[DEFAULT_CHANNELS] = { y_base, y_base };
Uint32 fpp = tMax<Uint32>( tMin<Uint32>( m_frames / w, 20 ),
1 );
const f_cnt_t fpp = tMax<f_cnt_t>( tMin<f_cnt_t>( m_frames / w,
20 ), 1 );
for( Uint32 frame = 0; frame < m_frames; frame += fpp )
for( f_cnt_t frame = 0; frame < m_frames; frame += fpp )
{
const int x = static_cast<int>( frame /
(float) m_frames * w ) +
_dr.x();
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
const Uint16 y = y_base +
static_cast<Uint16>( m_data[frame][chnl] * y_space );
@@ -920,10 +926,10 @@ void sampleBuffer::drawWaves( QPainter & _p, QRect _dr, drawMethods _dm )
}
else if( _dm == DOTS )
{
for( Uint32 frame = 0; frame < m_frames; ++frame )
for( f_cnt_t frame = 0; frame < m_frames; ++frame )
{
const int x = frame*w / m_frames + _dr.x();
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
const int x = frame * w / m_frames + _dr.x();
for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
_p.drawPoint( x, y_base +
static_cast<Uint16>( m_data[frame][chnl] * y_space ) );
@@ -1077,7 +1083,7 @@ QString & sampleBuffer::toBase64( QString & _dst ) const
}
#ifdef HAVE_FLAC_STREAM_ENCODER_H
const Uint32 FRAMES_PER_BUF = 1152;
const f_cnt_t FRAMES_PER_BUF = 1152;
FLAC__StreamEncoder * flac_enc = FLAC__stream_encoder_new();
FLAC__stream_encoder_set_channels( flac_enc, DEFAULT_CHANNELS );
@@ -1102,15 +1108,15 @@ QString & sampleBuffer::toBase64( QString & _dst ) const
{
printf( "error within FLAC__stream_encoder_init()!\n" );
}
Uint32 frame_cnt = 0;
f_cnt_t frame_cnt = 0;
while( frame_cnt < m_frames )
{
Uint32 remaining = tMin<Uint32>( FRAMES_PER_BUF,
f_cnt_t remaining = tMin<f_cnt_t>( FRAMES_PER_BUF,
m_frames - frame_cnt );
FLAC__int32 buf[FRAMES_PER_BUF * DEFAULT_CHANNELS];
for( Uint32 f = 0; f < remaining; ++f )
for( f_cnt_t f = 0; f < remaining; ++f )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
buf[f*DEFAULT_CHANNELS+ch] = (FLAC__int32)(
mixer::clip( m_data[f+frame_cnt][ch] ) *
@@ -1144,11 +1150,11 @@ QString & sampleBuffer::toBase64( QString & _dst ) const
sampleBuffer * sampleBuffer::resample( sampleFrame * _data,
const Uint32 _frames,
const Uint32 _src_sr,
const Uint32 _dst_sr )
const f_cnt_t _frames,
const sample_rate_t _src_sr,
const sample_rate_t _dst_sr )
{
const Uint32 dst_frames = static_cast<Uint32>( _frames /
const f_cnt_t dst_frames = static_cast<f_cnt_t>( _frames /
(float) _src_sr * (float) _dst_sr );
sampleBuffer * dst_sb = new sampleBuffer( dst_frames );
sampleFrame * dst_buf = dst_sb->m_origData;
@@ -1165,7 +1171,7 @@ sampleBuffer * sampleBuffer::resample( sampleFrame * _data,
src_data.data_out = dst_buf[0];
src_data.input_frames = _frames;
src_data.output_frames = dst_frames;
src_data.src_ratio = (float) _dst_sr / _src_sr;
src_data.src_ratio = (double) _dst_sr / _src_sr;
int error;
if( ( error = src_process( state, &src_data ) ) )
{
@@ -1180,15 +1186,15 @@ sampleBuffer * sampleBuffer::resample( sampleFrame * _data,
}
#else
// no libsamplerate, so do simple cubic interpolation
for( Uint32 frame = 0; frame < dst_frames; ++frame )
for( f_cnt_t frame = 0; frame < dst_frames; ++frame )
{
const float src_frame_float = frame * (float) _src_sr / _dst_sr;
const float frac_pos = src_frame_float -
static_cast<Uint32>( src_frame_float );
const Uint32 src_frame = tLimit<Uint32>(
static_cast<Uint32>( src_frame_float ),
static_cast<f_cnt_t>( src_frame_float );
const f_cnt_t src_frame = tLimit<f_cnt_t>(
static_cast<f_cnt_t>( src_frame_float ),
1, _frames - 2 );
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
for( ch_cnt_t ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
dst_buf[frame][ch] = cubicInterpolate(
_data[src_frame - 1][ch],
@@ -1282,8 +1288,8 @@ FLAC__StreamDecoderWriteStatus flacStreamDecoderWriteCallback(
return( FLAC__STREAM_DECODER_WRITE_STATUS_ABORT );
}
const Uint32 frames = _frame->header.blocksize;
for( Uint32 frame = 0; frame < frames; ++frame )
const f_cnt_t frames = _frame->header.blocksize;
for( f_cnt_t frame = 0; frame < frames; ++frame )
{
sampleFrame sframe = { _buffer[0][frame] /
OUTPUT_SAMPLE_MULTIPLIER,
@@ -1397,7 +1403,7 @@ void sampleBuffer::loadFromBase64( const QString & _data )
void sampleBuffer::setStartFrame( Uint32 _s )
void sampleBuffer::setStartFrame( const f_cnt_t _s )
{
// don't set this parameter while playing
m_dataMutex.lock();
@@ -1408,7 +1414,7 @@ void sampleBuffer::setStartFrame( Uint32 _s )
void sampleBuffer::setEndFrame( Uint32 _e )
void sampleBuffer::setEndFrame( const f_cnt_t _e )
{
// don't set this parameter while playing
m_dataMutex.lock();

View File

@@ -188,17 +188,18 @@ void groupBox::animate( void )
void groupBox::updatePixmap( void )
{
QColor bg_color = QApplication::palette().active().background();
QPixmap pm( size() );
pm.fill( QColor( 96, 96, 96 ) );
pm.fill( bg_color.dark( 132 ) );
QPainter p( &pm );
// outer rect
p.setPen( QColor( 64, 64, 64 ) );
p.setPen( bg_color.dark( 200 ) );
p.drawRect( 0, 0, width(), height() );
// brighter line at bottom/right
p.setPen( QColor( 160, 160, 160 ) );
p.setPen( bg_color.light( 125 ) );
p.drawLine( width() - 1, 0, width() - 1, height() - 1 );
p.drawLine( 0, height() - 1, width() - 1, height() - 1 );
@@ -206,17 +207,18 @@ void groupBox::updatePixmap( void )
p.drawPixmap( 2, 2, *s_ledBg );
// draw groupbox-titlebar
p.fillRect( 2, 2, width() - 4, 9, QColor( 30, 45, 60 ) );
p.fillRect( 2, 2, width() - 4, 9, bg_color.dark( 300 ) );
// draw line below titlebar
p.setPen( QColor( 0, 0, 0 ) );
p.setPen( bg_color.dark( 400 ) );
p.drawLine( 2 + s_ledBg->width(), 11, width() - 3, 11 );
// black inner rect
p.drawRect( 1, 1, width() - 2, height() - 2 );
p.setPen( QColor( 255, 255, 255 ) );
//p.setPen( QColor( 255, 255, 255 ) );
p.setPen( colorGroup().highlight() );
p.setFont( pointSize<7>( font() ) );
p.drawText( 22, 10, m_caption );
@@ -226,7 +228,7 @@ void groupBox::updatePixmap( void )
/* pal.setColor( QPalette::Background, QColor( 96, 96, 96 ) );*/
setPalette( pal );
#else
setPaletteBackgroundColor( QColor( 96, 96, 96 ) );
setPaletteBackgroundColor( bg_color.dark( 132 ) );
setErasePixmap( pm );
#endif
}

View File

@@ -64,7 +64,7 @@ visualizationWidget::visualizationWidget( const QPixmap & _bg, QWidget * _p,
setFixedSize( s_background.width(), s_background.height() );
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
const fpab_t frames = mixer::inst()->framesPerAudioBuffer();
m_buffer = bufferAllocator::alloc<surroundSampleFrame>( frames );
mixer::inst()->clearAudioBuffer( m_buffer, frames );
@@ -78,9 +78,9 @@ visualizationWidget::visualizationWidget( const QPixmap & _bg, QWidget * _p,
}
connect( mixer::inst(), SIGNAL( nextAudioBuffer(
const surroundSampleFrame *, Uint32 ) ),
const surroundSampleFrame *, const fpab_t ) ),
this, SLOT( setAudioBuffer(
const surroundSampleFrame *, Uint32 ) ) );
const surroundSampleFrame *, const fpab_t ) ) );
toolTip::add( this, tr( "click to enable/disable visualization of "
"master-output" ) );
@@ -97,7 +97,7 @@ visualizationWidget::~visualizationWidget()
void visualizationWidget::setAudioBuffer( const surroundSampleFrame * _ab,
Uint32 _frames )
const fpab_t _frames )
{
if( m_enabled == TRUE )
{
@@ -136,12 +136,12 @@ void visualizationWidget::paintEvent( QPaintEvent * )
float max_level = 0.0;
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
const fpab_t frames = mixer::inst()->framesPerAudioBuffer();
// analyse wave-stream for max-level
for( Uint32 frame = 0; frame < frames; ++frame )
for( fpab_t frame = 0; frame < frames; ++frame )
{
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
for( ch_cnt_t chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
{
if( tAbs<float>( m_buffer[frame][chnl] ) >
max_level )
@@ -166,7 +166,7 @@ void visualizationWidget::paintEvent( QPaintEvent * )
}
// now draw all that stuff
for( Uint32 frame = 0; frame < frames; ++frame )
for( fpab_t frame = 0; frame < frames; ++frame )
{
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{