completely new MIDI-subsystem and other bugfixes, see ChangeLog for details
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@20 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
62
ChangeLog
62
ChangeLog
@@ -1,3 +1,65 @@
|
||||
2005-10-23 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* src/widgets/led_checkbox.cpp:
|
||||
also emit toggled()-signal if state actually wasn't changed
|
||||
|
||||
* include/lcd_spinbox.h:
|
||||
* src/widgets/lcd_spinbox.cpp:
|
||||
- display special strings if value is a certain number
|
||||
- support for disabled-state (gray/no input)
|
||||
|
||||
* include/midi_tab_widget.h:
|
||||
* src/core/midi_tab_widget.cpp:
|
||||
* src/tracks/channel_track.cpp:
|
||||
added new tab "MIDI" for being able to setup MIDI-related stuff for
|
||||
each channel
|
||||
|
||||
* include/channel_track.h:
|
||||
* include/midi*:
|
||||
* include/piano_widget.h:
|
||||
* include/setup_dialog.h:
|
||||
* src/core/mixer.cpp:
|
||||
* src/core/piano_roll.cpp:
|
||||
* src/core/piano_widget.cpp:
|
||||
* src/core/setup_dialog.cpp:
|
||||
* src/core/song_editor.cpp:
|
||||
* src/midi/midi*:
|
||||
* src/tracks/channel_track.cpp:
|
||||
coded a completely new, powerful and clean MIDI-system which e.g. makes
|
||||
it possible to mask MIDI-events for each channel and to receive and send
|
||||
(timed!) MIDI-events on a separate MIDI-port for each channel, which
|
||||
only makes sense if using non-raw (sequenced) MIDI-client - currently
|
||||
none existing, but ALSA-sequencer-support is in progress
|
||||
|
||||
* include/midi_device.h:
|
||||
* src/midi/midi_device.cpp:
|
||||
removed
|
||||
|
||||
2005-10-21 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* src/widgets/tempo_sync_knob.cpp:
|
||||
do not implement the same code as knob does in mouseMoveEvent() - call
|
||||
knob::mouseMoveEvent() instead
|
||||
|
||||
* include/knob.h:
|
||||
* src/widgets/knob.cpp:
|
||||
cleaned up a lot and fixed some bugs
|
||||
|
||||
2005-10-20 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* include/song_editor.h:
|
||||
decreased MAX_BPM to 999 since BPM-LCD-spinbox is intended to have
|
||||
only three digits while 1000 has four of them... ;-)
|
||||
|
||||
* include/track_container.h:
|
||||
* src/core/track_container.cpp:
|
||||
trackContainer::scrollArea-class has now m_trackContainer-member
|
||||
for storing parent which makes cast of parent-widget to track-container
|
||||
(which sometimes failed...) obsolete
|
||||
|
||||
* configure.in:
|
||||
check for libfst and present VST-SDK header-files
|
||||
|
||||
2005-10-19 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
|
||||
* plugins/vestige/vestige.h:
|
||||
|
||||
24
Makefile.am
24
Makefile.am
@@ -62,6 +62,7 @@ lmms_MOC = \
|
||||
./mixer.moc \
|
||||
./name_label.moc \
|
||||
./nstate_button.moc \
|
||||
./midi_tab_widget.moc \
|
||||
./pattern.moc \
|
||||
./piano_roll.moc \
|
||||
./piano_widget.moc \
|
||||
@@ -117,6 +118,7 @@ lmms_SOURCES = \
|
||||
$(srcdir)/src/core/instrument.cpp \
|
||||
$(srcdir)/src/core/lmms_main_win.cpp \
|
||||
$(srcdir)/src/core/main.cpp \
|
||||
$(srcdir)/src/core/midi_tab_widget.cpp \
|
||||
$(srcdir)/src/core/mixer.cpp \
|
||||
$(srcdir)/src/core/name_label.cpp \
|
||||
$(srcdir)/src/core/note.cpp \
|
||||
@@ -142,10 +144,11 @@ lmms_SOURCES = \
|
||||
$(srcdir)/src/lib/sample_buffer.cpp \
|
||||
$(srcdir)/src/lib/string_pair_drag.cpp \
|
||||
$(srcdir)/src/midi/midi_alsa_raw.cpp \
|
||||
$(srcdir)/src/midi/midi_device.cpp \
|
||||
$(srcdir)/src/midi/midi_client.cpp \
|
||||
$(srcdir)/src/midi/midi_file.cpp \
|
||||
$(srcdir)/src/midi/midi_mapper.cpp \
|
||||
$(srcdir)/src/midi/midi_oss.cpp \
|
||||
$(srcdir)/src/midi/midi_port.cpp \
|
||||
$(srcdir)/src/tracks/bb_track.cpp \
|
||||
$(srcdir)/src/tracks/channel_track.cpp \
|
||||
$(srcdir)/src/tracks/pattern.cpp \
|
||||
@@ -190,7 +193,6 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/song_editor.h \
|
||||
$(srcdir)/include/plugin.h \
|
||||
$(srcdir)/include/instrument.h \
|
||||
$(srcdir)/include/midi_time.h \
|
||||
$(srcdir)/include/bb_editor.h \
|
||||
$(srcdir)/include/piano_widget.h \
|
||||
$(srcdir)/include/effect_board.h \
|
||||
@@ -227,10 +229,14 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/name_label.h \
|
||||
$(srcdir)/include/play_handle.h \
|
||||
$(srcdir)/include/mmp.h \
|
||||
$(srcdir)/include/midi_device.h \
|
||||
$(srcdir)/include/midi_file.h \
|
||||
$(srcdir)/include/midi.h \
|
||||
$(srcdir)/include/midi_alsa_raw.h \
|
||||
$(srcdir)/include/midi_client.h \
|
||||
$(srcdir)/include/midi_event_processor.h \
|
||||
$(srcdir)/include/midi_file.h \
|
||||
$(srcdir)/include/midi_oss.h \
|
||||
$(srcdir)/include/midi_port.h \
|
||||
$(srcdir)/include/midi_time.h \
|
||||
$(srcdir)/include/clipboard.h \
|
||||
$(srcdir)/include/types.h \
|
||||
$(srcdir)/include/qt3support.h \
|
||||
@@ -245,7 +251,6 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/endian_handling.h \
|
||||
$(srcdir)/include/preset_preview_play_handle.h \
|
||||
$(srcdir)/include/sample_play_handle.h \
|
||||
$(srcdir)/include/midi.h \
|
||||
$(srcdir)/include/nstate_button.h \
|
||||
$(srcdir)/include/midi_dummy.h \
|
||||
$(srcdir)/include/midi_mapper.h \
|
||||
@@ -260,7 +265,8 @@ lmms_SOURCES = \
|
||||
$(srcdir)/include/dummy_instrument.h \
|
||||
$(srcdir)/include/instrument_play_handle.h \
|
||||
$(srcdir)/include/string_pair_drag.h \
|
||||
$(srcdir)/include/ladspa_manager.h
|
||||
$(srcdir)/include/ladspa_manager.h \
|
||||
$(srcdir)/include/midi_tab_widget.h
|
||||
|
||||
|
||||
EXTRA_DIST = $(lmms_EMBEDDED_RESOURCES)
|
||||
@@ -296,6 +302,10 @@ if HAVE_LIBSF
|
||||
LIB_SF_LDADD = -lsndfile
|
||||
endif
|
||||
|
||||
lmms_LDADD = $(QT_LDADD) $(LIB_SDL_LDADD) $(LIB_ASOUND_LDADD) $(LIB_JACK_LDADD) $(LIB_SDL_SOUND_LDADD) $(LIB_VORBIS_LDADD) $(LIB_SRC_LDADD) $(LIB_SF_LDADD) -lfst -ldl
|
||||
if HAVE_LIBFST
|
||||
LIB_FST_LDADD = -lfst
|
||||
endif
|
||||
|
||||
lmms_LDADD = $(QT_LDADD) $(LIB_SDL_LDADD) $(LIB_ASOUND_LDADD) $(LIB_JACK_LDADD) $(LIB_SDL_SOUND_LDADD) $(LIB_VORBIS_LDADD) $(LIB_SRC_LDADD) $(LIB_SF_LDADD) $(LIB_FST_LDADD) -ldl
|
||||
lmms_LDFLAGS = -rdynamic -rpath $(pkglibdir)
|
||||
|
||||
|
||||
3
README
3
README
@@ -47,7 +47,8 @@ least 500 MHz, but for really enjoying LMMS less than 1 GHz makes no sense...
|
||||
|
||||
Required libraries are:
|
||||
|
||||
- Qt 3.0 (3.2 recommended) or higher (tested up to 4.0.0) with devel-files
|
||||
- multihreaded version of Qt 3.0 (3.2 recommended) or higher (tested up to
|
||||
4.0.0) with devel-files
|
||||
|
||||
Optional, but strongly recommended:
|
||||
- libvorbis with devel-files
|
||||
|
||||
8
TODO
8
TODO
@@ -1,8 +1,12 @@
|
||||
- arpeggio: send midi-out-events via channel-track
|
||||
- tooltips for controls in MIDI-tab
|
||||
- sample-track: sane bg and wave-color
|
||||
- complete toolbar-redesign in song-editor, bb-editor and piano-roll!!!
|
||||
- dnd everywhere: presets, samples (afp/sample-track), TCO's, knob-values
|
||||
- save/load parameters of VST-plugin
|
||||
- DSSI-support
|
||||
- move VST-code into separate class which can use several backends (libfst, dssi-vst and vst-server) -> add libfst/dssi-vst/vstserver-check to configure.in
|
||||
- somehow avoid hidden plugin-descriptor-widgets if height of window is too small -> add scrollbar
|
||||
- save/load parameters of VST-plugin
|
||||
- somehow avoid hidden plugin-descriptor-widgets plugin-browser if height of window is too small -> add scrollbar
|
||||
- use drawLineF() for drawing notes in pattern::paintEvent() in qt4-version
|
||||
- pattern freeze -> do not endless loop if looping-points are enabled
|
||||
- solve problem with knob-control-precision
|
||||
|
||||
75
configure.in
75
configure.in
@@ -2,8 +2,8 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.50)
|
||||
AC_INIT(lmms, 0.1.1-cvs20051019, tobydox@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051019)
|
||||
AC_INIT(lmms, 0.1.1-cvs20051023, tobydox@users.sourceforge.net)
|
||||
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051023)
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
@@ -154,6 +154,32 @@ fi
|
||||
AM_CONDITIONAL(HAVE_LIBJACK, test ! -z "$HAVE_JACK_JACK_H")
|
||||
|
||||
|
||||
# check for VST-backends (currently only libfst is supported)
|
||||
AC_ARG_WITH(vst,
|
||||
AS_HELP_STRING([--without-vst],
|
||||
[disable support for VST-plugin-hosting]), ,
|
||||
[ with_vst=yes ])
|
||||
AH_TEMPLATE(HAVE_VST_AEFFECTX_H, [Define to 1 if you have the <vst/aeffectx.h> header file.])
|
||||
AH_TEMPLATE(HAVE_FST_H, [Define to 1 if you have the <fst.h> header file.])
|
||||
if test "x$with_vst" = "xyes" ; then
|
||||
AC_CHECK_HEADER(vst/aeffectx.h, HAVE_VST_AEFFECTX_H="true")
|
||||
AC_CHECK_HEADER(fst.h, HAVE_FST_H="true")
|
||||
AC_CHECK_LIB([fst], [fst_init], HAVE_LIBFST="true", HAVE_FST_H="")
|
||||
fi
|
||||
if test ! -z "$HAVE_VST_AEFFECTX_H" ; then
|
||||
AC_DEFINE(HAVE_VST_AEFFECTX_H)
|
||||
if test ! -z "$HAVE_FST_H" ; then
|
||||
AC_DEFINE(HAVE_FST_H)
|
||||
FST_OK_BUT_VST_HEADERS_MISSING=""
|
||||
else
|
||||
FST_OK_BUT_VST_HEADERS_MISSING="true"
|
||||
fi
|
||||
else
|
||||
HAVE_FST_H=""
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_LIBFST, test ! -z "$HAVE_FST_H")
|
||||
|
||||
|
||||
# check for vorbis-lib
|
||||
AC_ARG_WITH(vorbis,
|
||||
AS_HELP_STRING([--without-vorbis],
|
||||
@@ -541,6 +567,49 @@ else
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if test ! -z "$FST_OK_BUT_VST_HEADERS_MISSING" ; then
|
||||
echo " ========================"
|
||||
echo " === LMMS - WARNING ======================================================="
|
||||
echo " ========================"
|
||||
echo " ="
|
||||
echo " = You seem to have a proper libfst-installation, but the header-files"
|
||||
echo " = (AEffect.h and aeffectx.h) from Steinberg-SDK are missing or not present"
|
||||
echo " = in /usr/include/vst. We cannot distribute them as they're licensed under"
|
||||
echo " = a non-GPL-compatible license, so you'll have to download them at"
|
||||
echo " ="
|
||||
echo " = ftp://ext2asio:sdk1ext@ftp.pinnaclesys.com/SDK"
|
||||
echo " ="
|
||||
echo " = and put the mentioned files into /usr/include."
|
||||
echo " = Otherwise (now!) configure will disable LMMS's support for built-in VST-"
|
||||
echo " = plugin-usage. If you do not intend to use VST-plugins with LMMS you can "
|
||||
echo " = ignore this warning."
|
||||
echo " = Consider installing the missing packages for using the full power of LMMS."
|
||||
echo " ="
|
||||
with_warnings="true"
|
||||
else
|
||||
if test ! -z "$HAVE_FST_H" ; then
|
||||
PLUGINS_TO_BUILD="$PLUGINS_TO_BUILD\n\t\* libfst for hosting VST-plugins"
|
||||
else
|
||||
echo " ========================"
|
||||
echo " === LMMS - WARNING ======================================================="
|
||||
echo " ========================"
|
||||
echo " ="
|
||||
echo " = You don't seem to have installed libfst, which is neccessary for building"
|
||||
echo " = LMMS with support for built-in VST-plugin. Furthermore LMMS needs"
|
||||
echo " = header-files (AEffect.h and aeffectx.h) from Steinberg-SDK, which are"
|
||||
echo " = likely to be installed by libfst, so after having coped with libfst-"
|
||||
echo " = installation (which is a mess... ;-), everything should be alright."
|
||||
echo " = If you do not intend to use VST-plugins with LMMS you can ignore this "
|
||||
echo " = warning."
|
||||
echo " = Consider installing the missing packages for using the full power of LMMS."
|
||||
echo " ="
|
||||
with_warnings="true"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
echo
|
||||
echo
|
||||
echo "LMMS will be able to use $PLUGINS_TO_BUILD" | sed -e "s/\\\n/\n/g" | sed -e "s/\\\t/\t/g" | sed -e "s/\\\\\*/\*/g"
|
||||
@@ -562,7 +631,7 @@ else
|
||||
fi
|
||||
echo " ="
|
||||
echo " = If there're problems while compiling LMMS, please send a mail to "
|
||||
echo " = tobydox@users.sourceforge.net!"
|
||||
echo " = tobydox [at] users.sourceforge.net!"
|
||||
echo " ="
|
||||
echo
|
||||
|
||||
|
||||
@@ -64,9 +64,8 @@ class arpAndChordsTabWidget : public QWidget, public settings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
arpAndChordsTabWidget( channelTrack * _channel_track,
|
||||
QWidget * _parent );
|
||||
~arpAndChordsTabWidget();
|
||||
arpAndChordsTabWidget( channelTrack * _channel_track );
|
||||
virtual ~arpAndChordsTabWidget();
|
||||
|
||||
static struct chord
|
||||
{
|
||||
@@ -114,8 +113,6 @@ private:
|
||||
RANDOM
|
||||
} m_arpDirection;
|
||||
|
||||
channelTrack * m_channelTrack;
|
||||
|
||||
// chord-stuff
|
||||
groupBox * m_chordsGroupBox;
|
||||
QComboBox * m_chordsComboBox;
|
||||
|
||||
@@ -59,8 +59,8 @@ class envelopeTabWidget : public QWidget, public settings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
envelopeTabWidget( channelTrack * _channel_track, QWidget * parent );
|
||||
~envelopeTabWidget();
|
||||
envelopeTabWidget( channelTrack * _channel_track );
|
||||
virtual ~envelopeTabWidget();
|
||||
|
||||
void FASTCALL processAudioBuffer( sampleFrame * _ab, Uint32 _frames,
|
||||
notePlayHandle * _n );
|
||||
@@ -91,8 +91,6 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
channelTrack * m_channelTrack;
|
||||
|
||||
tabWidget * m_targetsTabWidget;
|
||||
envelopeAndLFOWidget * m_envLFOWidgets[TARGET_COUNT];
|
||||
|
||||
|
||||
205
include/file_browser.h
Normal file
205
include/file_browser.h
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* file_browser.h - include file for fileBrowser
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FILE_BROWSER_H
|
||||
#define _FILE_BROWSER_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#else
|
||||
|
||||
#include <qlistview.h>
|
||||
#include <qdir.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "side_bar_widget.h"
|
||||
|
||||
|
||||
|
||||
class fileItem;
|
||||
class trackContainer;
|
||||
class QPixmap;
|
||||
class playHandle;
|
||||
|
||||
|
||||
class fileBrowser : public sideBarWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
fileBrowser( const QString & _path, const QString & _filter,
|
||||
const QString & _title, const QPixmap & _pm,
|
||||
QWidget * _parent );
|
||||
virtual ~fileBrowser();
|
||||
|
||||
|
||||
public slots:
|
||||
void reloadTree( void );
|
||||
|
||||
|
||||
protected:
|
||||
void keyPressEvent( QKeyEvent * _ke );
|
||||
|
||||
|
||||
protected slots:
|
||||
#ifdef QT4
|
||||
void itemPressed( int btn, Q3ListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
void itemReleased( int btn, Q3ListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
void itemDoubleClicked( Q3ListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
void contextMenuRequest( Q3ListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
#else
|
||||
void itemPressed( int btn, QListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
void itemReleased( int btn, QListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
void itemDoubleClicked( QListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
void contextMenuRequest( QListViewItem * _i, const QPoint & _pos,
|
||||
int _col );
|
||||
#endif
|
||||
void selectionChanged( void );
|
||||
void sendToActiveChannel( void );
|
||||
void openInNewChannelSE( void );
|
||||
void openInNewChannelBBE( void );
|
||||
void renameItem( void );
|
||||
|
||||
|
||||
private:
|
||||
void openInNewChannel( trackContainer * _tc );
|
||||
|
||||
Q3ListView * m_l;
|
||||
fileItem * m_contextMenuItem;
|
||||
|
||||
QString m_path;
|
||||
QString m_filter;
|
||||
|
||||
playHandle * m_previewPlayHandle;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class directory : public Q3ListViewItem
|
||||
{
|
||||
public:
|
||||
directory( Q3ListView * _parent, const QString & _filename,
|
||||
const QString & _path, const QString & _filter );
|
||||
directory( directory * _parent, const QString & _filename,
|
||||
const QString & _path, const QString & _filter );
|
||||
|
||||
void setOpen( bool );
|
||||
void setup( void );
|
||||
|
||||
inline QString fullName( void )
|
||||
{
|
||||
#ifdef QT4
|
||||
return( QDir::cleanPath( m_path + "/" + text( 0 ) + "/" ) );
|
||||
#else
|
||||
return( QDir::cleanDirPath( m_path + "/" + text( 0 ) + "/" ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
inline const QPixmap * pixmap( int ) const
|
||||
{
|
||||
return( m_pix );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void initPixmapStuff( void );
|
||||
//using Q3ListViewItem::setPixmap;
|
||||
void FASTCALL setPixmap( QPixmap * _px );
|
||||
|
||||
static QPixmap * s_folderPixmap;
|
||||
static QPixmap * s_folderOpenedPixmap;
|
||||
static QPixmap * s_folderLockedPixmap;
|
||||
|
||||
directory * m_p;
|
||||
QPixmap * m_pix;
|
||||
QString m_path;
|
||||
QString m_filter;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class fileItem : public Q3ListViewItem
|
||||
{
|
||||
public:
|
||||
fileItem( Q3ListView * _parent, const QString & _name,
|
||||
const QString & _path );
|
||||
fileItem( Q3ListViewItem * _parent, const QString & _name,
|
||||
const QString & _path );
|
||||
|
||||
inline QString fullName( void ) const
|
||||
{
|
||||
return( m_path + "/" + text( 0 ) );
|
||||
}
|
||||
inline const QPixmap * pixmap( int ) const
|
||||
{
|
||||
return( m_pix );
|
||||
}
|
||||
|
||||
enum fileTypes
|
||||
{
|
||||
SONG_FILE, PRESET_FILE, SAMPLE_FILE, UNKNOWN
|
||||
} ;
|
||||
|
||||
inline fileTypes type( void )
|
||||
{
|
||||
return( m_type );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void initPixmapStuff( void );
|
||||
void determineFileType( void );
|
||||
|
||||
static QPixmap * s_songFilePixmap;
|
||||
static QPixmap * s_presetFilePixmap;
|
||||
static QPixmap * s_sampleFilePixmap;
|
||||
static QPixmap * s_unknownFilePixmap;
|
||||
|
||||
QPixmap * m_pix;
|
||||
QString m_path;
|
||||
fileTypes m_type;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
122
include/instrument.h
Normal file
122
include/instrument.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* instrument.h - declaration of class instrument, which provides a
|
||||
* standard interface for all instrument plugins
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _INSTRUMENT_H
|
||||
#define _INSTRUMENT_H
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVector>
|
||||
|
||||
#else
|
||||
|
||||
#include <qwidget.h>
|
||||
#include <qvaluevector.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "plugin.h"
|
||||
#include "mixer.h"
|
||||
|
||||
|
||||
// forward-declarations
|
||||
class channelTrack;
|
||||
class notePlayHandle;
|
||||
|
||||
|
||||
class instrument : public QWidget, public plugin
|
||||
{
|
||||
public:
|
||||
instrument( channelTrack * _channel_track, const QString & _name );
|
||||
virtual ~instrument();
|
||||
|
||||
// if the plugin doesn't play each note, it can create an instrument-
|
||||
// play-handle and re-implement this method, so that it mixes it's
|
||||
// output buffer only once per mixer-period
|
||||
virtual void play( void );
|
||||
|
||||
// must be overloaded by actual plugin
|
||||
virtual void FASTCALL playNote( notePlayHandle * note_to_play );
|
||||
|
||||
// needed for deleting plugin-specific-data of a note - plugin has to
|
||||
// cast void-ptr so that the plugin-data is deleted properly
|
||||
// (call of dtor if it's a class etc.)
|
||||
virtual void FASTCALL deleteNotePluginData( notePlayHandle *
|
||||
_note_to_play );
|
||||
|
||||
// Get number of sample-frames that should be used when playing beat
|
||||
// (note with unspecified length)
|
||||
// Per default this function returns 0. In this case, channel is using
|
||||
// the length of the longest envelope (if one active).
|
||||
virtual Uint32 FASTCALL beatLen( notePlayHandle * _n ) const;
|
||||
|
||||
|
||||
// instrument-play-handles use this for checking whether they can mark
|
||||
// themselves as done, so that mixer trashes them
|
||||
inline virtual bool valid( void ) const
|
||||
{
|
||||
return( m_valid );
|
||||
}
|
||||
|
||||
|
||||
// instantiate instrument-plugin with given name or return NULL
|
||||
// on failure
|
||||
static instrument * FASTCALL instantiate( const QString & _plugin_name,
|
||||
channelTrack * _channel_track );
|
||||
|
||||
protected:
|
||||
inline channelTrack * getChannelTrack( void ) const
|
||||
{
|
||||
return( m_channelTrack );
|
||||
}
|
||||
|
||||
// instruments can use this for invalidating themselves, which is for
|
||||
// example neccessary when being destroyed and having instrument-play-
|
||||
// handles running
|
||||
inline void invalidate( void )
|
||||
{
|
||||
m_valid = FALSE;
|
||||
mixer::inst()->checkValidityOfPlayHandles();
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
channelTrack * m_channelTrack;
|
||||
bool m_valid;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
71
include/instrument_play_handle.h
Normal file
71
include/instrument_play_handle.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* instrument_play_handle.h - play-handle for playing an instrument
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _INSTRUMENT_PLAY_HANDLE_H
|
||||
#define _INSTRUMENT_PLAY_HANDLE_H
|
||||
|
||||
#include "play_handle.h"
|
||||
#include "instrument.h"
|
||||
|
||||
|
||||
class instrumentPlayHandle : public playHandle
|
||||
{
|
||||
public:
|
||||
inline instrumentPlayHandle( instrument * _instrument ) :
|
||||
playHandle(),
|
||||
m_instrument( _instrument )
|
||||
{
|
||||
}
|
||||
|
||||
inline virtual ~instrumentPlayHandle()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline virtual void play( void )
|
||||
{
|
||||
m_instrument->play();
|
||||
}
|
||||
|
||||
inline virtual bool done( void ) const
|
||||
{
|
||||
return( m_instrument == NULL );
|
||||
}
|
||||
|
||||
inline virtual void checkValidity( void )
|
||||
{
|
||||
if( !m_instrument->valid() )
|
||||
{
|
||||
m_instrument = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
instrument * m_instrument;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -61,16 +61,7 @@ public:
|
||||
knob( int _knob_num, QWidget * _parent, const QString & _name );
|
||||
virtual ~knob();
|
||||
|
||||
enum ScrollMode
|
||||
{
|
||||
ScrNone,
|
||||
ScrMouse,
|
||||
ScrTimer,
|
||||
ScrDirect,
|
||||
ScrPage
|
||||
} ;
|
||||
|
||||
void setTracking( bool _enable );
|
||||
void setHintText( const QString & _txt_before,
|
||||
const QString & _txt_after );
|
||||
void setLabel( const QString & _txt );
|
||||
@@ -110,6 +101,7 @@ public slots:
|
||||
void reset( void );
|
||||
void copyValue( void );
|
||||
void pasteValue( void );
|
||||
void enterValue( void );
|
||||
void connectToMidiDevice( void );
|
||||
void displayHelp( void );
|
||||
|
||||
@@ -127,6 +119,7 @@ protected:
|
||||
virtual void mousePressEvent( QMouseEvent * _me );
|
||||
virtual void mouseReleaseEvent( QMouseEvent * _me );
|
||||
virtual void mouseMoveEvent( QMouseEvent * _me );
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent * _me );
|
||||
virtual void wheelEvent( QWheelEvent * _me );
|
||||
virtual void contextMenuEvent( QContextMenuEvent * _me );
|
||||
|
||||
@@ -140,8 +133,6 @@ protected:
|
||||
//private:
|
||||
void layoutKnob( bool _update = TRUE );
|
||||
float getValue( const QPoint & _p );
|
||||
void getScrollMode( const QPoint & _p, int & _scroll_mode,
|
||||
int & _direction );
|
||||
void recalcAngle( void );
|
||||
|
||||
void valueChange( void );
|
||||
@@ -150,25 +141,20 @@ protected:
|
||||
|
||||
void buttonReleased( void );
|
||||
|
||||
void setNewValue( float x, int align = 0 );
|
||||
void setNewValue( float _x, bool _align = FALSE );
|
||||
|
||||
|
||||
static float s_copiedValue;
|
||||
static textFloat * s_textFloat;
|
||||
|
||||
|
||||
int m_knobWidth;
|
||||
int m_scrollMode;
|
||||
float m_mouseOffset;
|
||||
int m_direction;
|
||||
int m_tracking;
|
||||
QPoint m_origMousePos;
|
||||
bool m_buttonPressed;
|
||||
|
||||
|
||||
float m_angle;
|
||||
float m_oldAngle;
|
||||
float m_totalAngle;
|
||||
float m_nTurns;
|
||||
|
||||
QPixmap * m_knobPixmap;
|
||||
int m_knobNum;
|
||||
|
||||
@@ -30,14 +30,18 @@
|
||||
#ifdef QT4
|
||||
|
||||
#include <QLCDNumber>
|
||||
#include <QMap>
|
||||
|
||||
#else
|
||||
|
||||
#include <qlcdnumber.h>
|
||||
#include <qmap.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class QLabel;
|
||||
|
||||
|
||||
class lcdSpinBox : public QWidget
|
||||
{
|
||||
@@ -56,6 +60,15 @@ public:
|
||||
void setValue( int _value );
|
||||
void setLabel( const QString & _txt );
|
||||
|
||||
inline void addTextForValue( int _val, const QString & _text )
|
||||
{
|
||||
m_textForValue[_val] = _text;
|
||||
}
|
||||
|
||||
|
||||
public slots:
|
||||
virtual void setEnabled( bool _on );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent( QMouseEvent * _me );
|
||||
@@ -65,6 +78,8 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
QMap<int, QString> m_textForValue;
|
||||
|
||||
int m_value;
|
||||
int m_minValue;
|
||||
int m_maxValue;
|
||||
|
||||
@@ -70,6 +70,7 @@ public slots:
|
||||
void toggle( void );
|
||||
void setChecked( bool _on );
|
||||
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
virtual void mousePressEvent( QMouseEvent * _me );
|
||||
|
||||
@@ -61,11 +61,13 @@ enum midiEventTypes
|
||||
} ;
|
||||
|
||||
|
||||
const Sint8 MIDI_CHANNEL_COUNT = 16;
|
||||
|
||||
|
||||
struct midiEvent
|
||||
{
|
||||
midiEvent( midiEventTypes _type = MIDI_ACTIVE_SENSING,
|
||||
Uint8 _channel = 0,
|
||||
Sint8 _channel = 0,
|
||||
Uint16 _param1 = 0,
|
||||
Uint16 _param2 = 0 ) :
|
||||
m_type( _type ),
|
||||
@@ -75,7 +77,8 @@ struct midiEvent
|
||||
m_data.m_param[0] = _param1;
|
||||
m_data.m_param[1] = _param2;
|
||||
}
|
||||
midiEvent( midiEventTypes _type, char * _sysex_data, int _data_len ) :
|
||||
midiEvent( midiEventTypes _type, const char * _sysex_data,
|
||||
int _data_len ) :
|
||||
m_type( _type ),
|
||||
m_channel( 0 ),
|
||||
m_sysExData( _sysex_data )
|
||||
@@ -92,14 +95,14 @@ struct midiEvent
|
||||
}
|
||||
|
||||
midiEventTypes m_type; // MIDI event type
|
||||
Uint8 m_channel; // MIDI channel
|
||||
Sint8 m_channel; // MIDI channel
|
||||
union
|
||||
{
|
||||
Uint16 m_param[2]; // first/second parameter (key/velocity)
|
||||
int m_sysExDataLen; // len of m_sysExData
|
||||
} m_data;
|
||||
|
||||
char * m_sysExData;
|
||||
const char * m_sysExData;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* midi_alsa_raw.h - midi-device-driver for RawMIDI via ALSA
|
||||
* midi_alsa_raw.h - midi-client for RawMIDI via ALSA
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
@@ -50,17 +50,17 @@
|
||||
#endif
|
||||
|
||||
|
||||
#include "midi_device.h"
|
||||
#include "midi_client.h"
|
||||
|
||||
|
||||
struct pollfd;
|
||||
class QLineEdit;
|
||||
|
||||
|
||||
class midiALSARaw : public midiDevice, public QThread
|
||||
class midiALSARaw : public midiRawClient, public QThread
|
||||
{
|
||||
public:
|
||||
midiALSARaw( channelTrack * _ct = NULL );
|
||||
midiALSARaw( void );
|
||||
~midiALSARaw();
|
||||
|
||||
static QString probeDevice( void );
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
class setupWidget : public midiDevice::setupWidget
|
||||
class setupWidget : public midiRawClient::setupWidget
|
||||
{
|
||||
public:
|
||||
setupWidget( QWidget * _parent );
|
||||
@@ -88,8 +88,8 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
virtual void FASTCALL sendByte( Uint8 _c );
|
||||
virtual void FASTCALL run( void );
|
||||
virtual void FASTCALL sendByte( const Uint8 _c );
|
||||
virtual void run( void );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
153
include/midi_client.h
Normal file
153
include/midi_client.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* midi_client.h - base-class for MIDI-clients like ALSA-sequencer-client
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MIDI_CLIENT_H
|
||||
#define _MIDI_CLIENT_H
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QVector>
|
||||
|
||||
#else
|
||||
|
||||
#include <qvaluevector.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "midi.h"
|
||||
#include "midi_event_processor.h"
|
||||
#include "tab_widget.h"
|
||||
|
||||
|
||||
class midiPort;
|
||||
|
||||
|
||||
// base-class for all MIDI-clients
|
||||
class midiClient
|
||||
{
|
||||
public:
|
||||
midiClient( void );
|
||||
virtual ~midiClient();
|
||||
|
||||
virtual midiPort * FASTCALL createPort( midiEventProcessor * _mep,
|
||||
const QString & _desired_name ) = 0;
|
||||
|
||||
virtual void FASTCALL processOutEvent( const midiEvent & _me,
|
||||
const midiTime & _time,
|
||||
const midiPort * _port ) = 0;
|
||||
|
||||
// validate port-name by trying to change port name in underlying MIDI-
|
||||
// subsystem
|
||||
virtual void FASTCALL validatePortName( midiPort * _port ) = 0;
|
||||
|
||||
void FASTCALL removePort( midiPort * _port );
|
||||
|
||||
static midiClient * openMidiClient( void );
|
||||
|
||||
|
||||
class setupWidget : public tabWidget
|
||||
{
|
||||
public:
|
||||
setupWidget( const QString & _caption, QWidget * _parent ) :
|
||||
tabWidget( tabWidget::tr( "Settings for %1" ).arg(
|
||||
_caption ), _parent )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~setupWidget()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void saveSettings( void ) = 0;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
protected:
|
||||
inline void addPort( midiPort * _port )
|
||||
{
|
||||
m_midiPorts.push_back( _port );
|
||||
}
|
||||
|
||||
|
||||
vvector<midiPort *> m_midiPorts;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
const Uint8 RAW_MIDI_PARSE_BUF_SIZE = 16;
|
||||
|
||||
|
||||
class midiRawClient : public midiClient
|
||||
{
|
||||
public:
|
||||
midiRawClient( void );
|
||||
~midiRawClient();
|
||||
|
||||
|
||||
protected:
|
||||
virtual midiPort * FASTCALL createPort( midiEventProcessor * _mep,
|
||||
const QString & _desired_name );
|
||||
|
||||
virtual void FASTCALL validatePortName( midiPort * _port );
|
||||
|
||||
void FASTCALL parseData( const Uint8 _c );
|
||||
|
||||
virtual void FASTCALL sendByte( const Uint8 _c ) = 0;
|
||||
|
||||
|
||||
private:
|
||||
void processParsedEvent();
|
||||
void FASTCALL processOutEvent( const midiEvent & _me,
|
||||
const midiTime & _time,
|
||||
const midiPort * _port );
|
||||
|
||||
static Uint8 FASTCALL eventLength( const Uint8 _event );
|
||||
|
||||
|
||||
struct midiParserData
|
||||
{
|
||||
Uint8 m_status; // identifies the type of event, that
|
||||
// is currently received ('Noteon',
|
||||
// 'Pitch Bend' etc).
|
||||
Uint8 m_channel; // The channel of the event that is
|
||||
// received (in case of a channel event)
|
||||
Uint32 m_bytes; // How many bytes have been read for
|
||||
// the current event?
|
||||
Uint32 m_bytesTotal; // How many bytes does the current
|
||||
// event type include?
|
||||
Uint32 m_buffer[RAW_MIDI_PARSE_BUF_SIZE];
|
||||
// buffer for incoming data
|
||||
midiEvent m_midiEvent; // midi-event
|
||||
} m_midiParseData;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -26,15 +26,16 @@
|
||||
#define _MIDI_DUMMY_H
|
||||
|
||||
|
||||
#include "midi_device.h"
|
||||
#include "midi_client.h"
|
||||
#include "midi_port.h"
|
||||
#include "tab_widget.h"
|
||||
|
||||
|
||||
class midiDummy : public midiDevice
|
||||
class midiDummy : public midiRawClient
|
||||
{
|
||||
public:
|
||||
midiDummy() :
|
||||
midiDevice()
|
||||
midiRawClient()
|
||||
{
|
||||
}
|
||||
~midiDummy()
|
||||
@@ -47,11 +48,11 @@ public:
|
||||
}
|
||||
|
||||
|
||||
class setupWidget : public midiDevice::setupWidget
|
||||
class setupWidget : public midiClient::setupWidget
|
||||
{
|
||||
public:
|
||||
setupWidget( QWidget * _parent ) :
|
||||
midiDevice::setupWidget( midiDummy::name(), _parent )
|
||||
midiRawClient::setupWidget( midiDummy::name(), _parent )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
virtual void FASTCALL sendByte( Uint8 )
|
||||
virtual void FASTCALL sendByte( const Uint8 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
59
include/midi_event_processor.h
Normal file
59
include/midi_event_processor.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* midi_event_processor.h - base-class for midi-processing classes
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MIDI_EVENT_PROCESSOR_H
|
||||
#define _MIDI_EVENT_PROCESSOR_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "midi_time.h"
|
||||
|
||||
|
||||
class midiEvent;
|
||||
|
||||
|
||||
// all classes being able to process MIDI-events should inherit from this
|
||||
class midiEventProcessor
|
||||
{
|
||||
public:
|
||||
inline midiEventProcessor( void )
|
||||
{
|
||||
}
|
||||
|
||||
virtual inline ~midiEventProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
// to be implemented by inheriting classes
|
||||
virtual void FASTCALL processInEvent( const midiEvent & _me,
|
||||
const midiTime & _time ) = 0;
|
||||
virtual void FASTCALL processOutEvent( const midiEvent & _me,
|
||||
const midiTime & _time ) = 0;
|
||||
|
||||
} ;
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* midi_oss.h - OSS-driver for MIDI-port
|
||||
* midi_oss.h - OSS-raw-midi-client
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
@@ -33,16 +33,16 @@
|
||||
#include <qthread.h>
|
||||
#include <qfile.h>
|
||||
|
||||
#include "midi_device.h"
|
||||
#include "midi_client.h"
|
||||
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
|
||||
class midiOSS : public midiDevice, public QThread
|
||||
class midiOSS : public midiRawClient, public QThread
|
||||
{
|
||||
public:
|
||||
midiOSS( channelTrack * _ct = NULL );
|
||||
midiOSS( void );
|
||||
~midiOSS();
|
||||
|
||||
static QString probeDevice( void );
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
}
|
||||
|
||||
|
||||
class setupWidget : public midiDevice::setupWidget
|
||||
class setupWidget : public midiRawClient::setupWidget
|
||||
{
|
||||
public:
|
||||
setupWidget( QWidget * _parent );
|
||||
@@ -69,8 +69,8 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
virtual void FASTCALL sendByte( Uint8 _c );
|
||||
virtual void FASTCALL run( void );
|
||||
virtual void FASTCALL sendByte( const Uint8 _c );
|
||||
virtual void run( void );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
132
include/midi_port.h
Normal file
132
include/midi_port.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* midi_port.h - abstraction of MIDI-ports which are part of LMMS's MIDI-
|
||||
* sequencing system
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MIDI_PORT_H
|
||||
#define _MIDI_PORT_H
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QString>
|
||||
|
||||
#else
|
||||
|
||||
#include <qstring.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "types.h"
|
||||
#include "midi.h"
|
||||
#include "midi_time.h"
|
||||
|
||||
|
||||
class midiClient;
|
||||
class midiEventProcessor;
|
||||
|
||||
|
||||
// class for abstraction of MIDI-port
|
||||
class midiPort
|
||||
{
|
||||
public:
|
||||
enum modes
|
||||
{
|
||||
DUMMY, // don't route any MIDI-events (default)
|
||||
INPUT, // from MIDI-client to MIDI-event-processor
|
||||
OUTPUT, // from MIDI-event-processor to MIDI-client
|
||||
DUPLEX // both directions
|
||||
} ;
|
||||
|
||||
midiPort( midiClient * _mc, midiEventProcessor * _mep,
|
||||
const QString & _name, modes _mode = DUMMY );
|
||||
~midiPort();
|
||||
|
||||
inline const QString & name( void ) const
|
||||
{
|
||||
return( m_name );
|
||||
}
|
||||
|
||||
inline void setName( const QString & _name )
|
||||
{
|
||||
m_name = _name;
|
||||
}
|
||||
|
||||
void FASTCALL trySetName( const QString & _name );
|
||||
|
||||
inline modes mode( void ) const
|
||||
{
|
||||
return( m_mode );
|
||||
}
|
||||
|
||||
inline void setMode( modes _mode )
|
||||
{
|
||||
m_mode = _mode;
|
||||
}
|
||||
|
||||
inline Sint8 inputChannel( void ) const
|
||||
{
|
||||
return( m_inputChannel );
|
||||
}
|
||||
|
||||
inline void setInputChannel( Sint8 _chnl )
|
||||
{
|
||||
m_inputChannel = _chnl;
|
||||
}
|
||||
|
||||
inline Sint8 outputChannel( void ) const
|
||||
{
|
||||
return( m_outputChannel );
|
||||
}
|
||||
|
||||
inline void setOutputChannel( Sint8 _chnl )
|
||||
{
|
||||
m_outputChannel = _chnl;
|
||||
}
|
||||
|
||||
|
||||
void FASTCALL processInEvent( const midiEvent & _me,
|
||||
const midiTime & _time );
|
||||
void FASTCALL processOutEvent( const midiEvent & _me,
|
||||
const midiTime & _time );
|
||||
|
||||
|
||||
private:
|
||||
midiClient * m_midiClient;
|
||||
midiEventProcessor * m_midiEventProcessor;
|
||||
QString m_name;
|
||||
modes m_mode;
|
||||
Sint8 m_inputChannel;
|
||||
Sint8 m_outputChannel;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
96
include/midi_tab_widget.h
Normal file
96
include/midi_tab_widget.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* midi_tab_widget.h - tab-widget in channel-track-window for setting up
|
||||
* MIDI-related stuff
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _MIDI_TAB_WIDGET_H
|
||||
#define _MIDI_TAB_WIDGET_H
|
||||
|
||||
#include "qt3support.h"
|
||||
|
||||
#ifdef QT4
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#else
|
||||
|
||||
#include <qwidget.h>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
class QComboBox;
|
||||
class QPixmap;
|
||||
|
||||
class channelTrack;
|
||||
class tabWidget;
|
||||
class ledCheckBox;
|
||||
class lcdSpinBox;
|
||||
class midiPort;
|
||||
|
||||
|
||||
class midiTabWidget : public QWidget, public settings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
midiTabWidget( channelTrack * _channel_track, midiPort * _port );
|
||||
~midiTabWidget();
|
||||
|
||||
|
||||
virtual void FASTCALL saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent );
|
||||
virtual void FASTCALL loadSettings( const QDomElement & _this );
|
||||
inline virtual QString nodeName( void ) const
|
||||
{
|
||||
return( "midi" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected slots:
|
||||
void inputChannelChanged( int );
|
||||
void outputChannelChanged( int );
|
||||
void midiPortModeToggled( bool );
|
||||
|
||||
|
||||
private:
|
||||
channelTrack * m_channelTrack;
|
||||
midiPort * m_midiPort;
|
||||
|
||||
tabWidget * m_setupTabWidget;
|
||||
lcdSpinBox * m_inputChannelSpinBox;
|
||||
lcdSpinBox * m_outputChannelSpinBox;
|
||||
ledCheckBox * m_receiveCheckBox;
|
||||
ledCheckBox * m_sendCheckBox;
|
||||
ledCheckBox * m_routeCheckBox;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
#endif
|
||||
@@ -32,13 +32,13 @@
|
||||
class midiTime
|
||||
{
|
||||
public:
|
||||
inline midiTime( tact _tact, tact64th _tact_64th ) :
|
||||
inline midiTime( const tact _tact, const tact64th _tact_64th ) :
|
||||
m_tact( _tact ),
|
||||
m_tact64th( _tact_64th )
|
||||
{
|
||||
}
|
||||
|
||||
inline midiTime( Sint32 _abs = 0 ) :
|
||||
inline midiTime( const Sint32 _abs = 0 ) :
|
||||
m_tact( _abs / 64 ),
|
||||
m_tact64th( _abs % 64 )
|
||||
{
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
// calculate number of frame that are needed this time
|
||||
inline Uint32 frames( float _frames_per_tact ) const
|
||||
inline Uint32 frames( const float _frames_per_tact ) const
|
||||
{
|
||||
if( m_tact >= 0 )
|
||||
{
|
||||
@@ -110,6 +110,13 @@ public:
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
static inline midiTime fromFrames( Uint32 _frames,
|
||||
const float _frames_per_tact )
|
||||
{
|
||||
return( midiTime( static_cast<Sint32>( _frames * 64.0f /
|
||||
_frames_per_tact ) ) );
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
tact m_tact;
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
|
||||
class audioDevice;
|
||||
class midiDevice;
|
||||
class midiClient;
|
||||
class lmmsMainWin;
|
||||
class plugin;
|
||||
|
||||
@@ -153,15 +153,15 @@ public:
|
||||
void restoreAudioDevice( void );
|
||||
|
||||
|
||||
// MIDI-device-stuff
|
||||
inline const QString & midiDevName( void ) const
|
||||
// MIDI-client-stuff
|
||||
inline const QString & midiClientName( void ) const
|
||||
{
|
||||
return( m_midiDevName );
|
||||
return( m_midiClientName );
|
||||
}
|
||||
|
||||
inline midiDevice * getMIDIDevice( void )
|
||||
inline midiClient * getMIDIClient( void )
|
||||
{
|
||||
return( m_midiDev );
|
||||
return( m_midiClient );
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ private:
|
||||
|
||||
|
||||
audioDevice * tryAudioDevices( void );
|
||||
midiDevice * tryMIDIDevices( void );
|
||||
midiClient * tryMIDIClients( void );
|
||||
|
||||
|
||||
|
||||
@@ -326,8 +326,8 @@ private:
|
||||
QString m_audioDevName;
|
||||
|
||||
|
||||
midiDevice * m_midiDev;
|
||||
QString m_midiDevName;
|
||||
midiClient * m_midiClient;
|
||||
QString m_midiClientName;
|
||||
|
||||
|
||||
QMutex m_safetySyncMutex;
|
||||
|
||||
@@ -62,18 +62,17 @@ class pianoWidget : public QWidget
|
||||
Q_OBJECT
|
||||
public:
|
||||
pianoWidget( channelTrack * _channel_track );
|
||||
~pianoWidget();
|
||||
virtual ~pianoWidget();
|
||||
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent * );
|
||||
void mousePressEvent( QMouseEvent * me );
|
||||
void mouseReleaseEvent( QMouseEvent * me );
|
||||
void mouseMoveEvent( QMouseEvent * me );
|
||||
void keyPressEvent( QKeyEvent * ke );
|
||||
void keyReleaseEvent( QKeyEvent * ke );
|
||||
void focusInEvent( QFocusEvent * _fe );
|
||||
void focusOutEvent( QFocusEvent * _fe );
|
||||
virtual void paintEvent( QPaintEvent * );
|
||||
virtual void mousePressEvent( QMouseEvent * me );
|
||||
virtual void mouseReleaseEvent( QMouseEvent * me );
|
||||
virtual void mouseMoveEvent( QMouseEvent * me );
|
||||
virtual void keyPressEvent( QKeyEvent * ke );
|
||||
virtual void keyReleaseEvent( QKeyEvent * ke );
|
||||
virtual void focusOutEvent( QFocusEvent * _fe );
|
||||
|
||||
|
||||
private:
|
||||
@@ -86,6 +85,8 @@ private:
|
||||
static QPixmap * s_whiteKeyPressedPm;
|
||||
static QPixmap * s_blackKeyPressedPm;
|
||||
|
||||
bool m_pressedKeys[NOTES_PER_OCTAVE * OCTAVES];
|
||||
|
||||
QScrollBar * m_pianoScroll;
|
||||
channelTrack * m_channelTrack;
|
||||
tones m_startTone; // first key when drawing
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
#endif
|
||||
|
||||
#include "audio_device.h"
|
||||
#include "midi_device.h"
|
||||
#include "midi_client.h"
|
||||
|
||||
|
||||
class QComboBox;
|
||||
@@ -98,7 +98,7 @@ private:
|
||||
|
||||
|
||||
typedef QMap<QString, audioDevice::setupWidget *> aswMap;
|
||||
typedef QMap<QString, midiDevice::setupWidget *> mswMap;
|
||||
typedef QMap<QString, midiClient::setupWidget *> mswMap;
|
||||
|
||||
QComboBox * m_audioInterfaces;
|
||||
aswMap m_audioIfaceSetupWidgets;
|
||||
|
||||
@@ -63,7 +63,7 @@ class visualizationWidget;
|
||||
|
||||
const int MIN_BPM = 10;
|
||||
const int DEFAULT_BPM = 140;
|
||||
const int MAX_BPM = 1000;
|
||||
const int MAX_BPM = 999;
|
||||
const Uint16 MAX_SONG_LENGTH = 9999;
|
||||
|
||||
|
||||
|
||||
@@ -119,6 +119,9 @@ private:
|
||||
protected:
|
||||
virtual void wheelEvent( QWheelEvent * _we );
|
||||
|
||||
private:
|
||||
trackContainer * m_trackContainer;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
SUBDIRS = audio_file_processor ladspa_sine_1063 midi_out plucked_string_synth triple_oscillator vestige
|
||||
if HAVE_LIBFST
|
||||
VESTIGE_SUBDIR=vestige
|
||||
endif
|
||||
|
||||
SUBDIRS = audio_file_processor ladspa_sine_1063 midi_out plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR)
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="audiofileprocessor"
|
||||
MOC_FILES = ./audio_file_processor.moc
|
||||
|
||||
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
|
||||
|
||||
EMBEDDED_RESOURCES = $(wildcard *png)
|
||||
|
||||
./embedded_resources.h: $(EMBEDDED_RESOURCES)
|
||||
|
||||
@@ -68,7 +68,7 @@ plugin::descriptor audiofileprocessor_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"AudioFileProcessor",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"simple sampler with various settings for "
|
||||
"using samples (e.g. drums) in a channel" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
@@ -185,9 +185,9 @@ audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) :
|
||||
"actual sample-file isn't touched!)" ) );
|
||||
|
||||
m_startKnob = new knob( knobDark_28, this, tr( "Start of sample" ) );
|
||||
m_startKnob->setRange( 0, 1.0, 0.00001 );
|
||||
m_startKnob->setRange( 0.0f, 1.0f, 0.00001f );
|
||||
m_startKnob->move( 46, 114 );
|
||||
m_startKnob->setValue( 0.0, TRUE );
|
||||
m_startKnob->setValue( 0.0f, TRUE );
|
||||
m_startKnob->setHintText( tr( "Startpoint:" )+" ", "" );
|
||||
m_startKnob->setLabel( tr( "START" ) );
|
||||
connect( m_startKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
@@ -204,9 +204,9 @@ audioFileProcessor::audioFileProcessor( channelTrack * _channel_track ) :
|
||||
"than the sample between start- and end-point." ) );
|
||||
|
||||
m_endKnob = new knob( knobDark_28, this, tr( "End of sample" ) );
|
||||
m_endKnob->setRange( 0, 1.0, 0.00001 );
|
||||
m_endKnob->setRange( 0.0f, 1.0f, 0.00001f );
|
||||
m_endKnob->move( 84, 114 );
|
||||
m_endKnob->setValue( 1.0, TRUE );
|
||||
m_endKnob->setValue( 1.0f, TRUE );
|
||||
m_endKnob->setHintText( tr( "Endpoint:" )+" ", "" );
|
||||
m_endKnob->setLabel( tr( "END" ) );
|
||||
connect( m_endKnob, SIGNAL( valueChanged( float ) ), this,
|
||||
|
||||
@@ -54,7 +54,7 @@ plugin::descriptor pluckedstringsynth_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"PluckedStringSynth",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"cheap synthesis of guitar/harp-like sounds" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
0x0100,
|
||||
|
||||
@@ -63,7 +63,7 @@ plugin::descriptor tripleoscillator_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"TripleOscillator",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"three powerful oscillators you can modulate "
|
||||
"in several ways" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
|
||||
@@ -67,7 +67,7 @@ plugin::descriptor vestige_plugin_descriptor =
|
||||
{
|
||||
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
|
||||
"VeSTige",
|
||||
QT_TRANSLATE_NOOP( "plugin",
|
||||
QT_TRANSLATE_NOOP( "pluginBrowser",
|
||||
"experimental VST-hoster for using VST-plugins "
|
||||
"within LMMS" ),
|
||||
"Tobias Doerffel <tobydox@users.sf.net>",
|
||||
|
||||
@@ -44,6 +44,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include "arp_and_chords_tab_widget.h"
|
||||
#include "embed.h"
|
||||
#include "note_play_handle.h"
|
||||
@@ -54,10 +59,7 @@
|
||||
#include "tooltip.h"
|
||||
#include "gui_templates.h"
|
||||
#include "tempo_sync_knob.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include "channel_track.h"
|
||||
|
||||
|
||||
|
||||
@@ -194,12 +196,10 @@ const int ARP_GROUPBOX_HEIGHT = 200 - ARP_GROUPBOX_Y;
|
||||
|
||||
|
||||
|
||||
arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track,
|
||||
QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
arpAndChordsTabWidget::arpAndChordsTabWidget( channelTrack * _channel_track ) :
|
||||
QWidget( _channel_track->tabWidgetParent() ),
|
||||
settings(),
|
||||
m_arpDirection( UP ),
|
||||
m_channelTrack( _channel_track )
|
||||
m_arpDirection( UP )
|
||||
{
|
||||
m_chordsGroupBox = new groupBox( tr( "CHORDS" ), this );
|
||||
m_chordsGroupBox->setGeometry( CHORDS_GROUPBOX_X, CHORDS_GROUPBOX_Y,
|
||||
@@ -604,41 +604,41 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n )
|
||||
void arpAndChordsTabWidget::saveSettings( QDomDocument & _doc,
|
||||
QDomElement & _parent )
|
||||
{
|
||||
QDomElement elw_de = _doc.createElement( nodeName() );
|
||||
elw_de.setAttribute( "chorddisabled", QString::number(
|
||||
QDomElement act_de = _doc.createElement( nodeName() );
|
||||
act_de.setAttribute( "chorddisabled", QString::number(
|
||||
!m_chordsGroupBox->isActive() ) );
|
||||
#ifdef QT4
|
||||
elw_de.setAttribute( "chord", QString::number(
|
||||
act_de.setAttribute( "chord", QString::number(
|
||||
m_chordsComboBox->currentIndex() ) );
|
||||
#else
|
||||
elw_de.setAttribute( "chord", QString::number(
|
||||
act_de.setAttribute( "chord", QString::number(
|
||||
m_chordsComboBox->currentItem() ) );
|
||||
#endif
|
||||
elw_de.setAttribute( "chordrange", QString::number(
|
||||
act_de.setAttribute( "chordrange", QString::number(
|
||||
m_chordRangeKnob->value() ) );
|
||||
|
||||
elw_de.setAttribute( "arpdisabled", QString::number(
|
||||
act_de.setAttribute( "arpdisabled", QString::number(
|
||||
!m_arpGroupBox->isActive() ) );
|
||||
#ifdef QT4
|
||||
elw_de.setAttribute( "arp", QString::number(
|
||||
act_de.setAttribute( "arp", QString::number(
|
||||
m_arpComboBox->currentIndex() ) );
|
||||
#else
|
||||
elw_de.setAttribute( "arp", QString::number(
|
||||
act_de.setAttribute( "arp", QString::number(
|
||||
m_arpComboBox->currentItem() ) );
|
||||
#endif
|
||||
elw_de.setAttribute( "arprange", QString::number(
|
||||
act_de.setAttribute( "arprange", QString::number(
|
||||
m_arpRangeKnob->value() ) );
|
||||
elw_de.setAttribute( "arptime", QString::number(
|
||||
act_de.setAttribute( "arptime", QString::number(
|
||||
m_arpTimeKnob->value() ) );
|
||||
elw_de.setAttribute( "arpgate", QString::number(
|
||||
act_de.setAttribute( "arpgate", QString::number(
|
||||
m_arpGateKnob->value() ) );
|
||||
elw_de.setAttribute( "arpdir", QString::number(
|
||||
act_de.setAttribute( "arpdir", QString::number(
|
||||
m_arpDirection ) );
|
||||
elw_de.setAttribute( "arpsyncmode", QString::number(
|
||||
( int ) m_arpTimeKnob->getSyncMode() ) );
|
||||
act_de.setAttribute( "arpsyncmode", QString::number(
|
||||
( int ) m_arpTimeKnob->getSyncMode() ) );
|
||||
|
||||
|
||||
_parent.appendChild( elw_de );
|
||||
_parent.appendChild( act_de );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
#include "tab_widget.h"
|
||||
#include "embed.h"
|
||||
#include "gui_templates.h"
|
||||
#include "channel_track.h"
|
||||
|
||||
|
||||
|
||||
const int TARGETS_TABWIDGET_X = 4;
|
||||
@@ -82,11 +84,9 @@ static const QString targetNames[envelopeTabWidget::TARGET_COUNT][2] =
|
||||
|
||||
|
||||
|
||||
envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track,
|
||||
QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
settings(),
|
||||
m_channelTrack( _channel_track )
|
||||
envelopeTabWidget::envelopeTabWidget( channelTrack * _channel_track ) :
|
||||
QWidget( _channel_track->tabWidgetParent() ),
|
||||
settings()
|
||||
{
|
||||
|
||||
m_targetsTabWidget = new tabWidget( tr( "TARGET" ), this );
|
||||
|
||||
756
src/core/file_browser.cpp
Normal file
756
src/core/file_browser.cpp
Normal file
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* file_browser.cpp - implementation of the project-, preset- and sample-file-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 <QPushButton>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
|
||||
#else
|
||||
|
||||
#include <qpushbutton.h>
|
||||
#include <qpopupmenu.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "file_browser.h"
|
||||
#include "song_editor.h"
|
||||
#include "bb_editor.h"
|
||||
#include "embed.h"
|
||||
#include "channel_track.h"
|
||||
#include "mmp.h"
|
||||
#include "preset_preview_play_handle.h"
|
||||
#include "sample_play_handle.h"
|
||||
#include "debug.h"
|
||||
#include "gui_templates.h"
|
||||
#include "instrument.h"
|
||||
|
||||
|
||||
|
||||
fileBrowser::fileBrowser( const QString & _path, const QString & _filter,
|
||||
const QString & _title, const QPixmap & _pm,
|
||||
QWidget * _parent ) :
|
||||
sideBarWidget( _title, _pm, _parent ),
|
||||
m_contextMenuItem( NULL ),
|
||||
m_path( _path ),
|
||||
m_filter( _filter ),
|
||||
m_previewPlayHandle( NULL )
|
||||
{
|
||||
setWindowTitle( tr( "Browser" ) );
|
||||
m_l = new Q3ListView( contentParent() );
|
||||
addContentWidget( m_l );
|
||||
|
||||
#ifdef QT4
|
||||
connect( m_l, SIGNAL( mouseButtonPressed( int, Q3ListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( itemPressed( int, Q3ListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
connect( m_l, SIGNAL( mouseButtonClicked( int, Q3ListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( itemReleased( int, Q3ListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
connect( m_l, SIGNAL( doubleClicked( Q3ListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( itemDoubleClicked( Q3ListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
|
||||
connect( m_l, SIGNAL( contextMenuRequested( Q3ListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( contextMenuRequest( Q3ListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
#else
|
||||
connect( m_l, SIGNAL( mouseButtonPressed( int, QListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( itemPressed( int, QListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
connect( m_l, SIGNAL( mouseButtonClicked( int, QListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( itemReleased( int, QListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
/* connect( m_l, SIGNAL( pressed( QListViewItem * ) ),
|
||||
this, SLOT( itemClicked( QListViewItem * ) ) );*/
|
||||
connect( m_l, SIGNAL( doubleClicked( QListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( itemDoubleClicked( QListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
|
||||
connect( m_l, SIGNAL( contextMenuRequested( QListViewItem *,
|
||||
const QPoint &, int ) ),
|
||||
this, SLOT( contextMenuRequest( QListViewItem *,
|
||||
const QPoint &, int ) ) );
|
||||
#endif
|
||||
connect( m_l, SIGNAL( selectionChanged() ), this,
|
||||
SLOT( selectionChanged() ) );
|
||||
|
||||
m_l->addColumn( tr( "Files" ) );
|
||||
m_l->setTreeStepSize( 12 );
|
||||
m_l->setDefaultRenameAction( Q3ListView::Accept );
|
||||
m_l->setSorting( -1 );
|
||||
//setColumnWidthMode (0, Manual);
|
||||
//setColumnWidth (0, 196);
|
||||
m_l->setShowToolTips( TRUE );
|
||||
//m_l->setGeometry (0, 0, 200, 600);
|
||||
|
||||
m_l->setFont( pointSize<8>( m_l->font() ) );
|
||||
|
||||
|
||||
QPushButton * reload_btn = new QPushButton( embed::getIconPixmap(
|
||||
"reload" ), tr( "Reload (F5)" ), contentParent() );
|
||||
addContentWidget( reload_btn );
|
||||
connect( reload_btn, SIGNAL( clicked() ), this, SLOT( reloadTree() ) );
|
||||
|
||||
reloadTree();
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fileBrowser::~fileBrowser()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::reloadTree( void )
|
||||
{
|
||||
m_l->clear();
|
||||
QDir cdir( m_path );
|
||||
QStringList files = cdir.entryList( QDir::NoFilter, QDir::Name );
|
||||
|
||||
// TODO: after dropping qt3-support we can use QStringList's iterator
|
||||
// which makes it possible to travel through the list in reverse
|
||||
// direction
|
||||
|
||||
for( csize i = 0; i < files.size(); ++i )
|
||||
{
|
||||
QString cur_file = files[files.size() - i - 1];
|
||||
if( cur_file[0] != '.' &&
|
||||
!QFileInfo( m_path + "/" + cur_file ).isDir()
|
||||
#ifdef QT4
|
||||
// TBD
|
||||
#else
|
||||
&& QDir::match( m_filter, cur_file.lower() )
|
||||
#endif
|
||||
)
|
||||
{
|
||||
(void) new fileItem( m_l, cur_file, m_path );
|
||||
}
|
||||
}
|
||||
|
||||
for( csize i = 0; i < files.size(); ++i )
|
||||
{
|
||||
QString cur_file = files[files.size() - i - 1];
|
||||
if( cur_file[0] != '.' &&
|
||||
QFileInfo( m_path + "/" + cur_file ).isDir() )
|
||||
{
|
||||
(void) new directory( m_l, cur_file, m_path, m_filter );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::keyPressEvent( QKeyEvent * _ke )
|
||||
{
|
||||
if( _ke->key() == Qt::Key_F5 )
|
||||
{
|
||||
reloadTree();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ke->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
void fileBrowser::itemPressed( int _btn, Q3ListViewItem * i, const QPoint &, int )
|
||||
#else
|
||||
void fileBrowser::itemPressed( int _btn, QListViewItem * i, const QPoint &, int )
|
||||
#endif
|
||||
{
|
||||
fileItem * f = dynamic_cast<fileItem *>( i );
|
||||
if( f != NULL && _btn == Qt::LeftButton )
|
||||
{
|
||||
if( m_previewPlayHandle != NULL )
|
||||
{
|
||||
mixer::inst()->removePlayHandle( m_previewPlayHandle );
|
||||
m_previewPlayHandle = NULL;
|
||||
}
|
||||
if( f->type() == fileItem::SAMPLE_FILE )
|
||||
{
|
||||
samplePlayHandle * s = new samplePlayHandle(
|
||||
f->fullName() );
|
||||
s->setDoneMayReturnTrue( FALSE );
|
||||
m_previewPlayHandle = s;
|
||||
}
|
||||
else if( f->type() == fileItem::PRESET_FILE )
|
||||
{
|
||||
m_previewPlayHandle = new presetPreviewPlayHandle(
|
||||
f->fullName() );
|
||||
}
|
||||
if( m_previewPlayHandle != NULL )
|
||||
{
|
||||
mixer::inst()->addPlayHandle( m_previewPlayHandle );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
void fileBrowser::itemReleased( int, Q3ListViewItem * i, const QPoint &, int )
|
||||
#else
|
||||
void fileBrowser::itemReleased( int, QListViewItem * i, const QPoint &, int )
|
||||
#endif
|
||||
{
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::selectionChanged( void )
|
||||
{
|
||||
if( m_previewPlayHandle != NULL )
|
||||
{
|
||||
// if there're samples shorter than 3 seconds, we don't
|
||||
// stop them if the user releases mouse-button...
|
||||
samplePlayHandle * s = dynamic_cast<samplePlayHandle *>(
|
||||
m_previewPlayHandle );
|
||||
if( s != NULL )
|
||||
{
|
||||
if( s->totalFrames() - s->framesDone() <=
|
||||
static_cast<Uint32>(
|
||||
mixer::inst()->sampleRate() * 3 ) )
|
||||
{
|
||||
s->setDoneMayReturnTrue( TRUE );
|
||||
m_previewPlayHandle = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
mixer::inst()->removePlayHandle( m_previewPlayHandle );
|
||||
m_previewPlayHandle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
void fileBrowser::itemDoubleClicked( Q3ListViewItem * i, const QPoint &, int )
|
||||
#else
|
||||
void fileBrowser::itemDoubleClicked( QListViewItem * i, const QPoint &, int )
|
||||
#endif
|
||||
{
|
||||
fileItem * f = dynamic_cast<fileItem *>( i );
|
||||
if( f != NULL )
|
||||
{
|
||||
if( f->type() == fileItem::SAMPLE_FILE )
|
||||
{
|
||||
// samples are per default opened in bb-editor because
|
||||
// they're likely drum-samples etc.
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>(
|
||||
track::create(
|
||||
track::CHANNEL_TRACK,
|
||||
bbEditor::inst() ) );
|
||||
#ifdef LMMS_DEBUG
|
||||
assert( ct != NULL );
|
||||
#endif
|
||||
instrument * afp = ct->loadInstrument(
|
||||
"audiofileprocessor" );
|
||||
if( afp != NULL )
|
||||
{
|
||||
afp->setParameter( "audiofile", f->fullName() );
|
||||
}
|
||||
ct->toggledChannelButton( TRUE );
|
||||
}
|
||||
else if( f->type() == fileItem::PRESET_FILE )
|
||||
{
|
||||
// presets are per default opened in bb-editor
|
||||
multimediaProject mmp( f->fullName() );
|
||||
track * t = track::create( track::CHANNEL_TRACK,
|
||||
bbEditor::inst() );
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>( t );
|
||||
if( ct != NULL )
|
||||
{
|
||||
ct->loadTrackSpecificSettings( mmp.content().
|
||||
firstChild().
|
||||
toElement() );
|
||||
ct->toggledChannelButton( TRUE );
|
||||
}
|
||||
}
|
||||
else if( f->type() == fileItem::SONG_FILE )
|
||||
{
|
||||
if( songEditor::inst()->mayChangeProject() == TRUE )
|
||||
{
|
||||
songEditor::inst()->loadProject(
|
||||
f->fullName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef QT4
|
||||
void fileBrowser::contextMenuRequest( Q3ListViewItem * i, const QPoint &, int )
|
||||
#else
|
||||
void fileBrowser::contextMenuRequest( QListViewItem * i, const QPoint &, int )
|
||||
#endif
|
||||
{
|
||||
fileItem * f = dynamic_cast<fileItem *>( i );
|
||||
if( f != NULL && ( f->type() == fileItem::SAMPLE_FILE ||
|
||||
f->type() == fileItem::PRESET_FILE ) )
|
||||
{
|
||||
m_contextMenuItem = f;
|
||||
QMenu * contextMenu = new QMenu( this );
|
||||
contextMenu->addAction( tr( "Send to active channel" ), this,
|
||||
SLOT( sendToActiveChannel() ) );
|
||||
contextMenu->addAction( tr( "Open in new channel/Song-Editor" ),
|
||||
this,
|
||||
SLOT( openInNewChannelSE() ) );
|
||||
contextMenu->addAction( tr( "Open in new channel/B+B Editor" ),
|
||||
this,
|
||||
SLOT( openInNewChannelBBE() ) );
|
||||
//contextMenu->addSeparator ();
|
||||
//contextMenu->addAction (tr("Rename"), this, SLOT(renameItem()));
|
||||
contextMenu->exec( QCursor::pos() );
|
||||
m_contextMenuItem = NULL;
|
||||
delete contextMenu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::sendToActiveChannel( void )
|
||||
{
|
||||
// get all windows opened in the workspace
|
||||
QWidgetList pl = lmmsMainWin::inst()->workspace()->windowList(
|
||||
#if QT_VERSION >= 0x030200
|
||||
QWorkspace::StackingOrder
|
||||
#endif
|
||||
);
|
||||
#ifdef QT4
|
||||
QListIterator<QWidget *> w( pl );
|
||||
w.toBack();
|
||||
// now we travel through the window-list until we find a channel-track
|
||||
while( w.hasPrevious() )
|
||||
{
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>(
|
||||
w.previous() );
|
||||
#else
|
||||
QWidget * w = pl.last();
|
||||
// now we travel through the window-list until we find a channel-track
|
||||
while( w != NULL )
|
||||
{
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>( w );
|
||||
#endif
|
||||
if( ct != NULL && ct->isHidden() == FALSE )
|
||||
{
|
||||
// ok, it's a channel-track, so we can apply the
|
||||
// sample or the preset
|
||||
if( m_contextMenuItem->type() == fileItem::SAMPLE_FILE )
|
||||
{
|
||||
instrument * afp = ct->loadInstrument(
|
||||
"audiofileprocessor" );
|
||||
if( afp != NULL )
|
||||
{
|
||||
afp->setParameter( "audiofile",
|
||||
m_contextMenuItem->fullName() );
|
||||
}
|
||||
}
|
||||
else if( m_contextMenuItem->type() ==
|
||||
fileItem::PRESET_FILE )
|
||||
{
|
||||
multimediaProject mmp(
|
||||
m_contextMenuItem->fullName() );
|
||||
ct->loadTrackSpecificSettings(
|
||||
mmp.content().
|
||||
firstChild().
|
||||
toElement() );
|
||||
}
|
||||
ct->toggledChannelButton( TRUE );
|
||||
break;
|
||||
}
|
||||
#ifndef QT4
|
||||
w = pl.prev();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::openInNewChannel( trackContainer * _tc )
|
||||
{
|
||||
if( m_contextMenuItem->type() == fileItem::SAMPLE_FILE )
|
||||
{
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>(
|
||||
track::create( track::CHANNEL_TRACK, _tc ) );
|
||||
#ifdef LMMS_DEBUG
|
||||
assert( ct != NULL );
|
||||
#endif
|
||||
instrument * afp = ct->loadInstrument( "audiofileprocessor" );
|
||||
if( afp != NULL )
|
||||
{
|
||||
afp->setParameter( "audiofile",
|
||||
m_contextMenuItem->fullName() );
|
||||
}
|
||||
ct->toggledChannelButton( TRUE );
|
||||
}
|
||||
else if( m_contextMenuItem->type() == fileItem::PRESET_FILE )
|
||||
{
|
||||
multimediaProject mmp( m_contextMenuItem->fullName() );
|
||||
track * t = track::create( track::CHANNEL_TRACK, _tc );
|
||||
channelTrack * ct = dynamic_cast<channelTrack *>( t );
|
||||
if( ct != NULL )
|
||||
{
|
||||
ct->loadTrackSpecificSettings( mmp.content().
|
||||
firstChild().
|
||||
toElement() );
|
||||
ct->toggledChannelButton( TRUE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::openInNewChannelSE( void )
|
||||
{
|
||||
openInNewChannel( songEditor::inst() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::openInNewChannelBBE( void )
|
||||
{
|
||||
openInNewChannel( bbEditor::inst() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileBrowser::renameItem( void )
|
||||
{
|
||||
m_contextMenuItem->startRename( 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QPixmap * directory::s_folderPixmap = NULL;
|
||||
QPixmap * directory::s_folderOpenedPixmap = NULL;
|
||||
QPixmap * directory::s_folderLockedPixmap = NULL;
|
||||
|
||||
|
||||
directory::directory( directory * _parent, const QString & _name,
|
||||
const QString & _path, const QString & _filter ) :
|
||||
Q3ListViewItem( _parent, _name ),
|
||||
m_p( _parent ),
|
||||
m_pix( NULL ),
|
||||
m_path( _path ),
|
||||
m_filter( _filter )
|
||||
{
|
||||
initPixmapStuff();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
directory::directory( Q3ListView * _parent, const QString & _name,
|
||||
const QString & _path, const QString & _filter ) :
|
||||
Q3ListViewItem( _parent, _name ),
|
||||
m_p( NULL ),
|
||||
m_pix( NULL ),
|
||||
m_path( _path ),
|
||||
m_filter( _filter )
|
||||
{
|
||||
initPixmapStuff();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void directory::initPixmapStuff( void )
|
||||
{
|
||||
if( s_folderPixmap == NULL )
|
||||
{
|
||||
s_folderPixmap = new QPixmap(
|
||||
embed::getIconPixmap( "folder" ) );
|
||||
}
|
||||
if( s_folderOpenedPixmap == NULL )
|
||||
{
|
||||
s_folderOpenedPixmap = new QPixmap(
|
||||
embed::getIconPixmap( "folder_opened" ) );
|
||||
}
|
||||
if( s_folderLockedPixmap == NULL )
|
||||
{
|
||||
s_folderLockedPixmap = new QPixmap(
|
||||
embed::getIconPixmap( "folder_locked" ) );
|
||||
}
|
||||
|
||||
if( !QDir( fullName() ).isReadable() )
|
||||
{
|
||||
setPixmap( s_folderLockedPixmap );
|
||||
}
|
||||
else
|
||||
{
|
||||
setPixmap( s_folderPixmap );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void directory::setPixmap( QPixmap * _px )
|
||||
{
|
||||
m_pix = _px;
|
||||
setup();
|
||||
widthChanged( 0 );
|
||||
invalidateHeight();
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void directory::setOpen( bool _o )
|
||||
{
|
||||
if( _o )
|
||||
{
|
||||
setPixmap( s_folderOpenedPixmap );
|
||||
}
|
||||
else
|
||||
{
|
||||
setPixmap( s_folderPixmap );
|
||||
}
|
||||
|
||||
if( _o && !childCount() )
|
||||
{
|
||||
QString s( fullName() );
|
||||
QDir thisDir( s );
|
||||
if( !thisDir.isReadable() )
|
||||
{
|
||||
//readable = FALSE;
|
||||
setExpandable( FALSE );
|
||||
return;
|
||||
}
|
||||
|
||||
listView()->setUpdatesEnabled( FALSE );
|
||||
|
||||
QStringList files = thisDir.entryList( QDir::NoFilter,
|
||||
QDir::Name );
|
||||
for( csize i = 0; i < files.size(); ++i )
|
||||
{
|
||||
QString cur_file = files[files.size()-i-1];
|
||||
#ifdef QT4
|
||||
if( cur_file[0] != '.' && !QFileInfo(
|
||||
thisDir.absolutePath() + "/" +
|
||||
cur_file ).isDir() &&
|
||||
thisDir.match( m_filter, cur_file.lower() )
|
||||
/*QDir::match( FILE_FILTER, cur_file )*/ )
|
||||
#else
|
||||
if( cur_file[0] != '.' && !QFileInfo(
|
||||
thisDir.absPath() + "/" +
|
||||
cur_file ).isDir() &&
|
||||
thisDir.match( m_filter, cur_file.lower() )
|
||||
/*QDir::match( FILE_FILTER, cur_file )*/ )
|
||||
#endif
|
||||
{
|
||||
(void) new fileItem( this, cur_file, s );
|
||||
}
|
||||
}
|
||||
for( csize i = 0; i < files.size(); ++i )
|
||||
{
|
||||
QString cur_file = files[files.size()-i-1];
|
||||
#ifdef QT4
|
||||
if( cur_file[0] != '.' && QFileInfo(
|
||||
thisDir.absolutePath() + "/" +
|
||||
cur_file ).isDir() )
|
||||
#else
|
||||
if( cur_file[0] != '.' && QFileInfo(
|
||||
thisDir.absPath() + "/" +
|
||||
cur_file ).isDir() )
|
||||
#endif
|
||||
{
|
||||
(void) new directory( this, cur_file, s,
|
||||
m_filter );
|
||||
}
|
||||
}
|
||||
listView()->setUpdatesEnabled( TRUE );
|
||||
}
|
||||
Q3ListViewItem::setOpen( _o );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void directory::setup( void )
|
||||
{
|
||||
setExpandable( TRUE );
|
||||
Q3ListViewItem::setup();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QPixmap * fileItem::s_songFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_presetFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_sampleFilePixmap = NULL;
|
||||
QPixmap * fileItem::s_unknownFilePixmap = NULL;
|
||||
|
||||
|
||||
fileItem::fileItem( Q3ListView * _parent, const QString & _name,
|
||||
const QString & _path ) :
|
||||
Q3ListViewItem( _parent, _name ),
|
||||
m_path( _path )
|
||||
{
|
||||
determineFileType();
|
||||
initPixmapStuff();
|
||||
setDragEnabled( TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fileItem::fileItem( Q3ListViewItem * _parent, const QString & _name,
|
||||
const QString & _path ) :
|
||||
Q3ListViewItem( _parent, _name ),
|
||||
m_path( _path )
|
||||
{
|
||||
determineFileType();
|
||||
initPixmapStuff();
|
||||
setDragEnabled( TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileItem::initPixmapStuff( void )
|
||||
{
|
||||
if( s_songFilePixmap == NULL )
|
||||
{
|
||||
s_songFilePixmap = new QPixmap( embed::getIconPixmap(
|
||||
"project_file", 16, 16 ) );
|
||||
}
|
||||
if( s_presetFilePixmap == NULL )
|
||||
{
|
||||
s_presetFilePixmap = new QPixmap( embed::getIconPixmap(
|
||||
"preset_file", 16, 16 ) );
|
||||
}
|
||||
if( s_sampleFilePixmap == NULL )
|
||||
{
|
||||
s_sampleFilePixmap = new QPixmap( embed::getIconPixmap(
|
||||
"sound_file", 16, 16 ) );
|
||||
}
|
||||
if( s_unknownFilePixmap == NULL )
|
||||
{
|
||||
s_unknownFilePixmap = new QPixmap( embed::getIconPixmap(
|
||||
"unknown_file" ) );
|
||||
}
|
||||
|
||||
switch( m_type )
|
||||
{
|
||||
case SONG_FILE: m_pix = s_songFilePixmap; break;
|
||||
case PRESET_FILE: m_pix = s_presetFilePixmap; break;
|
||||
case SAMPLE_FILE: m_pix = s_sampleFilePixmap; break;
|
||||
case UNKNOWN: m_pix = s_unknownFilePixmap; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fileItem::determineFileType( void )
|
||||
{
|
||||
#ifdef QT4
|
||||
QString ext = QFileInfo( fullName() ).suffix().toLower();
|
||||
#else
|
||||
QString ext = QFileInfo( fullName() ).extension( FALSE ).toLower();
|
||||
#endif
|
||||
if( ext == "mmp" )
|
||||
{
|
||||
m_type = SONG_FILE;
|
||||
}
|
||||
else if( ext == "xml" )
|
||||
{
|
||||
multimediaProject::projectTypes t =
|
||||
multimediaProject::typeOfFile( fullName() );
|
||||
if( t == multimediaProject::SONG_PROJECT )
|
||||
{
|
||||
m_type = SONG_FILE;
|
||||
}
|
||||
else if( t == multimediaProject::CHANNEL_SETTINGS )
|
||||
{
|
||||
m_type = PRESET_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = UNKNOWN;
|
||||
}
|
||||
}
|
||||
else if( ext == "csf" )
|
||||
{
|
||||
m_type = PRESET_FILE;
|
||||
}
|
||||
else if( ext == "wav" || ext == "ogg" || ext == "mp3" ||
|
||||
ext == "aiff" || ext == "aif" || ext == "voc" ||
|
||||
ext == "au" || ext == "raw" )
|
||||
{
|
||||
m_type = SAMPLE_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "file_browser.moc"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
|
||||
instrument::instrument( channelTrack * _channel_track, const QString & _name ) :
|
||||
QWidget( _channel_track->pluginParent() ),
|
||||
QWidget( _channel_track->tabWidgetParent() ),
|
||||
plugin( _name, INSTRUMENT ),
|
||||
m_channelTrack( _channel_track ),
|
||||
m_valid( TRUE )
|
||||
|
||||
196
src/core/midi_tab_widget.cpp
Normal file
196
src/core/midi_tab_widget.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* midi_tab_widget.cpp - tab-widget in channel-track-window for setting up
|
||||
* MIDI-related stuff
|
||||
*
|
||||
* 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 <Qt/QtXml>
|
||||
|
||||
#else
|
||||
|
||||
#include <qdom.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include "midi_tab_widget.h"
|
||||
#include "channel_track.h"
|
||||
#include "midi_port.h"
|
||||
#include "tab_widget.h"
|
||||
#include "led_checkbox.h"
|
||||
#include "lcd_spinbox.h"
|
||||
#include "tooltip.h"
|
||||
#include "song_editor.h"
|
||||
|
||||
|
||||
|
||||
|
||||
midiTabWidget::midiTabWidget( channelTrack * _channel_track,
|
||||
midiPort * _port ) :
|
||||
QWidget( _channel_track->tabWidgetParent() ),
|
||||
settings(),
|
||||
m_channelTrack( _channel_track ),
|
||||
m_midiPort( _port )
|
||||
{
|
||||
m_setupTabWidget = new tabWidget( tr( "MIDI-SETUP FOR THIS CHANNEL" ),
|
||||
this );
|
||||
m_setupTabWidget->setGeometry( 4, 5, 238, 130 );
|
||||
|
||||
|
||||
m_inputChannelSpinBox = new lcdSpinBox( 0, MIDI_CHANNEL_COUNT, 3,
|
||||
m_setupTabWidget );
|
||||
m_inputChannelSpinBox->addTextForValue( 0, "---" );
|
||||
m_inputChannelSpinBox->setValue( m_midiPort->inputChannel() + 1 );
|
||||
m_inputChannelSpinBox->setLabel( tr( "CHANNEL" ) );
|
||||
m_inputChannelSpinBox->move( 190, 30 );
|
||||
connect( m_inputChannelSpinBox, SIGNAL( valueChanged( int ) ),
|
||||
this, SLOT( inputChannelChanged( int ) ) );
|
||||
|
||||
m_outputChannelSpinBox = new lcdSpinBox( 0, MIDI_CHANNEL_COUNT, 3,
|
||||
m_setupTabWidget );
|
||||
m_outputChannelSpinBox->addTextForValue( 0, "---" );
|
||||
m_outputChannelSpinBox->setValue( m_midiPort->outputChannel() + 1 );
|
||||
m_outputChannelSpinBox->setLabel( tr( "CHANNEL" ) );
|
||||
m_outputChannelSpinBox->move( 190, 60 );
|
||||
connect( m_outputChannelSpinBox, SIGNAL( valueChanged( int ) ),
|
||||
this, SLOT( outputChannelChanged( int ) ) );
|
||||
|
||||
|
||||
m_receiveCheckBox = new ledCheckBox( tr( "RECEIVE MIDI-EVENTS" ),
|
||||
m_setupTabWidget );
|
||||
m_receiveCheckBox->move( 10, 34 );
|
||||
connect( m_receiveCheckBox, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( midiPortModeToggled( bool ) ) );
|
||||
connect( m_receiveCheckBox, SIGNAL( toggled( bool ) ),
|
||||
m_inputChannelSpinBox, SLOT( setEnabled( bool ) ) );
|
||||
|
||||
|
||||
m_sendCheckBox = new ledCheckBox( tr( "SEND MIDI-EVENTS" ),
|
||||
m_setupTabWidget );
|
||||
m_sendCheckBox->move( 10, 64 );
|
||||
connect( m_sendCheckBox, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( midiPortModeToggled( bool ) ) );
|
||||
connect( m_sendCheckBox, SIGNAL( toggled( bool ) ),
|
||||
m_outputChannelSpinBox, SLOT( setEnabled( bool ) ) );
|
||||
|
||||
|
||||
m_routeCheckBox = new ledCheckBox( tr( "SEND RECEIVED MIDI-EVENTS" ),
|
||||
m_setupTabWidget );
|
||||
m_routeCheckBox->setChecked(
|
||||
m_channelTrack->midiEventRoutingEnabled() );
|
||||
m_routeCheckBox->move( 10, 100 );
|
||||
connect( m_sendCheckBox, SIGNAL( toggled( bool ) ),
|
||||
m_channelTrack, SLOT( toggleMidiEventRouting( bool ) ) );
|
||||
|
||||
midiPort::modes m = m_midiPort->mode();
|
||||
m_receiveCheckBox->setChecked( m == midiPort::INPUT ||
|
||||
m == midiPort::DUPLEX );
|
||||
m_sendCheckBox->setChecked( m == midiPort::OUTPUT ||
|
||||
m == midiPort::DUPLEX );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
midiTabWidget::~midiTabWidget()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::saveSettings( QDomDocument & _doc, QDomElement & _parent )
|
||||
{
|
||||
QDomElement mw_de = _doc.createElement( nodeName() );
|
||||
mw_de.setAttribute( "inputchannel", QString::number(
|
||||
m_inputChannelSpinBox->value() ) );
|
||||
mw_de.setAttribute( "outputchannel", QString::number(
|
||||
m_outputChannelSpinBox->value() ) );
|
||||
mw_de.setAttribute( "receive", QString::number(
|
||||
m_receiveCheckBox->isChecked() ) );
|
||||
mw_de.setAttribute( "send", QString::number(
|
||||
m_sendCheckBox->isChecked() ) );
|
||||
mw_de.setAttribute( "route", QString::number(
|
||||
m_routeCheckBox->isChecked() ) );
|
||||
|
||||
_parent.appendChild( mw_de );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_inputChannelSpinBox->setValue( _this.attribute( "inputchannel"
|
||||
).toInt() );
|
||||
m_outputChannelSpinBox->setValue( _this.attribute( "outputchannel"
|
||||
).toInt() );
|
||||
m_receiveCheckBox->setChecked( _this.attribute( "receive" ).toInt() );
|
||||
m_sendCheckBox->setChecked( _this.attribute( "send" ).toInt() );
|
||||
m_routeCheckBox->setChecked( _this.attribute( "route" ).toInt() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::inputChannelChanged( int _new_chnl )
|
||||
{
|
||||
m_midiPort->setInputChannel( _new_chnl - 1 );
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::outputChannelChanged( int _new_chnl )
|
||||
{
|
||||
m_midiPort->setOutputChannel( _new_chnl - 1 );
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiTabWidget::midiPortModeToggled( bool )
|
||||
{
|
||||
// this small lookup-table makes everything easier
|
||||
static const midiPort::modes modeTable[2][2] =
|
||||
{
|
||||
{ midiPort::DUMMY, midiPort::OUTPUT },
|
||||
{ midiPort::INPUT, midiPort::DUPLEX }
|
||||
} ;
|
||||
m_midiPort->setMode( modeTable[m_receiveCheckBox->isChecked()]
|
||||
[m_sendCheckBox->isChecked()] );
|
||||
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#include "midi_tab_widget.moc"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "config_mgr.h"
|
||||
|
||||
#include "audio_device.h"
|
||||
#include "midi_device.h"
|
||||
#include "midi_client.h"
|
||||
|
||||
// platform-specific audio-interface-classes
|
||||
#include "audio_alsa.h"
|
||||
@@ -100,7 +100,7 @@ mixer::mixer() :
|
||||
|
||||
|
||||
m_audioDev = tryAudioDevices();
|
||||
m_midiDev = tryMIDIDevices();
|
||||
m_midiClient = tryMIDIClients();
|
||||
|
||||
|
||||
for( int i = 0; i < MAX_SAMPLE_PACKETS; ++i )
|
||||
@@ -303,7 +303,7 @@ void mixer::run( void )
|
||||
// all remaining notes etc. would be played until their end
|
||||
void mixer::clear( void )
|
||||
{
|
||||
m_midiDev->noteOffAll();
|
||||
// TODO: m_midiClient->noteOffAll();
|
||||
for( playHandleVector::iterator it = m_playHandles.begin();
|
||||
it != m_playHandles.end(); ++it )
|
||||
{
|
||||
@@ -639,17 +639,18 @@ audioDevice * mixer::tryAudioDevices( void )
|
||||
|
||||
|
||||
|
||||
midiDevice * mixer::tryMIDIDevices( void )
|
||||
midiClient * mixer::tryMIDIClients( void )
|
||||
{
|
||||
QString dev_name = configManager::inst()->value( "mixer", "mididev" );
|
||||
QString client_name = configManager::inst()->value( "mixer",
|
||||
"midiclient" );
|
||||
|
||||
#ifdef ALSA_SUPPORT
|
||||
if( dev_name == midiALSARaw::name() || dev_name == "" )
|
||||
if( client_name == midiALSARaw::name() || client_name == "" )
|
||||
{
|
||||
midiALSARaw * malsa = new midiALSARaw();
|
||||
if( malsa->isRunning() )
|
||||
{
|
||||
m_midiDevName = midiALSARaw::name();
|
||||
m_midiClientName = midiALSARaw::name();
|
||||
return( malsa );
|
||||
}
|
||||
delete malsa;
|
||||
@@ -657,22 +658,22 @@ midiDevice * mixer::tryMIDIDevices( void )
|
||||
#endif
|
||||
|
||||
#ifdef OSS_SUPPORT
|
||||
if( dev_name == midiOSS::name() || dev_name == "" )
|
||||
if( client_name == midiOSS::name() || client_name == "" )
|
||||
{
|
||||
midiOSS * moss = new midiOSS();
|
||||
if( moss->isRunning() )
|
||||
{
|
||||
m_midiDevName = midiOSS::name();
|
||||
m_midiClientName = midiOSS::name();
|
||||
return( moss );
|
||||
}
|
||||
delete moss;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf( "Couldn't open a MIDI-device, neither with ALSA nor with "
|
||||
"OSS. Will use dummy-MIDI-device.\n" );
|
||||
printf( "Couldn't create MIDI-client, neither with ALSA nor with "
|
||||
"OSS. Will use dummy-MIDI-client.\n" );
|
||||
|
||||
m_midiDevName = midiDummy::name();
|
||||
m_midiClientName = midiDummy::name();
|
||||
|
||||
return( new midiDummy() );
|
||||
}
|
||||
|
||||
@@ -46,17 +46,25 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __USE_XOPEN
|
||||
#define __USE_XOPEN
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#include "piano_roll.h"
|
||||
#include "song_editor.h"
|
||||
#include "pattern.h"
|
||||
#include "embed.h"
|
||||
#include "crystal_button.h"
|
||||
#include "pixmap_button.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "templates.h"
|
||||
#include "gui_templates.h"
|
||||
#include "timeline.h"
|
||||
#include "channel_track.h"
|
||||
#include "tooltip.h"
|
||||
#include "midi.h"
|
||||
|
||||
|
||||
extern tones whiteKeys[]; // defined in piano_widget.cpp
|
||||
@@ -518,10 +526,10 @@ void pianoRoll::setCurrentPattern( pattern * _new_pattern )
|
||||
// remove all connections to other channel-tracks
|
||||
disconnect( this, SLOT( recordNote( const note & ) ) );
|
||||
|
||||
// and now connect to noetFromMidiDeviceDone of channel so that
|
||||
// we receive note-off-events from midi-keyboard for recording it
|
||||
// and now connect to noteDone()-signal of channel so that
|
||||
// we receive note-off-events from it's midi-port for recording it
|
||||
connect( m_pattern->getChannelTrack(),
|
||||
SIGNAL( noteFromMidiDeviceDone( const note & ) ),
|
||||
SIGNAL( noteDone( const note & ) ),
|
||||
this, SLOT( recordNote( const note & ) ) );
|
||||
|
||||
setWindowTitle( tr( "Piano-Roll - %1" ).arg( m_pattern->name() ) );
|
||||
@@ -1260,7 +1268,8 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
|
||||
songEditor::inst()->playing() == FALSE )
|
||||
{
|
||||
m_pattern->getChannelTrack()->processInEvent(
|
||||
midiEvent( NOTE_ON, 0, key_num, vol ) );
|
||||
midiEvent( NOTE_ON, 0, key_num, vol ),
|
||||
midiTime() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1276,12 +1285,13 @@ void pianoRoll::mouseReleaseEvent( QMouseEvent * _me )
|
||||
{
|
||||
m_pattern->getChannelTrack()->processInEvent(
|
||||
midiEvent( NOTE_OFF, 0,
|
||||
m_currentNote->key() ) );
|
||||
m_currentNote->key() ), midiTime() );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pattern->getChannelTrack()->processInEvent(
|
||||
midiEvent( NOTE_OFF, 0, getKey( _me->y() ) ) );
|
||||
midiEvent( NOTE_OFF, 0, getKey( _me->y() ) ),
|
||||
midiTime() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1325,7 +1335,8 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
edit_note == FALSE )
|
||||
{
|
||||
m_pattern->getChannelTrack()->processInEvent(
|
||||
midiEvent( NOTE_OFF, 0, released_key ) );
|
||||
midiEvent( NOTE_OFF, 0, released_key ),
|
||||
midiTime() );
|
||||
if(
|
||||
#ifdef QT4
|
||||
_me->buttons() &
|
||||
@@ -1340,7 +1351,8 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
m_pattern->getChannelTrack()->processInEvent(
|
||||
midiEvent( NOTE_ON, 0, key_num,
|
||||
DEFAULT_VOLUME ) );
|
||||
DEFAULT_VOLUME ),
|
||||
midiTime() );
|
||||
}
|
||||
}
|
||||
if( _me->x() <= WHITE_KEY_WIDTH )
|
||||
@@ -1361,12 +1373,10 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
|
||||
MIN_VOLUME,
|
||||
MAX_VOLUME );
|
||||
m_currentNote->setVolume( vol );
|
||||
if( m_pattern->getChannelTrack()->keyPressed(
|
||||
m_currentNote->key() ) == TRUE )
|
||||
{
|
||||
m_pattern->getChannelTrack()->noteForKey( m_currentNote->key()
|
||||
)->setVolume( vol );
|
||||
}
|
||||
m_pattern->getChannelTrack()->processInEvent(
|
||||
midiEvent( KEY_PRESSURE, 0, key_num,
|
||||
vol ),
|
||||
midiTime() );
|
||||
}
|
||||
}
|
||||
else if( m_currentNote != NULL &&
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
|
||||
#include "piano_widget.h"
|
||||
#include "channel_track.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "midi.h"
|
||||
#include "templates.h"
|
||||
#include "embed.h"
|
||||
|
||||
|
||||
@@ -106,6 +107,11 @@ pianoWidget::pianoWidget (channelTrack * _parent ) :
|
||||
"black_key_pressed" ) );
|
||||
}
|
||||
|
||||
for( int i = 0; i < NOTES_PER_OCTAVE * OCTAVES; ++i )
|
||||
{
|
||||
m_pressedKeys[i] = FALSE;
|
||||
}
|
||||
|
||||
#ifdef QT4
|
||||
m_pianoScroll = new QScrollBar( Qt::Horizontal, this );
|
||||
m_pianoScroll->setRange( 0, WHITE_KEYS_PER_OCTAVE * ( OCTAVES - 3 ) -
|
||||
@@ -231,7 +237,9 @@ void pianoWidget::mousePressEvent( QMouseEvent * _me )
|
||||
}
|
||||
// set note on
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( NOTE_ON, 0, key_num, vol ) );
|
||||
midiEvent( NOTE_ON, 0, key_num, vol ),
|
||||
midiTime() );
|
||||
m_pressedKeys[key_num] = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -255,7 +263,8 @@ void pianoWidget::mouseReleaseEvent( QMouseEvent * _me )
|
||||
int released_key = getKeyFromMouse( _me->pos() );
|
||||
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent ( NOTE_OFF, 0, released_key ) );
|
||||
midiEvent( NOTE_OFF, 0, released_key, 0 ), midiTime() );
|
||||
m_pressedKeys[released_key] = FALSE;
|
||||
|
||||
// and let the user see that he released a key... :)
|
||||
update();
|
||||
@@ -294,7 +303,9 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me )
|
||||
if( key_num != released_key )
|
||||
{
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( NOTE_OFF, 0, released_key ) );
|
||||
midiEvent( NOTE_OFF, 0, released_key, 0 ),
|
||||
midiTime() );
|
||||
m_pressedKeys[released_key] = FALSE;
|
||||
#ifdef QT4
|
||||
if( _me->buttons() & Qt::LeftButton )
|
||||
#else
|
||||
@@ -304,7 +315,9 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me )
|
||||
if( _me->pos().y() > PIANO_BASE )
|
||||
{
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( NOTE_ON, 0, key_num, vol ) );
|
||||
midiEvent( NOTE_ON, 0, key_num, vol ),
|
||||
midiTime() );
|
||||
m_pressedKeys[key_num] = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -317,9 +330,11 @@ void pianoWidget::mouseMoveEvent( QMouseEvent * _me )
|
||||
// and let the user see that he pressed a key... :)
|
||||
update();
|
||||
}
|
||||
else if( m_channelTrack->keyPressed( key_num ) == TRUE )
|
||||
else if( m_pressedKeys[key_num] == TRUE )
|
||||
{
|
||||
m_channelTrack->noteForKey( key_num )->setVolume( vol );
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( KEY_PRESSURE, 0, key_num, vol ),
|
||||
midiTime() );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -376,7 +391,9 @@ void pianoWidget::keyPressEvent( QKeyEvent * _ke )
|
||||
if( _ke->isAutoRepeat() == FALSE && key_num > -1 )
|
||||
{
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( NOTE_ON, 0, key_num, DEFAULT_VOLUME ) );
|
||||
midiEvent( NOTE_ON, 0, key_num, DEFAULT_VOLUME ),
|
||||
midiTime() );
|
||||
m_pressedKeys[key_num] = TRUE;
|
||||
update();
|
||||
}
|
||||
else
|
||||
@@ -395,7 +412,9 @@ void pianoWidget::keyReleaseEvent( QKeyEvent * _ke )
|
||||
if( _ke->isAutoRepeat() == FALSE && key_num > -1 )
|
||||
{
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( NOTE_OFF, 0, key_num ) );
|
||||
midiEvent( NOTE_OFF, 0, key_num, 0 ),
|
||||
midiTime() );
|
||||
m_pressedKeys[key_num] = FALSE;
|
||||
update();
|
||||
}
|
||||
else
|
||||
@@ -407,25 +426,19 @@ void pianoWidget::keyReleaseEvent( QKeyEvent * _ke )
|
||||
|
||||
|
||||
|
||||
void pianoWidget::focusInEvent( QFocusEvent * )
|
||||
{
|
||||
mixer::inst()->getMIDIDevice()->setChannelTrack( m_channelTrack );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void pianoWidget::focusOutEvent( QFocusEvent * )
|
||||
{
|
||||
// if we loose focus, we HAVE to note off all "running" notes because
|
||||
// if we loose focus, we HAVE to note off all running notes because
|
||||
// we don't receive key-release-events anymore and so the notes would
|
||||
// hang otherwise
|
||||
for( int i = 0; i < NOTES_PER_OCTAVE * OCTAVES; ++i )
|
||||
{
|
||||
if( m_channelTrack->keyPressed( i ) )
|
||||
if( m_pressedKeys[i] == TRUE )
|
||||
{
|
||||
m_channelTrack->processInEvent(
|
||||
midiEvent( NOTE_OFF, 0, i ) );
|
||||
midiEvent( NOTE_OFF, 0, i, 0 ),
|
||||
midiTime() );
|
||||
m_pressedKeys[i] = FALSE;
|
||||
}
|
||||
}
|
||||
update();
|
||||
@@ -531,7 +544,7 @@ void pianoWidget::paintEvent( QPaintEvent * )
|
||||
|
||||
// draw pressed or not pressed key, depending on state of
|
||||
// current key
|
||||
if( m_channelTrack->keyPressed( cur_key ) == TRUE )
|
||||
if( m_pressedKeys[cur_key] == TRUE )
|
||||
{
|
||||
p.drawPixmap( x, PIANO_BASE, *s_whiteKeyPressedPm );
|
||||
}
|
||||
@@ -562,7 +575,7 @@ void pianoWidget::paintEvent( QPaintEvent * )
|
||||
if( s_key > 0 &&
|
||||
KEY_ORDER[(tones)( --s_key ) % NOTES_PER_OCTAVE] == BLACK_KEY )
|
||||
{
|
||||
if( m_channelTrack->keyPressed( s_key ) == TRUE )
|
||||
if( m_pressedKeys[s_key] == TRUE )
|
||||
{
|
||||
p.drawPixmap( 0 - WHITE_KEY_WIDTH / 2, PIANO_BASE,
|
||||
*s_blackKeyPressedPm );
|
||||
@@ -581,7 +594,7 @@ void pianoWidget::paintEvent( QPaintEvent * )
|
||||
{
|
||||
// draw pressed or not pressed key, depending on
|
||||
// state of current key
|
||||
if( m_channelTrack->keyPressed( cur_key ) == TRUE )
|
||||
if( m_pressedKeys[cur_key] == TRUE )
|
||||
{
|
||||
p.drawPixmap( x + WHITE_KEY_WIDTH / 2,
|
||||
PIANO_BASE,
|
||||
|
||||
@@ -156,7 +156,7 @@ void pluginDescWidget::paintEvent( QPaintEvent * )
|
||||
f.setBold( FALSE );
|
||||
p.setFont( pointSize<7>( f ) );
|
||||
QStringList words = QStringList::split( ' ',
|
||||
plugin::tr( m_pluginDescriptor.description ) );
|
||||
pluginBrowser::tr( m_pluginDescriptor.description ) );
|
||||
for( QStringList::iterator it = words.begin(); it != words.end(); ++it )
|
||||
{
|
||||
if( ( *it ).contains( '-' ) )
|
||||
|
||||
@@ -328,11 +328,11 @@ setupDialog::setupDialog( configTabs _tab_to_open ) :
|
||||
|
||||
#ifdef QT4
|
||||
m_midiInterfaces->setCurrentIndex( m_midiInterfaces->findText(
|
||||
mixer::inst()->midiDevName() ) );
|
||||
mixer::inst()->midiClientName() ) );
|
||||
#else
|
||||
m_midiInterfaces->setCurrentText( mixer::inst()->midiDevName() );
|
||||
m_midiInterfaces->setCurrentText( mixer::inst()->midiClientName() );
|
||||
#endif
|
||||
m_midiIfaceSetupWidgets[mixer::inst()->midiDevName()]->show();
|
||||
m_midiIfaceSetupWidgets[mixer::inst()->midiClientName()]->show();
|
||||
|
||||
connect( m_midiInterfaces, SIGNAL( activated( const QString & ) ),
|
||||
this, SLOT( midiInterfaceChanged( const QString & ) ) );
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
#include "bb_track.h"
|
||||
#include "channel_track.h"
|
||||
#include "mmp.h"
|
||||
#include "midi_device.h"
|
||||
#include "midi_client.h"
|
||||
#include "timeline.h"
|
||||
#include "pattern.h"
|
||||
#include "piano_roll.h"
|
||||
|
||||
@@ -416,7 +416,8 @@ void trackContainer::updateScrollArea( void )
|
||||
|
||||
|
||||
trackContainer::scrollArea::scrollArea( trackContainer * _parent ) :
|
||||
QScrollArea( _parent )
|
||||
QScrollArea( _parent ),
|
||||
m_trackContainer( _parent )
|
||||
{
|
||||
setFrameStyle( QFrame::NoFrame );
|
||||
setHorizontalScrollBarPolicy(
|
||||
@@ -444,7 +445,7 @@ void trackContainer::scrollArea::wheelEvent( QWheelEvent * _we )
|
||||
// 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 );
|
||||
m_trackContainer->wheelEvent( _we );
|
||||
if( !_we->isAccepted() )
|
||||
{
|
||||
QScrollArea::wheelEvent( _we );
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* midi_alsa_raw.cpp - midi-device-driver for RawMIDI via ALSA
|
||||
* midi_alsa_raw.cpp - midi-client for RawMIDI via ALSA
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
@@ -46,8 +46,8 @@
|
||||
#ifdef ALSA_SUPPORT
|
||||
|
||||
|
||||
midiALSARaw::midiALSARaw( channelTrack * _ct ) :
|
||||
midiDevice( _ct ),
|
||||
midiALSARaw::midiALSARaw( void ) :
|
||||
midiRawClient(),
|
||||
QThread(),
|
||||
m_inputp( &m_input ),
|
||||
m_outputp( &m_output ),
|
||||
@@ -184,14 +184,12 @@ void midiALSARaw::run( void )
|
||||
break;
|
||||
}
|
||||
if( err == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
for( int i = 0; i < err; ++i )
|
||||
{
|
||||
const midiEvent * midi_event = parseData( buf[i] );
|
||||
if( midi_event != NULL )
|
||||
{
|
||||
processInEvent( *midi_event );
|
||||
}
|
||||
parseData( buf[i] );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +199,7 @@ void midiALSARaw::run( void )
|
||||
|
||||
|
||||
midiALSARaw::setupWidget::setupWidget( QWidget * _parent ) :
|
||||
midiDevice::setupWidget( midiALSARaw::name(), _parent )
|
||||
midiRawClient::setupWidget( midiALSARaw::name(), _parent )
|
||||
{
|
||||
m_device = new QLineEdit( midiALSARaw::probeDevice(), this );
|
||||
m_device->setGeometry( 10, 20, 160, 20 );
|
||||
|
||||
339
src/midi/midi_client.cpp
Normal file
339
src/midi/midi_client.cpp
Normal file
@@ -0,0 +1,339 @@
|
||||
/*
|
||||
* midi_client.cpp - base-class for MIDI-clients like ALSA-sequencer-client
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (_c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
* This file partly contains code from Fluidsynth, Peter Hanappe
|
||||
*
|
||||
* 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"
|
||||
#ifndef QT4
|
||||
#include <qmap.h>
|
||||
#endif
|
||||
|
||||
#include "midi_client.h"
|
||||
/*#include "midi_mapper.h"*/
|
||||
#include "templates.h"
|
||||
#include "midi_port.h"
|
||||
|
||||
|
||||
#include "midi_alsa_raw.h"
|
||||
#include "midi_oss.h"
|
||||
#include "midi_dummy.h"
|
||||
|
||||
|
||||
|
||||
midiClient::midiClient( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
midiClient::~midiClient()
|
||||
{
|
||||
//TODO: noteOffAll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiClient::removePort( midiPort * _port )
|
||||
{
|
||||
vvector<midiPort *>::iterator it = qFind( m_midiPorts.begin(),
|
||||
m_midiPorts.end(),
|
||||
_port );
|
||||
if( it != m_midiPorts.end() )
|
||||
{
|
||||
m_midiPorts.erase( it );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
midiRawClient::midiRawClient() :
|
||||
midiClient()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
midiRawClient::~midiRawClient()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
midiPort * FASTCALL midiRawClient::createPort( midiEventProcessor * _mep,
|
||||
const QString & _desired_name )
|
||||
{
|
||||
midiPort * mp = new midiPort( this, _mep, _desired_name );
|
||||
addPort( mp );
|
||||
return( mp );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// raw-MIDI-clients to not have real ports, therefore the name doesn't matter
|
||||
// and we can dummy-implement validation-method
|
||||
void midiRawClient::validatePortName( midiPort * )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiRawClient::parseData( const Uint8 _c )
|
||||
{
|
||||
/*********************************************************************/
|
||||
/* 'Process' system real-time messages */
|
||||
/*********************************************************************/
|
||||
/* There are not too many real-time messages that are of interest here.
|
||||
* They can occur anywhere, even in the middle of a noteon message!
|
||||
* Real-time range: 0xF8 .. 0xFF
|
||||
* Note: Real-time does not affect (running) status.
|
||||
*/
|
||||
if( _c >= 0xF8 )
|
||||
{
|
||||
if( _c == MIDI_SYSTEM_RESET )
|
||||
{
|
||||
m_midiParseData.m_midiEvent.m_type = MIDI_SYSTEM_RESET;
|
||||
m_midiParseData.m_status = 0;
|
||||
processParsedEvent();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* 'Process' system common messages (again, just skip them) */
|
||||
/*********************************************************************/
|
||||
/* There are no system common messages that are of interest here.
|
||||
* System common range: 0xF0 .. 0xF7
|
||||
*/
|
||||
if( _c > 0xF0 )
|
||||
{
|
||||
/* MIDI spec say: To ignore a non-real-time message, just discard all
|
||||
* data up to the next status byte. And our parser will ignore data
|
||||
* that is received without a valid status.
|
||||
* Note: system common cancels running status. */
|
||||
m_midiParseData.m_status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* Process voice category messages: */
|
||||
/*********************************************************************/
|
||||
/* Now that we have handled realtime and system common messages, only
|
||||
* voice messages are left.
|
||||
* Only a status byte has bit # 7 set.
|
||||
* So no matter the status of the parser (in case we have lost sync),
|
||||
* as soon as a byte >= 0x80 comes in, we are dealing with a status byte
|
||||
* and start a new event.
|
||||
*/
|
||||
if( _c & 0x80 )
|
||||
{
|
||||
m_midiParseData.m_channel = _c & 0x0F;
|
||||
m_midiParseData.m_status = _c & 0xF0;
|
||||
/* The event consumes x bytes of data...
|
||||
(subtract 1 for the status byte) */
|
||||
m_midiParseData.m_bytesTotal = eventLength(
|
||||
m_midiParseData.m_status ) - 1;
|
||||
/* of which we have read 0 at this time. */
|
||||
m_midiParseData.m_bytes = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* Process data */
|
||||
/*********************************************************************/
|
||||
/* If we made it this far, then the received char belongs to the data
|
||||
* of the last event. */
|
||||
if( m_midiParseData.m_status == 0 )
|
||||
{
|
||||
/* We are not interested in the event currently received.
|
||||
Discard the data. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store the first couple of bytes */
|
||||
if( m_midiParseData.m_bytes < RAW_MIDI_PARSE_BUF_SIZE )
|
||||
{
|
||||
m_midiParseData.m_buffer[m_midiParseData.m_bytes] = _c;
|
||||
}
|
||||
++m_midiParseData.m_bytes;
|
||||
|
||||
/* Do we still need more data to get this event complete? */
|
||||
if( m_midiParseData.m_bytes < m_midiParseData.m_bytesTotal )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
/* Send the event */
|
||||
/*********************************************************************/
|
||||
/* The event is ready-to-go. About 'running status':
|
||||
*
|
||||
* The MIDI protocol has a built-in compression mechanism. If several
|
||||
* similar events are sent in-a-row, for example note-ons, then the
|
||||
* event type is only sent once. For this case, the last event type
|
||||
* (status) is remembered.
|
||||
* We simply keep the status as it is, just reset the parameter counter.
|
||||
* If another status byte comes in, it will overwrite the status.
|
||||
*/
|
||||
m_midiParseData.m_midiEvent.m_type = static_cast<midiEventTypes>(
|
||||
m_midiParseData.m_status );
|
||||
m_midiParseData.m_midiEvent.m_channel = m_midiParseData.m_channel;
|
||||
m_midiParseData.m_bytes = 0; /* Related to running status! */
|
||||
switch( m_midiParseData.m_midiEvent.m_type )
|
||||
{
|
||||
case NOTE_OFF:
|
||||
case NOTE_ON:
|
||||
case KEY_PRESSURE:
|
||||
case CONTROL_CHANGE:
|
||||
case PROGRAM_CHANGE:
|
||||
case CHANNEL_PRESSURE:
|
||||
m_midiParseData.m_midiEvent.m_data.m_param[0] =
|
||||
m_midiParseData.m_buffer[0] - NOTES_PER_OCTAVE;
|
||||
m_midiParseData.m_midiEvent.m_data.m_param[1] =
|
||||
m_midiParseData.m_buffer[1];
|
||||
break;
|
||||
|
||||
case PITCH_BEND:
|
||||
// Pitch-bend is transmitted with 14-bit precision.
|
||||
// Note: '|' does here the same as '+' (no common bits),
|
||||
// but might be faster
|
||||
m_midiParseData.m_midiEvent.m_data.m_param[0] =
|
||||
( ( m_midiParseData.m_buffer[1] * 128 ) |
|
||||
m_midiParseData.m_buffer[0] );
|
||||
break;
|
||||
|
||||
default:
|
||||
// Unlikely
|
||||
return;
|
||||
}
|
||||
|
||||
processParsedEvent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiRawClient::processParsedEvent()
|
||||
{
|
||||
for( csize i = 0; i < m_midiPorts.size(); ++i )
|
||||
{
|
||||
m_midiPorts[i]->processInEvent( m_midiParseData.m_midiEvent,
|
||||
midiTime() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiRawClient::processOutEvent( const midiEvent & _me,
|
||||
const midiTime & ,
|
||||
const midiPort * _port )
|
||||
{
|
||||
// TODO: also evaluate _time and queue event if neccessary
|
||||
switch( _me.m_type )
|
||||
{
|
||||
case NOTE_ON:
|
||||
case NOTE_OFF:
|
||||
if( _port->outputChannel() >= 0 )
|
||||
{
|
||||
sendByte( _me.m_type | _port->outputChannel() );
|
||||
sendByte( _me.m_data.m_param[0] +
|
||||
NOTES_PER_OCTAVE );
|
||||
sendByte( tLimit( (int) _me.m_data.m_param[1],
|
||||
0, 127 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
for( Sint8 i = 0; i < MIDI_CHANNEL_COUNT; ++i )
|
||||
{
|
||||
sendByte( _me.m_type | i );
|
||||
sendByte( _me.m_data.m_param[0] +
|
||||
NOTES_PER_OCTAVE );
|
||||
sendByte( tLimit( (int)
|
||||
_me.m_data.m_param[1],
|
||||
0, 127 ) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Taken from Nagano Daisuke's USB-MIDI driver
|
||||
const Uint8 REMAINS_F0F6[] =
|
||||
{
|
||||
0, /* 0xF0 */
|
||||
2, /* 0XF1 */
|
||||
3, /* 0XF2 */
|
||||
2, /* 0XF3 */
|
||||
2, /* 0XF4 (Undefined by MIDI Spec, and subject to change) */
|
||||
2, /* 0XF5 (Undefined by MIDI Spec, and subject to change) */
|
||||
1 /* 0XF6 */
|
||||
} ;
|
||||
|
||||
const Uint8 REMAINS_80E0[] =
|
||||
{
|
||||
3, /* 0x8X Note Off */
|
||||
3, /* 0x9X Note On */
|
||||
3, /* 0xAX Poly-key pressure */
|
||||
3, /* 0xBX Control Change */
|
||||
2, /* 0xCX Program Change */
|
||||
2, /* 0xDX Channel pressure */
|
||||
3 /* 0xEX PitchBend Change */
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
// Returns the length of the MIDI message starting with _event.
|
||||
// Taken from Nagano Daisuke's USB-MIDI driver
|
||||
Uint8 midiRawClient::eventLength( const Uint8 _event )
|
||||
{
|
||||
if ( _event < 0xF0 )
|
||||
{
|
||||
return( REMAINS_80E0[( ( _event - 0x80 ) >>4 ) & 0x0F] );
|
||||
}
|
||||
else if ( _event < 0xF7 )
|
||||
{
|
||||
return( REMAINS_F0F6[_event - 0xF0] );
|
||||
}
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* midi_oss.cpp - simple midi-device-driver for OSS
|
||||
* midi_oss.cpp - OSS-raw-midi-client
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
@@ -52,8 +52,8 @@
|
||||
|
||||
|
||||
|
||||
midiOSS::midiOSS( channelTrack * _ct ) :
|
||||
midiDevice( _ct ),
|
||||
midiOSS::midiOSS( void ) :
|
||||
midiRawClient(),
|
||||
QThread(),
|
||||
m_midiDev( probeDevice() ),
|
||||
m_quit( FALSE )
|
||||
@@ -108,7 +108,7 @@ QString midiOSS::probeDevice( void )
|
||||
|
||||
|
||||
|
||||
void midiOSS::sendByte( Uint8 _c )
|
||||
void midiOSS::sendByte( const Uint8 _c )
|
||||
{
|
||||
#ifdef QT4
|
||||
m_midiDev.putChar( _c );
|
||||
@@ -130,14 +130,10 @@ void midiOSS::run( void )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const midiEvent * midi_event = parseData( c );
|
||||
parseData( c );
|
||||
#else
|
||||
const midiEvent * midi_event = parseData( m_midiDev.getch() );
|
||||
parseData( m_midiDev.getch() );
|
||||
#endif
|
||||
if( midi_event != NULL )
|
||||
{
|
||||
processInEvent( *midi_event );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +142,7 @@ void midiOSS::run( void )
|
||||
|
||||
|
||||
midiOSS::setupWidget::setupWidget( QWidget * _parent ) :
|
||||
midiDevice::setupWidget( midiOSS::name(), _parent )
|
||||
midiRawClient::setupWidget( midiOSS::name(), _parent )
|
||||
{
|
||||
m_device = new QLineEdit( midiOSS::probeDevice(), this );
|
||||
m_device->setGeometry( 10, 20, 160, 20 );
|
||||
|
||||
85
src/midi/midi_port.cpp
Normal file
85
src/midi/midi_port.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* midi_port.cpp - abstraction of MIDI-ports which are part of LMMS's MIDI-
|
||||
* sequencing system
|
||||
*
|
||||
* Linux MultiMedia Studio
|
||||
* Copyright (_c) 2004-2005 Tobias Doerffel <tobydox@users.sourceforge.net>
|
||||
* This file partly contains code from Fluidsynth, Peter Hanappe
|
||||
*
|
||||
* 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 "midi_port.h"
|
||||
#include "midi_client.h"
|
||||
|
||||
|
||||
|
||||
midiPort::midiPort( midiClient * _mc, midiEventProcessor * _mep,
|
||||
const QString & _name, modes _mode ) :
|
||||
m_midiClient( _mc ),
|
||||
m_midiEventProcessor( _mep ),
|
||||
m_name( _name ),
|
||||
m_mode( _mode ),
|
||||
m_inputChannel( -1 ),
|
||||
m_outputChannel( -1 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
midiPort::~midiPort()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiPort::trySetName( const QString & _name )
|
||||
{
|
||||
setName( _name );
|
||||
m_midiClient->validatePortName( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiPort::processInEvent( const midiEvent & _me, const midiTime & _time )
|
||||
{
|
||||
// mask event
|
||||
if( ( mode() == INPUT || mode() == DUPLEX ) &&
|
||||
( inputChannel() == _me.m_channel || inputChannel() == -1 ) )
|
||||
{
|
||||
m_midiEventProcessor->processInEvent( _me, _time );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void midiPort::processOutEvent( const midiEvent & _me, const midiTime & _time )
|
||||
{
|
||||
// mask event
|
||||
if( ( mode() == OUTPUT || mode() == DUPLEX ) &&
|
||||
( outputChannel() == _me.m_channel || outputChannel() == -1 ) )
|
||||
{
|
||||
m_midiClient->processOutEvent( _me, _time, this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <QStatusBar>
|
||||
#include <QFontMetrics>
|
||||
#include <QApplication>
|
||||
#include <QInputDialog>
|
||||
|
||||
#else
|
||||
|
||||
@@ -50,6 +51,7 @@
|
||||
#include <qstatusbar.h>
|
||||
#include <qfontmetrics.h>
|
||||
#include <qapplication.h>
|
||||
#include <qinputdialog.h>
|
||||
|
||||
#define addSeparator insertSeparator
|
||||
|
||||
@@ -62,7 +64,7 @@
|
||||
|
||||
#include "knob.h"
|
||||
#include "song_editor.h"
|
||||
#include "midi_device.h"
|
||||
/*#include "midi_client.h"*/
|
||||
#include "embed.h"
|
||||
#include "spc_bg_hndl_widget.h"
|
||||
#include "config_mgr.h"
|
||||
@@ -91,12 +93,9 @@ knob::knob( int _knob_num, QWidget * _parent, const QString & _name ) :
|
||||
, _name.ascii()
|
||||
#endif
|
||||
),
|
||||
m_scrollMode( ScrNone ),
|
||||
m_mouseOffset( 0.0f ),
|
||||
m_tracking( TRUE ),
|
||||
m_buttonPressed( FALSE ),
|
||||
m_angle( 0.0f ),
|
||||
m_oldAngle( 0.0f ),
|
||||
m_nTurns( 0.0f ),
|
||||
m_knobNum( _knob_num ),
|
||||
m_hintTextBeforeValue( "" ),
|
||||
m_hintTextAfterValue( "" ),
|
||||
@@ -116,23 +115,14 @@ knob::knob( int _knob_num, QWidget * _parent, const QString & _name ) :
|
||||
|
||||
#ifdef QT4
|
||||
setAccessibleName( _name );
|
||||
#endif
|
||||
setRange( 0.0, 100.0, 1.0 );
|
||||
|
||||
#ifdef QT4
|
||||
m_knobPixmap = new QPixmap( embed::getIconPixmap( QString( "knob0" +
|
||||
QString::number( m_knobNum + 1 ) ).toAscii().constData() ) );
|
||||
#else
|
||||
setBackgroundMode( Qt::NoBackground );
|
||||
m_knobPixmap = new QPixmap( embed::getIconPixmap( "knob0" +
|
||||
QString::number( m_knobNum + 1 ) ) );
|
||||
#endif
|
||||
#ifdef QT4
|
||||
// setAttribute( Qt::WA_NoBackground );
|
||||
#else
|
||||
setBackgroundMode( Qt::NoBackground );
|
||||
#endif
|
||||
|
||||
m_knobWidth = m_knobPixmap->width();
|
||||
setRange( 0.0f, 100.0f, 1.0f );
|
||||
|
||||
setFixedSize( m_knobPixmap->width(), m_knobPixmap->height() );
|
||||
setTotalAngle( 270.0f );
|
||||
@@ -146,12 +136,12 @@ knob::knob( int _knob_num, QWidget * _parent, const QString & _name ) :
|
||||
// Destructor
|
||||
knob::~knob()
|
||||
{
|
||||
// make sure pointer to this knob isn't used anymore in active
|
||||
/* // make sure pointer to this knob isn't used anymore in active
|
||||
// midi-device-class
|
||||
if( mixer::inst()->getMIDIDevice()->pitchBendKnob() == this )
|
||||
if( mixer::inst()->getMIDIClient()->pitchBendKnob() == this )
|
||||
{
|
||||
mixer::inst()->getMIDIDevice()->setPitchBendKnob( NULL );
|
||||
}
|
||||
mixer::inst()->getMIDIClient()->setPitchBendKnob( NULL );
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
@@ -251,10 +241,7 @@ void knob::valueChange( void )
|
||||
{
|
||||
recalcAngle();
|
||||
update();
|
||||
if( m_tracking )
|
||||
{
|
||||
emit valueChanged( value() );
|
||||
}
|
||||
emit valueChanged( value() );
|
||||
}
|
||||
|
||||
|
||||
@@ -273,8 +260,7 @@ float knob::getValue( const QPoint & _p )
|
||||
const float arc = atan2( -dx, dy ) * 180.0 / M_PI;
|
||||
|
||||
float new_value = 0.5 * ( m_minValue + m_maxValue ) +
|
||||
( arc + m_nTurns * 360.0 ) *
|
||||
( m_maxValue - m_minValue ) /
|
||||
arc * ( m_maxValue - m_minValue ) /
|
||||
m_totalAngle;
|
||||
|
||||
const float oneTurn = tAbs<float>( m_maxValue - m_minValue ) *
|
||||
@@ -294,17 +280,7 @@ float knob::getValue( const QPoint & _p )
|
||||
}
|
||||
return( new_value );
|
||||
}
|
||||
|
||||
return( ( _p.y() - m_origMousePos.y() ) * m_step );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void knob::getScrollMode( const QPoint &, int & _scroll_mode, int & _direction )
|
||||
{
|
||||
_scroll_mode = ScrMouse;
|
||||
_direction = 0;
|
||||
return( ( _p.y() - m_origMousePos.y() ) * m_pageSize );
|
||||
}
|
||||
|
||||
|
||||
@@ -343,7 +319,6 @@ void knob::layoutKnob( bool _update_geometry )
|
||||
|
||||
void knob::paintEvent( QPaintEvent * _me )
|
||||
{
|
||||
// Use double-buffering
|
||||
QRect ur = _me->rect();
|
||||
#ifndef QT4
|
||||
if( ur.isValid() )
|
||||
@@ -378,22 +353,18 @@ void knob::paintEvent( QPaintEvent * _me )
|
||||
|
||||
void knob::recalcAngle( void )
|
||||
{
|
||||
m_oldAngle = m_angle;
|
||||
|
||||
//
|
||||
// calculate the angle corresponding to the value
|
||||
//
|
||||
if( m_maxValue == m_minValue )
|
||||
{
|
||||
m_angle = 0;
|
||||
m_nTurns = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_angle = ( value() - 0.5 * ( m_minValue + m_maxValue ) ) /
|
||||
( m_maxValue - m_minValue ) * m_totalAngle;
|
||||
m_nTurns = floor( ( m_angle + 180.0 ) / 360.0 );
|
||||
m_angle = m_angle - m_nTurns * 360.0;
|
||||
m_angle = static_cast<int>( m_angle ) % 360;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,26 +374,18 @@ void knob::recalcAngle( void )
|
||||
//! Mouse press event handler
|
||||
void knob::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
const QPoint & p = _me->pos();
|
||||
m_origMousePos = p;
|
||||
|
||||
getScrollMode( p, m_scrollMode, m_direction );
|
||||
|
||||
switch( m_scrollMode )
|
||||
{
|
||||
case ScrMouse:
|
||||
m_mouseOffset = getValue( p ) - value();
|
||||
emit sliderPressed();
|
||||
break;
|
||||
|
||||
default:
|
||||
m_mouseOffset = 0;
|
||||
m_direction = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if( _me->button() == Qt::LeftButton )
|
||||
{
|
||||
const QPoint & p = _me->pos();
|
||||
m_origMousePos = p;
|
||||
|
||||
if( configManager::inst()->value( "knobs",
|
||||
"classicalusability").toInt() )
|
||||
{
|
||||
m_mouseOffset = getValue( p ) - value();
|
||||
}
|
||||
emit sliderPressed();
|
||||
|
||||
if( !configManager::inst()->value( "knobs", "classicalusability"
|
||||
).toInt() )
|
||||
{
|
||||
@@ -435,6 +398,11 @@ void knob::mousePressEvent( QMouseEvent * _me )
|
||||
s_textFloat->move( mapTo( topLevelWidget(), QPoint( 0, 0 ) ) +
|
||||
QPoint( m_knobPixmap->width() + 2, 0 ) );
|
||||
s_textFloat->show();
|
||||
m_buttonPressed = TRUE;
|
||||
}
|
||||
else if( _me->button() == Qt::MidButton )
|
||||
{
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,26 +412,21 @@ void knob::mousePressEvent( QMouseEvent * _me )
|
||||
//! Mouse Move Event handler
|
||||
void knob::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( m_scrollMode == ScrMouse )
|
||||
if( m_buttonPressed == TRUE )
|
||||
{
|
||||
setPosition( _me->pos() );
|
||||
if( value() != m_prevValue )
|
||||
{
|
||||
emit sliderMoved( value() );
|
||||
if( !configManager::inst()->value( "knobs",
|
||||
emit sliderMoved( value() );
|
||||
if( !configManager::inst()->value( "knobs",
|
||||
"classicalusability").toInt() )
|
||||
{
|
||||
QCursor::setPos( mapToGlobal(
|
||||
m_origMousePos ) );
|
||||
}
|
||||
{
|
||||
QCursor::setPos( mapToGlobal( m_origMousePos ) );
|
||||
}
|
||||
songEditor::inst()->setModified();
|
||||
}
|
||||
songEditor::inst()->setModified();
|
||||
|
||||
s_textFloat->setText( m_hintTextBeforeValue +
|
||||
QString::number( value() ) +
|
||||
m_hintTextAfterValue );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -472,30 +435,14 @@ void knob::mouseMoveEvent( QMouseEvent * _me )
|
||||
//! Mouse Release Event handler
|
||||
void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ )
|
||||
{
|
||||
if( m_scrollMode != ScrNone )
|
||||
if( m_buttonPressed )
|
||||
{
|
||||
m_scrollMode = ScrNone;
|
||||
m_buttonPressed = TRUE;
|
||||
buttonReleased();
|
||||
}
|
||||
|
||||
switch( m_scrollMode )
|
||||
{
|
||||
case ScrMouse:
|
||||
//setPosition( _me->pos() );
|
||||
m_direction = 0;
|
||||
m_mouseOffset = 0;
|
||||
emit sliderReleased();
|
||||
break;
|
||||
|
||||
case ScrDirect:
|
||||
//setPosition( _me->pos() );
|
||||
m_direction = 0;
|
||||
m_mouseOffset = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_mouseOffset = 0;
|
||||
emit sliderReleased();
|
||||
|
||||
if( !configManager::inst()->value( "knobs", "classicalusability"
|
||||
).toInt() )
|
||||
@@ -509,15 +456,23 @@ void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ )
|
||||
|
||||
|
||||
|
||||
//! Qt wheel event
|
||||
void knob::wheelEvent( QWheelEvent * _me )
|
||||
void knob::mouseDoubleClickEvent( QMouseEvent * )
|
||||
{
|
||||
_me->accept();
|
||||
const int inc = _me->delta() / WHEEL_DELTA;
|
||||
incPages( inc );
|
||||
enterValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//! Qt wheel event
|
||||
void knob::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_we->accept();
|
||||
const int inc = _we->delta() / WHEEL_DELTA;
|
||||
incValue( inc );
|
||||
songEditor::inst()->setModified();
|
||||
|
||||
|
||||
s_textFloat->reparent( this );
|
||||
s_textFloat->setText( m_hintTextBeforeValue +
|
||||
QString::number( value() ) +
|
||||
@@ -538,7 +493,7 @@ void knob::wheelEvent( QWheelEvent * _me )
|
||||
//! Emits a valueChanged() signal if necessary
|
||||
void knob::buttonReleased( void )
|
||||
{
|
||||
if( ( !m_tracking ) || ( value() != m_prevValue ) )
|
||||
if( value() != m_prevValue )
|
||||
{
|
||||
emit valueChanged( value() );
|
||||
}
|
||||
@@ -552,26 +507,17 @@ void knob::setPosition( const QPoint & _p )
|
||||
if( configManager::inst()->value( "knobs", "classicalusability"
|
||||
).toInt() )
|
||||
{
|
||||
setNewValue( getValue( _p ) - m_mouseOffset, 1 );
|
||||
setValue( getValue( _p ) - m_mouseOffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
setNewValue( m_value - getValue( _p ), 1 );
|
||||
setValue( m_value - getValue( _p ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void knob::setTracking( bool _enable )
|
||||
{
|
||||
m_tracking = _enable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void knob::setValue( float _val, bool _is_init_value )
|
||||
{
|
||||
if( _is_init_value )
|
||||
@@ -579,7 +525,7 @@ void knob::setValue( float _val, bool _is_init_value )
|
||||
m_initValue = _val;
|
||||
}
|
||||
|
||||
setNewValue( _val, 0 );
|
||||
setNewValue( _val, TRUE );
|
||||
}
|
||||
|
||||
|
||||
@@ -587,7 +533,7 @@ void knob::setValue( float _val, bool _is_init_value )
|
||||
|
||||
void knob::fitValue( float _val )
|
||||
{
|
||||
setNewValue( _val, 1 );
|
||||
setValue( _val );
|
||||
}
|
||||
|
||||
|
||||
@@ -595,7 +541,7 @@ void knob::fitValue( float _val )
|
||||
|
||||
void knob::incValue( int _steps )
|
||||
{
|
||||
setNewValue( m_value + float( _steps ) * m_step, 1 );
|
||||
setValue( m_value + float( _steps ) * m_step );
|
||||
}
|
||||
|
||||
|
||||
@@ -622,13 +568,14 @@ void knob::setRange( float _vmin, float _vmax, float _vstep, int _page_size )
|
||||
//
|
||||
/* m_pageSize = tLimit( pageSize, 0, int( tAbs<float>( ( m_maxValue -
|
||||
m_minValue ) / m_step ) ) ); */
|
||||
m_pageSize = tMax<float>( ( m_maxValue - m_minValue ) / 40.0f, _vstep );
|
||||
m_pageSize = tMax<float>( ( m_maxValue - m_minValue ) / 100.0f,
|
||||
m_step );
|
||||
|
||||
//
|
||||
// If the value lies out of the range, it
|
||||
// will be changed. Note that it will not be adjusted to
|
||||
// the new step width.
|
||||
setNewValue( m_value, 0 );
|
||||
setNewValue( m_value, FALSE );
|
||||
|
||||
// call notifier after the step width has been
|
||||
// adjusted.
|
||||
@@ -641,7 +588,7 @@ void knob::setRange( float _vmin, float _vmax, float _vstep, int _page_size )
|
||||
|
||||
|
||||
|
||||
void knob::setNewValue( float _x, int _align )
|
||||
void knob::setNewValue( float _x, bool _align )
|
||||
{
|
||||
m_prevValue = m_value;
|
||||
|
||||
@@ -768,6 +715,14 @@ void knob::contextMenuEvent( QContextMenuEvent * )
|
||||
void knob::reset( void )
|
||||
{
|
||||
setValue( m_initValue );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -784,6 +739,32 @@ void knob::copyValue( void )
|
||||
void knob::pasteValue( void )
|
||||
{
|
||||
setValue( s_copiedValue );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void knob::enterValue( void )
|
||||
{
|
||||
bool ok;
|
||||
float new_val = QInputDialog::getDouble( accessibleName(),
|
||||
tr( "Please enter a new value between "
|
||||
"%1 and %2:" ).arg(
|
||||
minValue() ).arg( maxValue() ),
|
||||
value(), minValue(), maxValue(),
|
||||
4, &ok, this );
|
||||
if( ok )
|
||||
{
|
||||
setValue( new_val );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -791,7 +772,7 @@ void knob::pasteValue( void )
|
||||
|
||||
void knob::connectToMidiDevice( void )
|
||||
{
|
||||
mixer::inst()->getMIDIDevice()->setPitchBendKnob( this );
|
||||
//mixer::inst()->getMIDIDevice()->setPitchBendKnob( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,15 +58,8 @@ lcdSpinBox::lcdSpinBox( int _min, int _max, int _num_digits,
|
||||
m_number->setFrameShape( QFrame::Panel );
|
||||
m_number->setFrameShadow( QFrame::Sunken );
|
||||
m_number->setSegmentStyle( QLCDNumber::Flat );
|
||||
#ifdef QT4
|
||||
QPalette pal = m_number->palette();
|
||||
pal.setColor( QPalette::Background, QColor( 32, 32, 32 ) );
|
||||
pal.setColor( QPalette::Foreground, QColor( 255, 180, 0 ) );
|
||||
m_number->setPalette( pal );
|
||||
#else
|
||||
m_number->setPaletteBackgroundColor( QColor( 32, 32, 32 ) );
|
||||
m_number->setPaletteForegroundColor( QColor( 255, 180, 0 ) );
|
||||
#endif
|
||||
setEnabled( TRUE );
|
||||
|
||||
// value is automatically limited to given range
|
||||
setValue( 0 );
|
||||
|
||||
@@ -95,12 +88,15 @@ void lcdSpinBox::setValue( int _value )
|
||||
{
|
||||
_value = ( ( tLimit( _value, m_minValue, m_maxValue ) - m_minValue ) /
|
||||
m_step ) * m_step + m_minValue;
|
||||
QString s = QString::number( _value );
|
||||
while( (int) s.length() < m_number->numDigits() )
|
||||
QString s = m_textForValue[_value];
|
||||
if( s == "" )
|
||||
{
|
||||
s = "0" + s;
|
||||
s = QString::number( _value );
|
||||
while( (int) s.length() < m_number->numDigits() )
|
||||
{
|
||||
s = "0" + s;
|
||||
}
|
||||
}
|
||||
|
||||
m_number->display( s );
|
||||
}
|
||||
|
||||
@@ -127,6 +123,28 @@ void lcdSpinBox::setLabel( const QString & _txt )
|
||||
|
||||
|
||||
|
||||
void lcdSpinBox::setEnabled( bool _on )
|
||||
{
|
||||
QColor fg( 255, 180, 0 );
|
||||
if( _on == FALSE )
|
||||
{
|
||||
fg = QColor( 160, 160, 160 );
|
||||
}
|
||||
#ifdef QT4
|
||||
QPalette pal = m_number->palette();
|
||||
pal.setColor( QPalette::Background, QColor( 32, 32, 32 ) );
|
||||
pal.setColor( QPalette::Foreground, fg );
|
||||
m_number->setPalette( pal );
|
||||
#else
|
||||
m_number->setPaletteBackgroundColor( QColor( 32, 32, 32 ) );
|
||||
m_number->setPaletteForegroundColor( fg );
|
||||
#endif
|
||||
QWidget::setEnabled( _on );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void lcdSpinBox::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( _me->button() == Qt::LeftButton && _me->y() < m_number->height() )
|
||||
@@ -138,6 +156,7 @@ void lcdSpinBox::mousePressEvent( QMouseEvent * _me )
|
||||
|
||||
|
||||
|
||||
|
||||
void lcdSpinBox::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( _me->modifiers() == Qt::LeftButton )
|
||||
|
||||
@@ -117,6 +117,10 @@ void ledCheckBox::setChecked( bool _on )
|
||||
{
|
||||
toggle();
|
||||
}
|
||||
else
|
||||
{
|
||||
emit( toggled( m_checked ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,22 +49,15 @@
|
||||
|
||||
#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,
|
||||
@@ -171,59 +164,19 @@ void tempoSyncKnob::contextMenuEvent( QContextMenuEvent * )
|
||||
|
||||
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 );
|
||||
|
||||
m_tempoSyncMode = NO_SYNC;
|
||||
calculateTempoSyncTime( songEditor::inst()->getBPM() );
|
||||
knob::mouseMoveEvent( _me );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void tempoSyncKnob::wheelEvent( QWheelEvent * _me )
|
||||
void tempoSyncKnob::wheelEvent( QWheelEvent * _we )
|
||||
{
|
||||
_me->accept();
|
||||
const int inc = _me->delta() / WHEEL_DELTA;
|
||||
incPages( inc );
|
||||
|
||||
knob::wheelEvent( _we );
|
||||
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() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -283,7 +236,7 @@ void tempoSyncKnob::calculateTempoSyncTime( int _bpm )
|
||||
conversionFactor = 8.0;
|
||||
break;
|
||||
default:
|
||||
printf( "arpAndChordsTabWidget::calculateTempoSyncTime: invalid tempoSyncMode" );
|
||||
printf( "tempoSyncKnob::calculateTempoSyncTime: invalid tempoSyncMode" );
|
||||
break;
|
||||
}
|
||||
setValue( 60000.0 / ( _bpm * conversionFactor * m_scale ),
|
||||
|
||||
Reference in New Issue
Block a user