fundamental changes in plugin-architecture, added plugin-browser, bug-fixes - see ChangeLog for further details

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@18 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2005-10-20 13:02:26 +00:00
parent 58fe360793
commit f55c124be6
96 changed files with 5262 additions and 234 deletions

View File

@@ -175,13 +175,13 @@ int audioALSA::handleError( int _err )
void audioALSA::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_output )
float _master_gain )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
bufferAllocator::autoCleaner<> ac( outbuf );
convertToS16( _ab, _frames, _master_output, outbuf,
convertToS16( _ab, _frames, _master_gain, outbuf,
m_littleEndian != isLittleEndian() );
Uint32 frame = 0;

View File

@@ -70,7 +70,7 @@ audioDevice::~audioDevice()
void audioDevice::writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
Uint32 _src_sample_rate, float _master_output )
Uint32 _src_sample_rate, float _master_gain )
{
// make sure, no other thread is accessing device
lock();
@@ -82,12 +82,12 @@ void audioDevice::writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
_frames * channels() );
resample( _ab, _frames, temp, _src_sample_rate, m_sampleRate );
writeBufferToDev( temp, _frames * m_sampleRate /
_src_sample_rate, _master_output );
_src_sample_rate, _master_gain );
bufferAllocator::free( temp );
}
else
{
writeBufferToDev( _ab, _frames, _master_output );
writeBufferToDev( _ab, _frames, _master_gain );
}
// release lock
unlock();
@@ -240,7 +240,7 @@ LP_FILTER_COEFFS[tap] * lp_hist[( oldest + tap ) % LP_FILTER_TAPS][chnl];
int FASTCALL audioDevice::convertToS16( surroundSampleFrame * _ab,
Uint32 _frames, float _master_output,
Uint32 _frames, float _master_gain,
outputSampleType * _output_buffer,
bool _convert_endian )
{
@@ -251,7 +251,7 @@ int FASTCALL audioDevice::convertToS16( surroundSampleFrame * _ab,
( _output_buffer + frame * channels() )[chnl] =
static_cast<outputSampleType>(
mixer::clip( _ab[frame][chnl] *
_master_output ) *
_master_gain ) *
OUTPUT_SAMPLE_MULTIPLIER );
}
}

View File

@@ -186,7 +186,7 @@ bool audioFileOgg::startEncoding( void )
void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_output )
float _master_gain )
{
int eos = 0;
@@ -197,7 +197,7 @@ void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
{
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
{
buffer[chnl][frame] = _ab[frame][chnl] * _master_output;
buffer[chnl][frame] = _ab[frame][chnl] * _master_gain;
}
}

View File

@@ -88,11 +88,11 @@ bool audioFileWave::startEncoding( void )
void FASTCALL audioFileWave::writeBufferToDev( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_output )
float _master_gain )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
int bytes = convertToS16( _ab, _frames, _master_output, outbuf,
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
!isLittleEndian() );
writeData( outbuf, bytes );

View File

@@ -214,7 +214,7 @@ audioJACK::~audioJACK()
void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_output )
float _master_gain )
{
m_bufMutex.lock();
@@ -228,7 +228,7 @@ void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
_frames );
for( Uint32 frame = 0; frame < _frames; ++frame )
{
buf[frame] = _ab[frame][chnl] * _master_output;
buf[frame] = _ab[frame][chnl] * _master_gain;
}
bufset b = { buf, _frames } ;
bufs.push_back( b );
@@ -246,7 +246,10 @@ void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
#ifdef HAVE_UNISTD_H
#ifdef HAVE_USLEEP
// just wait and give cpu-time to other processes
usleep( 200 );
// tobydox 20051019: causes LMMS to hang up when locking
// several other mutexes, so skip it
//usleep( 200 );
#endif
#endif
}
@@ -264,6 +267,8 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
#endif
jack_transport_state_t ts = jack_transport_query( _this->m_client,
NULL );
_this->m_bufMutex.lock();
if( ts != JackTransportRolling )
{
// always decrease frame-sync-var as we would do it if running
@@ -276,6 +281,7 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
{
_this->m_frameSync = 0;
}
_this->m_bufMutex.unlock();
return( 0 );
}
@@ -289,7 +295,6 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
_this->m_outputPorts[ch], _nframes );
}
_this->m_bufMutex.lock();
jack_nframes_t done = 0;
while( done < _nframes )

