Files
lmms/include/note_play_handle.h
Tobias Doerffel 5977041b6e InstrumentTrack, NotePlayHandle: fixed note detuning processing
Note detuning did not work properly for patterns starting after the
first bar in the song editor. This has been fixed by introducing
additional information about parent's song-global offset to
NotePlayHandle objects.

Closes #3462555.
2012-01-29 11:36:24 +01:00

281 lines
6.4 KiB
C++

/*
* note_play_handle.h - declaration of class notePlayHandle which is needed
* by LMMS-Play-Engine
*
* Copyright (c) 2004-2012 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 _NOTE_PLAY_HANDLE_H
#define _NOTE_PLAY_HANDLE_H
#include "lmmsconfig.h"
#include "mixer.h"
#include "note.h"
#include "engine.h"
#include "track.h"
class InstrumentTrack;
class notePlayHandle;
template<ch_cnt_t=DEFAULT_CHANNELS> class basicFilters;
typedef QList<notePlayHandle *> NotePlayHandleList;
typedef QList<const notePlayHandle *> ConstNotePlayHandleList;
class EXPORT notePlayHandle : public playHandle, public note
{
public:
void * m_pluginData;
basicFilters<> * m_filter;
notePlayHandle( InstrumentTrack * _instrument_track,
const f_cnt_t _offset,
const f_cnt_t _frames, const note & _n,
notePlayHandle * _parent = NULL,
const bool _part_of_arp = false );
virtual ~notePlayHandle();
virtual void setVolume( const volume_t _volume = DefaultVolume );
int midiVelocity() const;
int midiKey() const;
const float & frequency() const
{
return m_frequency;
}
void updateFrequency();
// returns frequency without pitch-wheel influence
float unpitchedFrequency() const
{
return m_unpitchedFrequency;
}
virtual void play( sampleFrame * _working_buffer );
virtual inline bool done() const
{
return m_released && framesLeft() <= 0;
}
f_cnt_t framesLeft() const;
inline fpp_t framesLeftForCurrentPeriod() const
{
return (fpp_t) qMin<f_cnt_t>( framesLeft(),
engine::getMixer()->framesPerPeriod() );
}
virtual bool isFromTrack( const track * _track ) const;
void noteOff( const f_cnt_t _s = 0 );
inline f_cnt_t framesBeforeRelease() const
{
return m_framesBeforeRelease;
}
inline f_cnt_t releaseFramesDone() const
{
return m_releaseFramesDone;
}
f_cnt_t actualReleaseFramesToDo() const;
// returns total numbers of frames to play
inline f_cnt_t frames() const
{
return m_frames;
}
void setFrames( const f_cnt_t _frames );
// returns whether note was released
inline bool released() const
{
return m_released;
}
// returns total numbers of played frames
inline f_cnt_t totalFramesPlayed() const
{
return m_totalFramesPlayed;
}
// returns volume-level at frame _frame (envelope/LFO)
float volumeLevel( const f_cnt_t _frame );
// returns instrument-track this note-play-handle plays
const InstrumentTrack *instrumentTrack() const
{
return m_instrumentTrack;
}
InstrumentTrack *instrumentTrack()
{
return m_instrumentTrack;
}
// returns whether note is a top note, e.g. is not part of an arpeggio
// or a chord
inline bool isTopNote() const
{
return m_topNote;
}
inline bool isPartOfArpeggio() const
{
return m_partOfArpeggio;
}
inline void setPartOfArpeggio( const bool _on )
{
m_partOfArpeggio = _on;
}
// returns whether note is base-note for arpeggio
bool isArpeggioBaseNote() const;
inline bool isMuted() const
{
return m_muted;
}
void mute();
// returns index of note-play-handle in vector of note-play-handles
// belonging to this instrument-track - used by arpeggiator
int index() const;
// note-play-handles belonging to given channel, if _all_ph = true,
// also released note-play-handles are returned
static ConstNotePlayHandleList nphsOfInstrumentTrack(
const InstrumentTrack * _ct, bool _all_ph = false );
// return whether given note-play-handle is equal to *this
bool operator==( const notePlayHandle & _nph ) const;
inline bool bbTrackMuted()
{
return m_bbTrack && m_bbTrack->isMuted();
}
void setBBTrack( track * _bb_track )
{
m_bbTrack = _bb_track;
}
void processMidiTime( const midiTime & _time );
void resize( const bpm_t _new_tempo );
void setSongGlobalParentOffset( const midiTime &offset )
{
m_songGlobalParentOffset = offset;
}
const midiTime &songGlobalParentOffset() const
{
return m_songGlobalParentOffset;
}
#ifdef LMMS_SINGERBOT_SUPPORT
int patternIndex()
{
return m_patternIndex;
}
void setPatternIndex( int _i )
{
m_patternIndex = _i;
}
#endif
private:
class BaseDetuning
{
public:
BaseDetuning( DetuningHelper *detuning );
void setValue( float val )
{
m_value = val;
}
float value() const
{
return m_value;
}
private:
DetuningHelper * m_detuning;
float m_value;
} ;
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_topNote; // indicates whether note is a
// base-note (i.e. no sub-note)
bool m_partOfArpeggio; // indicates whether note is part of
// an arpeggio (either base-note or
// sub-note)
bool m_muted; // indicates whether note is muted
track * m_bbTrack; // related BB track
#ifdef LMMS_SINGERBOT_SUPPORT
int m_patternIndex; // position among relevant notes
#endif
// 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;
midiTime m_songGlobalParentOffset;
} ;
#endif