heavy improvements on mixer-system and GUI

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@26 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2005-12-05 12:26:16 +00:00
parent ab719618f7
commit 614b106752
79 changed files with 1429 additions and 1445 deletions

View File

@@ -1,3 +1,98 @@
2005-12-04 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* include/midi_alsa_raw.h:
* include/midi_client.h:
* include/midi_dummy.h:
* include/midi_oss.h:
* src/midi/midi_alsa_raw.cpp:
* src/midi/midi_client.cpp:
* src/midi/midi_oss.cpp:
renamed class midiRawClient to midiClientRaw
* include/pattern.h:
* src/core/song_editor.cpp:
* src/tracks/pattern.cpp:
do not hang in endless loop when rendering pattern with enabled
looping-points
* src/core/time_line.cpp:
align looping-points on bars
* include/bb_editor.h:
* include/piano_roll.h:
* include/song_editor.h:
* include/timeline.h:
* include/tool_button.h:
* src/core/bb_editor.cpp:
* src/core/piano_roll.cpp:
* src/core/song_editor.cpp:
* src/core/timeline.cpp:
redesigned toolbars of song-editor, bb-editor and piano-roll - now
they're looking really cool and especially time-line-features are much
more usable
* include/song_editor.cpp:
* src/core/lmms_main_win.cpp:
* src/core/song_editor.cpp:
- added main-toolbar at bottom of screen and moved several widgets from
song-editor-toolbar into it
- added high-quality-button for switching to 88200/96000 Hz
* src/widgets/tab_widget.cpp:
reversed scroll-wheel-direction for changing tab
2005-12-03 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* src/core/main.cpp:
- better handling of command-line options
- added help switch
- fixed bugs concerning rendering from command-line
* include/audio_alsa.h:
* include/audio_device.h:
* include/audio_dummy.h:
* include/audio_file_device.h:
* include/audio_file_ogg.h:
* include/audio_file_wave.h
* include/audio_jack.h:
* include/audio_oss.h:
* include/audio_sdl.h:
* include/export.h:
* include/export_project_dialog.h:
* include/mixer.h:
* include/pattern.h
* include/song_editor.h:
* src/audio/audio_alsa.cpp:
* src/audio/audio_device.cpp:
* src/audio/audio_file_device.cpp:
* src/audio/audio_file_ogg.cpp:
* src/audio/audio_file_wave.cpp:
* src/audio/audio_jack.cpp:
* src/audio/audio_oss.cpp:
* src/audio/audio_port.cpp:
* src/audio/audio_sdl.cpp:
* src/core/export_project_dialog.cpp:
* src/core/lmms_main_win.cpp:
* src/core/main.cpp:
* src/core/mixer.cpp:
* src/core/song_editor.cpp:
* src/track/pattern.cpp:
changed architecture of mixer-system from push- to pull-architecture
which makes almost all things (song-export, pattern-freezing etc.) much
easier and also results in a better performance (especially when using
JACK) - additionally LMMS doesn't take 100% CPU anymore
2005-12-02 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* src/core/config_mgr.cpp:
do not try to re-run wizard in case of version mismatches
* configure.in:
* plugins/Makefile.am:
* presets/Makefile.am:
dropped ladspa_sine_1063-plugin as it is only for experimental
purposes
2005-11-29 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* plugins/vestige/vestige.h:

View File

@@ -48,7 +48,6 @@ lmms_MOC = \
./bb_track.moc \
./channel_track.moc \
./config_mgr.moc \
./crystal_button.moc \
./envelope_and_lfo_widget.moc \
./envelope_tab_widget.moc \
./export_project_dialog.moc \
@@ -157,7 +156,6 @@ lmms_SOURCES = \
$(srcdir)/src/tracks/channel_track.cpp \
$(srcdir)/src/tracks/pattern.cpp \
$(srcdir)/src/tracks/sample_track.cpp \
$(srcdir)/src/widgets/crystal_button.cpp \
$(srcdir)/src/widgets/group_box.cpp \
$(srcdir)/src/widgets/kmultitabbar.cpp \
$(srcdir)/src/widgets/knob.cpp \
@@ -212,7 +210,6 @@ lmms_SOURCES = \
$(srcdir)/include/envelope_and_lfo_widget.h \
$(srcdir)/include/about_dialog.h \
$(srcdir)/include/oscillator.h \
$(srcdir)/include/crystal_button.h \
$(srcdir)/include/arp_and_chords_tab_widget.h \
$(srcdir)/include/export.h \
$(srcdir)/include/group_box.h \
@@ -274,6 +271,7 @@ lmms_SOURCES = \
$(srcdir)/include/midi_tab_widget.h \
$(srcdir)/include/audio_port.h \
$(srcdir)/include/qxembed.h \
$(srcdir)/include/tool_button.h \
$(srcdir)/include/midi_alsa_seq.h

36
README
View File

@@ -1,10 +1,10 @@
Linux MultiMedia Studio 0.1.1
==============================
Copyright (c) 2004-2005 by Tobias Doerffel and others
Copyright (c) 2004-2005 by Tobias Doerffel and others.
The whole program is free software; you can redistribute it and/or modify
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.
@@ -26,9 +26,9 @@ What is LMMS??
LMMS aims to be a free alternative to popular (but commercial and closed-
source) programs like FruityLoops, Cubase and Logic giving you the ability of
producing music with your computer by creating/synthesizing sounds, arranging
samples, playing live with keyboard and much more...
samples, using effects, playing live with keyboard and much more...
LMMS combines the features of a tracker-/sequencer-program (pattern-/channel-/
LMMS combines the features of a sequencer-program (pattern-/channel-/
sample-/song-/effect-management) and those of powerful synthesizers and
samplers in a modern, user-friendly and easy to use graphical user-interface.
@@ -47,23 +47,23 @@ least 500 MHz, but for really enjoying LMMS less than 1 GHz makes no sense...
Required libraries are:
- multihreaded version of Qt 3.0 (3.2 recommended) or higher (tested up to
4.0.0) with devel-files
- multithreaded version of Qt 3.0 (at least 3.2 recommended) or higher (tested
up to 4.0.0) with devel-files
Optional, but strongly recommended:
- JACK with devel-files
- libvorbis with devel-files
- libalsa with devel-files
- SDL_sound (tested with 0.1.5 & 1.0.1) with devel-files
- SDL with devel-files
- libsamplerate with devel-files
- libsndfile with devel-files
- JACK with devel-files
- libfst + header-files from Steinberg SDK
- WINE, WINE-devel-files + header-files from Steinberg SDK
For compiling you should have an up to date GCC with g++.
LMMS has been (successfully) tested under Debian Sarge 3.1, Fedora Core 2-4,
and SuSE Linux 9.0-9.3 with Qt 3.[23].x and Qt 4.0.0.
It was compiled using GCC 3.3.x, GCC 3.4.x and GCC 4.0.x.
LMMS has been (successfully) tested under Debian Sarge 3.1 / unstable,
Fedora Core 2-4, and SuSE Linux 9.0-9.3 with Qt 3.[23].x and Qt 4.0.0.
It was compiled using GCC 2.95, 3.3.x, GCC 3.4.x and GCC 4.0.x.
If you have problems with compiling or running LMMS, find any bug or have
suggestions and so on, please feel free to e-mail me (for mail-address see
@@ -71,6 +71,20 @@ below)!
Building
--------
See INSTALL for information on how to build LMMS.
Please also take a look at
./configure --help
There you'll see a lot of options which partly might be interesting for you.
For example if you want to build LMMS with VST-support, you have to run
configure with --with-vst switch. Otherwise LMMS support won't be built!
Join LMMS-development
----------------------

26
TODO
View File

@@ -1,23 +1,21 @@
to be done as soon as possible:
- add note-len- and note-alignment-selectbox to piano-roll
- make it possible in bb-editor to add single beats to beat-patterns
- MIDI/note-debug!!
- select connected midi-device in midi-setup-tabwidget
- fix audio/midi-settings stuff/translation
- check ladspa-header
- 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
- 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
- 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
- add note-len- and note-alignment-selectbox to piano-roll
- only redraw region given by paint-event in pattern, bbTCO, sampleTCO etc.
- make LMMS an ALSA-sequencer-client
- use midi-maps
- process program-/channel-change-events from MIDI-files
- setup MIDI-channel and -program in MIDI-Out
- use midi-maps
- process program-/channel-change-events from MIDI-files
- pre-listen when opening sample with QFileDialog
- level-meters in output-graph and channel-track
- panning-editing in piano-roll
@@ -32,7 +30,7 @@
- rewrite export-project-dialog using layout-mechanism
- dynamic pitch-change
- make piano-roll use the global clipboard??
- add languages:
- add more localizations:
- Italian
- Swedish
- Norwegian
@@ -41,14 +39,12 @@
Things to be done anytime in the future
to be done somewhen in the future:
- effect-board -> live-fx from input
- event-system
- event/automation-system
- chord-editor?
- WAVE/OGG/MP3-Import -> FFT-analysis -> write notes
- FLP-Import
- classical note-edit-window -> also ability of printing and maybe later scanning & recognition of notes
- add FLAC as export-format?
- better commented source...
- optimize, optimize, optimize.....

View File

@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(lmms, 0.1.1-cvs20051129, tobydox/at/users.sourceforge.net)
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051129)
AC_INIT(lmms, 0.1.1-cvs20051204, tobydox/at/users.sourceforge.net)
AM_INIT_AUTOMAKE(lmms, 0.1.1-cvs20051204)
AM_CONFIG_HEADER(config.h)
@@ -62,8 +62,6 @@ AH_TEMPLATE(SDL_SDL_SOUND_H, [Define to location of SDL_sound.h])
OLD_LIBS="$LIBS"
LIBS="$LIBS -lpthread"
AC_CHECK_FUNCS([pthread_getattr_np])
# check for SDL-lib
AC_ARG_WITH(sdl,
AS_HELP_STRING([--without-sdl],
@@ -158,10 +156,10 @@ fi
AM_CONDITIONAL(HAVE_LIBJACK, test ! -z "$HAVE_JACK_JACK_H")
# check for proper wine-installation and existing steinberg headers
# check for proper wine-installation and existing Steinberg headers
AC_ARG_WITH(vst,
AS_HELP_STRING([--with-vst],
[enable support for VST-plugin-hosting]), [ with_vst=yes ], [ with_vst=no ])
[enable support for builtin VST-plugin-hosting]), [ with_vst=yes ], [ with_vst=no ])
AH_TEMPLATE(HAVE_VST_AEFFECTX_H, [Define to 1 if you have the <vst/aeffectx.h> header file.])
if test "x$with_vst" = "xyes" ; then
AC_CHECK_HEADER(vst/aeffectx.h, HAVE_VST_AEFFECTX_H="true")
@@ -251,11 +249,11 @@ AM_CONDITIONAL(HAVE_LIBSF, test ! -z "$HAVE_SNDFILE_H")
AC_ARG_WITH(nosmpdecs,
AS_HELP_STRING([--without-sample-decoders],
[force compiling LMMS even if libraries for sample-decoding were found]),
[force compiling LMMS even if no usable libraries for sample-decoding were found]),
[ with_smpdecs=yes ])
if test -z "$HAVE_SND_FILE" -a -z "$HAVE_SDL_SDL_SOUND_H" -a -z "$OGG_SUPPORT" -a ! -z "$with_smpdecs"; then
AC_MSG_ERROR([*** neither libsndfile nor SDL_sound nor libvorbis (or according devel-files) were found which would make LMMS unable to load any samples, so please install at least one of the packages and try again! Use --without-sample-decoders to force compiling LMMS.])
AC_MSG_ERROR([*** neither libsndfile nor SDL_sound nor libvorbis (or according devel-files) were found which would make LMMS unable to load any samples so please install at least one of the packages and try again! Use --without-sample-decoders to force compiling without any sample-decoding-libraries.])
fi
@@ -388,7 +386,6 @@ AC_CONFIG_FILES([Makefile
presets/AudioFileProcessor/Makefile
presets/MIDI-Out/Makefile
presets/PluckedStringSynth/Makefile
presets/Sine1063Oscillator/Makefile
presets/TripleOscillator/Makefile
presets/VeSTige/Makefile
projects/Makefile

View File

@@ -48,7 +48,7 @@ class lcdSpinBox;
class QLineEdit;
class audioALSA : public audioDevice
class audioALSA : public audioDevice, public QThread
{
public:
audioALSA( Uint32 _sample_rate, bool & _success_ful );
@@ -79,9 +79,9 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void run( void );
int FASTCALL setHWParams( Uint32 _sample_rate, Uint32 _channels,
snd_pcm_access_t _access );
@@ -98,6 +98,7 @@ private:
snd_pcm_sw_params_t * m_swParams;
bool m_littleEndian;
volatile bool m_quit;
} ;

View File

@@ -32,11 +32,13 @@
#include <QPair>
#include <QMutex>
#include <QThread>
#else
#include <qpair.h>
#include <qmutex.h>
#include <qthread.h>
#endif
@@ -74,12 +76,6 @@ public:
m_devMutex.unlock();
}
// called by mixer for writing final output-buffer with given sample-
// rate and master-gain
void FASTCALL writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
Uint32 _src_sample_rate,
float _master_gain );
// if audio-driver supports ports, classes inherting audioPort
// (e.g. channel-tracks) can register themselves for making
@@ -87,7 +83,7 @@ public:
// them at a specific port - currently only supported by JACK
virtual void registerPort( audioPort * _port );
virtual void unregisterPort( audioPort * _port );
virtual void renamePort( audioPort * _port, const QString & _name );
virtual void renamePort( audioPort * _port );
inline Uint32 sampleRate( void ) const
@@ -100,6 +96,15 @@ public:
return( m_channels );
}
void processNextBuffer( void );
virtual void startProcessing( void )
{
}
virtual void stopProcessing( void )
{
}
class setupWidget : public tabWidget
@@ -122,10 +127,16 @@ public:
protected:
// to be implemented by audio-driver - last step in a mixer period
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
// subclasses can overload this for being used in conjunction with
// processNextBuffer()
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain ) = 0;
float _master_gain )
{
}
// called by according driver for fetching new sound-data
Uint32 FASTCALL getNextBuffer( surroundSampleFrame * _ab );
// convert a given audio-buffer to a buffer in signed 16-bit samples
// returns num of bytes in outbuf
@@ -139,7 +150,8 @@ protected:
Uint32 _frames );
// resample given buffer from samplerate _src_src to samplerate _dst_src
void FASTCALL resample( surroundSampleFrame * _src, Uint32 _frames,
void FASTCALL resample( const surroundSampleFrame * _src,
Uint32 _frames,
surroundSampleFrame * _dst,
Uint32 _src_sr, Uint32 _dst_sr );
@@ -159,6 +171,8 @@ private:
SRC_STATE * m_srcState;
#endif
surroundSampleFrame * m_buffer;
} ;

View File

@@ -68,13 +68,8 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame *,
Uint32 /*_frames*/, float )
{
//usleep( (Uint32)( _frames * 1000.0f * 1000.0f /
// DEFAULT_SAMPLE_RATE ) );
}
// TODO: derive from QThread and call getNextBuffer() in an
// endless loop
} ;

View File

@@ -54,6 +54,7 @@ public:
virtual ~audioFileDevice();
protected:
int FASTCALL writeData( const void * _data, int _len );
void seekToBegin( void );

View File

@@ -48,7 +48,7 @@ public:
Uint16 _min_bitrate, Uint16 _max_bitrate );
~audioFileOgg();
static audioDevice * getInst( Uint32 _sample_rate, Uint32 _channels,
static audioFileDevice * getInst( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful,
const QString & _file,
bool _use_vbr,
@@ -63,7 +63,7 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );

View File

@@ -41,7 +41,7 @@ public:
Uint16 _min_bitrate, Uint16 _max_bitrate );
virtual ~audioFileWave();
static audioDevice * getInst( Uint32 _sample_rate, Uint32 _channels,
static audioFileDevice * getInst( Uint32 _sample_rate, Uint32 _channels,
bool & _success_ful,
const QString & _file, bool _use_vbr,
Uint16 _nom_bitrate,
@@ -56,7 +56,7 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
@@ -83,8 +83,6 @@ private:
Uint32 data_bytes; // total size of sample-data
} m_waveFileHeader;
//outputSampleType * m_outputBuffer;
} ;

View File

@@ -44,12 +44,14 @@
#include <QMutex>
#include <QVector>
#include <QList>
#include <QMap>
#else
#include <qmutex.h>
#include <qvaluevector.h>
#include <qvaluelist.h>
#include <qmap.h>
#endif
@@ -90,34 +92,38 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void registerPort( audioPort * _port );
virtual void unregisterPort( audioPort * _port );
virtual void renamePort( audioPort * _port, const QString & _name );
virtual void renamePort( audioPort * _port );
static int processCallback( jack_nframes_t _nframes, void * _udata );
static int bufSizeCallback( jack_nframes_t _nframes, void * _udata );
static void shutdownCallback( void * _udata );
jack_client_t * m_client;
bool m_stopped;
QMutex m_processCallbackMutex;
vvector<jack_port_t *> m_outputPorts;
struct bufset
surroundSampleFrame * m_outBuf;
Uint32 m_framesDoneInCurBuf;
Uint32 m_framesToDoInCurBuf;
struct stereoPort
{
sampleType * buf;
Uint32 frames;
jack_port_t * ports[2];
} ;
vlist<vvector<bufset> > m_bufferSets;
Uint32 m_framesDoneInCurBuf;
volatile Uint32 m_frameSync;
Uint32 m_jackBufSize;
QMutex m_bufMutex;
typedef QMap<audioPort *, stereoPort> jackPortMap;
jackPortMap m_portMap;
} ;

View File

@@ -44,7 +44,7 @@ class lcdSpinBox;
class QLineEdit;
class audioOSS : public audioDevice
class audioOSS : public audioDevice, public QThread
{
public:
audioOSS( Uint32 _sample_rate, bool & _success_ful );
@@ -74,13 +74,14 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
virtual void startProcessing( void );
virtual void stopProcessing( void );
virtual void run( void );
int m_audioFD;
bool m_convertEndian;
volatile bool m_quit;
} ;

View File

