123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 |
- /*
- * NotePlayHandle.h - declaration of class NotePlayHandle which manages
- * playback of a single note by an instrument
- *
- * Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
- *
- * This file is part of LMMS - https://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 NOTE_PLAY_HANDLE_H
- #define NOTE_PLAY_HANDLE_H
- #include <memory>
- #include "BasicFilters.h"
- #include "Note.h"
- #include "PlayHandle.h"
- #include "Track.h"
- #include "MemoryManager.h"
- class QReadWriteLock;
- class InstrumentTrack;
- class NotePlayHandle;
- typedef QList<NotePlayHandle *> NotePlayHandleList;
- typedef QList<const NotePlayHandle *> ConstNotePlayHandleList;
- class LMMS_EXPORT NotePlayHandle : public PlayHandle, public Note
- {
- MM_OPERATORS
- public:
- void * m_pluginData;
- std::unique_ptr<BasicFilters<>> m_filter;
- // length of the declicking fade in
- fpp_t m_fadeInLength;
- // specifies origin of NotePlayHandle
- enum Origins
- {
- OriginMidiClip, /*! playback of a note from a MIDI clip */
- OriginMidiInput, /*! playback of a MIDI note input event */
- OriginNoteStacking, /*! created by note stacking instrument function */
- OriginArpeggio, /*! created by arpeggio instrument function */
- OriginCount
- };
- typedef Origins Origin;
- NotePlayHandle( InstrumentTrack* instrumentTrack,
- const f_cnt_t offset,
- const f_cnt_t frames,
- const Note& noteToPlay,
- NotePlayHandle* parent = nullptr,
- int midiEventChannel = -1,
- Origin origin = OriginMidiClip );
- virtual ~NotePlayHandle();
- void * operator new ( size_t size, void * p )
- {
- return p;
- }
- void setVolume( volume_t volume ) override;
- void setPanning( panning_t panning ) override;
- int midiKey() const;
- int midiChannel() const
- {
- return m_midiChannel;
- }
- /*! convenience function that returns offset for the first period and zero otherwise,
- used by instruments to handle the offset: instruments have to check this property and
- add the correct number of empty frames in the beginning of the period */
- f_cnt_t noteOffset() const
- {
- return m_totalFramesPlayed == 0
- ? offset()
- : 0;
- }
- const float& frequency() const
- {
- return m_frequency;
- }
- /*! Returns frequency without pitch wheel influence */
- float unpitchedFrequency() const
- {
- return m_unpitchedFrequency;
- }
- /*! Renders one chunk using the attached instrument into the buffer */
- void play( sampleFrame* buffer ) override;
- /*! Returns whether playback of note is finished and thus handle can be deleted */
- bool isFinished() const override
- {
- return m_released && framesLeft() <= 0;
- }
- /*! Returns number of frames left for playback */
- f_cnt_t framesLeft() const;
- /*! Returns how many frames have to be rendered in current period */
- fpp_t framesLeftForCurrentPeriod() const;
- /*! Returns whether the play handle plays on a certain track */
- bool isFromTrack( const Track* _track ) const override;
- /*! Releases the note (and plays release frames) */
- void noteOff( const f_cnt_t offset = 0 );
- /*! Returns number of frames to be played until the note is going to be released */
- f_cnt_t framesBeforeRelease() const
- {
- return m_framesBeforeRelease;
- }
- /*! Returns how many frames were played since release */
- f_cnt_t releaseFramesDone() const
- {
- return m_releaseFramesDone;
- }
- /*! Returns the number of frames to be played after release according to
- the release times in the envelopes */
- f_cnt_t actualReleaseFramesToDo() const;
- /*! Returns total numbers of frames to play (including release frames) */
- f_cnt_t frames() const
- {
- return m_frames;
- }
- /*! Sets the total number of frames to play (including release frames) */
- void setFrames( const f_cnt_t _frames );
- /*! Returns whether note was released */
- bool isReleased() const
- {
- return m_released;
- }
- bool isReleaseStarted() const
- {
- return m_releaseStarted;
- }
- /*! Returns total numbers of frames played so far */
- f_cnt_t totalFramesPlayed() const
- {
- return m_totalFramesPlayed;
- }
- /*! Returns volume level at given frame (envelope/LFO) */
- float volumeLevel( const f_cnt_t frame );
- /*! Returns instrument track which is being played by this handle (const version) */
- const InstrumentTrack* instrumentTrack() const
- {
- return m_instrumentTrack;
- }
- /*! Returns instrument track which is being played by this handle */
- InstrumentTrack* instrumentTrack()
- {
- return m_instrumentTrack;
- }
- /*! Returns whether note has a parent, e.g. is not part of an arpeggio or a chord */
- bool hasParent() const
- {
- return m_hasParent;
- }
- /*! Returns origin of note */
- Origin origin() const
- {
- return m_origin;
- }
- /*! Returns whether note has children */
- bool isMasterNote() const
- {
- return m_subNotes.size() > 0 || m_hadChildren;
- }
- void setMasterNote()
- {
- m_hadChildren = true;
- setUsesBuffer( false );
- }
- /*! Returns whether note is muted */
- bool isMuted() const
- {
- return m_muted;
- }
- /*! Mutes playback of note */
- void mute();
- /*! Returns index of NotePlayHandle in vector of note-play-handles
- belonging to this instrument track - used by arpeggiator.
- Ignores child note-play-handles, returns -1 when called on one */
- int index() const;
- /*! Returns list of note-play-handles belonging to given instrument track.
- If allPlayHandles = true, also released note-play-handles and children
- are returned */
- static ConstNotePlayHandleList nphsOfInstrumentTrack( const InstrumentTrack* Track, bool allPlayHandles = false );
- /*! Returns whether given NotePlayHandle instance is equal to *this */
- bool operator==( const NotePlayHandle & _nph ) const;
- /*! Returns whether NotePlayHandle belongs to pattern track and pattern track is muted */
- bool isPatternTrackMuted()
- {
- return m_patternTrack && m_patternTrack->isMuted();
- }
- /*! Sets attached pattern track */
- void setPatternTrack(Track* t)
- {
- m_patternTrack = t;
- }
- /*! Process note detuning automation */
- void processTimePos( const TimePos& time );
- /*! Updates total length (m_frames) depending on a new tempo */
- void resize( const bpm_t newTempo );
- /*! Set song-global offset (relative to containing MIDI clip) in order to properly perform the note detuning */
- void setSongGlobalParentOffset( const TimePos& offset )
- {
- m_songGlobalParentOffset = offset;
- }
- /*! Returns song-global offset */
- const TimePos& songGlobalParentOffset() const
- {
- return m_songGlobalParentOffset;
- }
- void setFrequencyUpdate()
- {
- m_frequencyNeedsUpdate = true;
- }
- private:
- class BaseDetuning
- {
- MM_OPERATORS
- public:
- BaseDetuning( DetuningHelper* detuning );
- void setValue( float val )
- {
- m_value = val;
- }
- float value() const
- {
- return m_value;
- }
- private:
- float m_value;
- } ;
- void updateFrequency();
- InstrumentTrack* m_instrumentTrack; // needed for calling
- // InstrumentTrack::playNote
- f_cnt_t m_frames; // total frames to play
- f_cnt_t m_totalFramesPlayed; // total frame-counter - used for
- // figuring out whether a whole note
- // has been played
- f_cnt_t m_framesBeforeRelease; // number of frames after which note
- // is released
- f_cnt_t m_releaseFramesToDo; // total numbers of frames to be
- // played after release
- f_cnt_t m_releaseFramesDone; // number of frames done after
- // release of note
- NotePlayHandleList m_subNotes; // used for chords and arpeggios
- volatile bool m_released; // indicates whether note is released
- bool m_releaseStarted;
- bool m_hasMidiNote;
- bool m_hasParent; // indicates whether note has parent
- NotePlayHandle * m_parent; // parent note
- bool m_hadChildren;
- bool m_muted; // indicates whether note is muted
- Track* m_patternTrack; // related pattern track
- // tempo reaction
- bpm_t m_origTempo; // original tempo
- f_cnt_t m_origFrames; // original m_frames
- int m_origBaseNote;
- float m_frequency;
- float m_unpitchedFrequency;
- BaseDetuning* m_baseDetuning;
- TimePos m_songGlobalParentOffset;
- int m_midiChannel;
- Origin m_origin;
- bool m_frequencyNeedsUpdate; // used to update pitch
- } ;
- const int INITIAL_NPH_CACHE = 256;
- const int NPH_CACHE_INCREMENT = 16;
- class NotePlayHandleManager
- {
- MM_OPERATORS
- public:
- static void init();
- static NotePlayHandle * acquire( InstrumentTrack* instrumentTrack,
- const f_cnt_t offset,
- const f_cnt_t frames,
- const Note& noteToPlay,
- NotePlayHandle* parent = nullptr,
- int midiEventChannel = -1,
- NotePlayHandle::Origin origin = NotePlayHandle::OriginMidiClip );
- static void release( NotePlayHandle * nph );
- static void extend( int i );
- static void free();
- private:
- static NotePlayHandle ** s_available;
- static QReadWriteLock s_mutex;
- static std::atomic_int s_availableIndex;
- static int s_size;
- };
- #endif
|