mirror of
https://github.com/LMMS/lmms.git
synced 2026-02-02 18:54:29 -05:00
The translation of the instrument plugins description does not work in Instruments pluginBrowser Translation of the effect plugins description not showing in effects selector Replace tabs with spaces in the fix indentation (as Tres request) More French translations added Remove the call to tr() inside the macro makeknob (DualFilterControlDialog.cpp) and tr() the strings before calling makeknob Fix DualFilter description (was labeled as "A native amplifier plugin") (DualFilter.cpp) Add French translation for the Dual filter knobs. Move tr() out of macro's so lupdate find them for translation (extract litterals in "ts" file). Full French translation of Monstro :-) Make NES translatable (some tr() missing) Remove tr() from macros (litterals not extracted by lupdate Translate NES to French Translate Watsyn Synth as others Missing Q_OBJECT in DelayControlsDialog definition prevents its translation Translate Delay plugin to French Make EqControlsDialog translatable Fix selected-note volume bug Closes #2070 Fix a typo in French translation. Add EqControlsDialog.h to the MOCFILES list in Eq CMakeLists.txt Remove definition of slot updateVuMeters() in EqControlsDialog.h which is not implemented
364 lines
8.2 KiB
C++
364 lines
8.2 KiB
C++
/* Nes.h - A NES instrument plugin for LMMS
|
|
*
|
|
* Copyright (c) 2014 Vesa Kivimäki
|
|
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
|
*
|
|
* This file is part of LMMS - http://lmms.io
|
|
*
|
|
* 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 NES_H
|
|
#define NES_H
|
|
|
|
#include "Instrument.h"
|
|
#include "InstrumentView.h"
|
|
#include "AutomatableModel.h"
|
|
#include "AutomatableButton.h"
|
|
#include "TempoSyncKnob.h"
|
|
#include "NotePlayHandle.h"
|
|
#include "PixmapButton.h"
|
|
#include "MemoryManager.h"
|
|
|
|
|
|
#define makeknob( name, x, y, hint, unit, oname ) \
|
|
name = new Knob( knobStyled, this ); \
|
|
name ->move( x, y ); \
|
|
name ->setHintText( hint, unit ); \
|
|
name ->setObjectName( oname ); \
|
|
name ->setFixedSize( 29, 29 );
|
|
|
|
#define makenesled( name, x, y, ttip ) \
|
|
name = new PixmapButton( this, NULL ); \
|
|
name -> setCheckable( true ); \
|
|
name -> move( x, y ); \
|
|
name -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "nesled_on" ) ); \
|
|
name -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "nesled_off" ) ); \
|
|
ToolTip::add( name, ttip );
|
|
|
|
#define makedcled( name, x, y, ttip, active ) \
|
|
PixmapButton * name = new PixmapButton( this, NULL ); \
|
|
name -> move( x, y ); \
|
|
name -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( active ) ); \
|
|
name -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "nesdc_off" ) ); \
|
|
ToolTip::add( name, ttip );
|
|
|
|
const float NES_SIMPLE_FILTER = 1.0 / 20.0; // simulate nes analog audio output
|
|
const float NFB = 895000.0f;
|
|
const float NOISE_FREQS[16] =
|
|
{ NFB/5, NFB/9, NFB/17, NFB/33, NFB/65, NFB/97, NFB/129, NFB/161, NFB/193, NFB/255, NFB/381, NFB/509, NFB/763, NFB/1017, NFB/2035, NFB/4069 };
|
|
const uint16_t LFSR_INIT = 1;
|
|
const float DUTY_CYCLE[4] = { 0.125, 0.25, 0.5, 0.75 };
|
|
const float DITHER_AMP = 1.0 / 60.0;
|
|
const float MIN_FREQ = 10.0;
|
|
const int TRIANGLE_WAVETABLE[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
|
|
|
|
const float NES_DIST = 0.9f; // simulate the slight nonlinear distortion in nes audio output
|
|
|
|
const float NES_MIXING_12 = 1.0 / 20.0;
|
|
const float NES_MIXING_34 = 1.0 / 12.0;
|
|
const float NES_MIXING_ALL = 1.0 / ( NES_MIXING_12 + NES_MIXING_34 ); // constants to simulate the hardwired mixing values for nes channels
|
|
|
|
const int MIN_WLEN = 4;
|
|
|
|
|
|
class NesInstrument;
|
|
|
|
class NesObject
|
|
{
|
|
MM_OPERATORS
|
|
public:
|
|
NesObject( NesInstrument * nes, const sample_rate_t samplerate, NotePlayHandle * nph );
|
|
virtual ~NesObject();
|
|
|
|
void renderOutput( sampleFrame * buf, fpp_t frames );
|
|
void updateVibrato( float * freq );
|
|
void updatePitch();
|
|
|
|
void updateLFSR( bool mode )
|
|
{
|
|
uint16_t LFSRx;
|
|
if( mode )
|
|
{
|
|
LFSRx = m_LFSR & ( 1 << 8 ); // get bit 13
|
|
LFSRx <<= 6; // shit to left so it overlaps with bit 14
|
|
}
|
|
else
|
|
{
|
|
LFSRx = m_LFSR & ( 1 << 13 ); // get bit 13
|
|
LFSRx <<= 1; // shit to left so it overlaps with bit 14
|
|
}
|
|
m_LFSR ^= LFSRx; // xor bit 14 with bit 8/13 depending on mode
|
|
m_LFSR <<= 1; // shift bit 14 to bit 15
|
|
|
|
// cycle bit 14 to 0
|
|
if( m_LFSR & ( 1 << 15 ) ) // if bit 15 is set
|
|
{
|
|
m_LFSR++; // set bit 0 - we know it to be 0 because of the left shift so we can just inc here
|
|
}
|
|
}
|
|
|
|
inline bool LFSR() // returns true if bit 14 is set
|
|
{
|
|
if( m_LFSR & ( 1 << 14 ) )
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
inline int wavelength( float freq )
|
|
{
|
|
return static_cast<int>( m_samplerate / freq );
|
|
}
|
|
|
|
inline float signedPow( float f, float e )
|
|
{
|
|
return f < 0
|
|
? powf( qAbs( f ), e ) * -1.0f
|
|
: powf( f, e );
|
|
}
|
|
|
|
inline int nearestNoiseFreq( float f )
|
|
{
|
|
int n = 15;
|
|
for( int i = 15; i >= 0; i-- )
|
|
{
|
|
if( f >= NOISE_FREQS[ i ] )
|
|
{
|
|
n = i;
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
|
|
private:
|
|
NesInstrument * m_parent;
|
|
const sample_rate_t m_samplerate;
|
|
NotePlayHandle * m_nph;
|
|
|
|
int m_pitchUpdateCounter;
|
|
int m_pitchUpdateFreq;
|
|
|
|
int m_ch1Counter;
|
|
int m_ch2Counter;
|
|
int m_ch3Counter;
|
|
int m_ch4Counter;
|
|
|
|
int m_ch1EnvCounter;
|
|
int m_ch2EnvCounter;
|
|
int m_ch4EnvCounter;
|
|
|
|
int m_ch1EnvValue;
|
|
int m_ch2EnvValue;
|
|
int m_ch4EnvValue;
|
|
|
|
int m_ch1SweepCounter;
|
|
int m_ch2SweepCounter;
|
|
int m_ch4SweepCounter;
|
|
|
|
uint16_t m_LFSR;
|
|
|
|
float m_12Last;
|
|
float m_34Last;
|
|
|
|
float m_lastNoteFreq;
|
|
float m_lastNoiseFreq;
|
|
|
|
int m_maxWlen;
|
|
|
|
float m_nsf;
|
|
|
|
// wavelengths
|
|
int m_wlen1;
|
|
int m_wlen2;
|
|
int m_wlen3;
|
|
int m_wlen4;
|
|
|
|
// vibrato
|
|
int m_vibratoPhase;
|
|
};
|
|
|
|
|
|
class NesInstrument : public Instrument
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
NesInstrument( InstrumentTrack * instrumentTrack );
|
|
virtual ~NesInstrument();
|
|
|
|
virtual void playNote( NotePlayHandle * n,
|
|
sampleFrame * workingBuffer );
|
|
virtual void deleteNotePluginData( NotePlayHandle * n );
|
|
|
|
|
|
virtual void saveSettings( QDomDocument & doc,
|
|
QDomElement & element );
|
|
virtual void loadSettings( const QDomElement & element );
|
|
|
|
virtual QString nodeName() const;
|
|
|
|
virtual f_cnt_t desiredReleaseFrames() const
|
|
{
|
|
return( 8 );
|
|
}
|
|
|
|
virtual PluginView * instantiateView( QWidget * parent );
|
|
|
|
public slots:
|
|
void updateFreq1();
|
|
void updateFreq2();
|
|
void updateFreq3();
|
|
|
|
protected:
|
|
//freq helpers
|
|
float m_freq1;
|
|
float m_freq2;
|
|
float m_freq3;
|
|
|
|
private:
|
|
// channel 1
|
|
BoolModel m_ch1Enabled;
|
|
FloatModel m_ch1Crs;
|
|
FloatModel m_ch1Volume;
|
|
|
|
BoolModel m_ch1EnvEnabled;
|
|
BoolModel m_ch1EnvLooped;
|
|
FloatModel m_ch1EnvLen;
|
|
|
|
IntModel m_ch1DutyCycle;
|
|
|
|
BoolModel m_ch1SweepEnabled;
|
|
FloatModel m_ch1SweepAmt;
|
|
FloatModel m_ch1SweepRate;
|
|
|
|
// channel 2
|
|
BoolModel m_ch2Enabled;
|
|
FloatModel m_ch2Crs;
|
|
FloatModel m_ch2Volume;
|
|
|
|
BoolModel m_ch2EnvEnabled;
|
|
BoolModel m_ch2EnvLooped;
|
|
FloatModel m_ch2EnvLen;
|
|
|
|
IntModel m_ch2DutyCycle;
|
|
|
|
BoolModel m_ch2SweepEnabled;
|
|
FloatModel m_ch2SweepAmt;
|
|
FloatModel m_ch2SweepRate;
|
|
|
|
//channel 3
|
|
BoolModel m_ch3Enabled;
|
|
FloatModel m_ch3Crs;
|
|
FloatModel m_ch3Volume;
|
|
|
|
//channel 4
|
|
BoolModel m_ch4Enabled;
|
|
FloatModel m_ch4Volume;
|
|
|
|
BoolModel m_ch4EnvEnabled;
|
|
BoolModel m_ch4EnvLooped;
|
|
FloatModel m_ch4EnvLen;
|
|
|
|
BoolModel m_ch4NoiseMode;
|
|
BoolModel m_ch4NoiseFreqMode;
|
|
FloatModel m_ch4NoiseFreq;
|
|
|
|
FloatModel m_ch4Sweep;
|
|
BoolModel m_ch4NoiseQuantize;
|
|
|
|
//master
|
|
FloatModel m_masterVol;
|
|
FloatModel m_vibrato;
|
|
|
|
|
|
friend class NesObject;
|
|
friend class NesInstrumentView;
|
|
};
|
|
|
|
|
|
class NesInstrumentView : public InstrumentView
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
NesInstrumentView( Instrument * instrument,
|
|
QWidget * parent );
|
|
virtual ~NesInstrumentView();
|
|
|
|
private:
|
|
virtual void modelChanged();
|
|
|
|
// channel 1
|
|
PixmapButton * m_ch1EnabledBtn;
|
|
Knob * m_ch1CrsKnob;
|
|
Knob * m_ch1VolumeKnob;
|
|
|
|
PixmapButton * m_ch1EnvEnabledBtn;
|
|
PixmapButton * m_ch1EnvLoopedBtn;
|
|
Knob * m_ch1EnvLenKnob;
|
|
|
|
automatableButtonGroup * m_ch1DutyCycleGrp;
|
|
|
|
PixmapButton * m_ch1SweepEnabledBtn;
|
|
Knob * m_ch1SweepAmtKnob;
|
|
Knob * m_ch1SweepRateKnob;
|
|
|
|
// channel 2
|
|
PixmapButton * m_ch2EnabledBtn;
|
|
Knob * m_ch2CrsKnob;
|
|
Knob * m_ch2VolumeKnob;
|
|
|
|
PixmapButton * m_ch2EnvEnabledBtn;
|
|
PixmapButton * m_ch2EnvLoopedBtn;
|
|
Knob * m_ch2EnvLenKnob;
|
|
|
|
automatableButtonGroup * m_ch2DutyCycleGrp;
|
|
|
|
PixmapButton * m_ch2SweepEnabledBtn;
|
|
Knob * m_ch2SweepAmtKnob;
|
|
Knob * m_ch2SweepRateKnob;
|
|
|
|
//channel 3
|
|
PixmapButton * m_ch3EnabledBtn;
|
|
Knob * m_ch3CrsKnob;
|
|
Knob * m_ch3VolumeKnob;
|
|
|
|
//channel 4
|
|
PixmapButton * m_ch4EnabledBtn;
|
|
Knob * m_ch4VolumeKnob;
|
|
|
|
PixmapButton * m_ch4EnvEnabledBtn;
|
|
PixmapButton * m_ch4EnvLoopedBtn;
|
|
Knob * m_ch4EnvLenKnob;
|
|
|
|
PixmapButton * m_ch4NoiseModeBtn;
|
|
PixmapButton * m_ch4NoiseFreqModeBtn;
|
|
Knob * m_ch4NoiseFreqKnob;
|
|
|
|
Knob * m_ch4SweepKnob;
|
|
PixmapButton * m_ch4NoiseQuantizeBtn;
|
|
|
|
//master
|
|
Knob * m_masterVolKnob;
|
|
Knob * m_vibratoKnob;
|
|
|
|
static QPixmap * s_artwork;
|
|
};
|
|
|
|
#endif
|