@@ -80,6 +80,11 @@ public:
m_nextFxChannel = _chnl;
}
const QString & name( void ) const
{
return( m_name );
}
void setName( const QString & _new_name );
enum bufferUsages
@@ -94,6 +99,8 @@ private:
bool m_extOutputEnabled;
fxChnl m_nextFxChannel;
QString m_name;
} ;

View File

@@ -62,7 +62,7 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
virtual void FASTCALL writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );

View File

@@ -37,18 +37,6 @@
#endif
#include "qt3support.h"
#ifdef QT4
#include <QMutex>
#else
#include <qmutex.h>
#endif
#include SDL_SDL_H
#include SDL_SDL_AUDIO_H
@@ -87,20 +75,14 @@ public:
private:
virtual void FASTCALL writeBufferToDev( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain );
void clearBuffer( void );
virtual void startProcessing( void );
virtual void stopProcessing( void );
static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len );
SDL_AudioSpec m_audioHandle;
outputSampleType * m_buffer;
QMutex m_bufMutex;
QMutex m_callbackMutex;
surroundSampleFrame * m_outBuf;
bool m_convertEndian;

View File

@@ -33,7 +33,7 @@
#include "lmms_main_win.h"
class pixmapButton;
class toolButton;
class songEditor;
class QPixmap;
@@ -88,8 +88,6 @@ protected:
virtual void keyPressEvent( QKeyEvent * _ke );
virtual void resizeEvent( QResizeEvent * _re );
void updateBackground( void );
protected slots:
void play( void );
@@ -105,10 +103,11 @@ private:
static bbEditor * s_instanceOfMe;
static QPixmap * s_titleArtwork;
pixmapButton * m_playButton;
pixmapButton * m_stopButton;
QWidget * m_toolBar;
toolButton * m_playButton;
toolButton * m_stopButton;
friend class songEditor;

View File

@@ -27,10 +27,11 @@
#include "types.h"
class audioDevice;
class audioFileDevice;
typedef audioDevice * ( * getDeviceInst)( Uint32 _sample_rate,
typedef audioFileDevice * ( * getDeviceInst)( Uint32 _sample_rate,
Uint32 _channels,
bool & _success_ful,
const QString & _file,
@@ -48,6 +49,7 @@ enum fileTypes
} ;
struct fileEncodeDevice
{
fileTypes m_fileType;
@@ -56,6 +58,7 @@ struct fileEncodeDevice
getDeviceInst m_getDevInst;
} ;
extern fileEncodeDevice fileEncodeDevices[];

View File

@@ -62,7 +62,6 @@ class exportProjectDialog : public QDialog
public:
exportProjectDialog( const QString & _file_name, QWidget * _parent );
~exportProjectDialog();
void FASTCALL updateProgressBar( int _new_val );
public slots:
@@ -77,10 +76,16 @@ protected:
private slots:
void changedType( const QString & );
void cancelBtnClicked( void );
void redrawProgressBar( void );
private:
void finishProjectExport( void );
void abortProjectExport( void );
static fileTypes FASTCALL getFileTypeFromExtension( const QString &
_ext );
static Sint16 s_availableBitrates[];
QString m_fileName;
QLabel * m_typeLbl;
QComboBox * m_typeCombo;
@@ -92,20 +97,9 @@ private:
QPushButton * m_exportBtn;
QPushButton * m_cancelBtn;
QProgressBar * m_exportProgressBar;
fileTypes m_fileType;
bool m_deleteFile;
int m_oldProgressVal;
int m_progressVal;
QTimer * m_progressBarUpdateTimer;
static Sint16 s_availableBitrates[];
void finishProjectExport( void );
void abortProjectExport( void );
static fileTypes FASTCALL getFileTypeFromExtension( const QString &
_ext );
} ;

View File

@@ -58,7 +58,7 @@ struct pollfd;
class QLineEdit;
class midiALSARaw : public midiRawClient, public QThread
class midiALSARaw : public midiClientRaw, public QThread
{
public:
midiALSARaw( void );
@@ -74,7 +74,7 @@ public:
}
class setupWidget : public midiRawClient::setupWidget
class setupWidget : public midiClientRaw::setupWidget
{
public:
setupWidget( QWidget * _parent );

View File

@@ -102,15 +102,14 @@ protected:
const Uint8 RAW_MIDI_PARSE_BUF_SIZE = 16;
class midiRawClient : public midiClient
class midiClientRaw : public midiClient
{
public:
midiRawClient( void );
~midiRawClient();
midiClientRaw( void );
virtual ~midiClientRaw();
protected:

View File

@@ -32,11 +32,11 @@
#include "tab_widget.h"
class midiDummy : public midiRawClient
class midiDummy : public midiClientRaw
{
public:
midiDummy() :
midiRawClient()
midiClientRaw()
{
}
~midiDummy()
@@ -53,7 +53,7 @@ public:
{
public:
setupWidget( QWidget * _parent ) :
midiRawClient::setupWidget( midiDummy::name(), _parent )
midiClientRaw::setupWidget( midiDummy::name(), _parent )
{
}

View File

@@ -40,7 +40,7 @@
class QLineEdit;
class midiOSS : public midiRawClient, public QThread
class midiOSS : public midiClientRaw, public QThread
{
public:
midiOSS( void );
@@ -55,7 +55,7 @@ public:
}
class setupWidget : public midiRawClient::setupWidget
class setupWidget : public midiClientRaw::setupWidget
{
public:
setupWidget( QWidget * _parent );

View File

@@ -34,14 +34,12 @@
#ifdef QT4
#include <QThread>
#include <QMutex>
#include <QVector>
#else
#include <qobject.h>
#include <qthread.h>
#include <qmutex.h>
#include <qvaluevector.h>
@@ -104,11 +102,7 @@ const octaves BASE_OCTAVE = OCTAVE_4;
class mixer :
#ifndef QT4
public QObject,
#endif
public QThread
class mixer : public QObject
{
Q_OBJECT
public:
@@ -202,20 +196,20 @@ public:
inline int sampleRate( void )
inline Uint32 sampleRate( void )
{
return( SAMPLE_RATES[m_qualityLevel] );
}
inline float masterOutput( void ) const
inline float masterGain( void ) const
{
return( m_masterOutput );
return( m_masterGain );
}
inline void setMasterOutput( float _mo )
inline void setMasterGain( float _mo )
{
m_masterOutput = _mo;
m_masterGain = _mo;
}
@@ -235,12 +229,12 @@ public:
void pause( void )
{
m_safetySyncMutex.lock();
m_mixMutex.lock();
}
void play( void )
{
m_safetySyncMutex.unlock();
m_mixMutex.unlock();
}
@@ -259,6 +253,8 @@ public:
}
const surroundSampleFrame * renderNextBuffer( void );
public slots:
void setHighQuality( bool _hq_on = FALSE );
@@ -275,7 +271,7 @@ private:
mixer();
~mixer();
void quitThread( void );
void stopProcessing( void );
// we don't allow to create mixer by using copy-ctor
@@ -283,7 +279,6 @@ private:
{
}
virtual void run( void );
audioDevice * tryAudioDevices( void );
@@ -292,11 +287,6 @@ private:
void processBuffer( surroundSampleFrame * _buf, fxChnl _fx_chnl );
/* sampleFrame * m_silence;
#ifndef DISABLE_SURROUND
surroundSampleFrame * m_surroundSilence;// cool, silence in surround ;-)
#endif*/
vvector<audioPort *> m_audioPorts;
@@ -305,16 +295,16 @@ private:
surroundSampleFrame * m_curBuf;
surroundSampleFrame * m_nextBuf;
bool m_discardCurBuf;
/* bool m_discardCurBuf;*/
playHandleVector m_playHandles;
playHandleVector m_playHandlesToRemove;
Uint8 m_qualityLevel;
volatile float m_masterOutput;
volatile float m_masterGain;
volatile bool m_quit;
/* volatile bool m_quit;*/
audioDevice * m_audioDev;
@@ -326,8 +316,8 @@ private:
QString m_midiClientName;
QMutex m_safetySyncMutex;
QMutex m_devMutex;
QMutex m_mixMutex;
/* QMutex m_devMutex;*/
friend class lmmsMainWin;

View File

@@ -34,14 +34,14 @@
#ifdef QT4
#include <QWidget>
#include <QPushButton>
#include <QPixmap>
#include <QVector>
#include <QPair>
#else
#include <qwidget.h>
#include <qpushbutton.h>
#include <qpixmap.h>
#include <qvaluevector.h>
#include <qpair.h>
@@ -49,7 +49,7 @@
#endif
class nStateButton : public QWidget
class nStateButton : public QPushButton
{
Q_OBJECT
public:
@@ -73,11 +73,11 @@ public slots:
signals:
void stateChanged( int _n );
void changedState( int _n );
protected:
virtual void paintEvent( QPaintEvent * _pe );
/* virtual void paintEvent( QPaintEvent * _pe );*/
virtual void mousePressEvent( QMouseEvent * _me );

View File

@@ -53,12 +53,9 @@
class channelTrack;
class sampleBuffer;
class audioSampleRecorder;
class QTimer;
class QProgressBar;
class QPushButton;
class QPixmap;
class patternFreezeStatusDialog;
@@ -72,7 +69,7 @@ class pattern : public trackContentObject
public:
enum patternTypes
{
BEAT_PATTERN, MELODY_PATTERN/*, EVENT_PATTERN*/
BEAT_PATTERN, MELODY_PATTERN/*, AUTOMATION_PATTERN*/
} ;
pattern( channelTrack * _channel_track );
@@ -83,9 +80,13 @@ public:
virtual midiTime length( void ) const;
note * FASTCALL addNote( const note & _new_note );
void FASTCALL removeNote( const note * _note_to_del );
note * FASTCALL rearrangeNote( const note * _note_to_proc );
void clearNotes( void );
inline noteVector & notes( void )
@@ -98,32 +99,39 @@ public:
return( m_patternType );
}
void FASTCALL setType( patternTypes _new_pattern_type );
inline const QString & name( void ) const
{
return( m_name );
}
inline void setName( const QString & _name )
{
m_name = _name;
update();
}
inline channelTrack * getChannelTrack( void )
{
return( m_channelTrack );
}
// functions which are part of freezing-feature
inline bool freezing( void ) const
{
return( m_freezing );
}
inline bool frozen( void ) const
{
return( m_frozenPattern != NULL );
}
void FASTCALL playFrozenData( sampleFrame * _ab, Uint32 _start_frame,
Uint32 _frames );
inline bool isFreezing( void ) const
{
return( m_freezeRecorder != NULL );
}
void finishFreeze( void );
note * FASTCALL noteAt( int _note_num );
@@ -147,7 +155,6 @@ protected slots:
void changeName( void );
void freeze( void );
void unfreeze( void );
void updateFreezeStatusDialog( void );
void abortFreeze( void );
@@ -177,9 +184,9 @@ private:
QMutex m_frozenPatternMutex;
sampleBuffer * m_frozenPattern;
audioSampleRecorder * m_freezeRecorder;
patternFreezeStatusDialog * m_freezeStatusDialog;
QTimer * m_freezeStatusUpdateTimer;
bool m_freezing;
volatile bool m_freezeAborted;
} ;

View File

@@ -50,10 +50,9 @@ class QPainter;
class QPixmap;
class QScrollBar;
class crystalButton;
class toolButton;
class pattern;
class notePlayHandle;
class pixmapButton;
class timeLine;
class lmmsMainWin;
@@ -112,10 +111,10 @@ protected slots:
void horScrolled( int _new_pos );
void verScrolled( int _new_pos );
void drawButtonToggled( bool = FALSE );
void eraseButtonToggled( bool = FALSE );
void selectButtonToggled( bool = FALSE );
void moveButtonToggled( bool = FALSE );
void drawButtonToggled( void );
void eraseButtonToggled( void );
void selectButtonToggled( void );
void moveButtonToggled( void );
void copySelectedNotes( void );
void cutSelectedNotes( void );
@@ -160,8 +159,6 @@ private:
static QPixmap * s_whiteKeyBigPm;
static QPixmap * s_whiteKeySmallPm;
static QPixmap * s_artwork1;
static QPixmap * s_artwork2;
static QPixmap * s_blackKeyPm;
static QPixmap * s_toolDraw;
static QPixmap * s_toolErase;
@@ -171,18 +168,20 @@ private:
static pianoRollKeyTypes prKeyOrder[];
pixmapButton * m_playButton;
pixmapButton * m_recordButton;
pixmapButton * m_stopButton;
QWidget * m_toolBar;
crystalButton * m_drawButton;
crystalButton * m_eraseButton;
crystalButton * m_selectButton;
crystalButton * m_moveButton;
toolButton * m_playButton;
toolButton * m_recordButton;
toolButton * m_stopButton;
crystalButton * m_cutButton;
crystalButton * m_copyButton;
crystalButton * m_pasteButton;
toolButton * m_drawButton;
toolButton * m_eraseButton;
toolButton * m_selectButton;
toolButton * m_moveButton;
toolButton * m_cutButton;
toolButton * m_copyButton;
toolButton * m_pasteButton;
QComboBox * m_zoomingComboBox;

View File

@@ -52,6 +52,14 @@ typedef int csize;
#define vvector QVector
#define vlist QList
#include <QFileInfo>
inline QString baseName( const QString & _file )
{
return( QFileInfo( _file ).absolutePath() + "/" +
QFileInfo( _file ).completeBaseName() );
}
#else
@@ -73,7 +81,6 @@ typedef int csize;
// QMenu/QPopupMenu
#define addAction insertItem
//#define addSeparator insertSeparator
// QFile/QIODevice
@@ -115,15 +122,8 @@ typedef int csize;
#define setTextVisible setPercentageVisible
// QFileInfo
//#define completeSuffix extension
//#define suffix() extension( FALSE )
// QComboBox
#define addItem insertItem
//#define currentIndex currentItem
//#define setCurrentIndex setCurrentItem
// QString
@@ -148,7 +148,6 @@ typedef int csize;
#define NoFilter DefaultFilter
#define homePath homeDirPath
#define rootPath rootDirPath
//#define absolutePath absPath
// QToolButton
@@ -178,6 +177,17 @@ typedef unsigned int csize;
#endif
#include <qfileinfo.h>
inline QString baseName( const QString & _file )
{
return( QFileInfo( _file ).dirPath() + "/" +
QFileInfo( _file ).baseName( TRUE ) );
}
#if QT_VERSION < 0x030100
#include <qmutex.h>

View File

@@ -40,7 +40,6 @@
#endif
#include "lmms_main_win.h"
#include "track_container.h"
#include "types.h"
@@ -48,20 +47,18 @@
class QComboBox;
class QLabel;
class QPixmap;
class QPushButton;
class QScrollBar;
class QSlider;
class QToolButton;
class exportProjectDialog;
class lcdSpinBox;
class lmmsMainWin;
class pattern;
class projectNotes;
class timeLine;
class toolButton;
class visualizationWidget;
const int MIN_BPM = 10;
const int DEFAULT_BPM = 140;
const int MAX_BPM = 999;
@@ -142,19 +139,20 @@ public:
return( m_exporting == TRUE &&
m_playPos[PLAY_SONG].getTact() >= lengthInTacts() + 1 );
}
inline void setExportProjectDialog( exportProjectDialog * _epd )
{
m_epd = _epd;
}
inline playModes playMode( void ) const
{
return( m_playMode );
}
inline playPos & getPlayPos( playModes _pm )
{
return( m_playPos[_pm] );
}
tact lengthInTacts( void ) const;
int getBPM( void );
// every function that replaces current file (e.g. creates new file,
@@ -228,8 +226,8 @@ protected:
protected slots:
void insertTact( void );
void removeTact( void );
void insertBar( void );
void removeBar( void );
void addBBTrack( void );
void addSampleTrack( void );
void scrolled( int _new_pos );
@@ -243,7 +241,6 @@ protected slots:
void masterPitchPressed( void );
void masterPitchMoved( int _new_val );
void masterPitchReleased( void );
void toggleHQMode( void );
void updatePosition( const midiTime & _t );
@@ -264,7 +261,6 @@ private:
}
midiTime length( void ) const;
tact lengthInTacts( void ) const;
inline tact64th currentTact64th( void ) const
{
return( m_playPos[m_playMode].getTact64th() );
@@ -278,8 +274,10 @@ private:
QScrollBar * m_leftRightScroll;
QToolButton * m_playButton;
QToolButton * m_stopButton;
QWidget * m_toolBar;
toolButton * m_playButton;
toolButton * m_stopButton;
lcdSpinBox * m_bpmSpinBox;
QSlider * m_masterVolumeSlider;
@@ -288,11 +286,10 @@ private:
visualizationWidget * m_masterOutputGraph;
QToolButton * m_addChannelTrackButton;
QToolButton * m_addBBTrackButton;
QToolButton * m_addSampleTrackButton;
QToolButton * m_insertTactButton;
QToolButton * m_removeTactButton;
toolButton * m_addBBTrackButton;
toolButton * m_addSampleTrackButton;
toolButton * m_insertBarButton;
toolButton * m_removeBarButton;
QComboBox * m_zoomingComboBox;
@@ -314,8 +311,6 @@ private:
bool m_scrollBack;
exportProjectDialog * m_epd;
projectNotes * m_projectNotes;
@@ -336,7 +331,7 @@ private:
friend lmmsMainWin::~lmmsMainWin();
friend class lmmsMainWin;

View File

@@ -50,6 +50,22 @@ class timeLine : public QWidget
{
Q_OBJECT
public:
enum autoScrollStates
{
AUTOSCROLL_ENABLED, AUTOSCROLL_DISABLED
} ;
enum loopPointStates
{
LOOP_POINTS_DISABLED, LOOP_POINTS_ENABLED
} ;
enum behaviourAtStopStates
{
BACK_TO_ZERO, BACK_TO_START, KEEP_STOP_POSITION
} ;
timeLine( int _xoff, int _yoff, float _ppt, songEditor::playPos & _pos,
const midiTime & _begin, QWidget * _parent );
~timeLine();
@@ -59,15 +75,16 @@ public:
return( m_pos );
}
enum behaviourAtStopStates
behaviourAtStopStates behaviourAtStop( void ) const
{
BACK_TO_ZERO, BACK_TO_START, KEEP_STOP_POSITION
} ;
return( m_behaviourAtStop );
}
bool loopPointsEnabled( void ) const
{
return( m_loopPoints == LOOP_POINTS_ENABLED );
}
behaviourAtStopStates behaviourAtStop( void ) const;
bool loopPointsEnabled( void ) const;
inline const midiTime & loopBegin( void ) const
{
return( ( m_loopPos[0] < m_loopPos[1] ) ?
@@ -94,10 +111,14 @@ public:
update();
}
void addToolButtons( QWidget * _tool_bar );
public slots:
void updatePosition( const midiTime & = 0 );
void toggleAutoScroll( int _n );
void toggleLoopPoints( int _n );
void toggleBehaviourAtStop( int _n );
protected:
@@ -114,14 +135,14 @@ private:
m_ppt / 64.0f ) );
}
static QPixmap * s_timeLinePixmap;
static QPixmap * s_posMarkerPixmap;
static QPixmap * s_loopPointPixmap;
static QPixmap * s_loopPointDisabledPixmap;
nStateButton * m_autoScroll;
nStateButton * m_loopPoints;
nStateButton * m_behaviourAtStop;
autoScrollStates m_autoScroll;
loopPointStates m_loopPoints;
behaviourAtStopStates m_behaviourAtStop;
int m_xOffset;
int m_posMarkerX;
@@ -141,17 +162,6 @@ private:
int m_moveXOff;
enum autoScrollStates
{
AUTOSCROLL_ENABLED, AUTOSCROLL_DISABLED
} ;
enum loopPointStates
{
LOOP_POINTS_DISABLED, LOOP_POINTS_ENABLED
} ;
signals:
void positionChanged( const midiTime & _t );

