LMMS
Loading...
Searching...
No Matches
Nes.h
Go to the documentation of this file.
1/* Nes.h - A NES instrument plugin for LMMS
2 *
3 * Copyright (c) 2014 Vesa Kivimäki
4 * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
5 *
6 * This file is part of LMMS - https://lmms.io
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
22 *
23 */
24
25#ifndef NES_H
26#define NES_H
27
28
29#include "Instrument.h"
30#include "InstrumentView.h"
31#include "AutomatableModel.h"
32#include "PixmapButton.h"
33
34
35#define makeknob( name, x, y, hint, unit, oname ) \
36 name = new Knob( KnobType::Styled, this ); \
37 name ->move( x, y ); \
38 name ->setHintText( hint, unit ); \
39 name ->setObjectName( oname ); \
40 name ->setFixedSize( 29, 29 );
41
42#define makenesled( name, x, y, ttip ) \
43 name = new PixmapButton( this, nullptr ); \
44 name -> setCheckable( true ); \
45 name -> move( x, y ); \
46 name -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( "nesled_on" ) ); \
47 name -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "nesled_off" ) ); \
48 name->setToolTip(ttip);
49
50#define makedcled( name, x, y, ttip, active ) \
51 PixmapButton * name = new PixmapButton( this, nullptr ); \
52 name -> move( x, y ); \
53 name -> setActiveGraphic( PLUGIN_NAME::getIconPixmap( active ) ); \
54 name -> setInactiveGraphic( PLUGIN_NAME::getIconPixmap( "nesdc_off" ) ); \
55 name->setToolTip(ttip);
56
57
58namespace lmms
59{
60
61
62const float NES_SIMPLE_FILTER = 1.f / 20.f; // simulate nes analog audio output
63const float NFB = 895000.0f;
64const float NOISE_FREQS[16] =
65 { 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 };
67const float DUTY_CYCLE[4] = { 0.125, 0.25, 0.5, 0.75 };
68const float DITHER_AMP = 1.f / 60.f;
69const float MIN_FREQ = 10.0;
70const int TRIANGLE_WAVETABLE[32] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
71 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
72
73const float NES_DIST = 0.9f; // simulate the slight nonlinear distortion in nes audio output
74
75const float NES_MIXING_12 = 1.f / 20.f;
76const float NES_MIXING_34 = 1.f / 12.f;
77const float NES_MIXING_ALL = 1.f / (NES_MIXING_12 + NES_MIXING_34); // constants to simulate the hardwired mixing values for nes channels
78
79const int MIN_WLEN = 4;
80
81
82class NesInstrument;
83
84namespace gui
85{
86class Knob; // IWYU pragma: keep
87class NesInstrumentView;
88} // namespace gui
89
90
92{
93public:
94 NesObject( NesInstrument * nes, const sample_rate_t samplerate, NotePlayHandle * nph );
95 virtual ~NesObject() = default;
96
97 void renderOutput( SampleFrame* buf, f_cnt_t frames );
98 void updateVibrato( float * freq );
99 void updatePitch();
100
101 void updateLFSR( bool mode )
102 {
103 uint16_t LFSRx;
104 if( mode )
105 {
106 LFSRx = m_LFSR & ( 1 << 8 ); // get bit 13
107 LFSRx <<= 6; // shit to left so it overlaps with bit 14
108 }
109 else
110 {
111 LFSRx = m_LFSR & ( 1 << 13 ); // get bit 13
112 LFSRx <<= 1; // shit to left so it overlaps with bit 14
113 }
114 m_LFSR ^= LFSRx; // xor bit 14 with bit 8/13 depending on mode
115 m_LFSR <<= 1; // shift bit 14 to bit 15
116
117 // cycle bit 14 to 0
118 if( m_LFSR & ( 1 << 15 ) ) // if bit 15 is set
119 {
120 m_LFSR++; // set bit 0 - we know it to be 0 because of the left shift so we can just inc here
121 }
122 }
123
124 inline bool LFSR() // returns true if bit 14 is set
125 {
126 if( m_LFSR & ( 1 << 14 ) )
127 {
128 return true;
129 }
130 return false;
131 }
132
133 inline int wavelength( float freq )
134 {
135 return static_cast<int>( m_samplerate / freq );
136 }
137
138 inline int nearestNoiseFreq( float f )
139 {
140 int n = 15;
141 for( int i = 15; i >= 0; i-- )
142 {
143 if( f >= NOISE_FREQS[ i ] )
144 {
145 n = i;
146 }
147 }
148 return n;
149 }
150
151private:
155
158
163
167
171
175
177
178 float m_12Last;
179 float m_34Last;
180
183
185
186 float m_nsf;
187
188// wavelengths
193
194// vibrato
196};
197
198
200{
201 Q_OBJECT
202public:
204 ~NesInstrument() override = default;
205
206 void playNote( NotePlayHandle * n,
207 SampleFrame* workingBuffer ) override;
208 void deleteNotePluginData( NotePlayHandle * n ) override;
209
210
211 void saveSettings( QDomDocument & doc,
212 QDomElement & element ) override;
213 void loadSettings( const QDomElement & element ) override;
214
215 QString nodeName() const override;
216
217 float desiredReleaseTimeMs() const override
218 {
219 return 0.2f;
220 }
221
222 gui::PluginView* instantiateView( QWidget * parent ) override;
223
224public slots:
225 void updateFreq1();
226 void updateFreq2();
227 void updateFreq3();
228
229protected:
230 //freq helpers
231 float m_freq1;
232 float m_freq2;
233 float m_freq3;
234
235private:
236 // channel 1
240
244
246
250
251 // channel 2
255
259
261
265
266 //channel 3
270
271 //channel 4
274
278
282
285
286 //master
289
290
291 friend class NesObject;
293};
294
295
296namespace gui
297{
298
299
301{
302 Q_OBJECT
303public:
304 NesInstrumentView( Instrument * instrument,
305 QWidget * parent );
306 ~NesInstrumentView() override = default;
307
308private:
309 void modelChanged() override;
310
311 // channel 1
315
319
321
325
326 // channel 2
330
334
336
340
341 //channel 3
345
346 //channel 4
349
353
357
360
361 //master
364
365};
366
367
368} // namespace gui
369
370} // namespace lmms
371
372#endif
Definition AutomatableModel.h:497
Definition AutomatableModel.h:463
Definition Instrument.h:52
InstrumentTrack * instrumentTrack() const
Definition Instrument.h:156
Instrument(InstrumentTrack *_instrument_track, const Descriptor *_descriptor, const Descriptor::SubPluginFeatures::Key *key=nullptr, Flags flags=Flag::NoFlags)
Definition Instrument.cpp:38
Definition InstrumentTrack.h:62
Definition AutomatableModel.h:481
Definition Nes.h:200
BoolModel m_ch4Enabled
Definition Nes.h:272
FloatModel m_ch4Volume
Definition Nes.h:273
NesInstrument(InstrumentTrack *instrumentTrack)
Definition Nes.cpp:482
FloatModel m_ch2SweepAmt
Definition Nes.h:263
BoolModel m_ch4EnvEnabled
Definition Nes.h:275
BoolModel m_ch2EnvLooped
Definition Nes.h:257
FloatModel m_ch1SweepRate
Definition Nes.h:249
IntModel m_ch1DutyCycle
Definition Nes.h:245
float m_freq3
Definition Nes.h:233
BoolModel m_ch4NoiseMode
Definition Nes.h:279
BoolModel m_ch4NoiseQuantize
Definition Nes.h:284
FloatModel m_ch1Crs
Definition Nes.h:238
BoolModel m_ch2SweepEnabled
Definition Nes.h:262
void updateFreq2()
Definition Nes.cpp:705
FloatModel m_ch2Volume
Definition Nes.h:254
FloatModel m_ch4NoiseFreq
Definition Nes.h:281
FloatModel m_ch3Volume
Definition Nes.h:269
FloatModel m_ch2Crs
Definition Nes.h:253
QString nodeName() const override
Definition Nes.cpp:686
float desiredReleaseTimeMs() const override
Definition Nes.h:217
void playNote(NotePlayHandle *n, SampleFrame *workingBuffer) override
Definition Nes.cpp:547
FloatModel m_ch1EnvLen
Definition Nes.h:243
FloatModel m_vibrato
Definition Nes.h:288
~NesInstrument() override=default
BoolModel m_ch2Enabled
Definition Nes.h:252
FloatModel m_ch1Volume
Definition Nes.h:239
void deleteNotePluginData(NotePlayHandle *n) override
Definition Nes.cpp:566
FloatModel m_masterVol
Definition Nes.h:287
FloatModel m_ch2EnvLen
Definition Nes.h:258
FloatModel m_ch4Sweep
Definition Nes.h:283
friend class NesObject
Definition Nes.h:291
BoolModel m_ch1EnvEnabled
Definition Nes.h:241
gui::PluginView * instantiateView(QWidget *parent) override
Create a view for the model.
Definition Nes.cpp:692
BoolModel m_ch4EnvLooped
Definition Nes.h:276
BoolModel m_ch1Enabled
Definition Nes.h:237
BoolModel m_ch1SweepEnabled
Definition Nes.h:247
float m_freq1
Definition Nes.h:231
FloatModel m_ch1SweepAmt
Definition Nes.h:248
void updateFreq3()
Definition Nes.cpp:711
void saveSettings(QDomDocument &doc, QDomElement &element) override
Definition Nes.cpp:572
FloatModel m_ch4EnvLen
Definition Nes.h:277
BoolModel m_ch4NoiseFreqMode
Definition Nes.h:280
void loadSettings(const QDomElement &element) override
Definition Nes.cpp:629
void updateFreq1()
Definition Nes.cpp:699
FloatModel m_ch2SweepRate
Definition Nes.h:264
float m_freq2
Definition Nes.h:232
BoolModel m_ch2EnvEnabled
Definition Nes.h:256
BoolModel m_ch1EnvLooped
Definition Nes.h:242
FloatModel m_ch3Crs
Definition Nes.h:268
IntModel m_ch2DutyCycle
Definition Nes.h:260
BoolModel m_ch3Enabled
Definition Nes.h:267
virtual ~NesObject()=default
const sample_rate_t m_samplerate
Definition Nes.h:153
int m_ch4EnvCounter
Definition Nes.h:166
bool LFSR()
Definition Nes.h:124
int m_pitchUpdateCounter
Definition Nes.h:156
int m_ch1SweepCounter
Definition Nes.h:172
int nearestNoiseFreq(float f)
Definition Nes.h:138
void updateLFSR(bool mode)
Definition Nes.h:101
int m_wlen4
Definition Nes.h:192
NesObject(NesInstrument *nes, const sample_rate_t samplerate, NotePlayHandle *nph)
Definition Nes.cpp:62
int m_wlen1
Definition Nes.h:189
int wavelength(float freq)
Definition Nes.h:133
int m_pitchUpdateFreq
Definition Nes.h:157
int m_ch4EnvValue
Definition Nes.h:170
int m_ch1EnvCounter
Definition Nes.h:164
int m_vibratoPhase
Definition Nes.h:195
int m_ch2EnvCounter
Definition Nes.h:165
int m_ch2Counter
Definition Nes.h:160
float m_lastNoiseFreq
Definition Nes.h:182
int m_ch4Counter
Definition Nes.h:162
float m_12Last
Definition Nes.h:178
void updateVibrato(float *freq)
Definition Nes.cpp:435
uint16_t m_LFSR
Definition Nes.h:176
float m_lastNoteFreq
Definition Nes.h:181
int m_wlen2
Definition Nes.h:190
NotePlayHandle * m_nph
Definition Nes.h:154
int m_ch4SweepCounter
Definition Nes.h:174
int m_ch3Counter
Definition Nes.h:161
float m_nsf
Definition Nes.h:186
int m_ch2EnvValue
Definition Nes.h:169
NesInstrument * m_parent
Definition Nes.h:152
int m_ch1Counter
Definition Nes.h:159
void renderOutput(SampleFrame *buf, f_cnt_t frames)
Definition Nes.cpp:105
void updatePitch()
Definition Nes.cpp:445
float m_34Last
Definition Nes.h:179
int m_maxWlen
Definition Nes.h:184
int m_ch1EnvValue
Definition Nes.h:168
int m_wlen3
Definition Nes.h:191
int m_ch2SweepCounter
Definition Nes.h:173
Definition NotePlayHandle.h:48
Definition SampleFrame.h:41
Definition AutomatableButton.h:84
Instrument view with fixed LMMS-default size.
Definition InstrumentView.h:66
Definition Knob.h:47
Definition Nes.h:301
PixmapButton * m_ch2EnvLoopedBtn
Definition Nes.h:332
PixmapButton * m_ch4EnvEnabledBtn
Definition Nes.h:350
Knob * m_masterVolKnob
Definition Nes.h:362
Knob * m_ch1VolumeKnob
Definition Nes.h:314
PixmapButton * m_ch1SweepEnabledBtn
Definition Nes.h:322
PixmapButton * m_ch2SweepEnabledBtn
Definition Nes.h:337
Knob * m_ch2VolumeKnob
Definition Nes.h:329
PixmapButton * m_ch4NoiseQuantizeBtn
Definition Nes.h:359
PixmapButton * m_ch4NoiseModeBtn
Definition Nes.h:354
Knob * m_ch2CrsKnob
Definition Nes.h:328
~NesInstrumentView() override=default
Knob * m_ch4NoiseFreqKnob
Definition Nes.h:356
Knob * m_ch4EnvLenKnob
Definition Nes.h:352
Knob * m_ch3VolumeKnob
Definition Nes.h:344
PixmapButton * m_ch1EnvEnabledBtn
Definition Nes.h:316
AutomatableButtonGroup * m_ch1DutyCycleGrp
Definition Nes.h:320
PixmapButton * m_ch4EnabledBtn
Definition Nes.h:347
void modelChanged() override
Definition Nes.cpp:838
Knob * m_ch2SweepRateKnob
Definition Nes.h:339
NesInstrumentView(Instrument *instrument, QWidget *parent)
Definition Nes.cpp:723
Knob * m_ch1CrsKnob
Definition Nes.h:313
AutomatableButtonGroup * m_ch2DutyCycleGrp
Definition Nes.h:335
Knob * m_ch1EnvLenKnob
Definition Nes.h:318
PixmapButton * m_ch3EnabledBtn
Definition Nes.h:342
Knob * m_ch4SweepKnob
Definition Nes.h:358
PixmapButton * m_ch4EnvLoopedBtn
Definition Nes.h:351
PixmapButton * m_ch2EnvEnabledBtn
Definition Nes.h:331
Knob * m_ch2SweepAmtKnob
Definition Nes.h:338
Knob * m_ch2EnvLenKnob
Definition Nes.h:333
PixmapButton * m_ch1EnvLoopedBtn
Definition Nes.h:317
Knob * m_vibratoKnob
Definition Nes.h:363
PixmapButton * m_ch2EnabledBtn
Definition Nes.h:327
PixmapButton * m_ch1EnabledBtn
Definition Nes.h:312
PixmapButton * m_ch4NoiseFreqModeBtn
Definition Nes.h:355
Knob * m_ch3CrsKnob
Definition Nes.h:343
Knob * m_ch1SweepAmtKnob
Definition Nes.h:323
Knob * m_ch1SweepRateKnob
Definition Nes.h:324
Knob * m_ch4VolumeKnob
Definition Nes.h:348
Definition PixmapButton.h:37
Definition PluginView.h:36
register unsigned i
Definition inflate.c:1575
unsigned f
Definition inflate.c:1572
static uintptr_t parent
Definition pugl.h:1644
JHUFF_TBL long freq[]
Definition jchuff.h:50
unsigned short uint16_t
Definition mid.cpp:99
Definition AudioPortAudio.cpp:223
Definition AudioAlsa.cpp:35
const float NES_MIXING_12
Definition Nes.h:75
const float NES_MIXING_ALL
Definition Nes.h:77
const float NES_MIXING_34
Definition Nes.h:76
std::uint32_t sample_rate_t
Definition LmmsTypes.h:42
const uint16_t LFSR_INIT
Definition Nes.h:66
const int TRIANGLE_WAVETABLE[32]
Definition Nes.h:70
const float NES_DIST
Definition Nes.h:73
const float DUTY_CYCLE[4]
Definition Nes.h:67
const float DITHER_AMP
Definition Nes.h:68
const float MIN_FREQ
Definition Monstro.h:155
std::uint64_t f_cnt_t
Definition LmmsTypes.h:43
const float NFB
Definition Nes.h:63
const float NES_SIMPLE_FILTER
Definition Nes.h:62
const float NOISE_FREQS[16]
Definition Nes.h:64
const int MIN_WLEN
Definition Nes.h:79
png_structrp int mode
Definition png.h:1139
int n
Definition crypt.c:458