From deeca75b1fbb6e4ebb7d2aac7a95acf4bde2ec9a Mon Sep 17 00:00:00 2001 From: Javier Serrano Polo Date: Sun, 25 Feb 2007 19:12:26 +0000 Subject: [PATCH] singerbot, automation editor and other improvements git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@462 0778d3d1-df1d-0410-868b-ea421aaaa00d --- ChangeLog | 43 ++++++ configure.in | 100 ++++++------- include/effect_select_dialog.h | 7 +- include/plugin.h | 5 +- plugins/ladspa_base/ladspa_control.cpp | 10 +- plugins/ladspa_effect/ladspa_effect.cpp | 5 +- .../ladspa_subplugin_features.cpp | 133 +++++++----------- .../ladspa_effect/ladspa_subplugin_features.h | 17 +-- plugins/live_tool/live_tool.cpp | 24 +++- plugins/singerbot/singerbot.cpp | 115 +++++++++------ plugins/singerbot/singerbot.h | 5 +- plugins/vst_effect/vst_subplugin_features.cpp | 34 +---- plugins/vst_effect/vst_subplugin_features.h | 15 +- src/core/automation_editor.cpp | 81 +++++------ src/core/effect_select_dialog.cpp | 56 +++++--- src/core/piano_roll.cpp | 6 +- src/tracks/instrument_track.cpp | 3 +- 17 files changed, 352 insertions(+), 307 deletions(-) diff --git a/ChangeLog b/ChangeLog index d0e3ee5cf..241febb32 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +2007-02-25 Javier Serrano Polo + + * plugins/singerbot/singerbot.cpp: + * plugins/singerbot/singerbot.h: + use libsamplerate + + * plugins/singerbot/singerbot.cpp: + - resample while playing, reduced start-up CPU usage + - joined scheme commands + + * configure.in: + - added libsamplerate dependency to singerbot + - don't add plugin libraries to global LIBS + + * src/core/automation_editor.cpp: + - fixed selection + - values moved at time 0 don't move horizontally + + * src/core/piano_roll.cpp: + little optimization when selecting all notes + + * src/tracks/instrument_track.cpp: + emit sentMidiTime always, pitch automation mustn't be disabled + + * plugins/ladspa_base/ladspa_control.cpp: + * plugins/ladspa_effect/ladspa_effect.cpp: + raise gain range up to 10 + + * include/effect_select_dialog.h: + * include/plugin.h: + * plugins/ladspa_effect/ladspa_subplugin_features.cpp: + * plugins/ladspa_effect/ladspa_subplugin_features.h: + * plugins/vst_effect/vst_subplugin_features.cpp: + * plugins/vst_effect/vst_subplugin_features.h: + * src/core/effect_select_dialog.cpp: + changed description layout + + * plugins/ladspa_effect/ladspa_subplugin_features.cpp: + simplified translations + + * plugins/live_tool/live_tool.cpp: + added what's-this-text + 2007-02-20 Alexey Kouznetsov * data/locale/ru.ts: diff --git a/configure.in b/configure.in index 1f6c00cd7..28a7fe876 100644 --- a/configure.in +++ b/configure.in @@ -2,8 +2,8 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.50) -AC_INIT(lmms, 0.2.1-svn20070216, lmms-devel/at/lists/dot/sf/dot/net) -AM_INIT_AUTOMAKE(lmms, 0.2.1-svn20070216) +AC_INIT(lmms, 0.2.1-svn20070225, lmms-devel/at/lists/dot/sf/dot/net) +AM_INIT_AUTOMAKE(lmms, 0.2.1-svn20070225) AM_CONFIG_HEADER(config.h) @@ -227,7 +227,7 @@ if test "x$with_vst" = "xyes" ; then if test "$build_linux" = "true" ; then AC_CHECK_PROG(WINEGCC, winegcc, /usr/bin/winegcc,,/usr/bin) - AC_CHECK_LIB([wine], [wine_init]) + AC_CHECK_LIB([wine], [wine_init], true) if test ! -z "$WINEGCC" ; then if test ! -z "$HAVE_VST_AEFFECTX_H" ; then WINE_OK_BUT_VST_INCOMPLETE="" @@ -281,29 +281,6 @@ AM_CONDITIONAL(STK_SUPPORT, test ! -z "$HAVE_STK_H") AC_LANG_POP(C++) -# check for Festival -AC_LANG_PUSH(C++) -AC_ARG_WITH(singerbot, - AS_HELP_STRING([--without-singerbot], - [disable support for SingerBot plugin]), , - [ with_singerbot=yes ]) -AH_TEMPLATE(SINGERBOT_SUPPORT, - [Define to 1 to enable SingerBot plugin support.]) -if test "x$with_singerbot" = "xyes" ; then - ORIG_CPPFLAGS=$CPPFLAGS - CPPFLAGS+=" -I/usr/include/festival -I/usr/include/speech_tools" - CPPFLAGS+=" -Wno-non-template-friend" - AC_CHECK_HEADER([festival.h], FESTIVAL_SUPPORT="true") - AC_CHECK_LIB([Festival], [main], , FESTIVAL_SUPPORT="") - CPPFLAGS=$ORIG_CPPFLAGS -fi -if test ! -z "$FESTIVAL_SUPPORT" ; then - AC_DEFINE(SINGERBOT_SUPPORT) -fi -AM_CONDITIONAL(SINGERBOT_SUPPORT, test ! -z "$FESTIVAL_SUPPORT") -AC_LANG_POP(C++) - - # check for vorbis-lib AC_ARG_WITH(vorbis, AS_HELP_STRING([--without-vorbis], @@ -362,6 +339,31 @@ fi AM_CONDITIONAL(HAVE_LIBSRC, test ! -z "$HAVE_SAMPLERATE_H") +# check for Festival +if test ! -z "$HAVE_SAMPLERATE_H" ; then + AC_LANG_PUSH(C++) + AC_ARG_WITH(singerbot, + AS_HELP_STRING([--without-singerbot], + [disable support for SingerBot plugin]), , + [ with_singerbot=yes ]) + AH_TEMPLATE(SINGERBOT_SUPPORT, + [Define to 1 to enable SingerBot plugin support.]) + if test "x$with_singerbot" = "xyes" ; then + ORIG_CPPFLAGS=$CPPFLAGS + CPPFLAGS+=" -I/usr/include/festival -I/usr/include/speech_tools" + CPPFLAGS+=" -Wno-non-template-friend" + AC_CHECK_HEADER([festival.h], FESTIVAL_SUPPORT="true") + AC_CHECK_LIB([Festival], [main], true, FESTIVAL_SUPPORT="") + CPPFLAGS=$ORIG_CPPFLAGS + fi + if test ! -z "$FESTIVAL_SUPPORT" ; then + AC_DEFINE(SINGERBOT_SUPPORT) + fi + AM_CONDITIONAL(SINGERBOT_SUPPORT, test ! -z "$FESTIVAL_SUPPORT" ) + AC_LANG_POP(C++) +fi + + # libsndfile-stuff AC_ARG_WITH(sndfile, AS_HELP_STRING([--without-libsf], @@ -781,27 +783,6 @@ else fi -if test -z "$FESTIVAL_SUPPORT" ; then - if test "x$with_singerbot" = "xyes" ; then - echo " ========================" - echo " === LMMS - WARNING =======================================================" - echo " ========================" - echo " =" - echo " = You don't seem to have Festival development files." - echo " = The SingerBot instrument plugin will be ignored." - echo " = Before enabling this plugin, bear in mind that it is still experimental." - echo " =" - echo " = To remove this warning, please pass" - echo " = " - echo " = --without-singerbot" - echo " =" - with_warnings="true" - fi -else - PLUGINS_TO_BUILD="$PLUGINS_TO_BUILD\n\t\* SingerBot instrument plugin" -fi - - if test -z "$HAVE_SAMPLERATE_H" ; then echo " ========================" echo " === LMMS - WARNING =======================================================" @@ -819,6 +800,31 @@ else fi +if test -z "$FESTIVAL_SUPPORT" ; then + if test "x$with_singerbot" = "xyes" ; then + echo " ========================" + echo " === LMMS - WARNING =======================================================" + echo " ========================" + echo " =" + if test -z "$HAVE_SAMPLERATE_H" ; then + echo " = You don't seem to have libsamplerate support." + else + echo " = You don't seem to have Festival development files." + fi + echo " = The SingerBot instrument plugin will be ignored." + echo " = Before enabling this plugin, bear in mind that it is still experimental." + echo " =" + echo " = To remove this warning, please pass" + echo " = " + echo " = --without-singerbot" + echo " =" + with_warnings="true" + fi +else + PLUGINS_TO_BUILD="$PLUGINS_TO_BUILD\n\t\* SingerBot instrument plugin" +fi + + if test "x$with_vst" = "xno" ; then echo " ========================" echo " === LMMS - INFORMATION ===================================================" diff --git a/include/effect_select_dialog.h b/include/effect_select_dialog.h index e2c33ee3e..effe4a68f 100644 --- a/include/effect_select_dialog.h +++ b/include/effect_select_dialog.h @@ -1,7 +1,7 @@ /* * effect_select_dialog.h - dialog to choose effect plugin * - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -88,6 +88,10 @@ signals: void doubleClicked( const effectKey & _key ); +protected: + virtual void resizeEvent( QResizeEvent * ); + + protected slots: void onHighlighted( int _plugin ); void onAddButtonReleased(); @@ -100,7 +104,6 @@ private: effectKey m_currentSelection; Q3ListBox * m_pluginList; - QWidget * m_descriptionWidgetParent; QWidget * m_descriptionWidget; } ; diff --git a/include/plugin.h b/include/plugin.h index 51e294f87..3ad0da656 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -1,7 +1,7 @@ /* * plugin.h - class plugin, the base-class and generic interface for all plugins * - * Copyright (c) 2005-2006 Tobias Doerffel + * Copyright (c) 2005-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -134,10 +134,9 @@ public: { } - virtual QWidget * createDescriptionWidget( + virtual void fillDescriptionWidget( QWidget *, engine *, const key & ) { - return( NULL ); } virtual void listSubPluginKeys( engine *, plugin::descriptor *, diff --git a/plugins/ladspa_base/ladspa_control.cpp b/plugins/ladspa_base/ladspa_control.cpp index 163818150..9c9a78731 100644 --- a/plugins/ladspa_base/ladspa_control.cpp +++ b/plugins/ladspa_base/ladspa_control.cpp @@ -1,7 +1,7 @@ /* * ladspa_control.cpp - widget for controlling a LADSPA port * - * Copyright (c) 2006 Danny McRae + * Copyright (c) 2006-2007 Danny McRae * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -130,9 +130,11 @@ ladspaControl::ladspaControl( QWidget * _parent, connect( m_knob, SIGNAL( valueChanged( float ) ), this, SLOT( knobChange( float ) ) ); m_knob->setLabel( m_port->name ); - m_knob->setRange( m_port->min, m_port->max, - ( m_port->max - - m_port->min ) / 400.0f ); + m_knob->setRange( m_port->min, m_port->max, + ( m_port->max - m_port->min ) + / ( m_port->name.toUpper() == "GAIN" + && m_port->max == 10.0f ? 4000.0f : + 400.0f ) ); m_knob->setInitValue( m_port->def ); m_knob->setHintText( tr( "Value:" ) + " ", "" ); #ifdef QT4 diff --git a/plugins/ladspa_effect/ladspa_effect.cpp b/plugins/ladspa_effect/ladspa_effect.cpp index 96e9485f8..4eeefb650 100644 --- a/plugins/ladspa_effect/ladspa_effect.cpp +++ b/plugins/ladspa_effect/ladspa_effect.cpp @@ -1,7 +1,7 @@ /* * ladspa_effect.cpp - class for processing LADSPA effects * - * Copyright (c) 2006 Danny McRae + * Copyright (c) 2006-2007 Danny McRae * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -191,7 +191,8 @@ ladspaEffect::ladspaEffect( effect::constructionData * _cdata ) : p->max = m_ladspa->getUpperBound( m_key, port ); if( p->max == NOHINT ) { - p->max = 1.0f; + p->max = p->name.toUpper() == "GAIN" ? 10.0f : + 1.0f; } if( m_ladspa->areHintsSampleRateDependent( diff --git a/plugins/ladspa_effect/ladspa_subplugin_features.cpp b/plugins/ladspa_effect/ladspa_subplugin_features.cpp index fa181ab80..d26fc6f2a 100644 --- a/plugins/ladspa_effect/ladspa_subplugin_features.cpp +++ b/plugins/ladspa_effect/ladspa_subplugin_features.cpp @@ -3,8 +3,8 @@ * plugin::descriptor::subPluginFeatures for * hosting LADSPA-plugins * - * Copyright (c) 2006 Danny McRae - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2007 Danny McRae + * Copyright (c) 2006-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -31,13 +31,11 @@ #include #include -#include #else -#include +#include #include -#include #include #endif @@ -49,77 +47,6 @@ #include "audio_device.h" -ladspaSubPluginDescriptionWidget::ladspaSubPluginDescriptionWidget( - QWidget * _parent, engine * _engine, - const ladspa_key_t & _key ) : - QWidget( _parent -#ifdef QT3 - , "ladspaSubPluginDescriptionWidget" -#endif - ) -{ - ladspa2LMMS * lm = _engine->getLADSPAManager(); - QVBoxLayout * l = new QVBoxLayout( this ); - -#ifndef QT3 - QGroupBox * groupbox = new QGroupBox( tr( "Description" ), this ); -#else - QGroupBox * groupbox = new QGroupBox( 9, Qt::Vertical, - tr( "Description" ), this ); -#endif - - QLabel * label = new QLabel( groupbox ); - label->setText( tr( "Name: " ) + lm->getName( _key ) ); - - QLabel * maker = new QLabel( groupbox ); - maker->setText( tr( "Maker: " ) + lm->getMaker( _key ) ); - - QLabel * copyright = new QLabel( groupbox ); - copyright->setText( tr( "Copyright: " ) + lm->getCopyright( _key ) ); - - QLabel * requiresRealTime = new QLabel( groupbox ); - if( lm->hasRealTimeDependency( _key ) ) - { - requiresRealTime->setText( tr( "Requires Real Time: Yes" ) ); - } - else - { - requiresRealTime->setText( tr( "Requires Real Time: No" ) ); - } - - QLabel * realTimeCapable = new QLabel( groupbox ); - if( lm->isRealTimeCapable( _key ) ) - { - realTimeCapable->setText( tr( "Real Time Capable: Yes" ) ); - } - else - { - realTimeCapable->setText( tr( "Real Time Capable: No" ) ); - } - - QLabel * inplaceBroken = new QLabel( groupbox ); - if( lm->isInplaceBroken( _key ) ) - { - inplaceBroken->setText( tr( "In Place Broken: Yes" ) ); - } - else - { - inplaceBroken->setText( tr( "In Place Broken: No" ) ); - } - - QLabel * channelsIn = new QLabel( groupbox ); - channelsIn->setText( tr( "Channels In: " ) + - QString::number( lm->getDescription( _key )->inputChannels ) ); - - QLabel * channelsOut = new QLabel( groupbox ); - channelsOut->setText( tr( "Channels Out: " ) + - QString::number( lm->getDescription( _key )->outputChannels ) ); - l->addWidget( groupbox ); -} - - - - ladspaSubPluginFeatures::ladspaSubPluginFeatures( plugin::pluginTypes _type ) : subPluginFeatures( _type ) { @@ -128,11 +55,59 @@ ladspaSubPluginFeatures::ladspaSubPluginFeatures( plugin::pluginTypes _type ) : -QWidget * ladspaSubPluginFeatures::createDescriptionWidget( +void ladspaSubPluginFeatures::fillDescriptionWidget( QWidget * _parent, engine * _eng, const key & _key ) { - return( new ladspaSubPluginDescriptionWidget( _parent, _eng, - subPluginKeyToLadspaKey( _key ) ) ); + const ladspa_key_t & lkey = subPluginKeyToLadspaKey( _key ); + ladspa2LMMS * lm = _eng->getLADSPAManager(); + + QLabel * label = new QLabel( _parent ); + label->setText( QWidget::tr( "Name: " ) + lm->getName( lkey ) ); + + QHBox * maker = new QHBox( _parent ); + QLabel * maker_label = new QLabel( maker ); + maker_label->setText( QWidget::tr( "Maker: " ) ); + maker_label->setAlignment( Qt::AlignTop ); + QLabel * maker_content = new QLabel( maker ); + maker_content->setText( lm->getMaker( lkey ) ); + maker_content->setAlignment( Qt::WordBreak ); + maker->setStretchFactor( maker_content, 100 ); + + QHBox * copyright = new QHBox( _parent ); + copyright->setMinimumWidth( _parent->minimumWidth() ); + QLabel * copyright_label = new QLabel( copyright ); + copyright_label->setText( QWidget::tr( "Copyright: " ) ); + copyright_label->setAlignment( Qt::AlignTop ); + QLabel * copyright_content = new QLabel( copyright ); + copyright_content->setText( lm->getCopyright( lkey ) ); + copyright_content->setAlignment( Qt::WordBreak ); + copyright->setStretchFactor( copyright_content, 100 ); + + QLabel * requiresRealTime = new QLabel( _parent ); + requiresRealTime->setText( QWidget::tr( "Requires Real Time: " ) + + ( lm->hasRealTimeDependency( lkey ) ? + QWidget::tr( "Yes" ) : + QWidget::tr( "No" ) ) ); + + QLabel * realTimeCapable = new QLabel( _parent ); + realTimeCapable->setText( QWidget::tr( "Real Time Capable: " ) + + ( lm->isRealTimeCapable( lkey ) ? + QWidget::tr( "Yes" ) : + QWidget::tr( "No" ) ) ); + + QLabel * inplaceBroken = new QLabel( _parent ); + inplaceBroken->setText( QWidget::tr( "In Place Broken: " ) + + ( lm->isInplaceBroken( lkey ) ? + QWidget::tr( "Yes" ) : + QWidget::tr( "No" ) ) ); + + QLabel * channelsIn = new QLabel( _parent ); + channelsIn->setText( QWidget::tr( "Channels In: " ) + + QString::number( lm->getDescription( lkey )->inputChannels ) ); + + QLabel * channelsOut = new QLabel( _parent ); + channelsOut->setText( QWidget::tr( "Channels Out: " ) + + QString::number( lm->getDescription( lkey )->outputChannels ) ); } diff --git a/plugins/ladspa_effect/ladspa_subplugin_features.h b/plugins/ladspa_effect/ladspa_subplugin_features.h index ca3b7bbbb..d675b915b 100644 --- a/plugins/ladspa_effect/ladspa_subplugin_features.h +++ b/plugins/ladspa_effect/ladspa_subplugin_features.h @@ -3,8 +3,8 @@ * plugin::descriptor::subPluginFeatures for * hosting LADSPA-plugins * - * Copyright (c) 2006 Danny McRae - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2007 Danny McRae + * Copyright (c) 2006-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -33,23 +33,12 @@ #include "ladspa_base.h" -class ladspaSubPluginDescriptionWidget : public QWidget -{ -public: - ladspaSubPluginDescriptionWidget( QWidget * _parent, engine * _engine, - const ladspa_key_t & _key ); - - -} ; - - - class ladspaSubPluginFeatures : public plugin::descriptor::subPluginFeatures { public: ladspaSubPluginFeatures( plugin::pluginTypes _type ); - virtual QWidget * createDescriptionWidget( QWidget * _parent, + virtual void fillDescriptionWidget( QWidget * _parent, engine * _eng, const key & _key ); diff --git a/plugins/live_tool/live_tool.cpp b/plugins/live_tool/live_tool.cpp index da0e64f34..dbb331966 100644 --- a/plugins/live_tool/live_tool.cpp +++ b/plugins/live_tool/live_tool.cpp @@ -1,7 +1,7 @@ /* * live_tool.cpp - tool for live performance * - * Copyright (c) 2006 Javier Serrano Polo + * Copyright (c) 2006-2007 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -23,6 +23,13 @@ */ +#ifdef QT3 + +#include + +#endif + + #include "live_tool.h" #include "bb_editor.h" #include "song_editor.h" @@ -47,7 +54,7 @@ plugin::descriptor live_tool_plugin_descriptor = STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ), "LiveTool", QT_TRANSLATE_NOOP( "pluginBrowser", - "tool for live performance" ), + "Tool for live performance" ), "Javier Serrano Polo ", 0x0100, plugin::Tool, @@ -67,6 +74,19 @@ liveTool::liveTool( mainWindow * _window ) : setPaletteBackgroundPixmap( background ); setFixedSize( background.size() ); +#ifdef QT4 + setWhatsThis( +#else + QWhatsThis::add( this, +#endif + tr( + "This tool is intended to be used in live performances, though " + "you can use it for music production as well.\n" + "The following keys will work only if this window is active.\n" + "The spacebar toggles play and pause in the Song Editor.\n" + "F1-F10 keys mute the first 10 instruments in the " + "Beat+Baseline Editor." ) ); + hide(); } diff --git a/plugins/singerbot/singerbot.cpp b/plugins/singerbot/singerbot.cpp index 59907eecc..09c8906c6 100644 --- a/plugins/singerbot/singerbot.cpp +++ b/plugins/singerbot/singerbot.cpp @@ -147,9 +147,7 @@ void singerBot::playNote( notePlayHandle * _n, bool ) sampleBuffer * sample_buffer = hdata->remaining_frames ? readWave( hdata ) : new sampleBuffer( NULL, 0, eng() ); - if( sample_buffer->play( buf, 0, frames, BASE_FREQ, - FALSE, //loop - &hdata->resampling_data ) ) + if( sample_buffer->play( buf, 0, frames ) ) { getInstrumentTrack()->processAudioBuffer( buf, frames, _n ); } @@ -163,14 +161,14 @@ void singerBot::playNote( notePlayHandle * _n, bool ) void singerBot::deleteNotePluginData( notePlayHandle * _n ) { handle_data * hdata = (handle_data *)_n->m_pluginData; - if( hdata->resampling_data ) - { - sampleBuffer::deleteResamplingData( &hdata->resampling_data ); - } if( hdata->wave ) { delete hdata->wave; } + if( hdata->resampling_state ) + { + src_delete( hdata->resampling_state ); + } delete hdata; } @@ -236,9 +234,9 @@ void singerBot::createWave( notePlayHandle * _n ) { handle_data * hdata = new handle_data; _n->m_pluginData = hdata; - hdata->resampling_data = NULL; hdata->wave = NULL; hdata->remaining_frames = 0; + hdata->resampling_state = NULL; if( m_words_dirty ) { @@ -267,7 +265,18 @@ void singerBot::createWave( notePlayHandle * _n ) { return; } - hdata->wave->resample( eng()->getMixer()->sampleRate() ); + + int error; + hdata->resampling_state = src_new( SRC_LINEAR, 1, &error ); + if( !hdata->resampling_state ) + { + printf( "%s: src_new() error: %s\n", __FILE__, + src_strerror( error ) ); + } + + hdata->resampling_data.src_ratio = eng()->getMixer()->sampleRate() + / (double)hdata->wave->sample_rate(); + hdata->resampling_data.end_of_input = 0; hdata->remaining_frames = hdata->wave->num_samples(); } @@ -276,24 +285,49 @@ void singerBot::createWave( notePlayHandle * _n ) sampleBuffer * singerBot::readWave( handle_data * _hdata ) { - f_cnt_t buffer_size = eng()->getMixer()->framesPerAudioBuffer(); - f_cnt_t frames = tMin( buffer_size, _hdata->remaining_frames ); + f_cnt_t frames = eng()->getMixer()->framesPerAudioBuffer(); f_cnt_t offset = _hdata->wave->num_samples() - _hdata->remaining_frames; const float fac = 1.0f / OUTPUT_SAMPLE_MULTIPLIER; + f_cnt_t fragment_size = tMin( _hdata->remaining_frames, + 1 + (f_cnt_t)ceil( frames + / _hdata->resampling_data.src_ratio ) ); + sample_t * wave_samples = new sample_t[fragment_size]; + + for( f_cnt_t frame = 0; frame < fragment_size; ++frame ) + { + wave_samples[frame] = _hdata->wave->a( offset + frame ) * fac; + } + + sample_t * mono_data = new sample_t[frames]; + memset( mono_data, 0, sizeof( sample_t ) * frames ); + + _hdata->resampling_data.data_in = wave_samples; + _hdata->resampling_data.data_out = mono_data; + _hdata->resampling_data.input_frames = fragment_size; + _hdata->resampling_data.output_frames = frames; + int error = src_process( _hdata->resampling_state, + &_hdata->resampling_data ); + if( error ) + { + printf( "%s: src_process() error: %s\n", __FILE__, + src_strerror( error ) ); + } + sampleFrame * data = new sampleFrame[frames]; for( f_cnt_t frame = 0; frame < frames; ++frame ) { - sample_t wave_sample = _hdata->wave->a( offset + frame ) * fac; for( ch_cnt_t chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl ) { - data[frame][chnl] = wave_sample; + data[frame][chnl] = mono_data[frame]; } } sampleBuffer * buffer = new sampleBuffer( data, frames, eng() ); - _hdata->remaining_frames -= frames; + _hdata->remaining_frames -= _hdata->resampling_data.input_frames_used; + delete[] wave_samples; + delete[] mono_data; delete[] data; return( buffer ); } @@ -376,36 +410,29 @@ void singerBot::synThread::text_to_wave( void ) "(set! word " + quote_string( m_data->text, "\"", "\\", 1 ) + ")" ); festival_eval_command( - "(set! my_utt (eval (list 'Utterance 'Text word)))" ); - festival_eval_command( - " (get_segment my_utt)" ); - festival_eval_command( - "(if (equal? (length (utt.relation.leafs my_utt 'Segment)) 1)" - " (begin (set! my_utt (eval " - "(list 'Utterance 'Text (string-append word \" \" word))))" - " (get_segment my_utt)" - "))" ); - festival_eval_command( - " (Pauses my_utt)" ); - festival_eval_command( - " (item.delete (utt.relation.first my_utt 'Segment))" ); - festival_eval_command( - " (item.delete (utt.relation.last my_utt 'Segment))" ); - festival_eval_command( - " (Intonation my_utt)" ); - festival_eval_command( - " (PostLex my_utt)" ); - festival_eval_command( - " (Duration my_utt)" ); - festival_eval_command( - "(if (not (equal? total_time 0)) (begin" - "(set! utt_time" - " (item.feat (utt.relation.last my_utt 'Segment) 'end))" - "(Parameter.set 'Duration_Stretch (/ total_time utt_time))" - "(Duration my_utt)" - "))" ); - festival_eval_command( - " (Int_Targets my_utt)" ); + "(begin" + " (set! my_utt (eval (list 'Utterance 'Text word)))" + " (get_segment my_utt)" + " (if (equal? (length (utt.relation.leafs my_utt 'Segment)) 1)" + " (begin (set! my_utt (eval " + " (list 'Utterance 'Text (string-append word \" \" word))))" + " (get_segment my_utt)" + " ))" + " (Pauses my_utt)" + " (item.delete (utt.relation.first my_utt 'Segment))" + " (item.delete (utt.relation.last my_utt 'Segment))" + " (Intonation my_utt)" + " (PostLex my_utt)" + " (Duration my_utt)" + " (if (not (equal? total_time 0)) (begin" + " (set! utt_time" + " (item.feat (utt.relation.last my_utt 'Segment) 'end))" + " (Parameter.set 'Duration_Stretch (/ total_time utt_time))" + " (Duration my_utt)" + " ))" + " (Int_Targets my_utt)" + ")" ); + if( festival_eval_command( " (Wave_Synth my_utt)" ) ) { diff --git a/plugins/singerbot/singerbot.h b/plugins/singerbot/singerbot.h index 066a4aa77..280443b02 100644 --- a/plugins/singerbot/singerbot.h +++ b/plugins/singerbot/singerbot.h @@ -38,6 +38,8 @@ #endif +#include + #include "instrument.h" @@ -73,12 +75,13 @@ public slots: private: typedef struct { - void * resampling_data; EST_Wave * wave; int remaining_frames; float frequency; float duration; const char * text; + SRC_STATE * resampling_state; + SRC_DATA resampling_data; } handle_data; diff --git a/plugins/vst_effect/vst_subplugin_features.cpp b/plugins/vst_effect/vst_subplugin_features.cpp index c8f202f9e..1da9a0114 100644 --- a/plugins/vst_effect/vst_subplugin_features.cpp +++ b/plugins/vst_effect/vst_subplugin_features.cpp @@ -3,7 +3,7 @@ * plugin::descriptor::subPluginFeatures for * hosting VST-plugins * - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -28,16 +28,12 @@ #ifdef QT4 #include -#include #include -#include #else #include -#include #include -#include #endif @@ -46,29 +42,6 @@ #include "config_mgr.h" -vstSubPluginDescriptionWidget::vstSubPluginDescriptionWidget( - QWidget * _parent, engine * _engine, - const effectKey & _key ) : - QWidget( _parent ) -{ - QVBoxLayout * l = new QVBoxLayout( this ); - -#ifndef QT3 - QGroupBox * groupbox = new QGroupBox( tr( "Description" ), this ); -#else - QGroupBox * groupbox = new QGroupBox( 9, Qt::Vertical, - tr( "Description" ), this ); -#endif - - new QLabel( tr( "Name: " ) + _key.name, groupbox ); - new QLabel( tr( "File: " ) + _key.user.toString(), groupbox ); - - l->addWidget( groupbox ); -} - - - - vstSubPluginFeatures::vstSubPluginFeatures( plugin::pluginTypes _type ) : subPluginFeatures( _type ) { @@ -77,10 +50,11 @@ vstSubPluginFeatures::vstSubPluginFeatures( plugin::pluginTypes _type ) : -QWidget * vstSubPluginFeatures::createDescriptionWidget( +void vstSubPluginFeatures::fillDescriptionWidget( QWidget * _parent, engine * _eng, const key & _key ) { - return( new vstSubPluginDescriptionWidget( _parent, _eng, _key ) ); + new QLabel( QWidget::tr( "Name: " ) + _key.name, _parent ); + new QLabel( QWidget::tr( "File: " ) + _key.user.toString(), _parent ); } diff --git a/plugins/vst_effect/vst_subplugin_features.h b/plugins/vst_effect/vst_subplugin_features.h index 5d3c05428..be5ea15bf 100644 --- a/plugins/vst_effect/vst_subplugin_features.h +++ b/plugins/vst_effect/vst_subplugin_features.h @@ -3,7 +3,7 @@ * plugin::descriptor::subPluginFeatures for * hosting VST-plugins * - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -31,23 +31,12 @@ #include "effect.h" -class vstSubPluginDescriptionWidget : public QWidget -{ -public: - vstSubPluginDescriptionWidget( QWidget * _parent, engine * _engine, - const effectKey & _key ); - - -} ; - - - class vstSubPluginFeatures : public plugin::descriptor::subPluginFeatures { public: vstSubPluginFeatures( plugin::pluginTypes _type ); - virtual QWidget * createDescriptionWidget( QWidget * _parent, + virtual void fillDescriptionWidget( QWidget * _parent, engine * _eng, const key & _key ); diff --git a/src/core/automation_editor.cpp b/src/core/automation_editor.cpp index 6a6f0d21a..4dff2d270 100644 --- a/src/core/automation_editor.cpp +++ b/src/core/automation_editor.cpp @@ -4,7 +4,7 @@ * automation_editor.cpp - implementation of automationEditor which is used for * actual setting of dynamic values * - * Copyright (c) 2006 Javier Serrano Polo + * Copyright (c) 2006-2007 Javier Serrano Polo * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -661,7 +661,7 @@ void automationEditor::updatePaintPixmap( void ) // setup selection-vars int sel_pos_start = m_selectStartTact64th; - int sel_pos_end = m_selectStartTact64th+m_selectedTact64th; + int sel_pos_end = m_selectStartTact64th + m_selectedTact64th; if( sel_pos_start > sel_pos_end ) { qSwap( sel_pos_start, sel_pos_end ); @@ -731,9 +731,8 @@ void automationEditor::updatePaintPixmap( void ) // selection because the user moved it... if( m_editMode == MOVE ) { - if( qFind( m_selValuesForMove.begin(), - m_selValuesForMove.end(), *it ) - != m_selValuesForMove.end() ) + if( m_selValuesForMove.contains( + it.key() ) ) { is_selected = TRUE; } @@ -1439,18 +1438,24 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me ) for( timeMap::iterator it = m_selValuesForMove.begin(); it != m_selValuesForMove.end(); ++it ) { - int value_tact = ( -it.key() >> 6 ) + tact_diff; - int value_tact_64th = ( -it.key() & 63 ) + - tact_64th_diff; - // ensure value_tact_64th range - if( value_tact_64th >> 6 ) + midiTime new_value_pos; + if( -it.key() ) { - value_tact += value_tact_64th >> 6; - value_tact_64th &= 63; - } - m_pattern->removeValue( -it.key() ); - midiTime new_value_pos( value_tact, + int value_tact = ( -it.key() >> 6 ) + + tact_diff; + int value_tact_64th = ( -it.key() & 63 ) + + tact_64th_diff; + // ensure value_tact_64th range + if( value_tact_64th >> 6 ) + { + value_tact += value_tact_64th + >> 6; + value_tact_64th &= 63; + } + m_pattern->removeValue( -it.key() ); + new_value_pos = midiTime( value_tact, value_tact_64th ); + } #ifdef QT3 new_selValuesForMove[ -m_pattern->putValue( new_value_pos, @@ -1896,51 +1901,41 @@ void automationEditor::selectAll( void ) return; } + //TODO: Add constant + int len_tact_64th = 4; + timeMap & time_map = m_pattern->getTimeMap(); - // if first_time = TRUE, we HAVE to set the vars for select - bool first_time = TRUE; + timeMap::iterator it = time_map.begin(); + m_selectStartTact64th = 0; + m_selectedTact64th = -it.key() + len_tact_64th; +#ifdef QT3 + m_selectStartLevel = it.data(); +#else + m_selectStartLevel = it.value(); +#endif + m_selectedLevels = 1; - for( timeMap::iterator it = time_map.begin(); it != time_map.end(); - ++it ) + while( ++it != time_map.end() ) { - //TODO: Add constant - Uint32 len_tact_64th = 4; - #ifdef QT3 const int level = it.data(); #else const int level = it.value(); #endif - - Uint32 pos_tact_64th = -it.key(); - if( level <= m_selectStartLevel || first_time ) + if( level < m_selectStartLevel ) { // if we move start-level down, we have to add // the difference between old and new start-level // to m_selectedLevels, otherwise the selection // is just moved down... - int diff = m_selectStartLevel - ( level - 1 ); - m_selectStartLevel = level - 1; - m_selectedLevels += diff; + m_selectedLevels += m_selectStartLevel - level; + m_selectStartLevel = level; } - if( level >= m_selectedLevels + m_selectStartLevel - || first_time ) + else if( level >= m_selectStartLevel + m_selectedLevels ) { - m_selectedLevels = level - m_selectStartLevel; + m_selectedLevels = level - m_selectStartLevel + 1; } - if( pos_tact_64th < m_selectStartTact64th || first_time ) - { - m_selectStartTact64th = pos_tact_64th; - } - if( pos_tact_64th + len_tact_64th > - m_selectStartTact64th + m_selectedTact64th || - first_time ) - { - m_selectedTact64th = pos_tact_64th + len_tact_64th - - m_selectStartTact64th; - } - first_time = FALSE; } } diff --git a/src/core/effect_select_dialog.cpp b/src/core/effect_select_dialog.cpp index 50f804e7c..1bed2014a 100644 --- a/src/core/effect_select_dialog.cpp +++ b/src/core/effect_select_dialog.cpp @@ -3,7 +3,7 @@ /* * effect_select_dialog.cpp - dialog to choose effect plugin * - * Copyright (c) 2006 Tobias Doerffel + * Copyright (c) 2006-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -34,8 +34,10 @@ #else +#include #include #include +#include #endif @@ -165,9 +167,7 @@ void effectSelectDialog::selectPlugin( void ) effectList::effectList( QWidget * _parent, engine * _engine ) : QWidget( _parent ), - engineObject( _engine ), - m_descriptionWidgetParent( new QWidget( this ) ), - m_descriptionWidget( NULL ) + engineObject( _engine ) { plugin::getDescriptorsOfAvailPlugins( m_pluginDescriptors ); @@ -214,13 +214,26 @@ effectList::effectList( QWidget * _parent, engine * _engine ) : SLOT( onHighlighted( int ) ) ); connect( m_pluginList, SIGNAL( doubleClicked( QListBoxItem * ) ), SLOT( onDoubleClicked( QListBoxItem * ) ) ); + +#ifndef QT3 + QGroupBox * groupbox = new QGroupBox( tr( "Description" ), this ); +#else + QGroupBox * groupbox = new QGroupBox( 1, Qt::Vertical, + tr( "Description" ), this ); +#endif + groupbox->setFixedHeight( 200 ); + groupbox->setInsideMargin( 2 ); + QScrollView * scrollView = new QScrollView( groupbox ); + scrollView->setFrameStyle( 0 ); + scrollView->setMargin( 10 ); + m_descriptionWidget = new QVBox( scrollView->viewport() ); + scrollView->addChild( m_descriptionWidget ); + QVBoxLayout * vboxl = new QVBoxLayout( this ); vboxl->setMargin( 0 ); vboxl->setSpacing( 10 ); vboxl->addWidget( m_pluginList ); - vboxl->addWidget( m_descriptionWidgetParent ); - - new QVBoxLayout( m_descriptionWidgetParent ); + vboxl->addWidget( groupbox ); if( m_pluginList->numRows() > 0 ) { @@ -241,22 +254,20 @@ effectList::~effectList() void effectList::onHighlighted( int _pluginIndex ) { + QLayoutIterator it = m_descriptionWidget->layout()->iterator(); + while( it.current() ) + { + it.deleteCurrent(); + } + m_descriptionWidget->hide(); + m_currentSelection = m_effectKeys[_pluginIndex]; - delete m_descriptionWidget; - m_descriptionWidget = NULL; if( m_currentSelection.desc && m_currentSelection.desc->sub_plugin_features ) { - m_descriptionWidget = m_currentSelection.desc-> - sub_plugin_features-> - createDescriptionWidget( m_descriptionWidgetParent, + m_currentSelection.desc->sub_plugin_features-> + fillDescriptionWidget( m_descriptionWidget, eng(), m_currentSelection ); - } - if( m_descriptionWidget != NULL ) - { - dynamic_cast( - m_descriptionWidgetParent->layout() )-> - addWidget( m_descriptionWidget ); m_descriptionWidget->show(); } emit( highlighted( m_currentSelection ) ); @@ -280,6 +291,15 @@ void effectList::onAddButtonReleased() + +void effectList::resizeEvent( QResizeEvent * ) +{ + m_descriptionWidget->setFixedWidth( width() - 40 ); +} + + + + #include "effect_select_dialog.moc" #endif diff --git a/src/core/piano_roll.cpp b/src/core/piano_roll.cpp index e0fd35cd7..f511de37e 100644 --- a/src/core/piano_roll.cpp +++ b/src/core/piano_roll.cpp @@ -4,7 +4,7 @@ * piano_roll.cpp - implementation of piano-roll which is used for actual * writing of melodies * - * Copyright (c) 2004-2006 Tobias Doerffel + * Copyright (c) 2004-2007 Tobias Doerffel * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * @@ -2368,9 +2368,9 @@ void pianoRoll::selectAll( void ) // the difference between old and new start-key // to m_selectedKeys, otherwise the selection // is just moved down... - int diff = m_selectStartKey - ( key - 1 ); + m_selectedKeys += m_selectStartKey + - ( key - 1 ); m_selectStartKey = key - 1; - m_selectedKeys += diff; } if( key >= m_selectedKeys+m_selectStartKey || first_time ) diff --git a/src/tracks/instrument_track.cpp b/src/tracks/instrument_track.cpp index f253902a5..2b1b917a1 100644 --- a/src/tracks/instrument_track.cpp +++ b/src/tracks/instrument_track.cpp @@ -963,7 +963,6 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start, || dynamic_cast( tco )->empty() ) ) { sendMidiTime( _start ); - emit sentMidiTime( _start ); } } else @@ -972,8 +971,8 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start, _frames / frames_per_tact64th ) ); bb_track = NULL; sendMidiTime( _start ); - emit sentMidiTime( _start ); } + emit sentMidiTime( _start ); if ( tcos.size() == 0 ) {