69
include/tool_button.h Normal file
View File

@@ -0,0 +1,69 @@
/*
* tool_button.h - declaration of class toolButton
*
* Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*/
#ifndef _TOOL_BUTTON_H
#define _TOOL_BUTTON_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "qt3support.h"
#ifdef QT4
#include <QPushButton>
#else
#include <qpushbutton.h>
#endif
#include "tooltip.h"
class toolButton : public QPushButton
{
public:
toolButton( const QPixmap & _pixmap, const QString & _tooltip,
QObject * _receiver, const char * _slot,
QWidget * _parent ) :
QPushButton( _parent )
{
connect( this, SIGNAL( clicked() ), _receiver, _slot );
toolTip::add( this, _tooltip );
setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
setFixedSize( 30, 30 );
setPixmap( _pixmap );
}
~toolButton()
{
}
} ;
#endif

View File

@@ -2,6 +2,6 @@ if VST_SUPPORT
VESTIGE_SUBDIR=vestige
endif
SUBDIRS = audio_file_processor ladspa_sine_1063 midi_out plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR)
SUBDIRS = audio_file_processor midi_out plucked_string_synth triple_oscillator $(VESTIGE_SUBDIR)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
resources/drum.png Normal file

Binary file not shown.

BIN
resources/hq_mode.png Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -61,7 +61,8 @@ audioALSA::audioALSA( Uint32 _sample_rate, bool & _success_ful ) :
m_handle( NULL ),
m_hwParams( NULL ),
m_swParams( NULL ),
m_littleEndian( isLittleEndian() )
m_littleEndian( isLittleEndian() ),
m_quit( FALSE )
{
_success_ful = FALSE;
@@ -105,6 +106,7 @@ audioALSA::audioALSA( Uint32 _sample_rate, bool & _success_ful ) :
audioALSA::~audioALSA()
{
stopProcessing();
if( m_handle != NULL )
{
snd_pcm_close( m_handle );
@@ -175,40 +177,77 @@ int audioALSA::handleError( int _err )
void audioALSA::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioALSA::startProcessing( void )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
bufferAllocator::autoCleaner<> ac( outbuf );
if( !running() )
{
start();
}
}
convertToS16( _ab, _frames, _master_gain, outbuf,
void audioALSA::stopProcessing( void )
{
if( running() )
{
m_quit = TRUE;
wait( 500 );
terminate();
}
}
void audioALSA::run( void )
{
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() );
outputSampleType * outbuf =
bufferAllocator::alloc<outputSampleType>(
mixer::inst()->framesPerAudioBuffer() *
channels() );
m_quit = FALSE;
while( m_quit == FALSE )
{
const Uint32 frames = getNextBuffer( temp );
convertToS16( temp, frames, mixer::inst()->masterGain(), outbuf,
m_littleEndian != isLittleEndian() );
Uint32 frame = 0;
Uint32 frame = 0;
outputSampleType * ptr = outbuf;
while( frame < _frames )
{
int err = snd_pcm_writei( m_handle, outbuf, _frames );
if( err == -EAGAIN )
while( frame < frames )
{
continue;
}
int err = snd_pcm_writei( m_handle, ptr, frames );
if( err < 0 )
{
if( handleError( err ) < 0 )
if( err == -EAGAIN )
{
printf( "Write error: %s\n",
snd_strerror( err ) );
return;
usleep( 10 );
continue;
}
break; // skip this buffer
if( err < 0 )
{
if( handleError( err ) < 0 )
{
printf( "Write error: %s\n",
snd_strerror( err ) );
}
break; // skip this buffer
}
ptr += err * channels();
frame += err;
}
outbuf += err * channels();
frame += err;
}
bufferAllocator::free( temp );
bufferAllocator::free( outbuf );
}

View File

@@ -38,7 +38,9 @@
audioDevice::audioDevice( Uint32 _sample_rate, Uint8 _channels ) :
m_sampleRate( _sample_rate ),
m_channels( _channels )
m_channels( _channels ),
m_buffer( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) )
{
#ifdef HAVE_SAMPLERATE_H
int error;
@@ -64,34 +66,46 @@ audioDevice::~audioDevice()
#ifdef HAVE_SAMPLERATE_H
src_delete( m_srcState );
#endif
bufferAllocator::free( m_buffer );
unlock();
}
void audioDevice::writeBuffer( surroundSampleFrame * _ab, Uint32 _frames,
Uint32 _src_sample_rate, float _master_gain )
void audioDevice::processNextBuffer( void )
{
const Uint32 frames = getNextBuffer( m_buffer );
writeBuffer( m_buffer, frames, mixer::inst()->masterGain() );
}
Uint32 audioDevice::getNextBuffer( surroundSampleFrame * _ab )
{
Uint32 frames = mixer::inst()->framesPerAudioBuffer();
const surroundSampleFrame * b = mixer::inst()->renderNextBuffer();
// make sure, no other thread is accessing device
lock();
// now were save to access the device
if( _src_sample_rate != m_sampleRate )
// now were safe to access the device
if( mixer::inst()->sampleRate() != m_sampleRate )
{
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
_frames * channels() );
resample( _ab, _frames, temp, _src_sample_rate, m_sampleRate );
writeBufferToDev( temp, _frames * m_sampleRate /
_src_sample_rate, _master_gain );
bufferAllocator::free( temp );
resample( b, frames, _ab, mixer::inst()->sampleRate(),
m_sampleRate );
frames = frames * m_sampleRate / mixer::inst()->sampleRate();
}
else
{
writeBufferToDev( _ab, _frames, _master_gain );
memcpy( _ab, b, frames * sizeof( surroundSampleFrame ) );
}
// release lock
unlock();
return( frames );
}
@@ -111,7 +125,7 @@ void audioDevice::unregisterPort( audioPort * _port )
void audioDevice::renamePort( audioPort *, const QString & )
void audioDevice::renamePort( audioPort * )
{
}
@@ -150,7 +164,8 @@ const float LP_FILTER_COEFFS[LP_FILTER_TAPS] =
#endif
void FASTCALL audioDevice::resample( surroundSampleFrame * _src, Uint32 _frames,
void FASTCALL audioDevice::resample( const surroundSampleFrame * _src,
Uint32 _frames,
surroundSampleFrame * _dst,
Uint32 _src_sr, Uint32 _dst_sr )
{
@@ -161,7 +176,7 @@ void FASTCALL audioDevice::resample( surroundSampleFrame * _src, Uint32 _frames,
}
m_srcData.input_frames = _frames;
m_srcData.output_frames = _frames;
m_srcData.data_in = _src[0];
m_srcData.data_in = (float *) _src[0];
m_srcData.data_out = _dst[0];
m_srcData.src_ratio = (float) _dst_sr / _src_sr;
@@ -172,7 +187,7 @@ void FASTCALL audioDevice::resample( surroundSampleFrame * _src, Uint32 _frames,
src_strerror( error ) );
}
#else
if( _src_sr == 2*SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] )
if( _src_sr == 2 * SAMPLE_RATES[DEFAULT_QUALITY_LEVEL] )
{
// we use a simple N-tap FIR-Filter with
// precalculated/-designed LP-Coeffs

View File

@@ -39,6 +39,7 @@
#include "audio_file_device.h"
#include "export_project_dialog.h"
#include "buffer_allocator.h"
audioFileDevice::audioFileDevice( Uint32 _sample_rate, Uint8 _channels,

View File

@@ -1,5 +1,5 @@
/*
* audio_file_ogg.cpp - Audio-device which encodes wave-stream and writes it
* audio_file_ogg.cpp - audio-device which encodes wave-stream and writes it
* into an OGG-file. This is used for song-export.
*
* This file is based on encode.c from vorbis-tools-source, for more information
@@ -27,17 +27,6 @@
*/
/* OggEnc
**
** This program is distributed under the GNU General Public License, version 2.
** A copy of this license is included with this source.
**
** Copyright 2000-2002, Michael Smith <msmith@labyrinth.net.au>
**
** Portions from Vorbize, (c) Kenneth Arnold <kcarnold@yahoo.com>
** and libvorbis examples, (c) Monty <monty@xiph.org>
**/
#include <qpair.h>
@@ -84,7 +73,7 @@ inline int audioFileOgg::writePage( void )
bool audioFileOgg::startEncoding( void )
{
vorbis_comment vc;
char * comments = "Cool=This song was written with Linux "
char * comments = "Cool=This song has been made using Linux "
"MultiMedia Studio";
int comment_length = strlen( comments );
@@ -185,7 +174,7 @@ bool audioFileOgg::startEncoding( void )
void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
void FASTCALL audioFileOgg::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
{
@@ -253,7 +242,7 @@ void FASTCALL audioFileOgg::writeBufferToDev( surroundSampleFrame * _ab,
void audioFileOgg::finishEncoding( void )
{
// just for flushing buffers...
writeBufferToDev( NULL, 0, 0.0f );
writeBuffer( NULL, 0, 0.0f );
// clean up
ogg_stream_clear( &m_os );

View File

@@ -1,5 +1,5 @@
/*
* audio_file_wave.cpp - Audio-device which encodes wave-stream and writes it
* audio_file_wave.cpp - audio-device which encodes wave-stream and writes it
* into a WAVE-file. This is used for song-export.
*
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
@@ -87,7 +87,7 @@ bool audioFileWave::startEncoding( void )
void FASTCALL audioFileWave::writeBufferToDev( surroundSampleFrame * _ab,
void FASTCALL audioFileWave::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames,
float _master_gain )
{

View File

@@ -28,12 +28,6 @@
#ifdef JACK_SUPPORT
#ifdef HAVE_UNISTD_H
// for usleep
#include <unistd.h>
#endif
#ifdef QT4
#include <QLineEdit>
@@ -55,6 +49,7 @@
#include "buffer_allocator.h"
#include "config_mgr.h"
#include "lcd_spinbox.h"
#include "audio_port.h"
@@ -62,10 +57,13 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<int>( configManager::inst()->value(
"audiojack", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ) ),
m_client( NULL ),
m_stopped( FALSE ),
m_processCallbackMutex(),
m_outBuf( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
m_framesDoneInCurBuf( 0 ),
m_frameSync( 0 ),
m_jackBufSize( 0 ),
m_bufMutex()
m_framesToDoInCurBuf( 0 )
{
_success_ful = FALSE;
@@ -120,12 +118,6 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
// set process-callback
jack_set_process_callback( m_client, processCallback, this );
m_jackBufSize = jack_get_buffer_size( m_client );
// we need to know about buffer-size changes to know how long to block
// in writeToDev()-method
jack_set_buffer_size_callback( m_client, bufSizeCallback, this );
// set shutdown-callback
jack_on_shutdown( m_client, shutdownCallback, this );
@@ -140,7 +132,7 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
for( Uint8 ch = 0; ch < channels(); ++ch )
{
QString name = QString( "master_out_" ) +
QString name = QString( "master out " ) +
( ( ch % 2 ) ? "R" : "L" ) +
QString::number( ch / 2 + 1 );
m_outputPorts.push_back( jack_port_register( m_client,
@@ -212,80 +204,62 @@ audioJACK::audioJACK( Uint32 _sample_rate, bool & _success_ful ) :
audioJACK::~audioJACK()
{
while( m_portMap.size() )
{
unregisterPort( m_portMap.begin().key() );
}
if( m_client != NULL )
{
jack_deactivate( m_client );
jack_client_close( m_client );
}
while( m_bufferSets.size() )
{
while( m_bufferSets.front().size() )
{
bufferAllocator::free(
m_bufferSets.front().front().buf );
m_bufferSets.front().erase(
m_bufferSets.front().begin() );
}
m_bufferSets.erase( m_bufferSets.begin() );
}
bufferAllocator::free( m_outBuf );
}
void audioJACK::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioJACK::startProcessing( void )
{
if( m_client == NULL )
{
return;
}
m_bufMutex.lock();
jack_transport_state_t ts = jack_transport_query( m_client, NULL );
if( ts == JackTransportRolling )
{
vvector<bufset> bufs;
for( Uint8 chnl = 0; chnl < channels(); ++chnl )
{
sampleType * buf = bufferAllocator::alloc<sampleType>(
_frames );
for( Uint32 frame = 0; frame < _frames; ++frame )
{
buf[frame] = _ab[frame][chnl] * _master_gain;
}
bufset b = { buf, _frames } ;
bufs.push_back( b );
}
m_bufferSets.push_back( bufs );
}
m_frameSync += _frames;
m_bufMutex.unlock();
// now wait until data has been collected/skipped by processCallback()
while( m_frameSync > m_jackBufSize )
{
#ifdef HAVE_UNISTD_H
#ifdef HAVE_USLEEP
// just wait and give cpu-time to other processes
// tobydox 20051019: causes LMMS to hang up when locking
// several other mutexes, so skip it
//usleep( 200 );
#endif
#endif
}
m_stopped = FALSE;
}
void audioJACK::registerPort( audioPort * )
void audioJACK::stopProcessing( void )
{
m_stopped = TRUE;
}
void audioJACK::registerPort( audioPort * _port )
{
return;
/* // make sure, port is not already registered
unregisterPort( _port );
const QString name[2] = { _port->name() + " L",
_port->name() + " R" } ;
m_processCallbackMutex.lock();
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
m_portMap[_port].ports[ch] = jack_port_register( m_client,
name[ch].
#ifdef QT4
toAscii().constData(),
#else
ascii(),
#endif
JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0 );
}
m_processCallbackMutex.unlock();*/
}
@@ -293,13 +267,45 @@ void audioJACK::registerPort( audioPort * )
void audioJACK::unregisterPort( audioPort * _port )
{
return;
/* if( m_portMap.contains( _port ) )
{
m_processCallbackMutex.lock();
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
if( m_portMap[_port].ports[ch] != NULL )
{
jack_port_unregister( m_client,
m_portMap[_port].ports[ch] );
}
}
m_portMap.erase( m_portMap.find( _port ) );
m_processCallbackMutex.unlock();
}*/
}
void audioJACK::renamePort( audioPort *, const QString & )
void audioJACK::renamePort( audioPort * _port )
{
return;
/* if( m_portMap.contains( _port ) )
{
const QString name[2] = { _port->name() + " L",
_port->name() + " R" };
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
jack_port_set_name( m_portMap[_port].ports[ch],
name[ch].
#ifdef QT4
toAscii().constData()
#else
ascii()
#endif
) ;
}
}*/
}
@@ -308,6 +314,7 @@ void audioJACK::renamePort( audioPort *, const QString & )
int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
{
audioJACK * _this = static_cast<audioJACK *>( _udata );
_this->m_processCallbackMutex.lock();
/* printf( "%f\n", jack_cpu_load( _this->m_client ) );*/
@@ -316,104 +323,78 @@ int audioJACK::processCallback( jack_nframes_t _nframes, void * _udata )
#endif
jack_transport_state_t ts = jack_transport_query( _this->m_client,
NULL );
_this->m_bufMutex.lock();
if( ts != JackTransportRolling )
{
// always decrease frame-sync-var as we would do it if running
// in normal mode, so that the mixer-thread knows when to
// proceed
if( _nframes < _this->m_frameSync )
{
_this->m_frameSync -= _nframes;
}
else
{
_this->m_frameSync = 0;
}
_this->m_bufMutex.unlock();
return( 0 );
}
vvector<jack_default_audio_sample_t *> outbufs( _this->channels(),
NULL );
Uint8 ch = 0;
Uint8 chnl = 0;
for( vvector<jack_default_audio_sample_t *>::iterator it =
outbufs.begin(); it != outbufs.end(); ++it, ++ch )
outbufs.begin(); it != outbufs.end(); ++it, ++chnl )
{
*it = (jack_default_audio_sample_t *) jack_port_get_buffer(
_this->m_outputPorts[ch], _nframes );
_this->m_outputPorts[chnl], _nframes );
}
/* const Uint32 frames = tMin<Uint32>( _nframes,
mixer::inst()->framesPerAudioBuffer() );
for( jackPortMap::iterator it = _this->m_portMap.begin();
it != _this->m_portMap.end(); ++it )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
if( it.data().ports[ch] == NULL )
{
continue;
}
jack_default_audio_sample_t * buf =
(jack_default_audio_sample_t *) jack_port_get_buffer(
it.data().ports[ch],
_nframes );
for( Uint32 frame = 0; frame < frames; ++frame )
{
buf[frame] = it.key()->firstBuffer()[ch][frame];
}
}
}*/
jack_nframes_t done = 0;
while( done < _nframes )
while( done < _nframes && _this->m_stopped == FALSE )
{
if( _this->m_bufferSets.size() == 0 )
{
break;
}
jack_nframes_t todo = tMin( _nframes - done,
_this->m_bufferSets.front()[0].frames -
jack_nframes_t todo = tMin<jack_nframes_t>(
_nframes,
_this->m_framesToDoInCurBuf -
_this->m_framesDoneInCurBuf );
for( Uint8 ch = 0; ch < _this->channels(); ++ch )
if( ts == JackTransportRolling )
{
memcpy( outbufs[ch] + done,
_this->m_bufferSets.front()[ch].buf +
_this->m_framesDoneInCurBuf,
sizeof( jack_default_audio_sample_t ) *
todo );
}
_this->m_framesDoneInCurBuf += todo;
if( _this->m_framesDoneInCurBuf >=
_this->m_bufferSets.front()[0].frames )
{
for( Uint8 ch = 0; ch < _this->channels(); ++ch )
for( Uint8 chnl = 0; chnl < _this->channels(); ++chnl )
{
bufferAllocator::free(
_this->m_bufferSets.front()[ch].buf );
for( Uint32 frame = 0; frame < todo; ++frame )
{
outbufs[chnl][done+frame] =
_this->m_outBuf[_this->m_framesDoneInCurBuf+frame][chnl] *
mixer::inst()->masterGain();
}
}
_this->m_bufferSets.erase(
_this->m_bufferSets.begin() );
_this->m_framesDoneInCurBuf = 0;
}
done += todo;
_this->m_frameSync -= todo;
_this->m_framesDoneInCurBuf += todo;
if( _this->m_framesDoneInCurBuf == _this->m_framesToDoInCurBuf )
{
_this->m_framesToDoInCurBuf = _this->getNextBuffer(
_this->m_outBuf );
_this->m_framesDoneInCurBuf = 0;
}
}
// we have to clear the part of the buffers, if we could not fill
// because no usable data is left, otherwise there's baaaaaad
// noise... ;-)
if( done < _nframes )
if( ts != JackTransportRolling || _this->m_stopped == TRUE )
{
for( Uint8 ch = 0; ch < _this->channels(); ++ch )
{
jack_default_audio_sample_t * b = outbufs[ch];
memset( b + done, 0,
sizeof( *b ) * ( _nframes - done ) );
/* for( Uint32 frame = done; frame < _nframes; ++frame )
{
b[frame] = 0.0f;
}*/
memset( b, 0, sizeof( *b ) * _nframes );
}
}
_this->m_bufMutex.unlock();
return( 0 );
}
int audioJACK::bufSizeCallback( jack_nframes_t _nframes, void * _udata )
{
audioJACK * _this = static_cast<audioJACK *>( _udata );
#ifdef LMMS_DEBUG
assert( _this != NULL );
#endif
_this->m_jackBufSize = _nframes;
_this->m_processCallbackMutex.unlock();
return( 0 );
}

View File

@@ -95,7 +95,8 @@ audioOSS::audioOSS( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, tLimit<int>( configManager::inst()->value(
"audiooss", "channels" ).toInt(),
DEFAULT_CHANNELS, SURROUND_CHANNELS ) ),
m_convertEndian( FALSE )
m_convertEndian( FALSE ),
m_quit( FALSE )
{
_success_ful = FALSE;
@@ -231,6 +232,7 @@ audioOSS::audioOSS( Uint32 _sample_rate, bool & _success_ful ) :
audioOSS::~audioOSS()
{
stopProcessing();
close( m_audioFD );
}
@@ -278,15 +280,52 @@ QString audioOSS::probeDevice( void )
void audioOSS::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioOSS::startProcessing( void )
{
outputSampleType * outbuf = bufferAllocator::alloc<outputSampleType>(
_frames * channels() );
int bytes = convertToS16( _ab, _frames, _master_gain, outbuf,
m_convertEndian );
write( m_audioFD, outbuf, bytes );
if( !running() )
{
start();
}
}
void audioOSS::stopProcessing( void )
{
if( running() )
{
m_quit = TRUE;
wait( 500 );
terminate();
}
}
void audioOSS::run( void )
{
surroundSampleFrame * temp =
bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() );
outputSampleType * outbuf =
bufferAllocator::alloc<outputSampleType>(
mixer::inst()->framesPerAudioBuffer() *
channels() );
m_quit = FALSE;
while( m_quit == FALSE )
{
const Uint32 frames = getNextBuffer( temp );
int bytes = convertToS16( temp, frames,
mixer::inst()->masterGain(), outbuf,
m_convertEndian );
write( m_audioFD, outbuf, bytes );
}
bufferAllocator::free( temp );
bufferAllocator::free( outbuf );
}

View File

@@ -35,13 +35,15 @@ audioPort::audioPort( const QString & _name ) :
m_secondBuffer( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
m_extOutputEnabled( FALSE ),
m_nextFxChannel( -1 )
m_nextFxChannel( -1 ),
m_name( "unnamed port" )
{
mixer::inst()->clearAudioBuffer( m_firstBuffer,
mixer::inst()->framesPerAudioBuffer() );
mixer::inst()->clearAudioBuffer( m_secondBuffer,
mixer::inst()->framesPerAudioBuffer() );
mixer::inst()->addAudioPort( this );
setExtOutputEnabled( TRUE );
}
@@ -95,6 +97,7 @@ void audioPort::setExtOutputEnabled( bool _enabled )
void audioPort::setName( const QString & _name )
{
mixer::inst()->audioDev()->renamePort( this, _name );
m_name = _name;
mixer::inst()->audioDev()->renamePort( this );
}

View File

@@ -96,7 +96,7 @@ void audioSampleRecorder::createSampleBuffer( sampleBuffer * * _sample_buf )
void audioSampleRecorder::writeBufferToDev( surroundSampleFrame * _ab,
void audioSampleRecorder::writeBuffer( surroundSampleFrame * _ab,
Uint32 _frames, float )
{
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( _frames );

View File

@@ -50,11 +50,8 @@
audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
audioDevice( _sample_rate, DEFAULT_CHANNELS ),
m_buffer( bufferAllocator::alloc<outputSampleType>(
mixer::inst()->framesPerAudioBuffer() *
channels() ) ),
m_bufMutex(),
m_callbackMutex(),
m_outBuf( bufferAllocator::alloc<surroundSampleFrame>(
mixer::inst()->framesPerAudioBuffer() ) ),
m_convertEndian( FALSE )
{
_success_ful = FALSE;
@@ -99,11 +96,6 @@ audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
}
m_convertEndian = ( m_audioHandle.format != actual.format );
clearS16Buffer( m_buffer, m_audioHandle.samples );
// start playing
SDL_PauseAudio( 0 );
_success_ful = TRUE;
}
@@ -112,31 +104,31 @@ audioSDL::audioSDL( Uint32 _sample_rate, bool & _success_ful ) :
audioSDL::~audioSDL()
{
SDL_PauseAudio( 1 );
stopProcessing();
SDL_CloseAudio();
SDL_Quit();
m_bufMutex.lock();
bufferAllocator::free( m_buffer );
m_bufMutex.unlock();
bufferAllocator::free( m_outBuf );
}
void audioSDL::writeBufferToDev( surroundSampleFrame * _ab, Uint32 _frames,
float _master_gain )
void audioSDL::startProcessing( void )
{
m_bufMutex.lock();
convertToS16( _ab, _frames, _master_gain, m_buffer,
m_convertEndian );
m_bufMutex.unlock();
// before returning make sure, callback was called, so we're synced
// with it (otherwise it could be that (if there's not much to render)
// this function is called several times although we had to wait until
// we can proceed with next audio-output)
m_callbackMutex.lock();
SDL_PauseAudio( 0 );
SDL_UnlockAudio();
}
void audioSDL::stopProcessing( void )
{
if( SDL_GetAudioStatus() == SDL_AUDIO_PLAYING )
{
SDL_LockAudio();
SDL_PauseAudio( 1 );
}
}
@@ -150,21 +142,12 @@ void audioSDL::sdlAudioCallback( void * _udata, Uint8 * _buf, int _len )
assert( _this != NULL );
#endif
_this->m_bufMutex.lock();
const Uint32 frames = _this->getNextBuffer( _this->m_outBuf );
// writeBufferToDev() prepared everything for us, so we just have
// to do a memcpy() :-)
memcpy( _buf, _this->m_buffer, _len );
// clear our output buffer, so that we don't output the same noise
// when being called again without that writeBufferToDev() was called
// (e.g. if there's too much to render)
_this->clearS16Buffer( _this->m_buffer, _this->m_audioHandle.samples );
_this->m_bufMutex.unlock();
// we got our last buffer, so we let writeBufferToDev() return
_this->m_callbackMutex.unlock();
_this->convertToS16( _this->m_outBuf, frames,
mixer::inst()->masterGain(),
(outputSampleType *)( _buf ),
_this->m_convertEndian );
}

View File

@@ -39,6 +39,7 @@
#include <qdom.h>
#include <qlabel.h>
#include <qcombobox.h>
#include <qwhatsthis.h>
#define setChecked setOn

View File

@@ -30,10 +30,12 @@
#include <QPainter>
#include <QKeyEvent>
#include <QCloseEvent>
#include <QLayout>
#else
#include <qpainter.h>
#include <qlayout.h>
#endif
@@ -41,13 +43,12 @@
#include "bb_editor.h"
#include "song_editor.h"
#include "embed.h"
#include "pixmap_button.h"
#include "tool_button.h"
#include "track_container.h"
#include "bb_track.h"
#include "name_label.h"
#include "templates.h"
#include "debug.h"
#include "spc_bg_hndl_widget.h"
#include "tooltip.h"
@@ -57,18 +58,22 @@ const int BBE_PPT = 192;
bbEditor * bbEditor::s_instanceOfMe = NULL;
QPixmap * bbEditor::s_titleArtwork = NULL;
bbEditor::bbEditor() :
trackContainer()
{
if( s_titleArtwork == NULL )
{
s_titleArtwork = new QPixmap( embed::getIconPixmap(
"bb_editor_title_artwork" ) );
}
// create toolbar
m_toolBar = new QWidget( this );
m_toolBar->setFixedHeight( 32 );
m_toolBar->move( 0, 0 );
m_toolBar->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
QHBoxLayout * tb_layout = new QHBoxLayout( m_toolBar );
setWindowIcon( embed::getIconPixmap( "bb_track" ) );
setWindowTitle( tr( "Beat+Bassline Editor" ) );
@@ -83,33 +88,19 @@ bbEditor::bbEditor() :
setGeometry( 210, 340, minimumWidth(), 300 );
}
containerWidget()->move( 0, 47 );
containerWidget()->move( 0, 32 );
setPixelsPerTact( BBE_PPT );
updateBackground();
m_playButton = new pixmapButton( this );
m_playButton->move( 96, 7 );
m_playButton->setCheckable( FALSE );
m_playButton->setActiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setBgGraphic( specialBgHandlingWidget::getBackground(
m_playButton ) );
connect( m_playButton, SIGNAL( clicked() ), this, SLOT( play() ) );
m_stopButton = new pixmapButton( this );
m_stopButton->move( 136, 7 );
m_stopButton->setCheckable( FALSE );
m_stopButton->setActiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setInactiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setBgGraphic( specialBgHandlingWidget::getBackground(
m_playButton ) );
connect( m_stopButton, SIGNAL( clicked() ), this, SLOT( stop() ) );
toolTip::add( m_playButton,
tr( "Play/pause current beat/bassline (Space)" ) );
toolTip::add( m_stopButton,
tr( "Stop playing of current beat/bassline (Space)" ) );
m_playButton = new toolButton( embed::getIconPixmap( "play" ),
tr( "Play/pause current beat/bassline (Space)" ),
this, SLOT( play() ), m_toolBar );
m_stopButton = new toolButton( embed::getIconPixmap( "stop" ),
tr( "Stop playing of current beat/bassline (Space)" ),
this, SLOT( stop() ), m_toolBar );
#ifdef QT4
m_playButton->setWhatsThis(
#else
@@ -126,9 +117,15 @@ bbEditor::bbEditor() :
tr( "Click here, if you want to stop playing of current "
"beat/bassline." ) );
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
QLabel * l = new QLabel( m_toolBar );
l->setPixmap( embed::getIconPixmap( "drum" ) );
tb_layout->addSpacing( 5 );
tb_layout->addWidget( m_playButton );
tb_layout->addWidget( m_stopButton );
tb_layout->addStretch();
tb_layout->addWidget( l );
tb_layout->addSpacing( 15 );
show();
}
@@ -305,39 +302,11 @@ void bbEditor::keyPressEvent( QKeyEvent * _ke )
void bbEditor::resizeEvent( QResizeEvent * _re )
{
updateBackground();
setPixelsPerTact( width() - ( TRACK_OP_WIDTH +
DEFAULT_SETTINGS_WIDGET_WIDTH + 2 *
TCO_BORDER_WIDTH ) );
trackContainer::resizeEvent( _re );
}
void bbEditor::updateBackground( void )
{
QPixmap draw_pm( size() );
#ifdef QT4
draw_pm.fill( containerWidget()->palette().brush(
containerWidget()->backgroundRole() ).color() );
#else
draw_pm.fill( containerWidget()->paletteBackgroundColor() );
#endif
QPainter p( &draw_pm );
p.fillRect( 0, 0, width(), s_titleArtwork->height(),
QColor( 74, 125, 213 ) );
p.drawPixmap( 0, 0, *s_titleArtwork );
#ifdef QT4
QPalette pal = palette();
pal.setBrush( backgroundRole(), QBrush( draw_pm ) );
setPalette( pal );
#else
setErasePixmap( draw_pm );
#endif
m_toolBar->setFixedWidth( width() );
}
@@ -351,26 +320,24 @@ void bbEditor::play( void )
{
songEditor::inst()->stop();
songEditor::inst()->playBB();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"pause" ) );
}
else
{
songEditor::inst()->pause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"play" ) );
}
}
else if( songEditor::inst()->paused() )
{
songEditor::inst()->resumeFromPause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
}
else
{
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
songEditor::inst()->playBB();
}
@@ -382,7 +349,7 @@ void bbEditor::play( void )
void bbEditor::stop( void )
{
songEditor::inst()->stop();
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap( "play" ) );
m_playButton->update();
}

