- faster oscillator
- tempo-based arpeggiator and LFOs - bug-fixes - added another Moog-filter git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@14 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
3
AUTHORS
3
AUTHORS
@@ -2,6 +2,9 @@ Tobias Doerffel
|
||||
<tobydox@users.sourceforge.net>
|
||||
Maintainer, main-development, artwork etc.
|
||||
|
||||
Dany McRae
|
||||
<khjklujn@yahoo.com>
|
||||
development
|
||||
|
||||
Sebastian Tilsch
|
||||
<djcompilation@gmx.de>
|
||||
|
||||
45
ChangeLog
45
ChangeLog
@@ -1,3 +1,48 @@
|
||||
2005-10-05 Dany McRae <khjklujn@yahoo.com>
|
||||
|
||||
* resources/note_double_whole.png:
|
||||
* resources/note_eighth.png:
|
||||
* resources/note_half.png:
|
||||
* resources/note_none.png:
|
||||
* resources/note_quarter.png:
|
||||
* resources/note_sixteenth.png:
|
||||
* resources/note_thirtysecond.png:
|
||||
* resources/note_whole.png:
|
||||
* resources/xclock.png:
|
||||
added icons for context-menu of tempoSyncKnob
|
||||
|
||||
* src/widgets/lcd_spinbox.cpp:
|
||||
emit valueChanged()-signal in wheelEvent()-method
|
||||
|
||||
* include/song_editor.h:
|
||||
* src/core/song_editor.cpp:
|
||||
- added getBPM()-method
|
||||
- emit signal if BPM is changed
|
||||
|
||||
* include/arp_and_chords_tab_widget.h:
|
||||
* include/envelope_and_lfo_widget.h:
|
||||
* src/core/arp_and_chords_tab_widget.cpp:
|
||||
* src/core/envelope_and_lfo_widget.cpp:
|
||||
use new tempoSyncKnob-widget instead of traditional time-knob
|
||||
|
||||
* include/tempo_sync_knob.h:
|
||||
* src/widgets/tempo_sync_knob.cpp:
|
||||
added tempo-sync-knob which automatically converts fixed note-length's
|
||||
to a fixed time in ms everytime BPM is changed
|
||||
|
||||
2005-10-03 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* include/basic_filters.h:
|
||||
- added another moog-filter which sounds a bit better but needs MUCH
|
||||
more CPU-time...
|
||||
- cleaned up different filter-code-branches
|
||||
|
||||
2005-10-02 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* include/oscillator.h:
|
||||
cast to int instead of floor()ing value in oscillator::phase() which
|
||||
makes the whole thing faster again...
|
||||
|
||||
2005-09-29 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* src/widgets/tab_widget.cpp:
|
||||
|
||||
@@ -80,6 +80,7 @@ lmms_MOC = \
|
||||
./tab_bar.moc \
|
||||
./tab_button.moc \
|
||||
./tab_widget.moc \
|
||||
./tempo_sync_knob.moc \
|
||||
./timeline.moc \
|
||||
./track_container.moc \
|
||||
./track.moc \
|
||||
@@ -161,6 +162,7 @@ lmms_SOURCES = \
|
||||
$(srcdir)/src/widgets/tab_bar.cpp \
|
||||
$(srcdir)/src/widgets/tab_widget.cpp \
|
||||
$(srcdir)/src/widgets/text_float.cpp \
|
||||
$(srcdir)/src/widgets/tempo_sync_knob.cpp \
|
||||
$(srcdir)/src/widgets/tooltip.cpp \
|
||||
$(srcdir)/src/widgets/visualization_widget.cpp \
|
||||
$(srcdir)/include/pch.h \
|
||||
@@ -252,6 +254,7 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/tooltip.h \
|
||||
$(srcdir)/include/led_checkbox.h \
|
||||
$(srcdir)/include/text_float.h \
|
||||
$(srcdir)/include/tempo_sync_knob.h \
|
||||
$(srcdir)/include/setup_dialog.h \
|
||||
$(srcdir)/include/empty_sg_plugin.h
|
||||
|
||||
|
||||
1
TODO
1
TODO
@@ -5,7 +5,6 @@
|
||||
- make usable with Qt4
|
||||
- make LMMS an ALSA-sequencer-client
|
||||
- adchannel-toolbutton -> popup-menu with available soundgenerator-plugins
|
||||
- tempo-based arpeggio
|
||||
- pre-listen when opening sample with QFileDialog
|
||||
- level-meters in output-graph and channel-track
|
||||
- panning-editing in piano-roll
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.1.1-cvs20050929, tobydox@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20050929)
|
||||
AC_INIT(lmms, 0.1.1-cvs20051005, tobydox@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051005)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
|
||||
@@ -46,13 +46,15 @@
|
||||
#include "types.h"
|
||||
|
||||
|
||||
class QComboBox;
|
||||
class QPixmap;
|
||||
|
||||
class channelTrack;
|
||||
class groupBox;
|
||||
class knob;
|
||||
class pixmapButton;
|
||||
class QComboBox;
|
||||
class QPixmap;
|
||||
class notePlayHandle;
|
||||
class pixmapButton;
|
||||
class tempoSyncKnob;
|
||||
|
||||
|
||||
const int MAX_CHORD_POLYPHONY = 10;
|
||||
@@ -123,7 +125,7 @@ private:
|
||||
groupBox * m_arpGroupBox;
|
||||
QComboBox * m_arpComboBox;
|
||||
knob * m_arpRangeKnob;
|
||||
knob * m_arpTimeKnob;
|
||||
tempoSyncKnob * m_arpTimeKnob;
|
||||
knob * m_arpGateKnob;
|
||||
QLabel * m_arpDirectionLbl;
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "mixer.h"
|
||||
#include "templates.h"
|
||||
|
||||
const int MOOG_VOLTAGE = 40000;
|
||||
|
||||
template<Uint8 CHANNELS = DEFAULT_CHANNELS>
|
||||
class basicFilters
|
||||
@@ -53,10 +54,23 @@ public:
|
||||
NOTCH,
|
||||
ALLPASS,
|
||||
MOOG,
|
||||
DOUBLE_LOWPASS,
|
||||
DOUBLE_MOOG
|
||||
MOOG2,
|
||||
SIMPLE_FLT_CNT,
|
||||
DOUBLE_LOWPASS = 16+LOWPASS,
|
||||
DOUBLE_MOOG = 16+MOOG,
|
||||
DOUBLE_MOOG2 = 16+MOOG2
|
||||
} ;
|
||||
|
||||
static inline filterTypes getFilterType( const int _idx )
|
||||
{
|
||||
if( _idx < SIMPLE_FLT_CNT )
|
||||
{
|
||||
return( static_cast<filterTypes>( _idx ) );
|
||||
}
|
||||
return( static_cast<filterTypes>( DOUBLE_LOWPASS + _idx -
|
||||
SIMPLE_FLT_CNT ) );
|
||||
}
|
||||
|
||||
inline basicFilters( const float _sampleRate ) :
|
||||
m_b0a0( 0.0f ),
|
||||
m_b1a0( 0.0f ),
|
||||
@@ -87,40 +101,112 @@ public:
|
||||
inline sampleType update( sampleType _in0, Uint8 _chnl )
|
||||
{
|
||||
sampleType out;
|
||||
if( m_type != MOOG )
|
||||
switch( m_type )
|
||||
{
|
||||
// filter
|
||||
out = m_b0a0*_in0 + m_b1a0*m_in1[_chnl] +
|
||||
m_b2a0*m_in2[_chnl] - m_a1a0*m_ou1[_chnl] -
|
||||
m_a2a0*m_ou2[_chnl];
|
||||
|
||||
// push in/out buffers
|
||||
m_in2[_chnl] = m_in1[_chnl];
|
||||
m_in1[_chnl] = _in0;
|
||||
m_ou2[_chnl] = m_ou1[_chnl];
|
||||
|
||||
m_ou1[_chnl] = out;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleType x = _in0 - m_r*m_y4[_chnl];
|
||||
case MOOG:
|
||||
case DOUBLE_MOOG:
|
||||
{
|
||||
sampleType x = _in0 - m_r*m_y4[_chnl];
|
||||
|
||||
// Four cascaded onepole filters (bilinear transform)
|
||||
m_y1[_chnl] = x*m_p + m_oldx[_chnl]*m_p -
|
||||
// four cascaded onepole filters
|
||||
// (bilinear transform)
|
||||
m_y1[_chnl] = x*m_p + m_oldx[_chnl]*m_p -
|
||||
m_k*m_y1[_chnl];
|
||||
m_y2[_chnl] = m_y1[_chnl]*m_p+m_oldy1[_chnl]*m_p -
|
||||
m_k*m_y2[_chnl];
|
||||
m_y3[_chnl] = m_y2[_chnl]*m_p+m_oldy2[_chnl]*m_p -
|
||||
m_k*m_y3[_chnl];
|
||||
m_y4[_chnl] = m_y3[_chnl]*m_p+m_oldy3[_chnl]*m_p -
|
||||
m_k*m_y4[_chnl];
|
||||
m_y2[_chnl] = m_y1[_chnl]*m_p+m_oldy1[_chnl]*
|
||||
m_p - m_k*m_y2[_chnl];
|
||||
m_y3[_chnl] = m_y2[_chnl]*m_p+m_oldy2[_chnl]*
|
||||
m_p - m_k*m_y3[_chnl];
|
||||
m_y4[_chnl] = m_y3[_chnl]*m_p+m_oldy3[_chnl]*
|
||||
m_p - m_k*m_y4[_chnl];
|
||||
|
||||
m_oldx[_chnl] = x;
|
||||
m_oldy1[_chnl] = m_y1[_chnl];
|
||||
m_oldy2[_chnl] = m_y2[_chnl];
|
||||
m_oldy3[_chnl] = m_y3[_chnl];
|
||||
out = m_y4[_chnl] - m_y4[_chnl] * m_y4[_chnl] *
|
||||
m_y4[_chnl] * ( 1.0f/6.0f );
|
||||
m_oldx[_chnl] = x;
|
||||
m_oldy1[_chnl] = m_y1[_chnl];
|
||||
m_oldy2[_chnl] = m_y2[_chnl];
|
||||
m_oldy3[_chnl] = m_y3[_chnl];
|
||||
out = m_y4[_chnl] - m_y4[_chnl] * m_y4[_chnl] *
|
||||
m_y4[_chnl] * ( 1.0f / 6.0f );
|
||||
break;
|
||||
}
|
||||
case MOOG2:
|
||||
case DOUBLE_MOOG2:
|
||||
{
|
||||
const float x1 = ( _in0 - m_r *
|
||||
m_oldx[_chnl] ) / MOOG_VOLTAGE;
|
||||
const float tanh1 = tanhf( x1 );
|
||||
const float x2 = m_oldy1[_chnl] / MOOG_VOLTAGE;
|
||||
const float tanh2 = tanhf( x2 );
|
||||
m_y1[_chnl] = m_oldy1[_chnl] + m_p *
|
||||
( tanh1 - tanh2 );
|
||||
m_oldy1[_chnl] = m_y1[_chnl];
|
||||
m_y2[_chnl] = m_oldy2[_chnl] + m_p *
|
||||
( tanhf( m_y1[_chnl] /
|
||||
MOOG_VOLTAGE ) -
|
||||
tanhf( m_oldy2[_chnl] /
|
||||
MOOG_VOLTAGE ) );
|
||||
m_oldy2[_chnl] = m_y2[_chnl];
|
||||
m_y3[_chnl] = m_oldy3[_chnl] + m_p *
|
||||
( tanhf( m_y2[_chnl] /
|
||||
MOOG_VOLTAGE ) -
|
||||
tanhf( m_oldy3[_chnl] /
|
||||
MOOG_VOLTAGE ) );
|
||||
m_oldy3[_chnl] = m_y3[_chnl];
|
||||
m_y4[_chnl] = m_ou1[_chnl] + m_p *
|
||||
( tanhf( m_y3[_chnl] /
|
||||
MOOG_VOLTAGE ) -
|
||||
tanhf( m_ou1[_chnl] /
|
||||
MOOG_VOLTAGE ) );
|
||||
m_ou1[_chnl] = m_y4[_chnl];
|
||||
|
||||
m_oldx[_chnl] = ( m_y4[_chnl] +
|
||||
m_ou2[_chnl] ) * 0.5f;
|
||||
m_ou2[_chnl] = m_y4[_chnl];
|
||||
|
||||
// the same code again...
|
||||
m_y1[_chnl] = m_oldy1[_chnl] + m_p *
|
||||
( tanh1 - tanh2 );
|
||||
m_oldy1[_chnl] = m_y1[_chnl];
|
||||
m_y2[_chnl] = m_oldy2[_chnl] + m_p *
|
||||
( tanhf( m_y1[_chnl] /
|
||||
MOOG_VOLTAGE ) -
|
||||
tanhf( m_oldy2[_chnl] /
|
||||
MOOG_VOLTAGE ) );
|
||||
m_oldy2[_chnl] = m_y2[_chnl];
|
||||
m_y3[_chnl] = m_oldy3[_chnl] + m_p *
|
||||
( tanhf( m_y2[_chnl] /
|
||||
MOOG_VOLTAGE ) -
|
||||
tanhf( m_oldy3[_chnl] /
|
||||
MOOG_VOLTAGE ) );
|
||||
m_oldy3[_chnl] = m_y3[_chnl];
|
||||
m_y4[_chnl] = m_ou1[_chnl] + m_p *
|
||||
( tanhf( m_y3[_chnl] /
|
||||
MOOG_VOLTAGE ) -
|
||||
tanhf( m_ou1[_chnl] /
|
||||
MOOG_VOLTAGE ) );
|
||||
m_ou1[_chnl] = m_y4[_chnl];
|
||||
|
||||
m_oldx[_chnl] = ( m_y4[_chnl] +
|
||||
m_ou2[_chnl] ) * 0.5f;
|
||||
m_ou2[_chnl] = m_y4[_chnl];
|
||||
|
||||
out = m_oldx[_chnl];
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// filter
|
||||
out = m_b0a0*_in0 +
|
||||
m_b1a0*m_in1[_chnl] +
|
||||
m_b2a0*m_in2[_chnl] -
|
||||
m_a1a0*m_ou1[_chnl] -
|
||||
m_a2a0*m_ou2[_chnl];
|
||||
|
||||
// push in/out buffers
|
||||
m_in2[_chnl] = m_in1[_chnl];
|
||||
m_in1[_chnl] = _in0;
|
||||
m_ou2[_chnl] = m_ou1[_chnl];
|
||||
|
||||
m_ou1[_chnl] = out;
|
||||
break;
|
||||
}
|
||||
if( m_subFilter != NULL )
|
||||
{
|
||||
@@ -140,13 +226,9 @@ public:
|
||||
_freq = tMax( _freq, 0.01f );// limit freq for not getting
|
||||
// bad noise out of the filter...
|
||||
|
||||
if( m_type == MOOG || m_type == DOUBLE_MOOG )
|
||||
switch( m_type )
|
||||
{
|
||||
const float f = 2 * _freq / m_sampleRate; // [0 - 1]
|
||||
m_k = 3.6f*f - 1.6f*f*f - 1; // (Empirical tunning)
|
||||
m_p = (m_k+1)*0.5f;
|
||||
m_r = _q*powf( M_E, ( ( 1-m_p ) * 1.386249f ) );
|
||||
if( m_type == DOUBLE_MOOG )
|
||||
case DOUBLE_MOOG:
|
||||
{
|
||||
if( m_subFilter == NULL )
|
||||
{
|
||||
@@ -157,78 +239,121 @@ public:
|
||||
m_subFilter->calcFilterCoeffs( MOOG, _freq,
|
||||
_q );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// other filters
|
||||
const float omega = 2.0f * M_PI * _freq /
|
||||
m_sampleRate;
|
||||
const float tsin = sinf( omega );
|
||||
const float tcos = cosf( omega );
|
||||
//float alpha;
|
||||
|
||||
//if (q_is_bandwidth)
|
||||
//alpha = tsin*sinhf(logf(2.0f)/2.0f*q*omega/tsin);
|
||||
//else
|
||||
const float alpha = tsin / ( 2.0f*_q );
|
||||
|
||||
const float a0 = 1.0f / ( 1.0f+alpha );
|
||||
|
||||
if( m_type == LOWPASS || m_type == DOUBLE_LOWPASS )
|
||||
case MOOG:
|
||||
{
|
||||
m_b0a0 = ((1.0f-tcos)/2.0f)*a0;
|
||||
m_b1a0 = (1.0f-tcos)*a0;
|
||||
m_b2a0 = m_b0a0;//((1.0f-tcos)/2.0f)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
if( m_type == DOUBLE_LOWPASS )
|
||||
// [ 0 - 1 ]
|
||||
const float f = 2 * _freq / m_sampleRate;
|
||||
// (Empirical tunning)
|
||||
m_k = 3.6f*f - 1.6f*f*f - 1;
|
||||
m_p = (m_k+1)*0.5f;
|
||||
m_r = _q*powf( M_E, ( ( 1-m_p ) * 1.386249f ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case DOUBLE_MOOG2:
|
||||
{
|
||||
if( m_subFilter == NULL )
|
||||
{
|
||||
if( m_subFilter == NULL )
|
||||
m_subFilter =
|
||||
new basicFilters<CHANNELS>(
|
||||
m_sampleRate );
|
||||
}
|
||||
m_subFilter->calcFilterCoeffs( MOOG2, _freq,
|
||||
_q );
|
||||
}
|
||||
|
||||
case MOOG2:
|
||||
{
|
||||
const float kfc = 2 * _freq / m_sampleRate;
|
||||
const float kf = _freq / m_sampleRate;
|
||||
const float kfcr = 1.8730 * ( kfc*kfc*kfc ) +
|
||||
0.4955 * ( kfc*kfc ) +
|
||||
0.6490 * kfc + 0.9988;
|
||||
const float kacr = -3.9364 * ( kfc*kfc ) +
|
||||
1.8409 * kfc + 0.9968;
|
||||
m_p = MOOG_VOLTAGE * ( 1 - expf( -2.0 * M_PI *
|
||||
kfcr * kf ) );
|
||||
m_r = 4 * _q * kacr;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// other filters
|
||||
const float omega = 2.0f * M_PI * _freq /
|
||||
m_sampleRate;
|
||||
const float tsin = sinf( omega );
|
||||
const float tcos = cosf( omega );
|
||||
//float alpha;
|
||||
|
||||
//if (q_is_bandwidth)
|
||||
//alpha = tsin*sinhf(logf(2.0f)/2.0f*q*omega/
|
||||
// tsin);
|
||||
//else
|
||||
const float alpha = tsin / ( 2.0f * _q );
|
||||
|
||||
const float a0 = 1.0f / ( 1.0f+alpha );
|
||||
|
||||
if( m_type == LOWPASS ||
|
||||
m_type == DOUBLE_LOWPASS )
|
||||
{
|
||||
m_b0a0 = ((1.0f-tcos)/2.0f)*a0;
|
||||
m_b1a0 = (1.0f-tcos)*a0;
|
||||
m_b2a0 = m_b0a0;//((1.0f-tcos)/2.0f)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
if( m_type == DOUBLE_LOWPASS )
|
||||
{
|
||||
m_subFilter =
|
||||
if( m_subFilter == NULL )
|
||||
{
|
||||
m_subFilter =
|
||||
new basicFilters<CHANNELS>( m_sampleRate );
|
||||
}
|
||||
m_subFilter->calcFilterCoeffs( LOWPASS,
|
||||
}
|
||||
m_subFilter->calcFilterCoeffs(
|
||||
LOWPASS,
|
||||
_freq,
|
||||
_q );
|
||||
}
|
||||
}
|
||||
else if( m_type == HIPASS )
|
||||
{
|
||||
m_b0a0 = ((1.0f+tcos)/2.0f)*a0;
|
||||
m_b1a0 = (-1.0f-tcos)*a0;
|
||||
m_b2a0 = m_b0a0;//((1.0f+tcos)/2.0f)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == BANDPASS_CSG )
|
||||
{
|
||||
m_b0a0 = (tsin/2.0f)*a0;
|
||||
m_b1a0 = 0.0f;
|
||||
m_b2a0 = (-tsin/2.0f)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == BANDPASS_CZPG )
|
||||
{
|
||||
m_b0a0 = alpha*a0;
|
||||
m_b1a0 = 0.0f;
|
||||
m_b2a0 = (-alpha)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == NOTCH )
|
||||
{
|
||||
m_b0a0 = a0;
|
||||
m_b1a0 = (-2.0f*tcos)*a0;
|
||||
m_b2a0 = a0;
|
||||
m_a1a0 = m_b1a0;//(-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == ALLPASS )
|
||||
{
|
||||
m_b0a0 = (1.0f-alpha)*a0;
|
||||
m_b1a0 = (-2.0f*tcos)*a0;
|
||||
m_b2a0 = 1.0;//(1.0f+alpha)*a0;
|
||||
m_a1a0 = m_b1a0;//(-2.0f*tcos)*a0;
|
||||
//m_a2a0 = m_b0a0;//(1.0f-alpha)*a0;
|
||||
}
|
||||
m_a2a0 = (1.0f-alpha)*a0;
|
||||
break;
|
||||
}
|
||||
else if( m_type == HIPASS )
|
||||
{
|
||||
m_b0a0 = ((1.0f+tcos)/2.0f)*a0;
|
||||
m_b1a0 = (-1.0f-tcos)*a0;
|
||||
m_b2a0 = m_b0a0;//((1.0f+tcos)/2.0f)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == BANDPASS_CSG )
|
||||
{
|
||||
m_b0a0 = (tsin/2.0f)*a0;
|
||||
m_b1a0 = 0.0f;
|
||||
m_b2a0 = (-tsin/2.0f)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == BANDPASS_CZPG )
|
||||
{
|
||||
m_b0a0 = alpha*a0;
|
||||
m_b1a0 = 0.0f;
|
||||
m_b2a0 = (-alpha)*a0;
|
||||
m_a1a0 = (-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == NOTCH )
|
||||
{
|
||||
m_b0a0 = a0;
|
||||
m_b1a0 = (-2.0f*tcos)*a0;
|
||||
m_b2a0 = a0;
|
||||
m_a1a0 = m_b1a0;//(-2.0f*tcos)*a0;
|
||||
}
|
||||
else if( m_type == ALLPASS )
|
||||
{
|
||||
m_b0a0 = (1.0f-alpha)*a0;
|
||||
m_b1a0 = (-2.0f*tcos)*a0;
|
||||
m_b2a0 = 1.0;//(1.0f+alpha)*a0;
|
||||
m_a1a0 = m_b1a0;//(-2.0f*tcos)*a0;
|
||||
//m_a2a0 = m_b0a0;//(1.0f-alpha)*a0;
|
||||
}
|
||||
m_a2a0 = (1.0f-alpha)*a0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class envelopeTabWidget;
|
||||
class knob;
|
||||
class ledCheckBox;
|
||||
class pixmapButton;
|
||||
|
||||
class tempoSyncKnob;
|
||||
|
||||
|
||||
class envelopeAndLFOWidget : public QWidget, public settings,
|
||||
@@ -138,7 +138,7 @@ private:
|
||||
// LFO-stuff
|
||||
knob * m_lfoPredelayKnob;
|
||||
knob * m_lfoAttackKnob;
|
||||
knob * m_lfoSpeedKnob;
|
||||
tempoSyncKnob * m_lfoSpeedKnob;
|
||||
knob * m_lfoAmountKnob;
|
||||
pixmapButton * m_sinLfoBtn;
|
||||
pixmapButton * m_triangleLfoBtn;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* knob.h - powerful knob-widget
|
||||
*
|
||||
* This file is based on the knob-widget of the Qwt Widget Library by Josef Wilgen
|
||||
* This file is based on the knob-widget of the Qwt Widget Library by
|
||||
* Josef Wilgen
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
@@ -132,8 +133,11 @@ protected:
|
||||
void drawKnob( QPainter * _p );
|
||||
void setPosition( const QPoint & _p );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// TODO: Need to figure out what is really used by tempoSyncKnob
|
||||
// to get the private/protected attributes sorted out. Right
|
||||
// now, just make everything protected.
|
||||
//private:
|
||||
void layoutKnob( bool _update = TRUE );
|
||||
float getValue( const QPoint & _p );
|
||||
void getScrollMode( const QPoint & _p, int & _scroll_mode,
|
||||
|
||||
@@ -103,8 +103,7 @@ public:
|
||||
static oscillator * FASTCALL createOsc( waveShapes _wave_shape,
|
||||
modulationAlgos _modulation_algo, float _freq,
|
||||
Sint16 _phase_offset, float _volume_factor,
|
||||
oscillator * _m_subOsc = NULL );
|
||||
|
||||
oscillator * _m_subOsc = NULL );
|
||||
inline bool syncOk( void )
|
||||
{
|
||||
const float v1 = m_sample * m_oscCoeff;
|
||||
@@ -112,19 +111,20 @@ public:
|
||||
// check whether v2 is in next period
|
||||
return( floorf( v2 ) > floorf( v1 ) );
|
||||
}
|
||||
#define FLOAT_TO_INT(in,out) \
|
||||
register const float round_const = -0.5f; \
|
||||
__asm__ __volatile__ ("fadd %%st,%%st(0)\n" \
|
||||
"fadd %2\n" \
|
||||
"fistpl %0\n" \
|
||||
"shrl $1,%0" : "=m" (out) : "t" (in),"m"(round_const) : "st") ;
|
||||
|
||||
static inline float phase( float _sample )
|
||||
static inline float phase( const float _sample )
|
||||
{
|
||||
#ifndef modff
|
||||
float t;
|
||||
#else
|
||||
double t;
|
||||
#endif
|
||||
return( modff( _sample, &t ) );
|
||||
//return( _sample - floorf( _sample ) );
|
||||
return( _sample - static_cast<int>( _sample ) );
|
||||
}
|
||||
|
||||
// now follow the wave-shape-routines...
|
||||
|
||||
static inline sampleType sinSample( float _sample )
|
||||
{
|
||||
return( sinf( _sample * static_cast<sampleType>( 2.0f * M_PI
|
||||
@@ -157,7 +157,7 @@ public:
|
||||
|
||||
static inline sampleType moogSawSample( float _sample )
|
||||
{
|
||||
const float ph= phase( _sample );
|
||||
const float ph = phase( _sample );
|
||||
if( ph < 0.5f )
|
||||
{
|
||||
return( -1.0f + ph * 4.0f );
|
||||
|
||||
@@ -154,6 +154,8 @@ public:
|
||||
return( m_playPos[_pm] );
|
||||
}
|
||||
|
||||
int getBPM( void );
|
||||
|
||||
// every function that replaces current file (e.g. creates new file,
|
||||
// opens another file...) has to call this before and may only process
|
||||
// if this function returns true
|
||||
|
||||
109
include/tempo_sync_knob.h
Normal file
109
include/tempo_sync_knob.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* tempo_sync_knob.h - adds bpm to ms conversion for knob class
|
||||
*
|
||||
* This derived from the knob-widget by Tobias Doerffel
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Danny McRae <khjklujn@yahoo.com>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _TEMPO_SYNC_KNOB_H
|
||||
#define _TEMPO_SYNC_KNOB_H
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPixmap.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpixmap.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include "knob.h"
|
||||
|
||||
|
||||
enum tempoSyncMode
|
||||
{
|
||||
NO_SYNC,
|
||||
DOUBLE_WHOLE_NOTE,
|
||||
WHOLE_NOTE,
|
||||
HALF_NOTE,
|
||||
QUARTER_NOTE,
|
||||
EIGHTH_NOTE,
|
||||
SIXTEENTH_NOTE,
|
||||
THIRTYSECOND_NOTE
|
||||
} ;
|
||||
|
||||
|
||||
class tempoSyncKnob : public knob
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
tempoSyncKnob( int _knob_num, QWidget * _parent, const QString & _name,
|
||||
float _scale = 1.0f );
|
||||
virtual ~tempoSyncKnob();
|
||||
|
||||
tempoSyncMode getSyncMode( void );
|
||||
void setSyncMode( tempoSyncMode _new_mode );
|
||||
|
||||
float getScale( void );
|
||||
void setScale( float _new_scale );
|
||||
|
||||
const QString & getSyncDescription( void );
|
||||
void setSyncDescription( const QString & _new_description );
|
||||
|
||||
const QPixmap & getSyncIcon( void );
|
||||
void setSyncIcon( const QPixmap & _new_pix );
|
||||
|
||||
|
||||
signals:
|
||||
void syncModeChanged( tempoSyncMode _new_mode );
|
||||
void scaleChanged( float _new_scale );
|
||||
void syncDescriptionChanged( const QString & _new_description );
|
||||
void syncIconChanged( void );
|
||||
|
||||
|
||||
public slots:
|
||||
void setTempoSync( int _note_type );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void mouseMoveEvent( QMouseEvent * _me );
|
||||
virtual void contextMenuEvent( QContextMenuEvent * _me );
|
||||
virtual void wheelEvent( QWheelEvent * _me );
|
||||
|
||||
|
||||
protected slots:
|
||||
void calculateTempoSyncTime( int _bpm );
|
||||
|
||||
|
||||
private:
|
||||
tempoSyncMode m_tempoSyncMode;
|
||||
float m_scale;
|
||||
QPixmap m_tempoSyncIcon;
|
||||
QString m_tempoSyncDescription;
|
||||
|
||||
tempoSyncMode m_tempoLastSyncMode;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -53,7 +53,7 @@
|
||||
#include "knob.h"
|
||||
#include "tooltip.h"
|
||||
#include "gui_templates.h"
|
||||
|
||||
#include "tempo_sync_knob.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
@@ -286,7 +286,7 @@ arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track,
|
||||
"The selected arpeggio will be played within specified "
|
||||
"amount of octaves." ) );
|
||||
|
||||
m_arpTimeKnob = new knob( knobBright_26, m_arpGroupBox,
|
||||
m_arpTimeKnob = new tempoSyncKnob( knobBright_26, m_arpGroupBox,
|
||||
tr( "Arpeggio time" ) );
|
||||
m_arpTimeKnob->setLabel( tr( "TIME" ) );
|
||||
m_arpTimeKnob->setRange( 10.0, 1000.0, 1.0 );
|
||||
@@ -634,6 +634,9 @@ void arpAndChordsTabWidget::saveSettings( QDomDocument & _doc,
|
||||
m_arpGateKnob->value() ) );
|
||||
elw_de.setAttribute( "arpdir", QString::number(
|
||||
m_arpDirection ) );
|
||||
elw_de.setAttribute( "arpsyncmode", QString::number(
|
||||
( int ) m_arpTimeKnob->getSyncMode() ) );
|
||||
|
||||
|
||||
_parent.appendChild( elw_de );
|
||||
}
|
||||
@@ -661,6 +664,8 @@ void arpAndChordsTabWidget::loadSettings( const QDomElement & _this )
|
||||
m_arpGateKnob->setValue( _this.attribute( "arpgate" ).toFloat() );
|
||||
m_arpDirection = static_cast<arpDirections>(
|
||||
_this.attribute( "arpdir" ).toInt() );
|
||||
m_arpTimeKnob->setSyncMode(
|
||||
( tempoSyncMode ) _this.attribute( "arpsyncmode" ).toInt() );
|
||||
|
||||
m_arpGroupBox->setState( m_arpDirection != OFF &&
|
||||
!_this.attribute( "arpdisabled" ).toInt() );
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#include "tooltip.h"
|
||||
#include "gui_templates.h"
|
||||
#include "led_checkbox.h"
|
||||
|
||||
#include "tempo_sync_knob.h"
|
||||
|
||||
// how long should be each envelope-segment maximal (e.g. attack)?
|
||||
const float SECS_PER_ENV_SEGMENT = 5.0f;
|
||||
@@ -297,7 +297,8 @@ envelopeAndLFOWidget::envelopeAndLFOWidget( float _value_for_zero_amount,
|
||||
connect( m_lfoAttackKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
SLOT( updateAfterKnobChange( float ) ) );
|
||||
|
||||
m_lfoSpeedKnob = new knob( knobBright_26, this, tr( "LFO-speed" ) );
|
||||
m_lfoSpeedKnob = new tempoSyncKnob( knobBright_26, this, tr( "LFO-speed" ) ,
|
||||
20000.0 );
|
||||
m_lfoSpeedKnob->setLabel( tr( "SPD" ) );
|
||||
m_lfoSpeedKnob->setRange( 0.01, 1.0, 0.0001 );
|
||||
m_lfoSpeedKnob->setValue( 0.1, TRUE );
|
||||
@@ -584,6 +585,8 @@ void envelopeAndLFOWidget::saveSettings( QDomDocument & ,
|
||||
m_x100Cb->isChecked() ) );
|
||||
_parent.setAttribute( "ctlenvamt", QString::number(
|
||||
m_controlEnvAmountCb->isChecked() ) );
|
||||
_parent.setAttribute( "lfosyncmode", QString::number(
|
||||
( int ) m_lfoSpeedKnob->getSyncMode() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -609,6 +612,8 @@ void envelopeAndLFOWidget::loadSettings( const QDomElement & _this )
|
||||
m_x100Cb->setChecked( _this.attribute( "x100" ).toInt() );
|
||||
m_controlEnvAmountCb->setChecked( _this.attribute(
|
||||
"ctlenvamt" ).toInt() );
|
||||
m_lfoSpeedKnob->setSyncMode( ( tempoSyncMode ) _this.attribute(
|
||||
"lfosyncmode" ).toInt() );
|
||||
|
||||
switch( m_lfoShape )
|
||||
{
|
||||
|
||||
@@ -153,8 +153,10 @@ envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track,
|
||||
m_filterComboBox->addItem( tr( "Notch" ) );
|
||||
m_filterComboBox->addItem( tr( "Allpass" ) );
|
||||
m_filterComboBox->addItem( tr( "Moog" ) );
|
||||
m_filterComboBox->addItem( tr( "Moog 2" ) );
|
||||
m_filterComboBox->addItem( tr( "2x LowPass" ) );
|
||||
m_filterComboBox->addItem( tr( "2x Moog" ) );
|
||||
m_filterComboBox->addItem( tr( "2x Moog 2" ) );
|
||||
|
||||
#ifdef QT4
|
||||
m_filterComboBox->setWhatsThis(
|
||||
@@ -269,7 +271,7 @@ void envelopeTabWidget::processAudioBuffer( sampleFrame * _ab, Uint32 _frames,
|
||||
int old_filter_cut = 0;
|
||||
int old_filter_res = 0;
|
||||
|
||||
basicFilters<>::filterTypes filter = static_cast<basicFilters<>::filterTypes>( m_filterComboBox->
|
||||
basicFilters<>::filterTypes filter = basicFilters<>::getFilterType( m_filterComboBox->
|
||||
#ifdef QT4
|
||||
currentIndex()
|
||||
#else
|
||||
|
||||
@@ -1918,6 +1918,7 @@ void pianoRoll::keyReleaseEvent( QKeyEvent * )
|
||||
|
||||
void pianoRoll::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_we->accept();
|
||||
if( m_controlPressed )
|
||||
{
|
||||
if( _we->delta() > 0 )
|
||||
|
||||
@@ -609,6 +609,7 @@ void songEditor::scrolled( int _new_pos )
|
||||
|
||||
void songEditor::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_we->accept();
|
||||
if( m_controlPressed )
|
||||
{
|
||||
if( _we->delta() > 0 )
|
||||
@@ -757,6 +758,7 @@ void songEditor::setBPM( int _new_bpm )
|
||||
{
|
||||
m_bpmSpinBox->setValue( tLimit( _new_bpm, MIN_BPM, MAX_BPM ) );
|
||||
setModified();
|
||||
emit bpmChanged( _new_bpm );
|
||||
}
|
||||
|
||||
|
||||
@@ -1332,6 +1334,13 @@ float songEditor::framesPerTact( void ) const
|
||||
|
||||
|
||||
|
||||
int songEditor::getBPM( void )
|
||||
{
|
||||
return( m_bpmSpinBox->value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
bool songEditor::mayChangeProject( void )
|
||||
{
|
||||
|
||||
@@ -166,7 +166,9 @@ void lcdSpinBox::mouseReleaseEvent( QMouseEvent * _me )
|
||||
|
||||
void lcdSpinBox::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_we->accept();
|
||||
setValue( value() + _we->delta() / 120 * m_step );
|
||||
emit valueChanged( value() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ void ledCheckBox::paintEvent( QPaintEvent * )
|
||||
QPainter p( this );
|
||||
#else
|
||||
QPixmap draw_pm( rect().size() );
|
||||
draw_pm.fill( this, rect().topLeft() );
|
||||
//draw_pm.fill( this, rect().topLeft() );
|
||||
|
||||
QPainter p( &draw_pm, this );
|
||||
#endif
|
||||
|
||||
@@ -207,6 +207,7 @@ void tabWidget::paintEvent( QPaintEvent * _pe )
|
||||
|
||||
void tabWidget::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_we->accept();
|
||||
int dir = ( _we->delta() > 0 ) ? 1 : -1;
|
||||
int tab = m_activeTab;
|
||||
while( tab > -1 && static_cast<csize>( tab ) < m_widgets.count() )
|
||||
|
||||
385
src/widgets/tempo_sync_knob.cpp
Normal file
385
src/widgets/tempo_sync_knob.cpp
Normal file
@@ -0,0 +1,385 @@
|
||||
/*
|
||||
* tempo_sync_knob.h - adds bpm to ms conversion for knob class
|
||||
*
|
||||
* This file is derived from the knob-widget by Tobias Doerffel
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Danny McRae <khjklujn@yahoo.com>
|
||||
*
|
||||
* 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., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
#include <QBitmap>
|
||||
#include <QLabel>
|
||||
#include <QStatusBar>
|
||||
#include <QMouseEvent>
|
||||
#include <QMenu>
|
||||
#include <QStatusBar>
|
||||
#include <QFontMetrics>
|
||||
#include <QApplication>
|
||||
|
||||
#else
|
||||
|
||||
#include <qlabel.h>
|
||||
#include <qpopupmenu.h>
|
||||
|
||||
#define addSeparator insertSeparator
|
||||
#define addMenu insertItem
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __USE_XOPEN
|
||||
#define __USE_XOPEN
|
||||
#endif
|
||||
|
||||
#include "tempo_sync_knob.h"
|
||||
#include "song_editor.h"
|
||||
#include "midi_device.h"
|
||||
#include "embed.h"
|
||||
#include "tooltip.h"
|
||||
#include "config_mgr.h"
|
||||
#include "text_float.h"
|
||||
|
||||
|
||||
const int WHEEL_DELTA = 120;
|
||||
|
||||
|
||||
|
||||
|
||||
tempoSyncKnob::tempoSyncKnob( int _knob_num, QWidget * _parent, const QString & _name,
|
||||
float _scale ) :
|
||||
knob( _knob_num, _parent, _name ),
|
||||
m_tempoSyncMode( NO_SYNC ),
|
||||
m_scale( _scale ),
|
||||
m_tempoSyncIcon( embed::getIconPixmap( "xclock" ) ),
|
||||
m_tempoSyncDescription( tr( "Tempo Sync" ) ),
|
||||
m_tempoLastSyncMode( NO_SYNC )
|
||||
{
|
||||
connect( songEditor::inst(), SIGNAL( bpmChanged( int ) ),
|
||||
this, SLOT( calculateTempoSyncTime( int ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tempoSyncKnob::~tempoSyncKnob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::contextMenuEvent( QContextMenuEvent * )
|
||||
{
|
||||
QMenu contextMenu( this );
|
||||
#ifdef QT4
|
||||
contextMenu.setTitle( accessibleName() );
|
||||
#else
|
||||
QLabel * caption = new QLabel( "<font color=white><b>" +
|
||||
QString( accessibleName() ) + "</b></font>", this );
|
||||
caption->setPaletteBackgroundColor( QColor( 0, 0, 192 ) );
|
||||
caption->setAlignment( Qt::AlignCenter );
|
||||
contextMenu.addAction( caption );
|
||||
#endif
|
||||
contextMenu.addAction( embed::getIconPixmap( "reload" ),
|
||||
tr( "&Reset (%1%2)" ).arg( m_initValue ).arg(
|
||||
m_hintTextAfterValue ),
|
||||
this, SLOT( reset() ) );
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction( embed::getIconPixmap( "edit_copy" ),
|
||||
tr( "&Copy value (%1%2)" ).arg( value() ).arg(
|
||||
m_hintTextAfterValue ),
|
||||
this, SLOT( copyValue() ) );
|
||||
contextMenu.addAction( embed::getIconPixmap( "edit_paste" ),
|
||||
tr( "&Paste value (%1%2)"
|
||||
).arg( s_copiedValue ).arg(
|
||||
m_hintTextAfterValue ),
|
||||
this, SLOT( pasteValue() ) );
|
||||
contextMenu.addSeparator();
|
||||
|
||||
QMenu * syncMenu = new QMenu( this );
|
||||
int menuId;
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_none" ),
|
||||
tr( "No Sync" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) NO_SYNC );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_double_whole" ),
|
||||
tr( "Eight beats" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) DOUBLE_WHOLE_NOTE );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_whole" ),
|
||||
tr( "Whole note" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) WHOLE_NOTE );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_half" ),
|
||||
tr( "Half note" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) HALF_NOTE );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_quarter" ),
|
||||
tr( "Quarter note" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) QUARTER_NOTE );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_eighth" ),
|
||||
tr( "8th note" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) EIGHTH_NOTE );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_sixteenth" ),
|
||||
tr( "16th note" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) SIXTEENTH_NOTE );
|
||||
menuId = syncMenu->addAction( embed::getIconPixmap( "note_thirtysecond" ),
|
||||
tr( "32nd note" ),
|
||||
this, SLOT( setTempoSync( int ) ) );
|
||||
syncMenu->setItemParameter( menuId, ( int ) THIRTYSECOND_NOTE );
|
||||
|
||||
contextMenu.addMenu( m_tempoSyncIcon, m_tempoSyncDescription, syncMenu );
|
||||
contextMenu.addSeparator();
|
||||
|
||||
contextMenu.addAction( tr( "Connect to MIDI-device" ), this,
|
||||
SLOT( connectToMidiDevice() ) );
|
||||
contextMenu.addSeparator();
|
||||
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
|
||||
this, SLOT( displayHelp() ) );
|
||||
contextMenu.exec( QCursor::pos() );
|
||||
|
||||
delete syncMenu;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( m_scrollMode == ScrMouse )
|
||||
{
|
||||
m_tempoSyncMode = NO_SYNC;
|
||||
calculateTempoSyncTime( songEditor::inst()->getBPM() );
|
||||
|
||||
setPosition( _me->pos() );
|
||||
if( value() != m_prevValue )
|
||||
{
|
||||
emit sliderMoved( value() );
|
||||
}
|
||||
if( !configManager::inst()->value( "knobs", "classicalusability"
|
||||
).toInt() )
|
||||
{
|
||||
QCursor::setPos( mapToGlobal( m_origMousePos ) );
|
||||
}
|
||||
}
|
||||
songEditor::inst()->setModified();
|
||||
|
||||
s_textFloat->setText( m_hintTextBeforeValue +
|
||||
QString::number( value() ) +
|
||||
m_hintTextAfterValue );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::wheelEvent( QWheelEvent * _me )
|
||||
{
|
||||
_me->accept();
|
||||
const int inc = _me->delta() / WHEEL_DELTA;
|
||||
incPages( inc );
|
||||
|
||||
m_tempoSyncMode = NO_SYNC;
|
||||
calculateTempoSyncTime( songEditor::inst()->getBPM() );
|
||||
|
||||
songEditor::inst()->setModified();
|
||||
|
||||
s_textFloat->reparent( this );
|
||||
s_textFloat->setText( m_hintTextBeforeValue +
|
||||
QString::number( value() ) +
|
||||
m_hintTextAfterValue );
|
||||
s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) +
|
||||
QPoint( m_knobPixmap->width() + 2, 0 ) );
|
||||
s_textFloat->setVisibilityTimeOut( 1000 );
|
||||
|
||||
toolTip::add( this, m_hintTextBeforeValue+QString::number( value() ) +
|
||||
m_hintTextAfterValue );
|
||||
|
||||
if( value() != m_prevValue )
|
||||
{
|
||||
emit sliderMoved( value() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::setTempoSync( int _note_type )
|
||||
{
|
||||
m_tempoSyncMode = ( tempoSyncMode ) _note_type;
|
||||
calculateTempoSyncTime( songEditor::inst()->getBPM() );
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::calculateTempoSyncTime( int _bpm )
|
||||
{
|
||||
float conversionFactor = 1.0;
|
||||
|
||||
if( m_tempoSyncMode )
|
||||
{
|
||||
switch( m_tempoSyncMode )
|
||||
{
|
||||
case DOUBLE_WHOLE_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to Eight Beats" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_double_whole" );
|
||||
conversionFactor = 0.125;
|
||||
break;
|
||||
case WHOLE_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to Whole Note" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_whole" );
|
||||
conversionFactor = 0.25;
|
||||
break;
|
||||
case HALF_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to Half Note" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_half" );
|
||||
conversionFactor = 0.5;
|
||||
break;
|
||||
case QUARTER_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to Quarter Note" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_quarter" );
|
||||
conversionFactor = 1.0;
|
||||
break;
|
||||
case EIGHTH_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to 8th Note" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_eighth" );
|
||||
conversionFactor = 2.0;
|
||||
break;
|
||||
case SIXTEENTH_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to 16th Note" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_sixteenth" );
|
||||
conversionFactor = 4.0;
|
||||
break;
|
||||
case THIRTYSECOND_NOTE:
|
||||
m_tempoSyncDescription = tr( "Synced to 32nd Note" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "note_thirtysecond" );
|
||||
conversionFactor = 8.0;
|
||||
break;
|
||||
default:
|
||||
printf( "arpAndChordsTabWidget::calculateTempoSyncTime: invalid tempoSyncMode" );
|
||||
break;
|
||||
}
|
||||
setValue( 60000.0 / ( _bpm * conversionFactor * m_scale ),
|
||||
FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_tempoSyncDescription = tr( "Tempo Sync" );
|
||||
m_tempoSyncIcon = embed::getIconPixmap( "xclock" );
|
||||
}
|
||||
|
||||
if( m_tempoSyncMode != m_tempoLastSyncMode )
|
||||
{
|
||||
emit syncModeChanged( m_tempoSyncMode );
|
||||
emit syncDescriptionChanged( m_tempoSyncDescription );
|
||||
emit syncIconChanged();
|
||||
}
|
||||
|
||||
m_tempoLastSyncMode = m_tempoSyncMode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tempoSyncMode tempoSyncKnob::getSyncMode( void )
|
||||
{
|
||||
return( m_tempoSyncMode );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::setSyncMode( tempoSyncMode _new_mode )
|
||||
{
|
||||
m_tempoSyncMode = _new_mode;
|
||||
calculateTempoSyncTime( songEditor::inst()->getBPM() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
float tempoSyncKnob::getScale( void )
|
||||
{
|
||||
return( m_scale );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::setScale( float _new_scale )
|
||||
{
|
||||
m_scale = _new_scale;
|
||||
calculateTempoSyncTime( songEditor::inst()->getBPM() );
|
||||
emit scaleChanged( _new_scale );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const QString & tempoSyncKnob::getSyncDescription( void )
|
||||
{
|
||||
return( m_tempoSyncDescription );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::setSyncDescription( const QString & _new_description )
|
||||
{
|
||||
m_tempoSyncDescription = _new_description;
|
||||
emit syncDescriptionChanged( _new_description );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const QPixmap & tempoSyncKnob::getSyncIcon( void )
|
||||
{
|
||||
return( m_tempoSyncIcon );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::setSyncIcon( const QPixmap & _new_icon )
|
||||
{
|
||||
m_tempoSyncIcon = _new_icon;
|
||||
emit syncIconChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef QT4
|
||||
#undef addSeparator
|
||||
#endif
|
||||
|
||||
|
||||
#include "tempo_sync_knob.moc"
|
||||
|
||||
Reference in New Issue
Block a user