mirror of
https://github.com/LMMS/lmms.git
synced 2026-01-25 14:58:07 -05:00
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1097 0778d3d1-df1d-0410-868b-ea421aaaa00d
216 lines
5.0 KiB
C++
216 lines
5.0 KiB
C++
/*
|
|
* oscillator.h - header-file for oscillator.cpp, a powerful oscillator-class
|
|
*
|
|
* Copyright (c) 2004-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
|
*
|
|
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this program (see COPYING); if not, write to the
|
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA.
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef _OSCILLATOR_H
|
|
#define _OSCILLATOR_H
|
|
|
|
#include "lmmsconfig.h"
|
|
|
|
#ifdef LMMS_HAVE_STDLIB_H
|
|
#include <stdlib.h>
|
|
#endif
|
|
|
|
#include "mixer.h"
|
|
#include "sample_buffer.h"
|
|
#include "lmms_constants.h"
|
|
#include "lmms_math.h"
|
|
#include "automatable_model.h"
|
|
|
|
|
|
class EXPORT oscillator
|
|
{
|
|
public:
|
|
enum WaveShapes
|
|
{
|
|
SineWave,
|
|
TriangleWave,
|
|
SawWave,
|
|
SquareWave,
|
|
MoogSawWave,
|
|
ExponentialWave,
|
|
WhiteNoise,
|
|
UserDefinedWave,
|
|
NumWaveShapes
|
|
} ;
|
|
|
|
enum ModulationAlgos
|
|
{
|
|
PhaseModulation,
|
|
AmplitudeModulation,
|
|
SignalMix,
|
|
SynchronizedBySubOsc,
|
|
FrequencyModulation,
|
|
NumModulationAlgos,
|
|
} ;
|
|
|
|
|
|
oscillator( const intModel & _wave_shape_model,
|
|
const intModel & _mod_algo_model,
|
|
const float & _freq,
|
|
const float & _detuning,
|
|
const float & _phase_offset,
|
|
const float & _volume,
|
|
oscillator * _m_subOsc = NULL );
|
|
virtual ~oscillator()
|
|
{
|
|
delete m_subOsc;
|
|
}
|
|
|
|
|
|
inline void setUserWave( const sampleBuffer * _wave )
|
|
{
|
|
m_userWave = _wave;
|
|
}
|
|
|
|
void update( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
|
|
// now follow the wave-shape-routines...
|
|
|
|
static inline sample_t sinSample( const float _sample )
|
|
{
|
|
return( sinf( _sample * F_2PI ) );
|
|
}
|
|
|
|
static inline sample_t triangleSample( const float _sample )
|
|
{
|
|
const float ph = fraction( _sample );
|
|
if( ph <= 0.25f )
|
|
{
|
|
return( ph * 4.0f );
|
|
}
|
|
else if( ph <= 0.75f )
|
|
{
|
|
return( 2.0f - ph * 4.0f );
|
|
}
|
|
return( ph * 4.0f - 4.0f );
|
|
}
|
|
|
|
static inline sample_t sawSample( const float _sample )
|
|
{
|
|
return( -1.0f + fraction( _sample ) * 2.0f );
|
|
}
|
|
|
|
static inline sample_t squareSample( const float _sample )
|
|
{
|
|
return( ( fraction( _sample ) > 0.5f ) ? -1.0f : 1.0f );
|
|
}
|
|
|
|
static inline sample_t moogSawSample( const float _sample )
|
|
{
|
|
const float ph = fraction( _sample );
|
|
if( ph < 0.5f )
|
|
{
|
|
return( -1.0f + ph * 4.0f );
|
|
}
|
|
return( 1.0f - 2.0f * ph );
|
|
}
|
|
|
|
static inline sample_t expSample( const float _sample )
|
|
{
|
|
float ph = fraction( _sample );
|
|
if( ph > 0.5f )
|
|
{
|
|
ph = 1.0f - ph;
|
|
}
|
|
return( -1.0f + 8.0f * ph * ph );
|
|
}
|
|
|
|
static inline sample_t noiseSample( const float )
|
|
{
|
|
// Precise implementation
|
|
// return( 1.0f - rand() * 2.0f / RAND_MAX );
|
|
|
|
// Fast implementation
|
|
return( 1.0f - fast_rand() * 2.0f / FAST_RAND_MAX );
|
|
}
|
|
|
|
inline sample_t userWaveSample( const float _sample )
|
|
{
|
|
return( m_userWave->userWaveSample( _sample ) );
|
|
}
|
|
|
|
|
|
private:
|
|
const intModel & m_waveShapeModel;
|
|
const intModel & m_modulationAlgoModel;
|
|
const float & m_freq;
|
|
const float & m_detuning;
|
|
const float & m_volume;
|
|
const float & m_ext_phaseOffset;
|
|
oscillator * m_subOsc;
|
|
float m_phaseOffset;
|
|
float m_phase;
|
|
const sampleBuffer * m_userWave;
|
|
|
|
|
|
void updateNoSub( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
void updatePM( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
void updateAM( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
void updateMix( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
void updateSync( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
void updateFM( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
|
|
float syncInit( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
inline bool syncOk( float _osc_coeff );
|
|
|
|
template<WaveShapes W>
|
|
void updateNoSub( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
template<WaveShapes W>
|
|
void updatePM( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
template<WaveShapes W>
|
|
void updateAM( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
template<WaveShapes W>
|
|
void updateMix( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
template<WaveShapes W>
|
|
void updateSync( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
template<WaveShapes W>
|
|
void updateFM( sampleFrame * _ab, const fpp_t _frames,
|
|
const ch_cnt_t _chnl );
|
|
|
|
template<WaveShapes W>
|
|
inline sample_t getSample( const float _sample );
|
|
|
|
inline void recalcPhase( void );
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
#endif
|