View File

@@ -740,7 +740,7 @@ bool configManager::loadConfigFile( void )
// get the head information from the DOM
QDomElement root = dom_tree.documentElement();
if( root.isElement() )
/* if( root.isElement() )
{
QString cfg_file_ver = root.toElement().attribute( "version" );
if( ( cfg_file_ver.length() == 0 || cfg_file_ver != VERSION ) &&
@@ -771,7 +771,7 @@ bool configManager::loadConfigFile( void )
return( loadConfigFile() );
}
}
}
}*/
QDomNode node = root.firstChild();

View File

@@ -32,10 +32,10 @@
#include <QProgressBar>
#include <QComboBox>
#include <QCheckBox>
#include <QTimer>
#include <QLabel>
#include <QPushButton>
#include <QCloseEvent>
#include <QApplication>
#else
@@ -44,21 +44,25 @@
#include <qprogressbar.h>
#include <qcombobox.h>
#include <qcheckbox.h>
#include <qtimer.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qapplication.h>
#endif
#include "export_project_dialog.h"
#include "song_editor.h"
#include "lmms_main_win.h"
#include "embed.h"
#include "audio_file_wave.h"
#include "audio_file_ogg.h"
extern QString file_to_render;
fileEncodeDevice fileEncodeDevices[] =
{
@@ -129,9 +133,7 @@ exportProjectDialog::exportProjectDialog( const QString & _file_name,
QDialog( _parent ),
m_fileName( _file_name ),
m_hourglassLbl( NULL ),
m_exportProgressBar( NULL ),
m_deleteFile( FALSE ),
m_oldProgressVal( -1 )
m_deleteFile( FALSE )
{
#ifdef QT4
m_fileType = getFileTypeFromExtension( "." +
@@ -312,35 +314,6 @@ void exportProjectDialog::exportBtnClicked( void )
{
if( fileEncodeDevices[idx].m_fileType == m_fileType )
{
bool success_ful = FALSE;
audioDevice * dev = fileEncodeDevices[idx].m_getDevInst(
DEFAULT_SAMPLE_RATE,
DEFAULT_CHANNELS,
success_ful,
m_fileName,
m_vbrCb->isChecked(),
m_kbpsCombo->currentText().toInt(),
m_kbpsCombo->currentText().toInt() - 64,
m_kbpsCombo->currentText().toInt() + 64
);
if( success_ful == FALSE )
{
QMessageBox::information( this,
tr( "Export failed" ),
tr( "The project-export failed, "
"because the output-file/-"
"device could not be opened.\n"
"Make sure, you have write "
"access to the selected "
"file/device!" ),
QMessageBox::Ok );
return;
}
mixer::inst()->pause();
mixer::inst()->setAudioDevice( dev,
m_hqmCb->isChecked() );
songEditor::inst()->startExport();
mixer::inst()->play();
break;
}
++idx;
@@ -351,6 +324,32 @@ void exportProjectDialog::exportBtnClicked( void )
return;
}
bool success_ful = FALSE;
audioFileDevice * dev = fileEncodeDevices[idx].m_getDevInst(
DEFAULT_SAMPLE_RATE,
DEFAULT_CHANNELS,
success_ful,
m_fileName,
m_vbrCb->isChecked(),
m_kbpsCombo->currentText().toInt(),
m_kbpsCombo->currentText().toInt() - 64,
m_kbpsCombo->currentText().toInt() + 64
);
if( success_ful == FALSE )
{
QMessageBox::information( this,
tr( "Export failed" ),
tr( "The project-export failed, "
"because the output-file/-"
"device could not be opened.\n"
"Make sure, you have write "
"access to the selected "
"file/device!" ),
QMessageBox::Ok );
return;
}
setWindowTitle( tr( "Exporting project to %1" ).arg(
QFileInfo( m_fileName ).fileName() ) );
@@ -379,11 +378,40 @@ void exportProjectDialog::exportBtnClicked( void )
m_cancelBtn->move( CANCEL_X_WHILE_EXPORT, CANCEL_Y_WHILE_EXPORT );
m_progressBarUpdateTimer = new QTimer( this );
connect( m_progressBarUpdateTimer, SIGNAL( timeout() ), this,
SLOT( redrawProgressBar() ) );
m_progressBarUpdateTimer->start( 100 );
mixer::inst()->setAudioDevice( dev, m_hqmCb->isChecked() );
songEditor::inst()->startExport();
songEditor::playPos & pp = songEditor::inst()->getPlayPos(
songEditor::PLAY_SONG );
while( songEditor::inst()->exportDone() == FALSE &&
songEditor::inst()->exporting() == TRUE )
{
dev->processNextBuffer();
int pval = pp * 100 /
( ( songEditor::inst()->lengthInTacts() + 1 ) * 64 );
#ifdef QT4
m_exportProgressBar->setValue( pval );
#else
m_exportProgressBar->setProgress( pval );
#endif
// update lmms-main-win-caption
lmmsMainWin::inst()->setWindowTitle( tr( "Rendering:" ) + " " +
QString::number( pval ) + "%" );
// process paint-events etc.
qApp->processEvents();
}
// if m_deleteFile == TRUE, user aborted export and finalization-
// routines were already called, so we only need to call them if
// export went through without any problems
if( m_deleteFile == FALSE )
{
finishProjectExport();
}
}
@@ -398,19 +426,6 @@ void exportProjectDialog::cancelBtnClicked( void )
abortProjectExport();
return;
}
// if the user aborted export-process, the file has to be deleted
if( m_deleteFile )
{
QFile( m_fileName ).remove();
}
// restore window-title
lmmsMainWin::inst()->resetWindowTitle();
// let's close us...
accept();
}
@@ -419,7 +434,6 @@ void exportProjectDialog::cancelBtnClicked( void )
// called whenever there's a reason for aborting song-export (like user-input)
void exportProjectDialog::abortProjectExport( void )
{
mixer::inst()->pause();
m_deleteFile = TRUE;
finishProjectExport();
@@ -430,53 +444,32 @@ void exportProjectDialog::abortProjectExport( void )
void exportProjectDialog::finishProjectExport( void )
{
m_progressBarUpdateTimer->stop();
delete m_progressBarUpdateTimer;
mixer::inst()->restoreAudioDevice();
// if the user aborted export-process, the file has to be deleted
if( m_deleteFile )
{
QFile( m_fileName ).remove();
}
// restore window-title
lmmsMainWin::inst()->resetWindowTitle();
songEditor::inst()->stopExport();
mixer::inst()->play();
// this method does the final cleanup...
cancelBtnClicked();
}
void exportProjectDialog::redrawProgressBar( void )
{
if( m_progressVal != m_oldProgressVal )
// if we rendered file from command line, quit after export
if( file_to_render != "" )
{
#ifdef QT4
m_exportProgressBar->setValue( m_progressVal );
#else
m_exportProgressBar->setProgress( m_progressVal );
#endif
// update lmms-main-win-caption
lmmsMainWin::inst()->setWindowTitle( tr( "Rendering:" ) + " " +
QString::number( m_progressVal ) + "%" );
m_oldProgressVal = m_progressVal;
}
if( songEditor::inst()->exportDone() == TRUE ||
songEditor::inst()->exporting() == FALSE )
{
finishProjectExport();
// qApp->quit(); - doesn't work for some reason...
exit( 0 );
}
// let's close us...
accept();
}
void exportProjectDialog::updateProgressBar( int _new_val )
{
m_progressVal = _new_val;
}
#include "export_project_dialog.moc"

View File

@@ -61,17 +61,37 @@ int main( int argc, char * * argv )
{
QApplication app( argc, argv );
QString extension = "wav";
for( int i = 1; i < app.argc(); ++i )
{
if( QString( app.argv()[i] ) == "--version" ||
QString( app.argv()[i] ) == "-v" )
{
printf( "\n%s\n\n"
printf( "\nLinux MultiMedia Studio %s\n\n"
"Copyright (c) 2004-2005 Tobias Doerffel and others.\n\n"
"This program is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU General Public\n"
"License as published by the Free Software Foundation; either\n"
"version 2 of the License, or (at your option) any later version.\n\n",
PACKAGE_STRING );
"version 2 of the License, or (at your option) any later version.\n\n"
"Try \"%s --help\" for more information.\n\n", PACKAGE_VERSION,
argv[0] );
return( 0 );
}
else if( app.argc() > i &&
( QString( app.argv()[i] ) == "--help" ||
QString( app.argv()[i] ) == "-h" ) )
{
printf( "\nLinux MultiMedia Studio %s\n"
"Copyright (c) 2004-2005 Tobias Doerffel and others.\n\n"
"usage: lmms [ -r <file_to_render> [ -o <format> ] [ -h ] "
"[ <file_to_load> ]\n"
"-r, --render render given file.\n"
"-o, --output-format <format> specify format of render-output where\n"
" format is either 'wav' or 'ogg'.\n"
"-v, --version show version information and exit.\n"
"-h, --help show this usage message and exit.\n\n",
PACKAGE_VERSION );
return( 0 );
}
else if( app.argc() > i &&
@@ -79,14 +99,42 @@ int main( int argc, char * * argv )
QString( app.argv()[i] ) == "-r" ) )
{
file_to_load = QString( app.argv()[i+1] );
file_to_render = QString( app.argv()[i+1] ) + ".wav";
file_to_render = baseName( file_to_load ) + ".";
++i;
}
else if( app.argc() > i &&
( QString( app.argv()[i] ) == "--output-format" ||
QString( app.argv()[i] ) == "-o" ) )
{
extension = QString( app.argv()[i+1] );
if( extension != "wav" && extension != "ogg" )
{
printf( "\nInvalid output format %s.\n\n"
"Try \"%s --help\" for more information.\n\n", app.argv()[i+1],
argv[0] );
return( -1 );
}
++i;
}
else
{
if( app.argv()[i][0] == '-' )
{
printf( "\nInvalid option %s.\n\n"
"Try \"%s --help\" for more information.\n\n", app.argv()[i],
argv[0] );
return( -1 );
}
file_to_load = app.argv()[i];
}
}
if( file_to_render != "" )
{
file_to_render += extension;
}
QString pos =
#ifdef QT4
QLocale::system().name().left( 2 );
@@ -172,7 +220,6 @@ int main( int argc, char * * argv )
exportProjectDialog * e = new exportProjectDialog(
file_to_render,
lmmsMainWin::inst() );
songEditor::inst()->setExportProjectDialog( e );
e->show();
e->exportBtnClicked();
}

View File

@@ -57,21 +57,12 @@ mixer * mixer::s_instanceOfMe = NULL;
mixer::mixer() :
#ifndef QT4
QObject(),
#endif
QThread(),
/* m_silence(),
#ifndef DISABLE_SURROUND
m_surroundSilence(),
#endif*/
m_framesPerAudioBuffer( DEFAULT_BUFFER_SIZE ),
m_curBuf( NULL ),
m_nextBuf( NULL ),
m_discardCurBuf( FALSE ),
m_qualityLevel( DEFAULT_QUALITY_LEVEL ),
m_masterOutput( 1.0f ),
m_quit( FALSE ),
m_masterGain( 1.0f ),
m_audioDev( NULL ),
m_oldAudioDev( NULL )
{
@@ -101,30 +92,12 @@ mixer::mixer() :
m_midiClient = tryMIDIClients();
/* m_silence = bufferAllocator::alloc<sampleFrame>(
m_framesPerAudioBuffer );
#ifndef DISABLE_SURROUND
m_surroundSilence = bufferAllocator::alloc<surroundSampleFrame>(
m_framesPerAudioBuffer );
#endif
for( Uint32 frame = 0; frame < m_framesPerAudioBuffer; ++frame )
{
for( Uint8 chnl = 0; chnl < DEFAULT_CHANNELS; ++chnl )
{
m_silence[frame][chnl] = 0.0f;
}
#ifndef DISABLE_SURROUND
for( Uint8 chnl = 0; chnl < SURROUND_CHANNELS; ++chnl )
{
m_surroundSilence[frame][chnl] = 0.0f;
}
#endif
}*/
// now clear our two output-buffers before using them...
clearAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
clearAudioBuffer( m_nextBuf, m_framesPerAudioBuffer );
m_audioDev->startProcessing();
}
@@ -137,132 +110,98 @@ mixer::~mixer()
bufferAllocator::free( m_curBuf );
bufferAllocator::free( m_nextBuf );
/* bufferAllocator::free( m_silence );
#ifndef DISABLE_SURROUND
bufferAllocator::free( m_surroundSilence );
#endif*/
}
void mixer::quitThread( void )
void mixer::stopProcessing( void )
{
// make sure there're no mutexes locked anymore...
m_safetySyncMutex.unlock();
m_devMutex.unlock();
// now tell mixer-thread to quit
m_quit = TRUE;
wait( 1000 );
terminate();
m_audioDev->stopProcessing();
}
void mixer::run( void )
const surroundSampleFrame * mixer::renderNextBuffer( void )
{
while( m_quit == FALSE )
// remove all play-handles that have to be deleted and delete
// them if they still exist...
// maybe this algorithm could be optimized...
while( !m_playHandlesToRemove.empty() )
{
playHandleVector::iterator it = m_playHandles.begin();
// remove all play-handles that have to be deleted and delete
// them if they still exist...
// maybe this algorithm could be optimized...
while( !m_playHandlesToRemove.empty() )
while( it != m_playHandles.end() )
{
playHandleVector::iterator it = m_playHandles.begin();
while( it != m_playHandles.end() )
if( *it == m_playHandlesToRemove.front() )
{
if( *it == m_playHandlesToRemove.front() )
{
m_playHandles.erase( it );
delete m_playHandlesToRemove.front();
break;
}
++it;
m_playHandles.erase( it );
delete m_playHandlesToRemove.front();
break;
}
m_playHandlesToRemove.erase(
m_playHandlesToRemove.begin() );
++it;
}
// now we have to make sure no other thread does anything bad
// while we're acting...
m_safetySyncMutex.lock();
m_playHandlesToRemove.erase(
m_playHandlesToRemove.begin() );
}
csize idx = 0;
while( idx < m_playHandles.size() )
// now we have to make sure no other thread does anything bad
// while we're acting...
m_mixMutex.lock();
// now swap the buffers... current buffer becomes next (last)
// buffer and the next buffer becomes current (first) buffer
qSwap( m_curBuf, m_nextBuf );
// clear last audio-buffer
clearAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
csize idx = 0;
while( idx < m_playHandles.size() )
{
register playHandle * n = m_playHandles[idx];
if( n->done() )
{
register playHandle * n = m_playHandles[idx];
if( n->done() )
{
// delete all play-handles which have
// played completely now
delete n;
m_playHandles.erase( m_playHandles.begin() +
idx );
}
else
{
// play all uncompletely-played play-handles...
n->play();
++idx;
}
}
songEditor::inst()->processNextBuffer();
for( vvector<audioPort *>::iterator it = m_audioPorts.begin();
it != m_audioPorts.end(); ++it )
{
if( ( *it )->m_bufferUsage != audioPort::NONE )
{
processBuffer( ( *it )->firstBuffer(),
( *it )->nextFxChannel() );
( *it )->nextPeriod();
}
}
if( !m_discardCurBuf )
{
m_devMutex.lock();
// write actual data to our current output-device
// (blocking!)
m_audioDev->writeBuffer( m_curBuf,
m_framesPerAudioBuffer,
SAMPLE_RATES[m_qualityLevel],
m_masterOutput );
m_devMutex.unlock();
// delete all play-handles which have
// played completely now
delete n;
m_playHandles.erase( m_playHandles.begin() +
idx );
}
else
{
m_discardCurBuf = FALSE;
// play all uncompletely-played play-handles...
n->play();
++idx;
}
emit nextAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
usleep( 1 ); // give time to other threads/processes
m_safetySyncMutex.unlock();
// clear last audio-buffer
clearAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
// now swap the buffers... current buffer becomes next (last)
// buffer and the next buffer becomes current (first) buffer
qSwap( m_curBuf, m_nextBuf );
// and trigger LFOs
envelopeAndLFOWidget::triggerLFO();
}
songEditor::inst()->processNextBuffer();
for( vvector<audioPort *>::iterator it = m_audioPorts.begin();
it != m_audioPorts.end(); ++it )
{
if( ( *it )->m_bufferUsage != audioPort::NONE )
{
processBuffer( ( *it )->firstBuffer(),
( *it )->nextFxChannel() );
( *it )->nextPeriod();
}
}
emit nextAudioBuffer( m_curBuf, m_framesPerAudioBuffer );
m_mixMutex.unlock();
// and trigger LFOs
envelopeAndLFOWidget::triggerLFO();
return( m_curBuf );
}
@@ -286,21 +225,6 @@ void mixer::clear( void )
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab, Uint32 _frames )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
/* if( _frames == m_framesPerAudioBuffer )
{
memcpy( _ab, m_silence, m_framesPerAudioBuffer *
BYTES_PER_FRAME );
}
else
{
for( Uint32 frame = 0; frame < _frames; ++frame )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
_ab[frame][ch] = 0.0f;
}
}
}*/
}
@@ -310,21 +234,6 @@ void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
Uint32 _frames )
{
memset( _ab, 0, sizeof( *_ab ) * _frames );
/* if( _frames == m_framesPerAudioBuffer )
{
memcpy( _ab, m_surroundSilence, m_framesPerAudioBuffer *
BYTES_PER_SURROUND_FRAME );
}
else
{
for( Uint32 frame = 0; frame < _frames; ++frame )
{
for( Uint8 ch = 0; ch < DEFAULT_CHANNELS; ++ch )
{
_ab[frame][ch] = 0.0f;
}
}
}*/
}
#endif
@@ -377,8 +286,6 @@ void FASTCALL mixer::bufferToPort( sampleFrame * _buf, Uint32 _frames,
void mixer::setHighQuality( bool _hq_on )
{
m_safetySyncMutex.lock();
// delete (= close) our audio-device
delete m_audioDev;
@@ -393,8 +300,7 @@ void mixer::setHighQuality( bool _hq_on )
}
// and re-open device
m_audioDev = tryAudioDevices();
m_safetySyncMutex.unlock();
m_audioDev->startProcessing();
emit( sampleRateChanged() );
@@ -405,8 +311,7 @@ void mixer::setHighQuality( bool _hq_on )
void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
{
m_devMutex.lock();
m_audioDev->stopProcessing();
m_oldAudioDev = m_audioDev;
@@ -423,9 +328,6 @@ void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
m_qualityLevel = _hq ? 1 : 0;
emit sampleRateChanged();
m_devMutex.unlock();
}
@@ -433,11 +335,10 @@ void FASTCALL mixer::setAudioDevice( audioDevice * _dev, bool _hq )
void mixer::restoreAudioDevice( void )
{
m_devMutex.lock();
if( m_oldAudioDev != NULL )
{
delete m_audioDev;
delete m_audioDev; // dtor automatically calls
// stopProcessing()
m_audioDev = m_oldAudioDev;
for( Uint8 qli = 0; qli < QUALITY_LEVELS; ++qli )
{
@@ -449,10 +350,8 @@ void mixer::restoreAudioDevice( void )
}
}
m_oldAudioDev = NULL;
m_discardCurBuf = TRUE;
m_audioDev->startProcessing();
}
m_devMutex.unlock();
}
@@ -474,8 +373,6 @@ void mixer::checkValidityOfPlayHandles( void )
audioDevice * mixer::tryAudioDevices( void )
{
//m_discardCurBuf = TRUE;
bool success_ful = FALSE;
audioDevice * dev = NULL;
QString dev_name = configManager::inst()->value( "mixer", "audiodev" );

View File

@@ -34,6 +34,7 @@
#include <QKeyEvent>
#include <QWheelEvent>
#include <QComboBox>
#include <QLayout>
#else
@@ -41,6 +42,7 @@
#include <qbuttongroup.h>
#include <qpainter.h>
#include <qcombobox.h>
#include <qlayout.h>
#define setChecked setOn
@@ -56,9 +58,9 @@
#include "piano_roll.h"
#include "song_editor.h"
#include "lmms_main_win.h"
#include "pattern.h"
#include "embed.h"
#include "crystal_button.h"
#include "pixmap_button.h"
#include "templates.h"
#include "gui_templates.h"
@@ -66,6 +68,7 @@
#include "channel_track.h"
#include "tooltip.h"
#include "midi.h"
#include "tool_button.h"
extern tones whiteKeys[]; // defined in piano_widget.cpp
@@ -88,7 +91,7 @@ const int KEY_LINE_HEIGHT = 12;
const int OCTAVE_HEIGHT = KEY_LINE_HEIGHT * NOTES_PER_OCTAVE; // = 12 * 12;
const int PR_BOTTOM_MARGIN = SCROLLBAR_SIZE;
const int PR_TOP_MARGIN = 66;
const int PR_TOP_MARGIN = 48;
// width of area used for resizing (the grip at the end of a note)
const int RESIZE_AREA_WIDTH = 3;
@@ -106,8 +109,6 @@ pianoRoll * pianoRoll::s_instanceOfMe = NULL;
QPixmap * pianoRoll::s_whiteKeySmallPm = NULL;
QPixmap * pianoRoll::s_whiteKeyBigPm = NULL;
QPixmap * pianoRoll::s_blackKeyPm = NULL;
QPixmap * pianoRoll::s_artwork1 = NULL;
QPixmap * pianoRoll::s_artwork2 = NULL;
QPixmap * pianoRoll::s_toolDraw = NULL;
QPixmap * pianoRoll::s_toolErase = NULL;
QPixmap * pianoRoll::s_toolSelect = NULL;
@@ -160,16 +161,6 @@ pianoRoll::pianoRoll( void ) :
s_blackKeyPm = new QPixmap( embed::getIconPixmap(
"pr_black_key" ) );
}
if( s_artwork1 == NULL )
{
s_artwork1 = new QPixmap( embed::getIconPixmap(
"pr_artwork1" ) );
}
if( s_artwork2 == NULL )
{
s_artwork2 = new QPixmap( embed::getIconPixmap(
"pr_artwork2" ) );
}
if( s_toolDraw == NULL )
{
s_toolDraw = new QPixmap( embed::getIconPixmap(
@@ -196,39 +187,39 @@ pianoRoll::pianoRoll( void ) :
lmmsMainWin::inst()->workspace()->addWindow( this );
#endif
// add time-line
m_timeLine = new timeLine( WHITE_KEY_WIDTH, 32, m_ppt,
songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN ),
m_currentPosition, this );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
m_timeLine, SLOT( updatePosition( const midiTime & ) ) );
connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
m_toolBar = new QWidget( this );
m_toolBar->setFixedHeight( 32 );
m_toolBar->move( 0, 0 );
m_toolBar->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
QHBoxLayout * tb_layout = new QHBoxLayout( m_toolBar );
// init control-buttons at the top
m_playButton = new pixmapButton( this );
m_playButton->move( 8, 7 );
m_playButton->setCheckable( FALSE );
m_playButton->setActiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setBgGraphic( embed::getIconPixmap( "pr_play_ctrl_bg" ) );
connect( m_playButton, SIGNAL( clicked() ), this, SLOT( play() ) );
m_recordButton = new pixmapButton( this );
m_recordButton->move( 50, 7 );
m_recordButton->setCheckable( FALSE );
m_recordButton->setActiveGraphic( embed::getIconPixmap( "record" ) );
m_recordButton->setInactiveGraphic( embed::getIconPixmap( "record" ) );
m_recordButton->setBgGraphic(
embed::getIconPixmap( "pr_play_ctrl_bg" ) );
connect( m_recordButton, SIGNAL( clicked() ), this, SLOT( record() ) );
m_playButton = new toolButton( embed::getIconPixmap( "play" ),
tr( "Play/pause current pattern (Space)" ),
this, SLOT( play() ), m_toolBar );
m_stopButton = new pixmapButton( this );
m_stopButton->move( 92, 7 );
m_stopButton->setCheckable( FALSE );
m_stopButton->setActiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setInactiveGraphic( embed::getIconPixmap( "stop" ) );
m_stopButton->setBgGraphic( embed::getIconPixmap( "pr_play_ctrl_bg" ) );
connect( m_stopButton, SIGNAL( clicked() ), this, SLOT( stop() ) );
m_recordButton = new toolButton( embed::getIconPixmap( "record" ),
tr( "Record notes from MIDI-device/channel-piano" ),
this, SLOT( record() ), m_toolBar );
toolTip::add( m_playButton,
tr( "Play/pause current pattern (Space)" ) );
toolTip::add( m_recordButton,
tr( "Record notes from MIDI-device to current "
"pattern" ) );
toolTip::add( m_stopButton,
tr( "Stop playing of current pattern (Space)" ) );
m_stopButton = new toolButton( embed::getIconPixmap( "stop" ),
tr( "Stop playing of current pattern (Space)" ),
this, SLOT( stop() ), m_toolBar );
#ifdef QT4
m_playButton->setWhatsThis(
@@ -246,8 +237,8 @@ pianoRoll::pianoRoll( void ) :
tr( "Click here, if you want to record notes from a MIDI-"
"device or the virtual test-piano of the according "
"channel-window to the current pattern. When recording "
"all notes you play will be written to this pattern "
"and you can edit, play etc. them afterwards." ) );
"all notes you play will be written to this pattern "
"and you can play and edit them afterwards." ) );
#ifdef QT4
m_stopButton->setWhatsThis(
#else
@@ -269,33 +260,31 @@ pianoRoll::pianoRoll( void ) :
SLOT( verScrolled( int ) ) );
// init edit-buttons at the top
m_drawButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_draw" ), this );
m_drawButton->move( 170, 1 );
m_drawButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_drawButton = new toolButton( embed::getIconPixmap( "pr_tool_draw" ),
tr( "Draw mode (D)" ),
this, SLOT( drawButtonToggled() ),
m_toolBar );
m_drawButton->setCheckable( TRUE );
m_drawButton->setChecked( TRUE );
m_eraseButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_erase" ), this );
m_eraseButton->move( 220, 1 );
m_eraseButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_selectButton = new crystalButton( embed::getIconPixmap(
"pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_select" ), this );
m_selectButton->move( 270, 1 );
m_selectButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_moveButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_tool_move" ), this );
m_moveButton->move( 320, 1 );
m_moveButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_eraseButton = new toolButton( embed::getIconPixmap( "pr_tool_erase" ),
tr( "Erase mode (E)" ),
this, SLOT( eraseButtonToggled() ),
m_toolBar );
m_eraseButton->setCheckable( TRUE );
m_selectButton = new toolButton( embed::getIconPixmap(
"pr_tool_select" ),
tr( "Select mode (S)" ),
this, SLOT( selectButtonToggled() ),
m_toolBar );
m_selectButton->setCheckable( TRUE );
m_moveButton = new toolButton( embed::getIconPixmap( "pr_tool_move" ),
tr( "Move selection mode (M)" ),
this, SLOT( moveButtonToggled() ),
m_toolBar );
m_moveButton->setCheckable( TRUE );
QButtonGroup * tool_button_group = new QButtonGroup( this );
tool_button_group->addButton( m_drawButton );
@@ -307,26 +296,6 @@ pianoRoll::pianoRoll( void ) :
tool_button_group->hide();
#endif
connect( m_drawButton, SIGNAL( toggled( bool ) ), this,
SLOT( drawButtonToggled( bool ) ) );
connect( m_eraseButton, SIGNAL( toggled( bool ) ), this,
SLOT( eraseButtonToggled( bool ) ) );
connect( m_selectButton, SIGNAL( toggled( bool ) ), this,
SLOT( selectButtonToggled( bool ) ) );
connect( m_moveButton, SIGNAL( toggled( bool ) ), this,
SLOT( moveButtonToggled( bool ) ) );
toolTip::add( m_drawButton,
tr( "Click if you want to draw, resize or move single "
"notes (= key 'D')" ) );
toolTip::add( m_eraseButton,
tr( "Click if you want to erase single notes "
"(= key 'E')" ) );
toolTip::add( m_selectButton,
tr( "Click if you want to select notes (= key 'S')" ) );
toolTip::add( m_moveButton,
tr( "Click if you want to move selected notes "
"(= key 'M')" ) );
#ifdef QT4
m_drawButton->setWhatsThis(
#else
@@ -365,42 +334,22 @@ pianoRoll::pianoRoll( void ) :
"mode. You can also press 'M' on your keyboard to "
"activate this mode." ) );
m_cutButton = new toolButton( embed::getIconPixmap( "edit_cut" ),
tr( "Cut selected notes (Ctrl+X)" ),
this, SLOT( cutSelectedNotes() ),
m_toolBar );
m_cutButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_edit_cut" ), this );
m_cutButton->move( 390, 1 );
m_cutButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_cutButton->setCheckable( FALSE );
m_copyButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_edit_copy" ),
this );
m_copyButton->move( 440, 1 );
m_copyButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_copyButton->setCheckable( FALSE );
m_pasteButton = new crystalButton( embed::getIconPixmap( "pr_tool_bg" ),
embed::getIconPixmap(
"pr_edit_paste" ),
this );
m_pasteButton->move( 490, 1 );
m_pasteButton->setActiveButtonBg( embed::getIconPixmap(
"pr_tool_bg_inset" ) );
m_pasteButton->setCheckable( FALSE );
m_copyButton = new toolButton( embed::getIconPixmap( "edit_copy" ),
tr( "Copy selected notes (Ctrl+C)" ),
this, SLOT( copySelectedNotes() ),
m_toolBar );
connect( m_cutButton, SIGNAL( clicked() ), this,
SLOT( cutSelectedNotes() ) );
connect( m_copyButton, SIGNAL( clicked() ), this,
SLOT( copySelectedNotes() ) );
connect( m_pasteButton, SIGNAL( clicked() ), this,
SLOT( pasteNotes() ) );
m_pasteButton = new toolButton( embed::getIconPixmap( "edit_paste" ),
tr( "Paste notes from clipboard "
"(Ctrl+V)" ),
this, SLOT( pasteNotes() ),
m_toolBar );
toolTip::add( m_cutButton, tr( "Cut selected notes (Ctrl+X)" ) );
toolTip::add( m_copyButton, tr( "Copy selected notes (Ctrl+C)" ) );
toolTip::add( m_pasteButton, tr( "Paste notes from clipboard "
"(Ctrl+V)" ) );
#ifdef QT4
m_cutButton->setWhatsThis(
#else
@@ -427,9 +376,10 @@ pianoRoll::pianoRoll( void ) :
// setup zooming-stuff
m_zoomingComboBox = new QComboBox( this );
m_zoomingComboBox->setGeometry( 580, 10, 60, 20 );
m_zoomingComboBox = new QComboBox( m_toolBar );
m_zoomingComboBox->setGeometry( 580, 4, 80, 24 );
for( int i = 0; i < 6; ++i )
{
m_zoomingComboBox->insertItem( QString::number( 25 *
@@ -441,6 +391,26 @@ pianoRoll::pianoRoll( void ) :
this, SLOT( zoomingChanged( const QString & ) ) );
tb_layout->addSpacing( 5 );
tb_layout->addWidget( m_playButton );
tb_layout->addWidget( m_recordButton );
tb_layout->addWidget( m_stopButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_drawButton );
tb_layout->addWidget( m_eraseButton );
tb_layout->addWidget( m_selectButton );
tb_layout->addWidget( m_moveButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_cutButton );
tb_layout->addWidget( m_copyButton );
tb_layout->addWidget( m_pasteButton );
tb_layout->addSpacing( 10 );
m_timeLine->addToolButtons( m_toolBar );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_zoomingComboBox );
tb_layout->addStretch();
// setup our actual window
setWindowIcon( embed::getIconPixmap( "piano" ) );
resize( INITIAL_PIANOROLL_WIDTH, INITIAL_PIANOROLL_HEIGHT );
@@ -453,15 +423,6 @@ pianoRoll::pianoRoll( void ) :
hide();
// add time-line
m_timeLine = new timeLine( WHITE_KEY_WIDTH, 48, m_ppt,
songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN ),
m_currentPosition, this );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
m_timeLine, SLOT( updatePosition( const midiTime & ) ) );
connect( m_timeLine, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
}
@@ -785,7 +746,7 @@ void pianoRoll::paintEvent( QPaintEvent * )
// draw artwork-stuff
p.drawPixmap( 0, 0, *s_artwork1 );
/* p.drawPixmap( 0, 0, *s_artwork1 );
int artwork_x = s_artwork1->width();
@@ -793,10 +754,11 @@ void pianoRoll::paintEvent( QPaintEvent * )
{
p.drawPixmap( artwork_x, 0, *s_artwork2 );
artwork_x += s_artwork2->width();
}
}*/
// set clipping area, because we may not draw on keyboard...
// set clipping area, because we are not allowed to paint over
// keyboard...
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width()-WHITE_KEY_WIDTH,
height()-PR_TOP_MARGIN-PR_BOTTOM_MARGIN );
@@ -1027,6 +989,7 @@ void pianoRoll::resizeEvent( QResizeEvent * )
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLine->setFixedWidth( width() );
m_toolBar->setFixedWidth( width() );
}
@@ -1977,26 +1940,24 @@ void pianoRoll::play( void )
{
songEditor::inst()->stop();
songEditor::inst()->playPattern( m_pattern );
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"pause" ) );
}
else
{
songEditor::inst()->pause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap(
"play" ) );
}
}
else if( songEditor::inst()->paused() )
{
songEditor::inst()->resumeFromPause();
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
}
else
{
m_playButton->setInactiveGraphic(
embed::getIconPixmap( "pause" ) );
m_playButton->setPixmap( embed::getIconPixmap( "pause" ) );
songEditor::inst()->playPattern( m_pattern );
}
}
@@ -2025,7 +1986,7 @@ void pianoRoll::record( void )
void pianoRoll::stop( void )
{
songEditor::inst()->stop();
m_playButton->setInactiveGraphic( embed::getIconPixmap( "play" ) );
m_playButton->setPixmap( embed::getIconPixmap( "play" ) );
m_playButton->update();
m_recording = FALSE;
m_scrollBack = TRUE;
@@ -2071,56 +2032,47 @@ void pianoRoll::verScrolled( int _new_pos )
void pianoRoll::drawButtonToggled( bool _on )
void pianoRoll::drawButtonToggled( void )
{
if( _on )
{
m_editMode = DRAW;
removeSelection();
update();
}
}
void pianoRoll::eraseButtonToggled( bool _on )
{
if( _on )
{
m_editMode = ERASE;
removeSelection();
update();
}
m_editMode = DRAW;
removeSelection();
update();
}
void pianoRoll::selectButtonToggled( bool _on )
void pianoRoll::eraseButtonToggled( void )
{
if( _on )
{
m_editMode = SELECT;
removeSelection();
update();
}
m_editMode = ERASE;
removeSelection();
update();
}
void pianoRoll::moveButtonToggled( bool _on )
void pianoRoll::selectButtonToggled( void )
{
if( _on )
{
m_editMode = MOVE;
m_selNotesForMove.clear();
getSelectedNotes( m_selNotesForMove );
update();
}
m_editMode = SELECT;
removeSelection();
update();
}
void pianoRoll::moveButtonToggled( void )
{
m_editMode = MOVE;
m_selNotesForMove.clear();
getSelectedNotes( m_selNotesForMove );
update();
}
void pianoRoll::selectAll( void )
{
if( validPattern() == FALSE )

View File

@@ -44,11 +44,12 @@
#include <QStatusBar>
#include <QKeyEvent>
#include <QLabel>
#include <QToolButton>
#include <QStatusBar>
#include <QAction>
#include <QToolBar>
#include <QComboBox>
#include <QLayout>
#include <QToolButton>
#else
@@ -60,9 +61,10 @@
#include <qdom.h>
#include <qslider.h>
#include <qlabel.h>
#include <qtoolbutton.h>
#include <qstatusbar.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qtoolbutton.h>
#endif
@@ -87,13 +89,13 @@
#include "midi_file.h"
#include "lcd_spinbox.h"
#include "tooltip.h"
#include "tool_button.h"
#include "debug.h"
extern QString file_to_load;
extern QString file_to_render;
const int SCROLLBAR_SIZE = 16;
@@ -114,7 +116,6 @@ songEditor::songEditor() :
m_patternToPlay( NULL ),
m_loopPattern( FALSE ),
m_scrollBack( FALSE ),
m_epd( NULL ),
m_shiftPressed( FALSE ),
m_controlPressed( FALSE )
{
@@ -147,7 +148,7 @@ songEditor::songEditor() :
// create time-line
timeLine * tl = new timeLine( TRACK_OP_WIDTH +
DEFAULT_SETTINGS_WIDGET_WIDTH, 0,
DEFAULT_SETTINGS_WIDGET_WIDTH, 32,
pixelsPerTact(), m_playPos[PLAY_SONG],
m_currentPosition, cw );
connect( this, SIGNAL( positionChanged( const midiTime & ) ),
@@ -156,75 +157,41 @@ songEditor::songEditor() :
connect( tl, SIGNAL( positionChanged( const midiTime & ) ),
this, SLOT( updatePosition( const midiTime & ) ) );
// create toolbar
m_toolBar = new QWidget( cw );
m_toolBar->setFixedHeight( 32 );
m_toolBar->move( 0, 0 );
m_toolBar->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
QHBoxLayout * tb_layout = new QHBoxLayout( m_toolBar );
#ifdef QT4
containerWidget()->setParent( cw );
#else
containerWidget()->reparent( cw, 0, QPoint( 0, 0 ) );
#endif
containerWidget()->move( 0, tl->height() );
containerWidget()->move( 0, m_toolBar->height() + tl->height() );
QToolBar * song_control = new QToolBar( tr( "Song control" ), this );
#ifdef QT4
addToolBar( Qt::TopToolBarArea, song_control );
#else
addDockWindow( song_control, tr( "Song control" ), Qt::DockTop,
FALSE );
#endif
/* song_control->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
song_control->setErasePixmap( embed::getIconPixmap( "toolbar_bg" ) );*/
#ifdef QT4
QAction * a;
a = song_control->addAction( embed::getIconPixmap( "play" ),
tr( "Play song (Space)" ),
this, SLOT( play() ) );
a->setToolTip( tr( "Play/pause song (Space)" ) );
a->setWhatsThis( tr( "Click here, if you want to play your whole song. "
"Playing will be started at the song-position-"
"marker (green). You can also move it while "
"playing." ) );
#else
m_playButton = new QToolButton( embed::getIconPixmap( "play" ),
tr( "Play song (Space)" ),
QString::null, this, SLOT( play() ),
song_control );
#endif
#ifdef QT4
a = song_control->addAction( embed::getIconPixmap( "stop" ),
tr( "Stop song (Space)" ),
this, SLOT( stop() ) );
a->setToolTip( tr( "Stop song (Space)" ) );
a->setWhatsThis( tr( "Click here, if you want to stop playing of your "
"song. The song-position-marker will be set to "
"the start of your song." ) );
#else
m_stopButton = new QToolButton( embed::getIconPixmap( "stop" ),
tr( "Stop song (Space)" ),
QString::null, this, SLOT( stop() ),
song_control );
#endif
song_control->addSeparator();
QToolBar * main_tb = lmmsMainWin::inst()->mainToolBar();
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 10, 1 );
( new QWidget( main_tb ) )->setFixedSize( 10, 1 );
QLabel * bpm_label = new QLabel( song_control );
QLabel * bpm_label = new QLabel( main_tb );
bpm_label->setPixmap( embed::getIconPixmap( "clock" ) );
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 8, 1 );
( new QWidget( main_tb ) )->setFixedSize( 8, 1 );
m_bpmSpinBox = new lcdSpinBox( MIN_BPM, MAX_BPM, 3, song_control );
m_bpmSpinBox = new lcdSpinBox( MIN_BPM, MAX_BPM, 3, main_tb );
#ifdef QT4
song_control->addWidget( m_bpmSpinBox );
song_control->addWidget( bpm_label );
main_tb->addWidget( m_bpmSpinBox );
main_tb->addWidget( bpm_label );
#endif
m_bpmSpinBox->setLabel( tr( "TEMPO/BPM" ) );
connect( m_bpmSpinBox, SIGNAL( valueChanged( int ) ), this,
@@ -244,26 +211,26 @@ songEditor::songEditor() :
"should be played within four minutes)." ) );
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 10, 1 );
( new QWidget( main_tb ) )->setFixedSize( 10, 1 );
song_control->addSeparator();
main_tb->addSeparator();
QLabel * master_vol_lbl = new QLabel( song_control );
QLabel * master_vol_lbl = new QLabel( main_tb );
master_vol_lbl->setPixmap( embed::getIconPixmap( "master_volume" ) );
#ifdef QT4
m_masterVolumeSlider = new QSlider( Qt::Vertical, song_control );
m_masterVolumeSlider = new QSlider( Qt::Vertical, main_tb );
m_masterVolumeSlider->setRange( 0, 200 );
m_masterVolumeSlider->setPageStep( 10 );
m_masterVolumeSlider->setValue( 100 );
m_masterVolumeSlider->setTickPosition( QSlider::TicksLeft );
song_control->addWidget( master_vol_lbl );
song_control->addWidget( m_masterVolumeSlider );
main_tb->addWidget( master_vol_lbl );
main_tb->addWidget( m_masterVolumeSlider );
#else
m_masterVolumeSlider = new QSlider( 0, 200, 10, 100, Qt::Vertical,
song_control );
main_tb );
m_masterVolumeSlider->setTickPosition( QSlider::Left );
#endif
m_masterVolumeSlider->setFixedSize( 26, 48 );
@@ -281,22 +248,22 @@ songEditor::songEditor() :
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 10, 1 );
( new QWidget( main_tb ) )->setFixedSize( 10, 1 );
QLabel * master_pitch_lbl = new QLabel( song_control );
QLabel * master_pitch_lbl = new QLabel( main_tb );
master_pitch_lbl->setPixmap( embed::getIconPixmap( "master_pitch" ) );
#ifdef QT4
m_masterPitchSlider = new QSlider( Qt::Vertical, song_control );
m_masterPitchSlider = new QSlider( Qt::Vertical, main_tb );
m_masterPitchSlider->setRange( -12, 12 );
m_masterPitchSlider->setPageStep( 1 );
m_masterPitchSlider->setValue( 0 );
m_masterPitchSlider->setTickPosition( QSlider::TicksLeft );
song_control->addWidget( master_pitch_lbl );
song_control->addWidget( m_masterPitchSlider );
main_tb->addWidget( master_pitch_lbl );
main_tb->addWidget( m_masterPitchSlider );
#else
m_masterPitchSlider = new QSlider( -12, 12, 1, 0, Qt::Vertical,
song_control );
main_tb);
m_masterPitchSlider->setTickPosition( QSlider::Left );
#endif
m_masterPitchSlider->setFixedSize( 26, 48 );
@@ -312,28 +279,117 @@ songEditor::songEditor() :
SLOT( masterPitchReleased() ) );
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 5, 1 );
( new QWidget( main_tb ) )->setFixedSize( 5, 1 );
song_control->addSeparator();
main_tb->addSeparator();
// spacer-item
( new QWidget( song_control ) )->setFixedSize( 5, 1 );
( new QWidget( main_tb ) )->setFixedSize( 5, 1 );
m_masterOutputGraph = new visualizationWidget( embed::getIconPixmap(
"output_graph" ), song_control );
"output_graph" ), main_tb );
#ifdef QT4
song_control->addWidget( m_masterOutputGraph );
main_tb->addWidget( m_masterOutputGraph );
#endif
// live high-quality mode switching is somewhat experimental so we don't
// offer it...
/* QToolButton * hq = new QToolButton(
embed::getIconPixmap( "presetfile" ),
// spacer-item
( new QWidget( main_tb ) )->setFixedSize( 5, 1 );
main_tb->addSeparator();
QToolButton * hq = new QToolButton(
embed::getIconPixmap( "hq_mode" ),
tr( "High quality mode" ),
QString::null, NULL, NULL,
song_control );
main_tb );
hq->setToggleButton( TRUE );
connect( hq, SIGNAL( toggled( bool ) ), mixer::inst(),
SLOT( setHighQuality( bool ) ) );*/
SLOT( setHighQuality( bool ) ) );
m_playButton = new toolButton( embed::getIconPixmap( "play" ),
tr( "Play song (Space)" ),
this, SLOT( play() ), m_toolBar );
m_stopButton = new toolButton( embed::getIconPixmap( "stop" ),
tr( "Stop song (Space)" ),
this, SLOT( stop() ), m_toolBar );
m_addBBTrackButton = new toolButton( embed::getIconPixmap(
"add_bb_track" ),
tr( "Add beat/bassline" ),
this, SLOT( addBBTrack() ),
m_toolBar );
m_addSampleTrackButton = new toolButton( embed::getIconPixmap(
"add_sample_track" ),
tr( "Add sample-track" ),
this, SLOT( addSampleTrack() ),
m_toolBar );
m_insertBarButton = new toolButton( embed::getIconPixmap(
"insert_bar" ),
tr( "Insert bar "
"(Shift+Insert)" ),
this, SLOT( insertBar() ),
m_toolBar );
m_removeBarButton = new toolButton( embed::getIconPixmap(
"remove_bar" ),
tr( "Remove bar (Shift+Delete)" ),
this, SLOT( removeBar() ),
m_toolBar );
#ifdef QT4
#else
QWhatsThis::add( m_playButton, tr( "Click here, if you want to play "
"your whole song. Playing will "
"be started at the "
"song-position-marker (green). "
"You can also move it while "
"playing." ) );
QWhatsThis::add( m_stopButton, tr ( "Click here, if you want to stop "
"playing of your song. The "
"song-position-marker will be "
"set to the start of your song."
) );
QWhatsThis::add( m_insertBarButton, tr( "If you click here, a "
"bar will "
"be inserted at the "
"current bar." ) );
QWhatsThis::add( m_removeBarButton, tr( "If you click here, the "
"current bar will be "
"removed." ) );
#endif
// setup zooming-stuff
m_zoomingComboBox = new QComboBox( m_toolBar );
m_zoomingComboBox->setGeometry( 580, 4, 80, 24 );
for( int i = 0; i < 7; ++i )
{
m_zoomingComboBox->insertItem( QString::number( 25 *
static_cast<int>( powf( 2.0f, i ) ) ) +
"%" );
}
m_zoomingComboBox->setCurrentText( "100%" );
connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ),
this, SLOT( zoomingChanged( const QString & ) ) );
tb_layout->addSpacing( 5 );
tb_layout->addWidget( m_playButton );
tb_layout->addWidget( m_stopButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_addBBTrackButton );
tb_layout->addWidget( m_addSampleTrackButton );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_insertBarButton );
tb_layout->addWidget( m_removeBarButton );
tb_layout->addSpacing( 10 );
tl->addToolButtons( m_toolBar );
tb_layout->addSpacing( 10 );
tb_layout->addWidget( m_zoomingComboBox );
tb_layout->addStretch();
m_leftRightScroll = new QScrollBar( Qt::Horizontal, cw );
@@ -349,112 +405,6 @@ songEditor::songEditor() :
SLOT( scrolled( int ) ) );
QToolBar * edit_tb = new QToolBar( tr( "Edit" ), this );
#ifdef QT4
addToolBar( Qt::TopToolBarArea, edit_tb );
#else
addDockWindow( edit_tb, tr( "Edit" ), Qt::DockTop, FALSE );
#endif
/* edit_tb->setPaletteBackgroundPixmap( embed::getIconPixmap(
"toolbar_bg" ) );
edit_tb->setErasePixmap( embed::getIconPixmap( "toolbar_bg" ) );*/
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "add_bb_track" ), "",
this, SLOT( addBBTrack() ) );
a->setToolTip( tr( "Add beat/bassline" ) );
#else
m_addBBTrackButton = new QToolButton( embed::getIconPixmap(
"add_bb_track" ), "", "",
this, SLOT( addBBTrack() ),
edit_tb );
#endif
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "add_sample_track" ), "",
this, SLOT( addSampleTrack() ) );
a->setToolTip( tr( "Add sample-track" ) );
#else
m_addSampleTrackButton = new QToolButton( embed::getIconPixmap(
"add_sample_track" ), "", "",
this, SLOT( addSampleTrack() ),
edit_tb );
#endif
edit_tb->addSeparator();
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "se_insert_tact" ), "",
this, SLOT( insertTact() ) );
a->setToolTip( tr( "Insert bar at current tact (Shift+Insert)" ) );
a->setWhatsThis( tr( "If you click here, a tact will be inserted at "
"the current tact." ) );
#else
m_insertTactButton = new QToolButton( embed::getIconPixmap(
"se_insert_tact" ), "", "",
this, SLOT( insertTact() ),
edit_tb );
#endif
#ifdef QT4
a = edit_tb->addAction( embed::getIconPixmap( "se_remove_tact" ), "",
this, SLOT( removeTact() ) );
a->setToolTip( tr( "Remove bar at current tact (Shift+Delete)" ) );
a->setWhatsThis( tr( "If you click here, the tact at the current tact "
"will be removed." ) );
#else
m_removeTactButton = new QToolButton( embed::getIconPixmap(
"se_remove_tact" ), "", "",
this, SLOT( removeTact() ),
edit_tb );
#endif
// add tooltips and whats-this-texts to all buttons
toolTip::add( m_playButton, tr( "Play/pause song (Space)" ) );
toolTip::add( m_stopButton, tr( "Stop playing song (Space)" ) );
toolTip::add( m_addBBTrackButton, tr( "Add beat/bassline" ) );
toolTip::add( m_addSampleTrackButton, tr( "Add sample-track" ) );
toolTip::add( m_insertTactButton, tr( "Insert tact at current tact "
"(Shift+Insert)" ) );
toolTip::add( m_removeTactButton, tr( "Remove tact at current tact "
"(Shift+Delete)" ) );
#ifdef QT4
#else
QWhatsThis::add( m_playButton, tr( "Click here, if you want to play "
"your whole song. Playing will "
"be started at the "
"song-position-marker (green). "
"You can also move it while "
"playing." ) );
QWhatsThis::add( m_stopButton, tr ( "Click here, if you want to stop "
"playing of your song. The "
"song-position-marker will be "
"set to the start of your song."
) );
QWhatsThis::add( m_insertTactButton, tr( "If you click here, a "
"tact will "
"be inserted at the "
"current tact." ) );
QWhatsThis::add( m_removeTactButton, tr( "If you click here, the "
"tact at the "
"current tact will be "
"removed." ) );
#endif
edit_tb->addSeparator();
// setup zooming-stuff
m_zoomingComboBox = new QComboBox( edit_tb );
m_zoomingComboBox->setGeometry( 580, 10, 60, 20 );
for( int i = 0; i < 7; ++i )
{
m_zoomingComboBox->insertItem( QString::number( 25 *
static_cast<int>( powf( 2.0f, i ) ) ) +
"%" );
}
m_zoomingComboBox->setCurrentText( "100%" );
connect( m_zoomingComboBox, SIGNAL( activated( const QString & ) ),
this, SLOT( zoomingChanged( const QString & ) ) );
show();
@@ -524,6 +474,7 @@ void songEditor::resizeEvent( QResizeEvent * _re )
m_playPos[PLAY_SONG].m_timeLine->setFixedWidth(
centralWidget()->width() );
m_toolBar->setFixedWidth( centralWidget()->width() );
}
trackContainer::resizeEvent( _re );
}
@@ -553,12 +504,12 @@ void songEditor::keyPressEvent( QKeyEvent * _ke )
if( _ke->modifiers() & Qt::ShiftModifier &&
_ke->key() == Qt::Key_Insert )
{
insertTact();
insertBar();
}
else if( _ke->modifiers() & Qt::ShiftModifier &&
_ke->key() == Qt::Key_Delete )
{
removeTact();
removeBar();
}
else if( _ke->key() == Qt::Key_Left )
{
@@ -655,7 +606,7 @@ void songEditor::wheelEvent( QWheelEvent * _we )
void songEditor::masterVolumeChanged( int _new_val )
{
mixer::inst()->setMasterOutput( 2.0f - _new_val / 100.0f );
mixer::inst()->setMasterGain( 2.0f - _new_val / 100.0f );
setModified();
}
@@ -723,14 +674,6 @@ void songEditor::masterPitchReleased( void )
void songEditor::toggleHQMode( void )
{
//mixer::inst()->setHighQuality (hq_btn->isChecked());
}
void songEditor::updatePosition( const midiTime & _t )
{
if( ( m_playing && m_playMode == PLAY_SONG ) || m_scrollBack == TRUE )
@@ -953,7 +896,9 @@ void songEditor::processNextBuffer( void )
// check for looping-mode and act if neccessary
timeLine * tl = m_playPos[m_playMode].m_timeLine;
if( tl != NULL && m_exporting == FALSE && tl->loopPointsEnabled() )
if( tl != NULL && m_exporting == FALSE && tl->loopPointsEnabled() &&
!( m_playMode == PLAY_PATTERN &&
m_patternToPlay->freezing() == TRUE ) )
{
if( m_playPos[m_playMode] < tl->loopBegin() ||
m_playPos[m_playMode] >= tl->loopEnd() )
@@ -1056,33 +1001,6 @@ void songEditor::processNextBuffer( void )
{
m_playPos[m_playMode].m_timeLine->updatePosition();
}
if( m_exporting == TRUE )
{
tact tacts = lengthInTacts() + 1;
if( m_playPos[PLAY_SONG].getTact() >= tacts )
{
// now pause the mixer - method
// exportProjectDialog::redrawProgressBar() which is
// called every 100 ms will find out that export
// is done and will act according to this
mixer::inst()->pause();
}
else
{
m_epd->updateProgressBar(
( m_playPos[PLAY_SONG].getTact() * 64 +
m_playPos[PLAY_SONG].getTact64th() ) *
100 / ( tacts * 64 ) );
}
}
if( m_playMode == PLAY_PATTERN && m_loopPattern == FALSE &&
m_patternToPlay->isFreezing() == TRUE &&
m_playPos[PLAY_PATTERN] > m_patternToPlay->length() )
{
m_patternToPlay->finishFreeze();
}
}
@@ -1263,12 +1181,6 @@ void songEditor::stopExport( void )
{
stop();
m_exporting = FALSE;
// if we rendered file from cmd-line quit after export
if( file_to_render != "" )
{
qApp->quit();
}
}
@@ -1276,7 +1188,7 @@ void songEditor::stopExport( void )
void songEditor::insertTact( void )
void songEditor::insertBar( void )
{
trackVector tv = tracks();
for( trackVector::iterator it = tv.begin(); it != tv.end(); ++it )
@@ -1289,7 +1201,7 @@ void songEditor::insertTact( void )
void songEditor::removeTact( void )
void songEditor::removeBar( void )
{
trackVector tv = tracks();
for( trackVector::iterator it = tv.begin(); it != tv.end(); ++it )
@@ -1640,15 +1552,7 @@ void songEditor::exportProject( void )
if( m_fileName != "" )
{
#ifdef QT4
base_filename = QFileInfo( m_fileName ).absolutePath() + "/" +
QFileInfo( m_fileName
).completeBaseName();
#else
base_filename = QFileInfo( m_fileName ).dirPath() + "/" +
QFileInfo( m_fileName ).baseName(
TRUE );
#endif
base_filename = baseName( m_fileName );
}
else
{
@@ -1709,12 +1613,9 @@ void songEditor::exportProject( void )
{
return;
}
m_epd = new exportProjectDialog( export_file_name,
exportProjectDialog epd( export_file_name,
lmmsMainWin::inst() );
m_epd->exec();
delete m_epd;
m_epd = NULL;
epd.exec();
}
}

View File

@@ -31,11 +31,13 @@
#include <QPainter>
#include <QApplication>
#include <QMouseEvent>
#include <QLayout>
#else
#include <qpainter.h>
#include <qapplication.h>
#include <qlayout.h>
#endif
@@ -44,18 +46,23 @@
#include "nstate_button.h"
#include "embed.h"
#include "templates.h"
#include "nstate_button.h"
QPixmap * timeLine::s_timeLinePixmap = NULL;
QPixmap * timeLine::s_posMarkerPixmap = NULL;
QPixmap * timeLine::s_loopPointPixmap = NULL;
QPixmap * timeLine::s_loopPointDisabledPixmap = NULL;
timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt,
songEditor::playPos & _pos, const midiTime & _begin,
QWidget * _parent ) :
QWidget( _parent ),
m_autoScroll( AUTOSCROLL_ENABLED ),
m_loopPoints( LOOP_POINTS_DISABLED ),
m_behaviourAtStop( BACK_TO_ZERO ),
m_xOffset( _xoff ),
m_posMarkerX( 0 ),
m_ppt( _ppt ),
@@ -84,41 +91,17 @@ timeLine::timeLine( const int _xoff, const int _yoff, const float _ppt,
"loop_point" ) );
}
if( s_loopPointDisabledPixmap == NULL)
{
s_loopPointDisabledPixmap = new QPixmap( embed::getIconPixmap(
"loop_point_disabled" ) );
}
move( 0, _yoff );
setFixedHeight( s_timeLinePixmap->height() );
m_xOffset -= s_posMarkerPixmap->width() / 2;
m_autoScroll = new nStateButton( this );
m_autoScroll->move( 3, 3 );
m_autoScroll->setGeneralToolTip( tr( "Enable/disable "
"auto-scrolling" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_on" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_off" ) );
m_loopPoints = new nStateButton( this );
m_loopPoints->move( 20, 3 );
m_loopPoints->setGeneralToolTip( tr( "Enable/disable loop-points" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_off" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_on" ) );
connect( m_loopPoints, SIGNAL( stateChanged( int ) ), this,
SLOT( toggleLoopPoints( int ) ) );
m_behaviourAtStop = new nStateButton( this );
m_behaviourAtStop ->move( 37, 3 );
m_behaviourAtStop ->addState( embed::getIconPixmap( "back_to_zero" ),
tr( "After stopping go back to begin" )
);
m_behaviourAtStop ->addState( embed::getIconPixmap(
"back_to_start" ),
tr( "After stopping go back to "
"position at which playing was "
"started" ) );
m_behaviourAtStop ->addState( embed::getIconPixmap(
"keep_stop_position" ),
tr( "After stopping keep position" ) );
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
@@ -139,18 +122,45 @@ timeLine::~timeLine()
timeLine::behaviourAtStopStates timeLine::behaviourAtStop( void ) const
void timeLine::addToolButtons( QWidget * _tool_bar )
{
return( static_cast<behaviourAtStopStates>(
m_behaviourAtStop->state() ) );
}
nStateButton * m_autoScroll = new nStateButton( _tool_bar );
m_autoScroll->setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
m_autoScroll->setGeneralToolTip( tr( "Enable/disable "
"auto-scrolling" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_on" ) );
m_autoScroll->addState( embed::getIconPixmap( "autoscroll_off" ) );
connect( m_autoScroll, SIGNAL( changedState( int ) ), this,
SLOT( toggleAutoScroll( int ) ) );
nStateButton * m_loopPoints = new nStateButton( _tool_bar );
m_loopPoints->setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
m_loopPoints->setGeneralToolTip( tr( "Enable/disable loop-points" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_off" ) );
m_loopPoints->addState( embed::getIconPixmap( "loop_points_on" ) );
connect( m_loopPoints, SIGNAL( changedState( int ) ), this,
SLOT( toggleLoopPoints( int ) ) );
nStateButton * m_behaviourAtStop = new nStateButton( _tool_bar );
m_behaviourAtStop->setPaletteBackgroundColor( QColor( 224, 224, 224 ) );
m_behaviourAtStop ->addState( embed::getIconPixmap( "back_to_zero" ),
tr( "After stopping go back to begin" )
);
m_behaviourAtStop ->addState( embed::getIconPixmap(
"back_to_start" ),
tr( "After stopping go back to "
"position at which playing was "
"started" ) );
m_behaviourAtStop ->addState( embed::getIconPixmap(
"keep_stop_position" ),
tr( "After stopping keep position" ) );
connect( m_behaviourAtStop, SIGNAL( changedState( int ) ), this,
SLOT( toggleBehaviourAtStop( int ) ) );
bool timeLine::loopPointsEnabled( void ) const
{
return( m_loopPoints->state() == LOOP_POINTS_ENABLED );
QBoxLayout * layout = dynamic_cast<QBoxLayout *>( _tool_bar->layout() );
layout->addWidget( m_autoScroll );
layout->addWidget( m_loopPoints );
layout->addWidget( m_behaviourAtStop );
}
@@ -170,7 +180,7 @@ void timeLine::updatePosition( const midiTime & )
#ifndef QT4
qApp->unlock();
#endif
if( m_autoScroll->state() == AUTOSCROLL_ENABLED )
if( m_autoScroll == AUTOSCROLL_ENABLED )
{
emit positionChanged( m_pos );
}
@@ -180,14 +190,31 @@ void timeLine::updatePosition( const midiTime & )
void timeLine::toggleAutoScroll( int _n )
{
m_autoScroll = static_cast<autoScrollStates>( _n );
}
void timeLine::toggleLoopPoints( int _n )
{
m_loopPoints = static_cast<loopPointStates>( _n );
update();
}
void timeLine::toggleBehaviourAtStop( int _n )
{
m_behaviourAtStop = static_cast<behaviourAtStopStates>( _n );
}
void timeLine::paintEvent( QPaintEvent * )
{
#ifdef QT4
@@ -205,13 +232,11 @@ void timeLine::paintEvent( QPaintEvent * )
p.setClipRect( m_xOffset, 0, width() - m_xOffset, height() );
p.setPen( QColor( 0, 0, 0 ) );
if( m_loopPoints->state() == LOOP_POINTS_ENABLED )
{
p.drawPixmap( markerX( m_loopPos[0] ), 7,
*s_loopPointPixmap );
p.drawPixmap( markerX( m_loopPos[1] ), 7,
*s_loopPointPixmap );
}
const QPixmap & lpoint = loopPointsEnabled() ?
*s_loopPointPixmap :
*s_loopPointDisabledPixmap;
p.drawPixmap( markerX( m_loopPos[0] ), 7, lpoint );
p.drawPixmap( markerX( m_loopPos[1] ), 7, lpoint );
tact tact_num = m_begin.getTact();
@@ -225,7 +250,11 @@ void timeLine::paintEvent( QPaintEvent * )
if( ( tact_num - 1 ) %
tMax( 1, static_cast<int>( 64.0f / m_ppt ) ) == 0 )
{
p.drawText( x + static_cast<int>( i * m_ppt ), 16,
p.setPen( QColor( 224, 224, 224 ) );
p.drawText( x + static_cast<int>( i * m_ppt ) + 1, 15,
QString::number( tact_num ) );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( x + static_cast<int>( i * m_ppt ), 14,
QString::number( tact_num ) );
}
}
@@ -249,10 +278,6 @@ void timeLine::mousePressEvent( QMouseEvent * _me )
}
if( _me->button() == Qt::RightButton )
{
if( m_loopPoints->state() != LOOP_POINTS_ENABLED )
{
return;
}
if( _me->x() >= markerX( loopBegin() ) &&
_me->x() <= markerX( loopBegin() ) +
s_loopPointPixmap->width() )
@@ -300,12 +325,12 @@ void timeLine::mouseMoveEvent( QMouseEvent * _me )
break;
case MOVE_LOOP_BEGIN:
m_loopPos[0] = t;
m_loopPos[0] = t.getTact() * 64;
update();
break;
case MOVE_LOOP_END:
m_loopPos[1] = t;
m_loopPos[1] = t.getTact() * 64;
update();
break;

View File

@@ -40,6 +40,8 @@
#include <qdom.h>
#include <qpopupmenu.h>
#include <qlayout.h>
#include <qcursor.h>
#include <qwhatsthis.h>
#endif
@@ -594,7 +596,7 @@ trackWidget::trackWidget( track * _track, QWidget * _parent ) :
QPushButton * clntr_btn = new QPushButton( embed::getIconPixmap(
"pr_edit_copy", 12, 12 ),
"edit_copy", 12, 12 ),
"",
&m_trackOperationsWidget );
clntr_btn->setGeometry( 1, 1, TRACK_OP_BTN_WIDTH, TRACK_OP_BTN_HEIGHT );

View File

@@ -48,7 +48,7 @@
midiALSARaw::midiALSARaw( void ) :
midiRawClient(),
midiClientRaw(),
QThread(),
m_inputp( &m_input ),
m_outputp( &m_output ),
@@ -200,7 +200,7 @@ void midiALSARaw::run( void )
midiALSARaw::setupWidget::setupWidget( QWidget * _parent ) :
midiRawClient::setupWidget( midiALSARaw::name(), _parent )
midiClientRaw::setupWidget( midiALSARaw::name(), _parent )
{
m_device = new QLineEdit( midiALSARaw::probeDevice(), this );
m_device->setGeometry( 10, 20, 160, 20 );

View File

@@ -74,7 +74,8 @@ midiALSASeq::midiALSASeq( void ) :
m_queueID = snd_seq_alloc_queue( m_seqHandle );
snd_seq_queue_tempo_t * tempo;
snd_seq_queue_tempo_alloca( &tempo );
snd_seq_queue_tempo_set_tempo( tempo, 6000000 / songEditor::inst()->getBPM() );
snd_seq_queue_tempo_set_tempo( tempo, 6000000 /
songEditor::inst()->getBPM() );
snd_seq_queue_tempo_set_ppq( tempo, 16 );
snd_seq_set_queue_tempo( m_seqHandle, m_queueID, tempo );
@@ -154,10 +155,10 @@ void midiALSASeq::processOutEvent( const midiEvent & _me,
break;
case NOTE_OFF:
snd_seq_ev_set_note( &ev,
snd_seq_ev_set_noteoff( &ev,
_port->outputChannel(),
_me.key() + NOTES_PER_OCTAVE,
_me.velocity(), 500 );
_me.velocity() );
break;
case KEY_PRESSURE:

View File

@@ -35,10 +35,6 @@
#include "midi_port.h"
#include "note.h"
/*#include "midi_alsa_raw.h"
#include "midi_alsa_seq.h"
#include "midi_oss.h"
#include "midi_dummy.h"*/
@@ -98,7 +94,7 @@ void midiClient::removePort( midiPort * _port )
midiRawClient::midiRawClient() :
midiClientRaw::midiClientRaw() :
midiClient()
{
}
@@ -106,14 +102,14 @@ midiRawClient::midiRawClient() :
midiRawClient::~midiRawClient()
midiClientRaw::~midiClientRaw()
{
}
void midiRawClient::parseData( const Uint8 _c )
void midiClientRaw::parseData( const Uint8 _c )
{
/*********************************************************************/
/* 'Process' system real-time messages */
@@ -248,7 +244,7 @@ void midiRawClient::parseData( const Uint8 _c )
void midiRawClient::processParsedEvent()
void midiClientRaw::processParsedEvent()
{
for( csize i = 0; i < m_midiPorts.size(); ++i )
{
@@ -260,7 +256,7 @@ void midiRawClient::processParsedEvent()
void midiRawClient::processOutEvent( const midiEvent & _me,
void midiClientRaw::processOutEvent( const midiEvent & _me,
const midiTime & ,
const midiPort * _port )
{
@@ -293,7 +289,7 @@ void midiRawClient::processOutEvent( const midiEvent & _me,
break;
default:
printf( "midiRawClient: unhandled MIDI-event %d\n",
printf( "midiClientRaw: unhandled MIDI-event %d\n",
(int) _me.m_type );
break;
}
@@ -331,7 +327,7 @@ const Uint8 REMAINS_80E0[] =
// Returns the length of the MIDI message starting with _event.
// Taken from Nagano Daisuke's USB-MIDI driver
Uint8 midiRawClient::eventLength( const Uint8 _event )
Uint8 midiClientRaw::eventLength( const Uint8 _event )
{
if ( _event < 0xF0 )
{

View File

@@ -54,7 +54,7 @@
midiOSS::midiOSS( void ) :
midiRawClient(),
midiClientRaw(),
QThread(),
m_midiDev( probeDevice() ),
m_quit( FALSE )
@@ -143,7 +143,7 @@ void midiOSS::run( void )
midiOSS::setupWidget::setupWidget( QWidget * _parent ) :
midiRawClient::setupWidget( midiOSS::name(), _parent )
midiClientRaw::setupWidget( midiOSS::name(), _parent )
{
m_device = new QLineEdit( midiOSS::probeDevice(), this );
m_device->setGeometry( 10, 20, 160, 20 );

View File

@@ -31,7 +31,6 @@
#include <QMenu>
#include <QProgressBar>
#include <QPushButton>
#include <QTimer>
#include <QMessageBox>
#include <QImage>
#include <QMouseEvent>
@@ -42,7 +41,6 @@
#include <qpopupmenu.h>
#include <qprogressbar.h>
#include <qpushbutton.h>
#include <qtimer.h>
#include <qmessagebox.h>
#include <qimage.h>
@@ -79,9 +77,8 @@ pattern::pattern ( channelTrack * _channel_track ) :
m_name( _channel_track->name() ),
m_frozenPatternMutex(),
m_frozenPattern( NULL ),
m_freezeRecorder( NULL ),
m_freezeStatusDialog( NULL ),
m_freezeStatusUpdateTimer( NULL )
m_freezing( FALSE ),
m_freezeAborted( FALSE )
{
initPixmaps();
@@ -118,7 +115,8 @@ pattern::pattern( const pattern & _pat_to_copy ) :
m_patternType( _pat_to_copy.m_patternType ),
m_name( "" ),
m_frozenPatternMutex(),
m_frozenPattern( NULL )
m_frozenPattern( NULL ),
m_freezeAborted( FALSE )
{
initPixmaps();
@@ -573,7 +571,8 @@ void pattern::freeze( void )
( 0, tr( "Channel muted" ),
tr( "The channel this pattern "
"belongs to is "
"currently muted, so "
"currently muted "
"therefore "
"freezing makes no "
"sense! Do you still "
"want to continue?" ),
@@ -594,15 +593,17 @@ void pattern::freeze( void )
unfreeze();
}
mixer::inst()->pause();
// create and install audio-sample-recorder
bool b;
m_freezeRecorder = new audioSampleRecorder(
mixer::inst()->sampleRate(),
DEFAULT_CHANNELS, b );
mixer::inst()->setAudioDevice( m_freezeRecorder,
// we cannot create local copy, because at a later stage
// mixer::restoreAudioDevice(...) deletes old audio-dev and thus
// audioSampleRecorder would be destroyed two times...
audioSampleRecorder * freeze_recorder = new audioSampleRecorder(
mixer::inst()->sampleRate(), DEFAULT_CHANNELS, b );
mixer::inst()->setAudioDevice( freeze_recorder,
mixer::inst()->highQuality() );
// prepare stuff for playing correct things later
songEditor::inst()->playPattern( this, FALSE );
songEditor::playPos & ppp = songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN );
@@ -610,19 +611,41 @@ void pattern::freeze( void )
ppp.setTact64th( 0 );
ppp.setCurrentFrame( 0 );
ppp.m_timeLineUpdate = FALSE;
m_freezeStatusDialog = new patternFreezeStatusDialog;
connect( m_freezeStatusDialog, SIGNAL( aborted() ), this,
SLOT( abortFreeze() ) );
m_freezeStatusUpdateTimer = new QTimer( this );
connect( m_freezeStatusUpdateTimer, SIGNAL( timeout() ), this,
SLOT( updateFreezeStatusDialog() ) );
// create status-dialog
patternFreezeStatusDialog status_dlg;
status_dlg.show();
connect( &status_dlg, SIGNAL( aborted() ),
this, SLOT( abortFreeze() ) );
m_freezeStatusUpdateTimer->start( 50 );
m_freezeAborted = FALSE;
m_freezing = TRUE;
m_freezeStatusDialog->show();
// now render everything
while( ppp < length() && m_freezeAborted == FALSE )
{
freeze_recorder->processNextBuffer();
status_dlg.setProgress( ppp * 100 / length() );
qApp->processEvents();
}
mixer::inst()->play();
m_freezing = FALSE;
// reset song-editor settings
songEditor::inst()->stop();
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLineUpdate = TRUE;
// create final sample-buffer if freezing was successful
if( m_freezeAborted == FALSE )
{
m_frozenPatternMutex.lock();
freeze_recorder->createSampleBuffer( &m_frozenPattern );
m_frozenPatternMutex.unlock();
}
// restore original audio-device
mixer::inst()->restoreAudioDevice();
}
@@ -642,62 +665,9 @@ void pattern::unfreeze( void )
void pattern::updateFreezeStatusDialog( void )
{
m_freezeStatusDialog->setProgress( songEditor::inst()->getPlayPos(
songEditor::PLAY_PATTERN ) *
100 / length() );
m_frozenPatternMutex.lock();
// finishFreeze called?
if( m_freezeRecorder == NULL )
{
// then we're done and destroy the timer and the dialog
delete m_freezeStatusUpdateTimer;
delete m_freezeStatusDialog;
m_freezeStatusUpdateTimer = NULL;
m_freezeStatusDialog = NULL;
}
m_frozenPatternMutex.unlock();
}
void pattern::finishFreeze( void )
{
songEditor::inst()->stop();
m_frozenPatternMutex.lock();
m_freezeRecorder->createSampleBuffer( &m_frozenPattern );
mixer::inst()->restoreAudioDevice();
m_freezeRecorder = NULL;
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLineUpdate = TRUE;
m_frozenPatternMutex.unlock();
}
void pattern::abortFreeze( void )
{
songEditor::inst()->stop();
m_frozenPatternMutex.lock();
mixer::inst()->restoreAudioDevice();
m_freezeRecorder = NULL;
songEditor::inst()->getPlayPos( songEditor::PLAY_PATTERN
).m_timeLineUpdate = TRUE;
m_frozenPatternMutex.unlock();
m_freezeAborted = TRUE;
}
@@ -788,7 +758,7 @@ void pattern::removeNote( const note * _note_to_del )
noteVector::iterator it = m_notes.begin();
while( it != m_notes.end() )
{
if( ( *it ) == _note_to_del )
if( *it == _note_to_del )
{
delete *it;
m_notes.erase( it );
@@ -961,7 +931,8 @@ void pattern::loadSettings( const QDomElement & _this )
patternFreezeStatusDialog::patternFreezeStatusDialog( void )
patternFreezeStatusDialog::patternFreezeStatusDialog( void ) :
QDialog()
{
setWindowTitle( tr( "Freezing pattern..." ) );
#if QT_VERSION >= 0x030200
@@ -980,6 +951,7 @@ patternFreezeStatusDialog::patternFreezeStatusDialog( void )
m_cancelBtn = new QPushButton( embed::getIconPixmap( "cancel" ),
tr( "Cancel" ), this );
m_cancelBtn->setGeometry( 50, 38, 120, 28 );
m_cancelBtn->show();
connect( m_cancelBtn, SIGNAL( clicked() ), this,
SLOT( cancelBtnClicked() ) );
}

View File

@@ -44,13 +44,10 @@
nStateButton::nStateButton( QWidget * _parent ) :
QWidget( _parent ),
QPushButton( _parent ),
m_generalToolTip( "" ),
m_curState( -1 )
{
#ifndef QT4
setBackgroundMode( Qt::NoBackground );
#endif
}
@@ -75,7 +72,7 @@ void nStateButton::addState( const QPixmap & _pm, const QString & _tooltip )
if( m_states.size() == 1 )
{
// then resize ourself
resize( _pm.width(), _pm.height() );
setFixedSize( _pm.width() + 6, _pm.height() + 6 );
// and set state to first pixmap
changeState( 0 );
}
@@ -96,15 +93,17 @@ void nStateButton::changeState( int _n )
m_generalToolTip;
toolTip::add( this, _tooltip );
emit stateChanged( m_curState );
setPixmap( *m_states[m_curState].first );
update();
emit changedState( m_curState );
/* update();*/
}
}
/*
void nStateButton::paintEvent( QPaintEvent * )
{
#ifdef QT4
@@ -125,7 +124,7 @@ void nStateButton::paintEvent( QPaintEvent * )
bitBlt( this, rect().topLeft(), &draw_pm );
#endif
}
*/
@@ -135,6 +134,7 @@ void nStateButton::mousePressEvent( QMouseEvent * _me )
{
changeState( ( ++m_curState ) % m_states.size() );
}
QPushButton::mousePressEvent( _me );
}

View File

@@ -209,7 +209,7 @@ void tabWidget::paintEvent( QPaintEvent * _pe )
void tabWidget::wheelEvent( QWheelEvent * _we )
{
_we->accept();
int dir = ( _we->delta() > 0 ) ? 1 : -1;
int dir = ( _we->delta() < 0 ) ? 1 : -1;
int tab = m_activeTab;
while( tab > -1 && static_cast<csize>( tab ) < m_widgets.count() )
{

View File

@@ -129,7 +129,7 @@ void visualizationWidget::paintEvent( QPaintEvent * )
if( m_enabled )
{
float master_output = mixer::inst()->masterOutput();
float master_output = mixer::inst()->masterGain();
Uint16 w = width()-4;
float half_h = -( height() - 6 ) / 3.0 * master_output - 1;
Uint16 x_base = 2;