Improved metronome (on/off during song, pattern and bb playback)

There is a new tool button that can be used to turn the metronome on and
off. Per default the metronome is turned off. When enabled the metronome
will during on song playback, pattern playback and BB playback. During
export it is ignored.

A new icon was added as well.

The state is currently stored in the Mixer. It might make sense to put
the metronome configuration in its own class in the future. The state is
currently not stored in the file but this might be a good choice for now
until a better place is found for the metronome data.

Also removed some repeated calls to Engine::getSong() and
Engine::fxMixer().
This commit is contained in:
Michael Gregorius
2015-08-17 21:33:36 +02:00
parent 8fd5fe90d2
commit 5b2e77b444
6 changed files with 52 additions and 13 deletions

View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

View File

@@ -185,6 +185,8 @@ private:
QMenu * m_viewMenu;
ToolButton * m_metronomeToggle;
private slots:
void browseHelp();
void fillTemplatesMenu();
@@ -193,6 +195,7 @@ private slots:
void updateRecentlyOpenedProjectsMenu();
void updateViewMenu( void );
void updateConfig( QAction * _who );
void onToggleMetronome();
void autoSave();

View File

@@ -355,6 +355,9 @@ public:
void changeQuality( const struct qualitySettings & _qs );
inline bool isMetronomeActive() const { return m_metronomeActive; }
inline void setMetronomeActive(bool value = true) { m_metronomeActive = value; }
signals:
void qualitySettingsChanged();
@@ -457,6 +460,8 @@ private:
MixerProfiler m_profiler;
bool m_metronomeActive;
friend class Engine;
friend class MixerWorkerThread;

View File

@@ -73,7 +73,8 @@ Mixer::Mixer( bool renderOnly ) :
m_audioDev( NULL ),
m_oldAudioDev( NULL ),
m_globalMutex( QMutex::Recursive ),
m_profiler()
m_profiler(),
m_metronomeActive(false)
{
for( int i = 0; i < 2; ++i )
{
@@ -318,18 +319,25 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
static Song::PlayPos last_metro_pos = -1;
Song::PlayPos p = Engine::getSong()->getPlayPos(
Song::Mode_PlayPattern );
if( Engine::getSong()->playMode() == Song::Mode_PlayPattern &&
gui->pianoRoll()->isRecording() == true &&
Song *song = Engine::getSong();
Song::PlayModes currentPlayMode = song->playMode();
Song::PlayPos p = song->getPlayPos( currentPlayMode );
bool playModeSupportsMetronome = currentPlayMode == Song::Mode_PlayPattern ||
currentPlayMode == Song::Mode_PlaySong ||
currentPlayMode == Song::Mode_PlayBB;
if( playModeSupportsMetronome && m_metronomeActive && !song->isExporting() &&
p != last_metro_pos )
{
if ( p.getTicks() % (MidiTime::ticksPerTact() / 1 ) == 0 )
tick_t ticksPerTact = MidiTime::ticksPerTact();
if ( p.getTicks() % (ticksPerTact / 1 ) == 0 )
{
addPlayHandle( new SamplePlayHandle( "misc/metronome02.ogg" ) );
}
else if ( p.getTicks() % (MidiTime::ticksPerTact() /
Engine::getSong()->getTimeSigModel().getNumerator() ) == 0 )
else if ( p.getTicks() % (ticksPerTact /
song->getTimeSigModel().getNumerator() ) == 0 )
{
addPlayHandle( new SamplePlayHandle( "misc/metronome01.ogg" ) );
}
@@ -337,9 +345,11 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
}
lockInputFrames();
// swap buffer
m_inputBufferWrite = ( m_inputBufferWrite + 1 ) % 2;
m_inputBufferRead = ( m_inputBufferRead + 1 ) % 2;
// clear new write buffer
m_inputBufferFrames[ m_inputBufferWrite ] = 0;
unlockInputFrames();
@@ -383,10 +393,11 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
clearAudioBuffer( m_writeBuf, m_framesPerPeriod );
// prepare master mix (clear internal buffers etc.)
Engine::fxMixer()->prepareMasterMix();
FxMixer * fxMixer = Engine::fxMixer();
fxMixer->prepareMasterMix();
// create play-handles for new notes, samples etc.
Engine::getSong()->processNextBuffer();
song->processNextBuffer();
// add all play-handles that have to be added
m_playHandleMutex.lock();
@@ -432,7 +443,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
// STAGE 3: do master mix in FX mixer
Engine::fxMixer()->masterMix( m_writeBuf );
fxMixer->masterMix( m_writeBuf );
unlock();

View File

@@ -78,7 +78,8 @@ MainWindow::MainWindow() :
m_recentlyOpenedProjectsMenu( NULL ),
m_toolsMenu( NULL ),
m_autoSaveTimer( this ),
m_viewMenu( NULL )
m_viewMenu( NULL ),
m_metronomeToggle( 0 )
{
setAttribute( Qt::WA_DeleteOnClose );
@@ -430,6 +431,13 @@ void MainWindow::finalize()
this, SLOT( enterWhatsThisMode() ),
m_toolBar );
m_metronomeToggle = new ToolButton(
embed::getIconPixmap( "metronome" ),
tr( "Toggle metronome" ),
this, SLOT( onToggleMetronome() ),
m_toolBar );
m_metronomeToggle->setCheckable(true);
m_metronomeToggle->setChecked(Engine::mixer()->isMetronomeActive());
m_toolBarLayout->setColumnMinimumWidth( 0, 5 );
m_toolBarLayout->addWidget( project_new, 0, 1 );
@@ -439,6 +447,7 @@ void MainWindow::finalize()
m_toolBarLayout->addWidget( project_save, 0, 5 );
m_toolBarLayout->addWidget( project_export, 0, 6 );
m_toolBarLayout->addWidget( whatsthis, 0, 7 );
m_toolBarLayout->addWidget( m_metronomeToggle, 0, 8 );
// window-toolbar
@@ -1209,6 +1218,17 @@ void MainWindow::updateConfig( QAction * _who )
}
void MainWindow::onToggleMetronome()
{
Mixer * mixer = Engine::mixer();
mixer->setMetronomeActive( m_metronomeToggle->isChecked() );
}
void MainWindow::toggleControllerRack()
{
toggleWindow( gui->getControllerRackView() );

View File

@@ -111,7 +111,7 @@ SongEditor::SongEditor( Song * _song ) :
// add some essential widgets to global tool-bar
QWidget * tb = gui->mainWindow()->toolBar();
gui->mainWindow()->addSpacingToToolBar( 10 );
gui->mainWindow()->addSpacingToToolBar( 40 );
m_tempoSpinBox = new LcdSpinBox( 3, tb, tr( "Tempo" ) );
m_tempoSpinBox->setModel( &m_song->m_tempoModel );