Merge branch 'stable-1.1'
Conflicts: include/Plugin.h src/core/Plugin.cpp
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include "SongEditor.h"
|
||||
#include "Effect.h"
|
||||
#include "lmmsversion.h"
|
||||
#include "base64.h"
|
||||
|
||||
// bbTCO::defaultColor()
|
||||
#include "bb_track.h"
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include "config_mgr.h"
|
||||
#include "SamplePlayHandle.h"
|
||||
#include "PianoRoll.h"
|
||||
#include "MicroTimer.h"
|
||||
#include "atomic_int.h"
|
||||
|
||||
// platform-specific audio-interface-classes
|
||||
@@ -69,7 +68,6 @@ Mixer::Mixer() :
|
||||
m_inputBufferWrite( 1 ),
|
||||
m_readBuf( NULL ),
|
||||
m_writeBuf( NULL ),
|
||||
m_cpuLoad( 0 ),
|
||||
m_workers(),
|
||||
m_numWorkers( QThread::idealThreadCount()-1 ),
|
||||
m_queueReadyWaitCond(),
|
||||
@@ -77,7 +75,8 @@ Mixer::Mixer() :
|
||||
m_masterGain( 1.0f ),
|
||||
m_audioDev( NULL ),
|
||||
m_oldAudioDev( NULL ),
|
||||
m_globalMutex( QMutex::Recursive )
|
||||
m_globalMutex( QMutex::Recursive ),
|
||||
m_profiler()
|
||||
{
|
||||
for( int i = 0; i < 2; ++i )
|
||||
{
|
||||
@@ -277,7 +276,7 @@ sample_rate_t Mixer::processingSampleRate() const
|
||||
|
||||
bool Mixer::criticalXRuns() const
|
||||
{
|
||||
return m_cpuLoad >= 99 && engine::getSong()->isExporting() == false;
|
||||
return cpuLoad() >= 99 && engine::getSong()->isExporting() == false;
|
||||
}
|
||||
|
||||
|
||||
@@ -315,7 +314,8 @@ void Mixer::pushInputFrames( sampleFrame * _ab, const f_cnt_t _frames )
|
||||
|
||||
const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
{
|
||||
MicroTimer timer;
|
||||
m_profiler.startPeriod();
|
||||
|
||||
static song::playPos last_metro_pos = -1;
|
||||
|
||||
song::playPos p = engine::getSong()->getPlayPos(
|
||||
@@ -428,10 +428,7 @@ const surroundSampleFrame * Mixer::renderNextBuffer()
|
||||
Controller::triggerFrameCounter();
|
||||
AutomatableModel::incrementPeriodCounter();
|
||||
|
||||
const float new_cpu_load = timer.elapsed() / 10000.0f *
|
||||
processingSampleRate() / m_framesPerPeriod;
|
||||
m_cpuLoad = tLimit( (int) ( new_cpu_load * 0.1f + m_cpuLoad * 0.9f ), 0,
|
||||
100 );
|
||||
m_profiler.finishPeriod( processingSampleRate(), m_framesPerPeriod );
|
||||
|
||||
return m_readBuf;
|
||||
}
|
||||
|
||||
63
src/core/MixerProfiler.cpp
Normal file
63
src/core/MixerProfiler.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* MixerProfiler.cpp - class for profiling performance of Mixer
|
||||
*
|
||||
* Copyright (c) 2014 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "MixerProfiler.h"
|
||||
|
||||
|
||||
MixerProfiler::MixerProfiler() :
|
||||
m_periodTimer(),
|
||||
m_cpuLoad( 0 ),
|
||||
m_outputFile()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
MixerProfiler::~MixerProfiler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MixerProfiler::finishPeriod( sample_rate_t sampleRate, fpp_t framesPerPeriod )
|
||||
{
|
||||
int periodElapsed = m_periodTimer.elapsed();
|
||||
|
||||
const float newCpuLoad = periodElapsed / 10000.0f * sampleRate / framesPerPeriod;
|
||||
m_cpuLoad = qBound<int>( 0, ( newCpuLoad * 0.1f + m_cpuLoad * 0.9f ), 100 );
|
||||
|
||||
if( m_outputFile.isOpen() )
|
||||
{
|
||||
m_outputFile.write( QString( "%1\n" ).arg( periodElapsed ).toLatin1() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MixerProfiler::setOutputFile( const QString& outputFile )
|
||||
{
|
||||
m_outputFile.close();
|
||||
m_outputFile.setFileName( outputFile );
|
||||
m_outputFile.open( QFile::WriteOnly | QFile::Truncate );
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
#ifndef SINGLE_SOURCE_COMPILE
|
||||
|
||||
/*
|
||||
* Plugin.cpp - implementation of plugin-class including plugin-loader
|
||||
*
|
||||
* Copyright (c) 2005-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
* Copyright (c) 2005-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
@@ -24,9 +22,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QDir>
|
||||
#include <QLibrary>
|
||||
#include <QMessageBox>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
#include "Plugin.h"
|
||||
#include "embed.h"
|
||||
@@ -54,9 +53,9 @@ static Plugin::Descriptor dummy_plugin_descriptor =
|
||||
|
||||
|
||||
|
||||
Plugin::Plugin( const Descriptor * _descriptor, Model * _parent ) :
|
||||
Plugin::Plugin( const Descriptor * _descriptor, Model * parent ) :
|
||||
JournallingObject(),
|
||||
Model( _parent ),
|
||||
Model( parent ),
|
||||
m_descriptor( _descriptor )
|
||||
{
|
||||
if( m_descriptor == NULL )
|
||||
@@ -91,89 +90,80 @@ AutomatableModel * Plugin::childModel( const QString & )
|
||||
|
||||
|
||||
|
||||
Plugin * Plugin::instantiate( const QString & _plugin_name, Model * _parent,
|
||||
void * _data )
|
||||
Plugin * Plugin::instantiate( const QString & pluginName, Model * parent,
|
||||
void * data )
|
||||
{
|
||||
QLibrary plugin_lib( configManager::inst()->pluginDir() +
|
||||
_plugin_name );
|
||||
if( plugin_lib.load() == false )
|
||||
QLibrary pluginLibrary( configManager::inst()->pluginDir() + pluginName );
|
||||
if( pluginLibrary.load() == false )
|
||||
{
|
||||
if( engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
tr( "Plugin not found" ),
|
||||
tr( "The plugin \"%1\" wasn't found "
|
||||
"or could not be loaded!\n"
|
||||
"Reason: \"%2\"" ).arg( _plugin_name ).
|
||||
arg( plugin_lib.errorString() ),
|
||||
QMessageBox::Ok |
|
||||
QMessageBox::Default );
|
||||
tr( "The plugin \"%1\" wasn't found or could not be loaded!\nReason: \"%2\"" ).
|
||||
arg( pluginName ).arg( pluginLibrary.errorString() ),
|
||||
QMessageBox::Ok | QMessageBox::Default );
|
||||
}
|
||||
return new DummyPlugin();
|
||||
}
|
||||
instantiationHook inst_hook = ( instantiationHook ) plugin_lib.resolve(
|
||||
"lmms_plugin_main" );
|
||||
if( inst_hook == NULL )
|
||||
|
||||
InstantiationHook instantiationHook = ( InstantiationHook ) pluginLibrary.resolve( "lmms_plugin_main" );
|
||||
if( instantiationHook == NULL )
|
||||
{
|
||||
if( engine::hasGUI() )
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
tr( "Error while loading plugin" ),
|
||||
tr( "Failed to load plugin \"%1\"!"
|
||||
).arg( _plugin_name ),
|
||||
QMessageBox::Ok |
|
||||
QMessageBox::Default );
|
||||
tr( "Failed to load plugin \"%1\"!").arg( pluginName ),
|
||||
QMessageBox::Ok | QMessageBox::Default );
|
||||
}
|
||||
return new DummyPlugin();
|
||||
}
|
||||
Plugin * inst = inst_hook( _parent, _data );
|
||||
|
||||
Plugin * inst = instantiationHook( parent, data );
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Plugin::getDescriptorsOfAvailPlugins( DescriptorList & _plugin_descs )
|
||||
void Plugin::getDescriptorsOfAvailPlugins( DescriptorList& pluginDescriptors )
|
||||
{
|
||||
QDir directory( configManager::inst()->pluginDir() );
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
QFileInfoList list = directory.entryInfoList(
|
||||
QStringList( "*.dll" ) );
|
||||
QFileInfoList list = directory.entryInfoList( QStringList( "*.dll" ) );
|
||||
#else
|
||||
QFileInfoList list = directory.entryInfoList(
|
||||
QStringList( "lib*.so" ) );
|
||||
QFileInfoList list = directory.entryInfoList( QStringList( "lib*.so" ) );
|
||||
#endif
|
||||
foreach( const QFileInfo & f, list )
|
||||
foreach( const QFileInfo& f, list )
|
||||
{
|
||||
QLibrary( f.absoluteFilePath() ).load();
|
||||
}
|
||||
|
||||
foreach( const QFileInfo & f, list )
|
||||
foreach( const QFileInfo& f, list )
|
||||
{
|
||||
QLibrary plugin_lib( f.absoluteFilePath() );
|
||||
if( plugin_lib.load() == false ||
|
||||
plugin_lib.resolve( "lmms_plugin_main" ) == NULL )
|
||||
QLibrary pluginLibrary( f.absoluteFilePath() );
|
||||
if( pluginLibrary.load() == false ||
|
||||
pluginLibrary.resolve( "lmms_plugin_main" ) == NULL )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QString desc_name = f.fileName().section( '.', 0, 0 ) +
|
||||
"_plugin_descriptor";
|
||||
if( desc_name.left( 3 ) == "lib" )
|
||||
|
||||
QString descriptorName = f.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left( 3 ) == "lib" )
|
||||
{
|
||||
desc_name = desc_name.mid( 3 );
|
||||
descriptorName = descriptorName.mid( 3 );
|
||||
}
|
||||
Descriptor * plugin_desc =
|
||||
(Descriptor *) plugin_lib.resolve(
|
||||
desc_name.toUtf8().constData() );
|
||||
if( plugin_desc == NULL )
|
||||
|
||||
Descriptor* pluginDescriptor = (Descriptor *) pluginLibrary.resolve( descriptorName.toUtf8().constData() );
|
||||
if( pluginDescriptor == NULL )
|
||||
{
|
||||
printf( "LMMS plugin %s does not have a "
|
||||
"plugin descriptor named %s!\n",
|
||||
f.absoluteFilePath().toUtf8().constData(),
|
||||
desc_name.toUtf8().constData() );
|
||||
qWarning() << tr( "LMMS plugin %1 does not have a plugin descriptor named %2!" ).
|
||||
arg( f.absoluteFilePath() ).arg( descriptorName );
|
||||
continue;
|
||||
}
|
||||
_plugin_descs.push_back( *plugin_desc );
|
||||
|
||||
pluginDescriptors += *pluginDescriptor;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -181,9 +171,9 @@ void Plugin::getDescriptorsOfAvailPlugins( DescriptorList & _plugin_descs )
|
||||
|
||||
|
||||
|
||||
PluginView * Plugin::createView( QWidget * _parent )
|
||||
PluginView * Plugin::createView( QWidget * parent )
|
||||
{
|
||||
PluginView * pv = instantiateView( _parent );
|
||||
PluginView * pv = instantiateView( parent );
|
||||
if( pv != NULL )
|
||||
{
|
||||
pv->setModel( this );
|
||||
@@ -227,4 +217,3 @@ QDomElement Plugin::Descriptor::SubPluginFeatures::Key::saveXML(
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -95,7 +95,7 @@ int main( int argc, char * * argv )
|
||||
bool core_only = false;
|
||||
bool fullscreen = true;
|
||||
bool exit_after_import = false;
|
||||
QString file_to_load, file_to_save, file_to_import, render_out;
|
||||
QString file_to_load, file_to_save, file_to_import, render_out, profilerOutputFile;
|
||||
|
||||
for( int i = 1; i < argc; ++i )
|
||||
{
|
||||
@@ -341,6 +341,11 @@ int main( int argc, char * * argv )
|
||||
exit_after_import = true;
|
||||
}
|
||||
}
|
||||
else if( argc > i && ( QString( argv[i] ) == "--profile" || QString( argv[i] ) == "-p" ) )
|
||||
{
|
||||
profilerOutputFile = argv[i+1];
|
||||
++i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( argv[i][0] == '-' )
|
||||
@@ -496,6 +501,11 @@ int main( int argc, char * * argv )
|
||||
SLOT( updateConsoleProgress() ) );
|
||||
t->start( 200 );
|
||||
|
||||
if( profilerOutputFile.isEmpty() == false )
|
||||
{
|
||||
engine::mixer()->profiler().setOutputFile( profilerOutputFile );
|
||||
}
|
||||
|
||||
// start now!
|
||||
r->startProcessing();
|
||||
}
|
||||
|
||||
@@ -619,70 +619,53 @@ PianoRoll::PianoRoll() :
|
||||
tb_layout->addWidget( m_chordComboBox );
|
||||
tb_layout->addStretch();
|
||||
|
||||
m_zoomingComboBox->setWhatsThis( tr(
|
||||
"This controls the magnification over time. "
|
||||
"It can be useful choose a magnification for a specific task. "
|
||||
"For ordinary editing, the magnification should be fitted to your "
|
||||
"smallest used notes. "
|
||||
"Most will use the default magnification of 100%, "
|
||||
"when the shortest notes are 1/16. "
|
||||
"If you have used shorter notes, your editing will be easier, "
|
||||
"with a magnification of 200%, or more. "
|
||||
"You should use low magnification, if you need to move a block "
|
||||
"of notes many bars, or just to get an overview of the score."
|
||||
) );
|
||||
|
||||
m_quantizeComboBox->setWhatsThis( tr(
|
||||
"This 'Q' stands for quantification, and controls the minimum spacing "
|
||||
"between notes. "
|
||||
"In piano-roll this is very important, when you make syncopated patterns, "
|
||||
"and an absolute must, for swing-notes! "
|
||||
"Observe that the score segmentation also changes, depending on the selected Q. "
|
||||
"You should not use a Q-value that does not fit your chosen time-signature! "
|
||||
"The default value is 1/16, and that fits the default 4/4 timing. "
|
||||
"A Q of 1/16 will also work well in most editing."
|
||||
) );
|
||||
|
||||
m_noteLenComboBox->setWhatsThis( tr(
|
||||
"This lets you select the note you place in the score. "
|
||||
"In most circumstances the best choice is 'Last Note'."
|
||||
"The choice 'Last Note' means that LMMS will use the note you last clicked, "
|
||||
"when you place the next note. "
|
||||
"But you can choose any note-length from this drop-down, "
|
||||
"and your choice will be the note, that you can draw in the score."
|
||||
) );
|
||||
|
||||
m_scaleComboBox->setWhatsThis( tr(
|
||||
"This lets you select a music scale that LMMS then will annotate. "
|
||||
"The feature is directly connected to the context-menu "
|
||||
"on the virtual keyboard, to the left. "
|
||||
"First you chose which scale you will use. "
|
||||
"You do that in this very dropdown! "
|
||||
"Then you choose the key of your composition. "
|
||||
"Right mouse click on the selected key in the virtual keyboard, "
|
||||
"and then choose 'Mark current Scale' "
|
||||
"LMMS will annotate all notes that belongs to the chosen scale, "
|
||||
"and in the key you have selected! "
|
||||
"LMMS will not only annotate in the score you have open, "
|
||||
"but all scores in your project, will be correctly annotated. "
|
||||
"This will help you avoid using bum-notes, as you compose. "
|
||||
"You should know about principle scales in music. "
|
||||
"Search the net, if you do not! "
|
||||
) );
|
||||
|
||||
m_chordComboBox->setWhatsThis( tr(
|
||||
"This lets you select a standard music chord. "
|
||||
"All notes that are played simultaneous, are 'chords',"
|
||||
"but a large number of simultaneous key combinations, has own names, "
|
||||
"and its own place in music. "
|
||||
"They are standard chords, and it is these chords, "
|
||||
"you can find in this drop-down. "
|
||||
"After you have selected a chord, any click in the score, "
|
||||
"will place that chord, musically correctly, "
|
||||
"and with the Left mouse clicked note, as the root-note in the chord! "
|
||||
"To return to single note placement, you need to choose 'No chord' "
|
||||
"in this drop-down!"
|
||||
) );
|
||||
m_zoomingComboBox->setWhatsThis(
|
||||
tr(
|
||||
"This controls the magnification of an axis. "
|
||||
"It can be helpful to choose magnification for a specific "
|
||||
"task. For ordinary editing, the magnification should be "
|
||||
"fitted to your smallest notes. "
|
||||
) );
|
||||
|
||||
m_quantizeComboBox->setWhatsThis(
|
||||
tr(
|
||||
"The 'Q' stands for quantization, and controls the grid size "
|
||||
"notes and control points snap to. "
|
||||
"With smaller quantization values, you can draw shorter notes "
|
||||
"in Piano Roll, and more exact control points in the "
|
||||
"Automation Editor."
|
||||
|
||||
) );
|
||||
|
||||
m_noteLenComboBox->setWhatsThis(
|
||||
tr(
|
||||
"This lets you select the length of new notes. "
|
||||
"'Last Note' means that LMMS will use the note length of "
|
||||
"the note you last edited"
|
||||
) );
|
||||
|
||||
m_scaleComboBox->setWhatsThis(
|
||||
tr(
|
||||
"The feature is directly connected to the context-menu "
|
||||
"on the virtual keyboard, to the left in Piano Roll. "
|
||||
"After you have chosen the scale you want "
|
||||
"in this drop-down menu, "
|
||||
"you can right click on a desired key in the virtual keyboard, "
|
||||
"and then choose 'Mark current Scale'. "
|
||||
"LMMS will highlight all notes that belongs to the chosen scale, "
|
||||
"and in the key you have selected!"
|
||||
) );
|
||||
|
||||
|
||||
m_chordComboBox->setWhatsThis(
|
||||
tr(
|
||||
"Let you select a chord which LMMS then can draw or highlight."
|
||||
"You can find the most common chords in this drop-down menu. "
|
||||
"After you have selected a chord, click anywhere to place the chord, and right "
|
||||
"click on the virtual keyboard to open context menu and highlight the chord. "
|
||||
"To return to single note placement, you need to choose 'No chord' "
|
||||
"in this drop-down menu."
|
||||
) );
|
||||
|
||||
// setup our actual window
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
|
||||
Reference in New Issue
Block a user