lmms
Cross-platform music production software
Loading...
Searching...
No Matches
GigPlayer.h
Go to the documentation of this file.
1/*
2 * GigPlayer.h - a GIG player using libgig (based on Sf2 player plugin)
3 *
4 * Copyright (c) 2008 Paul Giblock <drfaygo/at/gmail/dot/com>
5 * Copyright (c) 2009-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6 *
7 * This file is part of LMMS - https://lmms.io
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program (see COPYING); if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA.
23 *
24 */
25
26
27#ifndef GIG_PLAYER_H
28#define GIG_PLAYER_H
29
30#include <QList>
31#include <QMutex>
32#include <QMutexLocker>
33#include <samplerate.h>
34
35#include "AudioEngine.h"
36#include "AudioResampler.h"
37#include "Instrument.h"
38#include "PixmapButton.h"
39#include "InstrumentView.h"
40#include "Knob.h"
41#include "LcdSpinBox.h"
42#include "SampleFrame.h"
43#include "gig.h"
44
45
46class QLabel;
47
48
49namespace lmms
50{
51
52
53class NotePlayHandle;
54
55namespace gui
56{
57class PatchesDialog;
59}
60
61
62
63
65{
67} ;
68
69
70
71
72// Load a GIG file using libgig
74{
75public:
76 GigInstance( QString filename ) :
77 riff( filename.toUtf8().constData() ),
78 gig( &riff )
79 {}
80
81private:
82 RIFF::File riff;
83
84public:
85 gig::File gig;
86} ;
87
88
89
90
91// Stores options for the notes, e.g. velocity and release time
93{
95 release( false )
96 {
97 for( int i = 0; i < 8; ++i )
98 {
99 DimValues[i] = 0;
100 }
101 }
102
103 uint DimValues[8];
105} ;
106
107
108
109
110// Takes information from the GIG file for a certain note and provides the
111// amplitude (0-1) to multiply the signal by (internally incrementing the
112// position in the envelope when asking for the amplitude).
113class ADSR
114{
115 // From the file
116 float preattack; // initial amplitude (0-1)
117 float attack; // 0-60s
118 float decay1; // 0-60s
119 float decay2; // 0-60s
120 bool infiniteSustain; // i.e., no decay2
121 float sustain; // sustain amplitude (0-1)
122 float release; // 0-60s
123
124 // Used to calculate current amplitude
128 bool isDone;
134
135public:
136 ADSR();
137 ADSR( gig::DimensionRegion * region, int sampleRate );
138 void keyup(); // We will begin releasing starting now
139 bool done(); // Is this sample done playing?
140 float value(); // What's the current amplitude
141 void inc( f_cnt_t num ); // Increment internal positions by num
142} ;
143
144
145
146
147// The sample from the GIG file with our current position in both the sample
148// and the envelope
150{
151public:
152 GigSample(gig::Sample* pSample, gig::DimensionRegion* pDimRegion, float attenuation,
153 AudioResampler::Mode interpolation, float desiredFreq);
154 ~GigSample() = default;
155
156 // Needed when initially creating in QList
157 GigSample( const GigSample& g );
158 GigSample& operator=( const GigSample& g );
159
160 gig::Sample * sample;
161 gig::DimensionRegion * region;
164
165 // The position in sample
167
168 // Whether to change the pitch of the samples, e.g. if there's only one
169 // sample per octave and you want that sample pitch shifted for the rest of
170 // the notes in the octave, this will be true
172
173 // Used to convert sample rates
175 std::array<SampleFrame, DEFAULT_BUFFER_SIZE> m_sourceBuffer;
176 std::array<SampleFrame, DEFAULT_BUFFER_SIZE> m_mixBuffer;
177 std::span<SampleFrame> m_sourceBufferView;
178 std::span<SampleFrame> m_mixBufferView;
179
180 // Used changing the pitch of the note if desired
183} ;
184
185
186
187
188// What portion of a note are we in?
189enum class GigState
190{
191 // We just pressed the key
193 // The note is currently playing
195 // We just released the key
197 // The note is being released, e.g. a release sample is playing
199 // The note is done playing, you can delete this note now
201} ;
202
203
204
205
206// Corresponds to a certain midi note pressed, but may contain multiple samples
208{
209public:
212 bool release; // Whether to trigger a release sample on key up
213 bool isRelease; // Whether this is a release sample, changes when we delete it
216 std::vector<GigSample> samples;
217
218 // Used to determine which note should be released on key up
219 //
220 // Note: if accessing the data, be careful not to access it after the key
221 // has been released since that's when it is deleted
223
226 release( false ), isRelease( false ), state( GigState::KeyDown ),
228 {
229 }
230} ;
231
232
233
234
236{
237 Q_OBJECT
238
239 mapPropertyFromModel( int, getBank, setBank, m_bankNum );
240 mapPropertyFromModel( int, getPatch, setPatch, m_patchNum );
241
242public:
243 GigInstrument( InstrumentTrack * _instrument_track );
244 ~GigInstrument() override;
245
246 void play( SampleFrame* _working_buffer ) override;
247
248 void playNote( NotePlayHandle * _n,
249 SampleFrame* _working_buffer ) override;
250 void deleteNotePluginData( NotePlayHandle * _n ) override;
251
252
253 void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
254 void loadSettings( const QDomElement & _this ) override;
255
256 void loadFile( const QString & _file ) override;
257
258 auto midiPatch() const -> std::optional<MidiPatch> override;
259 AutomatableModel* childModel(std::string_view modelName) override;
260
261 QString nodeName() const override;
262
263 gui::PluginView* instantiateView( QWidget * _parent ) override;
264
265 QString getCurrentPatchName();
266
267
268 void setParameter( const QString & _param, const QString & _value );
269
270
271public slots:
272 void openFile( const QString & _gigFile, bool updateTrackName = true );
273 void updatePatch();
274 void updateSampleRate();
275
276
277private:
278 // The GIG file and instrument we're using
281
282 // Part of the UI
283 QString m_filename;
284
285 gui::LcdSpinBoxModel m_bankNum;
286 gui::LcdSpinBoxModel m_patchNum;
287
289
290 // Locking for the data
293
294 // List of all the currently playing notes
296
297 // Used when determining which samples to use
298 uint32_t m_RandomSeed;
300
301private:
302 // Delete the current GIG instance if one is open
303 void freeInstance();
304
305 // Open the instrument in the currently-open GIG file
306 void getInstrument();
307
308 // Create "dimension" to select desired samples from GIG file based on
309 // parameters such as velocity
310 Dimension getDimensions( gig::Region * pRegion, int velocity, bool release );
311
312 // Load sample data from the Gig file, looping the sample where needed
313 void loadSample( GigSample& sample, SampleFrame* sampleData, f_cnt_t samples );
314 f_cnt_t getLoopedIndex( f_cnt_t index, f_cnt_t startf, f_cnt_t endf ) const;
315 f_cnt_t getPingPongIndex( f_cnt_t index, f_cnt_t startf, f_cnt_t endf ) const;
316
317 // Add the desired samples to the note, either normal samples or release
318 // samples
319 void addSamples( GigNote & gignote, bool wantReleaseSample );
320
321 friend class gui::GigInstrumentView;
322
323signals:
327
328} ;
329
330
331namespace gui
332{
333
334
336{
337 Q_OBJECT
338public:
339 GigInstrumentView( Instrument * _instrument,
340 QWidget * _parent );
341 ~GigInstrumentView() override = default;
342
343private:
344 void modelChanged() override;
345
348
351
353 QLabel * m_patchLabel;
354
356
358
359protected slots:
360 void invalidateFile();
361 void showFileDialog();
362 void showPatchDialog();
363 void updateFilename();
364 void updatePatchName();
365} ;
366
367
368} // namespace gui
369
370} // namespace lmms
371
372#endif
Definition GigPlayer.h:114
f_cnt_t attackPosition
Definition GigPlayer.h:129
float amplitude
Definition GigPlayer.h:125
f_cnt_t releasePosition
Definition GigPlayer.h:132
void inc(f_cnt_t num)
Definition GigPlayer.cpp:1275
float decay1
Definition GigPlayer.h:118
void keyup()
Definition GigPlayer.cpp:1197
bool isAttack
Definition GigPlayer.h:126
float sustain
Definition GigPlayer.h:121
f_cnt_t decayLength
Definition GigPlayer.h:131
bool done()
Definition GigPlayer.cpp:1206
bool infiniteSustain
Definition GigPlayer.h:120
float preattack
Definition GigPlayer.h:116
bool isDone
Definition GigPlayer.h:128
float release
Definition GigPlayer.h:122
ADSR()
Definition GigPlayer.cpp:1143
float value()
Definition GigPlayer.cpp:1215
f_cnt_t attackLength
Definition GigPlayer.h:130
bool isRelease
Definition GigPlayer.h:127
float decay2
Definition GigPlayer.h:119
float attack
Definition GigPlayer.h:117
f_cnt_t releaseLength
Definition GigPlayer.h:133
A utility class for resampling interleaved audio buffers using various resampling algorithms.
Definition AudioResampler.h:41
Mode
Defines the resampling method to use.
Definition AudioResampler.h:48
Definition AutomatableModel.h:77
Definition AutomatableModel.h:468
Definition GigPlayer.h:74
RIFF::File riff
Definition GigPlayer.h:82
gig::File gig
Definition GigPlayer.h:85
GigInstance(QString filename)
Definition GigPlayer.h:76
AutomatableModel * childModel(std::string_view modelName) override
Definition GigPlayer.cpp:166
void deleteNotePluginData(NotePlayHandle *_n) override
Definition GigPlayer.cpp:674
auto midiPatch() const -> std::optional< MidiPatch > override
For applicable instruments: Provides host with current MIDI bank and program.
Definition GigPlayer.cpp:155
gui::PluginView * instantiateView(QWidget *_parent) override
Create a view for the model.
Definition GigPlayer.cpp:698
void loadSettings(const QDomElement &_this) override
Definition GigPlayer.cpp:128
QMutex m_synthMutex
Definition GigPlayer.h:291
f_cnt_t getLoopedIndex(f_cnt_t index, f_cnt_t startf, f_cnt_t endf) const
Definition GigPlayer.cpp:641
void addSamples(GigNote &gignote, bool wantReleaseSample)
Definition GigPlayer.cpp:711
void play(SampleFrame *_working_buffer) override
Definition GigPlayer.cpp:331
float m_currentKeyDimension
Definition GigPlayer.h:299
QString getCurrentPatchName()
Definition GigPlayer.cpp:259
GigInstrument(InstrumentTrack *_instrument_track)
Definition GigPlayer.cpp:81
friend class gui::GigInstrumentView
Definition GigPlayer.h:321
void updatePatch()
Definition GigPlayer.cpp:248
FloatModel m_gain
Definition GigPlayer.h:288
void setParameter(const QString &_param, const QString &_value)
mapPropertyFromModel(int, getPatch, setPatch, m_patchNum)
void loadSample(GigSample &sample, SampleFrame *sampleData, f_cnt_t samples)
Definition GigPlayer.cpp:505
uint32_t m_RandomSeed
Definition GigPlayer.h:298
QMutex m_notesMutex
Definition GigPlayer.h:292
mapPropertyFromModel(int, getBank, setBank, m_bankNum)
GigInstance * m_instance
Definition GigPlayer.h:279
QString m_filename
Definition GigPlayer.h:283
gui::LcdSpinBoxModel m_patchNum
Definition GigPlayer.h:286
gui::LcdSpinBoxModel m_bankNum
Definition GigPlayer.h:285
void playNote(NotePlayHandle *_n, SampleFrame *_working_buffer) override
Definition GigPlayer.cpp:300
QString nodeName() const override
Definition GigPlayer.cpp:185
void getInstrument()
Definition GigPlayer.cpp:858
f_cnt_t getPingPongIndex(f_cnt_t index, f_cnt_t startf, f_cnt_t endf) const
Definition GigPlayer.cpp:655
gig::Instrument * m_instrument
Definition GigPlayer.h:280
Dimension getDimensions(gig::Region *pRegion, int velocity, bool release)
Definition GigPlayer.cpp:780
void loadFile(const QString &_file) override
Definition GigPlayer.cpp:142
QList< GigNote > m_notes
Definition GigPlayer.h:295
void updateSampleRate()
Definition GigPlayer.cpp:893
void openFile(const QString &_gigFile, bool updateTrackName=true)
Definition GigPlayer.cpp:214
void saveSettings(QDomDocument &_doc, QDomElement &_parent) override
Definition GigPlayer.cpp:116
void freeInstance()
Definition GigPlayer.cpp:193
Definition GigPlayer.h:208
GigState state
Definition GigPlayer.h:214
std::vector< GigSample > samples
Definition GigPlayer.h:216
GigNote(int midiNote, int velocity, float frequency, GIGPluginData *handle)
Definition GigPlayer.h:224
GIGPluginData * handle
Definition GigPlayer.h:222
bool isRelease
Definition GigPlayer.h:213
int velocity
Definition GigPlayer.h:211
bool release
Definition GigPlayer.h:212
float frequency
Definition GigPlayer.h:215
int midiNote
Definition GigPlayer.h:210
Definition GigPlayer.h:150
AudioResampler m_resampler
Definition GigPlayer.h:174
float freqFactor
Definition GigPlayer.h:182
std::span< SampleFrame > m_mixBufferView
Definition GigPlayer.h:178
std::array< SampleFrame, DEFAULT_BUFFER_SIZE > m_mixBuffer
Definition GigPlayer.h:176
GigSample(gig::Sample *pSample, gig::DimensionRegion *pDimRegion, float attenuation, AudioResampler::Mode interpolation, float desiredFreq)
Definition GigPlayer.cpp:1088
f_cnt_t pos
Definition GigPlayer.h:166
GigSample & operator=(const GigSample &g)
Definition GigPlayer.cpp:1131
float attenuation
Definition GigPlayer.h:162
ADSR adsr
Definition GigPlayer.h:163
gig::Sample * sample
Definition GigPlayer.h:160
float sampleFreq
Definition GigPlayer.h:181
std::span< SampleFrame > m_sourceBufferView
Definition GigPlayer.h:177
~GigSample()=default
std::array< SampleFrame, DEFAULT_BUFFER_SIZE > m_sourceBuffer
Definition GigPlayer.h:175
bool pitchtrack
Definition GigPlayer.h:171
gig::DimensionRegion * region
Definition GigPlayer.h:161
Definition Instrument.h:54
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 NotePlayHandle.h:48
Definition SampleFrame.h:41
Definition GigPlayer.h:336
LcdSpinBox * m_bankNumLcd
Definition GigPlayer.h:349
Knob * m_gainKnob
Definition GigPlayer.h:355
static PatchesDialog * s_patchDialog
Definition GigPlayer.h:357
PixmapButton * m_patchDialogButton
Definition GigPlayer.h:347
QLabel * m_filenameLabel
Definition GigPlayer.h:352
LcdSpinBox * m_patchNumLcd
Definition GigPlayer.h:350
void updatePatchName()
Definition GigPlayer.cpp:1013
GigInstrumentView(Instrument *_instrument, QWidget *_parent)
Definition GigPlayer.cpp:918
PixmapButton * m_fileDialogButton
Definition GigPlayer.h:346
void showFileDialog()
Definition GigPlayer.cpp:1034
void showPatchDialog()
Definition GigPlayer.cpp:1075
void updateFilename()
Definition GigPlayer.cpp:995
void invalidateFile()
Definition GigPlayer.cpp:1026
QLabel * m_patchLabel
Definition GigPlayer.h:353
~GigInstrumentView() override=default
void modelChanged() override
Definition GigPlayer.cpp:978
Instrument view with fixed LMMS-default size.
Definition InstrumentView.h:66
Definition Knob.h:47
Definition LcdSpinBox.h:35
Definition PatchesDialog.h:44
Definition PixmapButton.h:37
Definition AudioPortAudio.cpp:209
Definition RemotePluginBase.cpp:34
GigState
Definition GigPlayer.h:190
@ Completed
Definition GigPlayer.h:200
@ KeyUp
Definition GigPlayer.h:196
@ PlayingKeyUp
Definition GigPlayer.h:198
@ PlayingKeyDown
Definition GigPlayer.h:194
@ KeyDown
Definition GigPlayer.h:192
std::uint64_t f_cnt_t
Definition LmmsTypes.h:43
QString filename
Definition HydrogenImport.cpp:42
Definition GigPlayer.h:93
uint DimValues[8]
Definition GigPlayer.h:103
Dimension()
Definition GigPlayer.h:94
bool release
Definition GigPlayer.h:104
Definition GigPlayer.h:65
int midiNote
Definition GigPlayer.h:66
Definition MidiPatch.h:34