View File

@@ -278,11 +278,11 @@ QString audioOSS::probeDevice( void )
void audioOSS::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_output )
float _master_gain )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
int bytes = convertToS16( _ab, _frames, _master_output, outbuf,
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
m_convertEndian );
write( m_audioFD, outbuf, bytes );

View File

@@ -125,10 +125,10 @@ audioSDL::~audioSDL()
void audioSDL::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_output )
float _master_gain )
{
m_bufMutex.lock();
convertToS16( _ab, _frames, _master_output, m_buffer,
convertToS16( _ab, _frames, _master_gain, m_buffer,
m_convertEndian );
m_bufMutex.unlock();
// before returning make sure, callback was called, so we're synced

View File

@@ -294,14 +294,6 @@ void bbEditor::keyPressEvent( QKeyEvent * _ke )
void bbEditor::wheelEvent( QWheelEvent * _we )
{
lmmsMainWin::inst()->workspace()->wheelEvent( _we );
}
void bbEditor::resizeEvent( QResizeEvent * _re )
{
updateBackground();

View File

@@ -163,10 +163,19 @@ configManager::configManager( void ) :
m_lmmsDataDir( qApp->applicationDirPath().section( '/', 0, -2 ) +
"/share/lmms/" ),
#else
// hardcode since qt 3.0 doesn't know something like
// applicationDirPath and implmeneting own function would be senseless
// since real support for qt 3.0 is senseless too ;-)
// hardcode since qt < 3.2 doesn't know something like
// applicationDirPath and implementing own function would be senseless
// since real support for qt < 3.2 is senseless too ;-)
m_lmmsDataDir( "/usr/share/lmms" ),
#endif
#if QT_VERSION >= 0x030200
m_lmmsPluginDir( qApp->applicationDirPath().section( '/', 0, -2 ) +
"/lib/lmms/" ),
#else
// hardcode since qt < 3.2 doesn't know something like
// applicationDirPath and implementing own function would be senseless
// since real support for qt < 3.2 is senseless too ;-)
m_lmmsPluginDir( "/usr/lib/lmms" ),
#endif
m_currentPage( 0 )
{

View File

@@ -153,10 +153,7 @@ 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(

93
src/core/instrument.cpp Normal file
View File

@@ -0,0 +1,93 @@
/*
* instrument.cpp - base-class for all instrument-plugins (synths, samplers etc)
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "instrument.h"
#include "channel_track.h"
#include "dummy_instrument.h"
instrument::instrument( channelTrack * _channel_track, const QString & _name ) :
QWidget( _channel_track->pluginParent() ),
plugin( _name, INSTRUMENT ),
m_channelTrack( _channel_track ),
m_valid( TRUE )
{
setFixedSize( 250, 250 );
}
instrument::~instrument()
{
}
void instrument::play( void )
{
}
void instrument::playNote( notePlayHandle * )
{
}
void instrument::deleteNotePluginData( notePlayHandle * )
{
}
Uint32 instrument::beatLen( notePlayHandle * ) const
{
return( 0 );
}
instrument * instrument::instantiate( const QString & _plugin_name,
channelTrack * _channel_track )
{
plugin * p = plugin::instantiate( _plugin_name, _channel_track );
// check whether instantiated plugin is an instrument
if( dynamic_cast<instrument *>( p ) != NULL )
{
// everything ok, so return pointer
return( dynamic_cast<instrument *>( p ) );
}
// not quite... so delete plugin and return dummy instrument
delete p;
return( new dummyInstrument( _channel_track ) );
}

View File

@@ -163,6 +163,7 @@ int main( int argc, char * * argv )
e->show();
e->exportBtnClicked();
}
return( app.exec() );
}

View File

@@ -211,27 +211,6 @@ void mixer::run( void )
// while we're acting...
m_safetySyncMutex.lock();
/* following code is faster but unstable since using iterators
while deleting from vector is dangerous and often leads to
undefined results...
playHandleVector::iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
{
if( ( *it )->done() )
{
// delete all play-handles which have
// played completely now
delete *it;
m_playHandles.erase( it );
}
else
{
// play all uncompletely-played play-handles...
( *it )->play();
++it;
}
}*/
csize idx = 0;
while( idx < m_playHandles.size() )
{

175
src/core/plugin.cpp Normal file
View File

@@ -0,0 +1,175 @@
/*
* plugin.cpp - implemenation of plugin-class including plugin-loader
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#include "qt3support.h"
#ifdef QT4
#include <QMessageBox>
#include <QDir>
#else
#include <qmessagebox.h>
#include <qdir.h>
#endif
#include "plugin.h"
#include "mixer.h"
#include "config_mgr.h"
#include "dummy_plugin.h"
plugin::plugin( const QString & _public_name, pluginTypes _type ) :
settings(),
m_publicName( _public_name ),
m_type( _type )
{
}
plugin::~plugin()
{
}
void plugin::setParameter( const QString &, const QString & )
{
}
QString plugin::getParameter( const QString & )
{
return( "" );
}
plugin * plugin::instantiate( const QString & _plugin_name, void * _data )
{
#ifdef HAVE_DLFCN_H
void * handle = dlopen( QString( "lib" + _plugin_name + ".so" ).
#ifdef QT4
toAscii().constData()
#else
ascii()
#endif
, RTLD_LAZY );
if( handle == NULL )
{
QMessageBox::information( NULL,
mixer::tr( "Plugin not found" ),
mixer::tr( "The %1-plugin wasn't found!"
).arg( _plugin_name ),
QMessageBox::Ok |
QMessageBox::Default );
return( new dummyPlugin() );
}
dlerror();
instantiationHook inst_hook = ( instantiationHook )( dlsym( handle,
"lmms_plugin_main" ) );
char * error = dlerror();
if( error != NULL )
{
printf( "%s\n", error );
QMessageBox::information( NULL,
mixer::tr( "Error while loading plugin" ),
mixer::tr( "Failed loading plugin \"%1\"!"
).arg( _plugin_name ),
QMessageBox::Ok |
QMessageBox::Default );
return( new dummyPlugin() );
}
plugin * inst = inst_hook( _data );
//dlclose( handle );
return( inst );
#endif
return( new dummyPlugin() );
}
void plugin::getDescriptorsOfAvailPlugins( vvector<descriptor> & _plugin_descs )
{
QDir directory( configManager::inst()->pluginDir() );
const QFileInfoList * list = directory.entryInfoList( "*.so" );
if( list == NULL )
{
return;
}
for( QFileInfoList::iterator file = list->begin();
file != list->end(); ++file )
{
void * handle = dlopen( ( *file )->absFilePath().latin1(),
RTLD_LAZY );
char * msg = dlerror();
if( msg != NULL || handle == NULL )
{
printf( "plugin-loader: %s\n", msg );
continue;
}
void * foo = dlsym( handle, "lmms_plugin_main" );
msg = dlerror();
if( msg != NULL || foo == NULL )
{
printf( "plugin-loader: %s\n", msg );
continue;
}
QString desc_name = ( *file )->fileName().mid( 3 ).section(
'.', 0, 0 ) + "_plugin_descriptor";
descriptor * plugin_desc =
(descriptor *) dlsym( handle, desc_name.ascii() );
msg = dlerror();
if( msg != NULL || plugin_desc == NULL )
{
printf( "plugin-loader: %s\n", msg );
continue;
}
_plugin_descs.push_back( *plugin_desc );
//dlclose( handle );
}
}

248
src/core/plugin_browser.cpp Normal file
View File

@@ -0,0 +1,248 @@
/*
* plugin_browser.cpp - implementation of the plugin-browser
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "qt3support.h"
#ifdef QT4
#include <QLabel>
#include <QPainter>
/*#include <QScrollArea>*/
#include <QCursor>
#else
#include <qlabel.h>
#include <qpainter.h>
/*#include <qscrollview.h>*/
#include <qcursor.h>
#endif
#include "plugin_browser.h"
#include "embed.h"
#include "debug.h"
#include "gui_templates.h"
#include "string_pair_drag.h"
pluginBrowser::pluginBrowser( QWidget * _parent ) :
sideBarWidget( tr( "Instrument plugins" ),
embed::getIconPixmap( "plugins" ), _parent )
{
setWindowTitle( tr( "Plugin browser" ) );
m_view = new QWidget( contentParent() );
//m_view->setFrameShape( QFrame::NoFrame );
addContentWidget( m_view );
QVBoxLayout * view_layout = new QVBoxLayout( m_view, 5, 10 );
QLabel * hint = new QLabel( tr( "You can drag an instrument-plugin "
"into either the Song-Editor, the "
"Beat+Bassline Editor or just into a "
"channel-window or on the "
"corresponding channel-button." ),
m_view );
hint->setFont( pointSize<8>( hint->font() ) );
hint->setAlignment( hint->alignment() | WordBreak );
view_layout->addWidget( hint );
plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors );
for( vvector<plugin::descriptor>::iterator it =
m_pluginDescriptors.begin();
it != m_pluginDescriptors.end(); ++it )
{
pluginDescWidget * p = new pluginDescWidget( *it, m_view );
p->show();
view_layout->addWidget( p );
}
view_layout->addStretch();
show();
}
pluginBrowser::~pluginBrowser()
{
}
pluginDescWidget::pluginDescWidget( const plugin::descriptor & _pd,
QWidget * _parent ) :
QWidget( _parent ),
m_pluginDescriptor( _pd ),
m_logo(),
m_mouseOver( FALSE )
{
m_logo.loadFromData( _pd.logo.data, _pd.logo.size );
setFixedHeight( 60 );
setMouseTracking( TRUE );
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
setCursor( PointingHandCursor );
}
pluginDescWidget::~pluginDescWidget()
{
}
void pluginDescWidget::paintEvent( QPaintEvent * )
{
QColor fill_color( 192, 192, 192 );
if( m_mouseOver )
{
fill_color = QColor( 224, 224, 224 );
}
#ifdef QT4
QPainter p( this );
p.fillRect( rect(), fill_color );
#else
// create pixmap for whole widget
QPixmap pm( rect().size() );
pm.fill( fill_color );
// and a painter for it
QPainter p( &pm );
#endif
p.setPen( QColor( 64, 64, 64 ) );
p.drawRect( rect() );
p.drawPixmap( 4, 4, m_logo );
QFont f = pointSize<8>( p.font() );
f.setBold( TRUE );
p.setFont( f );
p.drawText( 58, 14, m_pluginDescriptor.public_name );
f.setBold( FALSE );
p.setFont( pointSize<7>( f ) );
QStringList words = QStringList::split( ' ',
plugin::tr( m_pluginDescriptor.description ) );
for( QStringList::iterator it = words.begin(); it != words.end(); ++it )
{
if( ( *it ).contains( '-' ) )
{
QStringList splitted_word = QStringList::split( '-',
*it );
QStringList::iterator orig_it = it;
for( QStringList::iterator it2 = splitted_word.begin();
it2 != splitted_word.end(); ++it2 )
{
if( it2 == splitted_word.fromLast() )
{
words.insert( it, *it2 );
}
else
{
words.insert( it, *it2 + "-" );
++it;
}
}
words.erase( orig_it );
--it;
}
}
int y = 26;
int avail_width = width() - 58 - 5;
QString s;
for( QStringList::iterator it = words.begin(); it != words.end(); ++it )
{
if( p.fontMetrics().width( s + *it + " " ) >= avail_width )
{
p.drawText( 58, y, s );
y += 10;
s = "";
}
s += *it;
if( ( *it ).right( 1 ) != "-" )
{
s += " ";
}
}
p.drawText( 58, y, s );
#ifndef QT4
// blit drawn pixmap to actual widget
bitBlt( this, rect().topLeft(), &pm );
#endif
}
void pluginDescWidget::mousePressEvent( QMouseEvent * _me )
{
if( _me->button() == Qt::LeftButton )
{
new stringPairDrag( "plugin", m_pluginDescriptor.name, m_logo,
this );
m_mouseOver = FALSE;
update();
}
}
void pluginDescWidget::mouseMoveEvent( QMouseEvent * _me )
{
bool new_mouse_over = rect().contains( _me->pos() );
if( new_mouse_over != m_mouseOver )
{
m_mouseOver = new_mouse_over;
update();
}
}
void pluginDescWidget::mouseReleaseEvent( QMouseEvent * _me )
{
mouseMoveEvent( _me );
}
#include "plugin_browser.moc"

View File

@@ -115,7 +115,7 @@ presetPreviewPlayHandle::presetPreviewPlayHandle(
multimediaProject mmp( _preset_file );
if( s_globalChannelTrack == NULL )
{
track * t = track::createTrack( track::CHANNEL_TRACK,
track * t = track::create( track::CHANNEL_TRACK,
blindTrackContainer::inst() );
s_globalChannelTrack = dynamic_cast<channelTrack *>( t );
#ifdef LMMS_DEBUG

View File

@@ -351,16 +351,6 @@ songEditor::songEditor() :
/* edit_tb->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
edit_tb->setErasePixmap( embed::getIconPixmap( "toolbar_bg" ) );*/
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "add_channel_track" ), "",
this, SLOT( addChannelTrack() ) );
a->setToolTip( tr( "Add channel-track" ) );
#else
m_addChannelTrackButton = new QToolButton( embed::getIconPixmap(
"add_channel_track" ), "", "",
this, SLOT( addChannelTrack() ),
edit_tb );
#endif
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "add_bb_track" ), "",
this, SLOT( addBBTrack() ) );
@@ -414,7 +404,6 @@ songEditor::songEditor() :
toolTip::add( m_playButton, tr( "Play/pause song (Space)" ) );
toolTip::add( m_stopButton, tr( "Stop playing song (Space)" ) );
toolTip::add( m_addChannelTrackButton, tr( "Add channel-track" ) );
toolTip::add( m_addBBTrackButton, tr( "Add beat/bassline" ) );
toolTip::add( m_addSampleTrackButton, tr( "Add sample-track" ) );
toolTip::add( m_insertTactButton, tr( "Insert tact at current tact "
@@ -609,7 +598,6 @@ void songEditor::scrolled( int _new_pos )
void songEditor::wheelEvent( QWheelEvent * _we )
{
_we->accept();
if( m_controlPressed )
{
if( _we->delta() > 0 )
@@ -636,6 +624,12 @@ void songEditor::wheelEvent( QWheelEvent * _we )
m_leftRightScroll->setValue( m_leftRightScroll->value() -
_we->delta() / 30 );
}
else
{
_we->ignore();
return;
}
_we->accept();
}
@@ -1290,24 +1284,9 @@ void songEditor::removeTact( void )
void songEditor::addChannelTrack( void )
{
channelTrack * t = dynamic_cast< channelTrack * >(
track::createTrack( track::CHANNEL_TRACK, this ) );
#ifdef LMMS_DEBUG
assert( t != NULL );
#endif
t->loadPlugin( "tripleoscillator" );
t->toggledChannelButton( TRUE );
t->show();
}
void songEditor::addBBTrack( void )
{
track * t = track::createTrack( track::BB_TRACK, this );
track * t = track::create( track::BB_TRACK, this );
if( dynamic_cast<bbTrack *>( t ) != NULL )
{
dynamic_cast<bbTrack *>( t )->clickedTrackLabel();
@@ -1319,7 +1298,7 @@ void songEditor::addBBTrack( void )
void songEditor::addSampleTrack( void )
{
(void) track::createTrack( track::SAMPLE_TRACK, this );
(void) track::create( track::SAMPLE_TRACK, this );
}
@@ -1435,14 +1414,14 @@ void songEditor::createNewProject( void )
clearProject();
track * t;
t = track::createTrack( track::CHANNEL_TRACK, this );
dynamic_cast< channelTrack * >( t )->loadPlugin(
t = track::create( track::CHANNEL_TRACK, this );
dynamic_cast< channelTrack * >( t )->loadInstrument(
"tripleoscillator" );
track::createTrack( track::SAMPLE_TRACK, this );
t = track::createTrack( track::CHANNEL_TRACK, bbEditor::inst() );
dynamic_cast< channelTrack * >( t )->loadPlugin(
track::create( track::SAMPLE_TRACK, this );
t = track::create( track::CHANNEL_TRACK, bbEditor::inst() );
dynamic_cast< channelTrack * >( t )->loadInstrument(
"tripleoscillator" );
track::createTrack( track::BB_TRACK, this );
track::create( track::BB_TRACK, this );
setBPM( DEFAULT_BPM );
m_masterVolumeSlider->setValue( 100 );

View File

@@ -607,10 +607,10 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) :
"", &m_trackOperationsWidget );
deltr_btn->setGeometry( 1, 1+TRACK_OP_BTN_HEIGHT, TRACK_OP_BTN_WIDTH,
TRACK_OP_BTN_HEIGHT );
connect( deltr_btn, SIGNAL( clicked() ), this, SLOT( deleteTrack() ) );
connect( deltr_btn, SIGNAL( clicked() ), this, SLOT( removeTrack() ) );
connect( deltr_btn, SIGNAL( clicked() ), deltr_btn,
SLOT( clearFocus() ) );
toolTip::add( deltr_btn, tr( "Delete this track" ) );
toolTip::add( deltr_btn, tr( "Remove this track" ) );
QPushButton * muptr_btn = new QPushButton( embed::getIconPixmap(
"arp_up_on", 12, 12 ),
@@ -718,7 +718,7 @@ void trackWidget::cloneTrack( void )
void trackWidget::deleteTrack( void )
void trackWidget::removeTrack( void )
{
m_track->getTrackContainer()->removeTrack( m_track );
}
@@ -873,7 +873,7 @@ track::~track()
track * FASTCALL track::createTrack( trackTypes _tt, trackContainer * _tc )
track * FASTCALL track::create( trackTypes _tt, trackContainer * _tc )
{
switch( _tt )
{
@@ -891,10 +891,10 @@ track * FASTCALL track::createTrack( trackTypes _tt, trackContainer * _tc )
track * FASTCALL track::createTrack( const QDomElement & _this,
track * FASTCALL track::create( const QDomElement & _this,
trackContainer * _tc )
{
track * t = createTrack( static_cast<trackTypes>( _this.attribute(
track * t = create( static_cast<trackTypes>( _this.attribute(
"type" ).toInt() ), _tc );
#ifdef LMMS_DEBUG
assert( t != NULL );
@@ -906,13 +906,13 @@ track * FASTCALL track::createTrack( const QDomElement & _this,
track * FASTCALL track::cloneTrack( track * _track )
track * FASTCALL track::clone( track * _track )
{
QDomDocument doc;
QDomElement parent = doc.createElement( "clone" );
_track->saveSettings( doc, parent );
QDomElement e = parent.firstChild().toElement();
return( createTrack( e, _track->getTrackContainer() ) );
return( create( e, _track->getTrackContainer() ) );
}

View File

@@ -51,7 +51,9 @@
#include "lmms_main_win.h"
#include "mixer.h"
#include "song_editor.h"
#include "string_pair_drag.h"
#include "channel_track.h"
#include "mmp.h"
@@ -69,15 +71,9 @@ trackContainer::trackContainer() :
lmmsMainWin::inst()->workspace()->addWindow( this );
#endif
m_scrollArea = new QScrollArea( this );
m_scrollArea->setFrameStyle( QFrame::NoFrame );
m_scrollArea->setHorizontalScrollBarPolicy(
#ifdef QT4
Qt::ScrollBarAlwaysOff
#else
QScrollArea::AlwaysOff
#endif
);
m_scrollArea = new scrollArea( this );
setAcceptDrops( TRUE );
}
@@ -157,7 +153,7 @@ void trackContainer::loadSettings( const QDomElement & _this )
if( node.isElement() )
{
track::createTrack( node.toElement(), this );
track::create( node.toElement(), this );
}
node = node.nextSibling();
}
@@ -176,7 +172,7 @@ void trackContainer::loadSettings( const QDomElement & _this )
void trackContainer::cloneTrack( track * _track )
{
track::cloneTrack( _track );
track::clone( _track );
}
@@ -372,6 +368,41 @@ void trackContainer::resizeEvent( QResizeEvent * )
void trackContainer::dragEnterEvent( QDragEnterEvent * _dee )
{
stringPairDrag::processDragEnterEvent( _dee, "preset,plugin" );
}
void trackContainer::dropEvent( QDropEvent * _de )
{
QString type = stringPairDrag::decodeKey( _de );
QString value = stringPairDrag::decodeValue( _de );
if( type == "plugin" )
{
channelTrack * ct = dynamic_cast<channelTrack *>(
track::create( track::CHANNEL_TRACK,
this ) );
ct->loadInstrument( value );
ct->toggledChannelButton( TRUE );
}
else if( type == "preset" )
{
multimediaProject mmp( value );
channelTrack * ct = dynamic_cast<channelTrack *>(
track::create( track::CHANNEL_TRACK,
this ) );
ct->loadTrackSpecificSettings( mmp.content().firstChild().
toElement() );
ct->toggledChannelButton( TRUE );
}
}
void trackContainer::updateScrollArea( void )
{
m_scrollArea->resize( tMax( m_scrollArea->parentWidget()->width() -
@@ -384,6 +415,45 @@ void trackContainer::updateScrollArea( void )
trackContainer::scrollArea::scrollArea( trackContainer * _parent ) :
QScrollArea( _parent )
{
setFrameStyle( QFrame::NoFrame );
setHorizontalScrollBarPolicy(
#ifdef QT4
Qt::ScrollBarAlwaysOff
#else
QScrollArea::AlwaysOff
#endif
);
}
trackContainer::scrollArea::~scrollArea()
{
}
void trackContainer::scrollArea::wheelEvent( QWheelEvent * _we )
{
// always pass wheel-event to parent-widget (song-editor
// bb-editor etc.) because they might want to use it for zooming
// or scrolling left/right if a modifier-key is pressed, otherwise
// they do not accept it and we pass it up to QScrollArea
dynamic_cast<trackContainer *>( parentWidget() )->wheelEvent( _we );
if( !_we->isAccepted() )
{
QScrollArea::wheelEvent( _we );
}
}
#include "track_container.moc"
#undef setValue

View File

@@ -188,7 +188,7 @@ void * bufferAllocator::allocBytes( Uint32 _bytes )
}
// nothing so far, so we'll alloc a new (aligned) buf
// got nothing so far, so we'll alloc a new (aligned) buf
bufDesc d = { FALSE, new char[_bytes + BUFFER_ALIGN], NULL, _bytes, 0 };
d.buf = (void *)( (size_t) d.origPtr + ( BUFFER_ALIGN -
( (size_t) d.origPtr &

View File

@@ -43,9 +43,15 @@
#include "config_mgr.h"
#ifndef PLUGIN_NAME
namespace embed
#else
namespace PLUGIN_NAME
#endif
{
#include "embedded_resources.h"
@@ -55,10 +61,10 @@ QPixmap getIconPixmap( const char * _name, int _w, int _h )
{
QString name = QString( _name ) + ".png";
#ifdef QT4
const embedDesc & e = findEmbeddedData(
const embed::descriptor & e = findEmbeddedData(
name.toAscii().constData() );
#else
const embedDesc & e = findEmbeddedData( name.ascii() );
const embed::descriptor & e = findEmbeddedData( name.ascii() );
#endif
// not found?
if( QString( e.name ) != name )
@@ -88,13 +94,12 @@ QPixmap getIconPixmap( const char * _name, int _w, int _h )
QString getText( const char * _name )
{
const embedDesc & e = findEmbeddedData( _name );
const embed::descriptor & e = findEmbeddedData( _name );
return( QString::fromLatin1( (const char *) e.data, e.size ) );
}
void loadTranslation( const QString & _tname )
{
QTranslator * t = new QTranslator( 0 );
@@ -103,9 +108,10 @@ void loadTranslation( const QString & _tname )
#if QT_VERSION >= 0x030100
#ifdef QT4
const embedDesc & e = findEmbeddedData( name.toAscii().constData() );
const embed::descriptor & e = findEmbeddedData(
name.toAscii().constData() );
#else
const embedDesc & e = findEmbeddedData( name.ascii() );
const embed::descriptor & e = findEmbeddedData( name.ascii() );
#endif
// not found?
if( QString( e.name ) != name )
@@ -126,3 +132,4 @@ void loadTranslation( const QString & _tname )
}

View File

@@ -23,26 +23,31 @@
*/
#include "ladspa_manager.h"
#ifdef LADSPA_SUPPORT
#ifdef QT4
#include <QDir>
#include <QFileInfo>
#include <QPair>
#else
#include <qdir.h>
#include <qfileinfo.h>
#include <qpair.h>
#endif
#include <ladspa.h>
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#include <math.h>
#include "ladspa_manager.h"
ladspaManager * ladspaManager::s_instanceOfMe = NULL;
@@ -55,19 +60,25 @@ ladspaManager::ladspaManager( void )
// TODO Need to move the search path definition to the config file to have
// more control over where it tries to find the plugins.
QStringList ladspaDirectories = QStringList::split( QString( ":" ),
QStringList ladspaDirectories = QStringList::split( ':',
QString( getenv( "LADSPA_PATH" ) ) );
// set default-directory if nothing is specified...
if( ladspaDirectories.isEmpty() )
{
ladspaDirectories.push_back( "/usr/lib/ladspa" );
ladspaDirectories.push_back( "/usr/local/lib/ladspa" );
}
for( QStringList::iterator it = ladspaDirectories.begin();
it != ladspaDirectories.end(); ++it )
{
QDir directory( ( *it ) );
const QFileInfoList * list = directory.entryInfoList();
// if directory doesn't exist or isn't readable, we get NULL which
// would crash LMMS...
if( list == NULL )
{
continue;
}
for( QFileInfoList::iterator file = list->begin();
file != list->end(); ++file )
{
@@ -842,3 +853,6 @@ void FASTCALL ladspaManager::cleanup( const ladspaKey & _plugin,
}
}
#endif

View File

@@ -0,0 +1,112 @@
/*
* string_pair_drag.cpp - class stringPairDrag which provides general support
* for drag'n'drop of string-pairs
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#include "string_pair_drag.h"
stringPairDrag::stringPairDrag( const QString & _key, const QString & _value,
const QPixmap & _icon, QWidget * _w ) :
#ifdef QT4
QDrag( _w )
#else
QStoredDrag( "lmms/stringpair", _w )
#endif
{
setPixmap( _icon );
QString txt = _key + ":" + _value;
#ifdef QT4
QMimeData * m = new QMimeData();
m->setData( "lmms/stringpair", txt.toAscii() );
setMimeData( m );
start( /*Qt::CopyAction*/ Qt::IgnoreAction );
#else
setEncodedData( txt.utf8() );
drag();
#endif
}
stringPairDrag::~stringPairDrag()
{
// TODO: do we have to delete anything???
}
void stringPairDrag::processDragEnterEvent( QDragEnterEvent * _dee,
const QString & _allowed_keys )
{
#ifdef QT4
if( !_dee->mimeData()->hasFormat( "lmms/stringpair" ) )
{
return;
}
QString txt = _dee->mimeData()->data();
#else
QString txt = _dee->encodedData( "lmms/stringpair" );
#endif
bool accepted = QStringList::split( ',', _allowed_keys ).contains(
txt.section( ':', 0, 0 ) );
#ifdef QT4
if( accepted )
{
_dee->acceptProposedAction();
}
#else
_dee->accept( accepted );
#endif
}
QString stringPairDrag::decodeKey( QDropEvent * _de )
{
#ifdef QT4
return( QString( _de->mimeData()->data() ).section( ':', 0, 0 ) );
#else
return( QString( _de->encodedData( "lmms/stringpair" ) ).section(
':', 0, 0 ) );
#endif
}
QString stringPairDrag::decodeValue( QDropEvent * _de )
{
#ifdef QT4
return( QString( _de->mimeData()->data() ).section( ':', 1, 1 ) );
#else
return( QString( _de->encodedData( "lmms/stringpair" ) ).section(
':', 1, 1 ) );
#endif
}

View File

@@ -29,6 +29,7 @@
#include <QPainter>
#include <QMouseEvent>
#else
#include <qpainter.h>
@@ -87,9 +88,9 @@ void pixmapButton::paintEvent( QPaintEvent * )
}
#ifdef QT4
if( isChecked() )
if( isChecked() || isDown() )
#else
if( isOn() )
if( isOn() || isDown() )
#endif
{
if( m_activePixmap != NULL )