added initial FX-mixer implementation - not perfect and very usable yet but the basics work so far
git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@789 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
@@ -40,9 +40,9 @@ audioPort::audioPort( const QString & _name, track * _track ) :
|
||||
m_secondBuffer( new surroundSampleFrame[
|
||||
engine::getMixer()->framesPerPeriod()] ),
|
||||
m_extOutputEnabled( FALSE ),
|
||||
m_nextFxChannel( -1 ),
|
||||
m_nextFxChannel( 0 ),
|
||||
m_name( "unnamed port" ),
|
||||
m_effects( this, _track ),
|
||||
m_effects( _track ),
|
||||
m_frames( engine::getMixer()->framesPerPeriod() )
|
||||
{
|
||||
engine::getMixer()->clearAudioBuffer( m_firstBuffer,
|
||||
|
||||
@@ -33,9 +33,8 @@
|
||||
|
||||
|
||||
|
||||
effectChain::effectChain( audioPort * _port, track * _track ) :
|
||||
effectChain::effectChain( track * _track ) :
|
||||
model( /*_track*/ NULL ),
|
||||
m_port( _port ),
|
||||
m_track( _track ),
|
||||
m_enabledModel( FALSE, FALSE, TRUE )
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "automation_editor.h"
|
||||
#include "bb_editor.h"
|
||||
#include "config_mgr.h"
|
||||
#include "fx_mixer.h"
|
||||
#include "ladspa_2_lmms.h"
|
||||
#include "main_window.h"
|
||||
#include "mixer.h"
|
||||
@@ -44,6 +45,8 @@
|
||||
bool engine::s_hasGUI = TRUE;
|
||||
float engine::s_framesPerTact64th;
|
||||
mixer * engine::s_mixer = NULL;
|
||||
fxMixer * engine::s_fxMixer = NULL;
|
||||
fxMixerView * engine::s_fxMixerView = NULL;
|
||||
mainWindow * engine::s_mainWindow = NULL;
|
||||
bbTrackContainer * engine::s_bbTrackContainer = NULL;
|
||||
song * engine::s_song = NULL;
|
||||
@@ -67,12 +70,14 @@ void engine::init( const bool _has_gui )
|
||||
|
||||
s_projectJournal = new projectJournal;
|
||||
s_mixer = new mixer;
|
||||
s_fxMixer = new fxMixer;
|
||||
s_song = new song;
|
||||
s_bbTrackContainer = new bbTrackContainer;
|
||||
|
||||
if( s_hasGUI )
|
||||
{
|
||||
s_mainWindow = new mainWindow;
|
||||
s_fxMixerView = new fxMixerView;
|
||||
s_songEditor = new songEditor( s_song );
|
||||
s_projectNotes = new projectNotes;
|
||||
s_bbEditor = new bbEditor( s_bbTrackContainer );
|
||||
|
||||
402
src/core/fx_mixer.cpp
Normal file
402
src/core/fx_mixer.cpp
Normal file
@@ -0,0 +1,402 @@
|
||||
#ifndef SINGLE_SOURCE_COMPILE
|
||||
|
||||
/*
|
||||
* fx_mixer.cpp - effect-mixer for LMMS
|
||||
*
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <QtGui/QInputDialog>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QMdiArea>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QScrollArea>
|
||||
#include <QtGui/QScrollBar>
|
||||
|
||||
#include "fx_mixer.h"
|
||||
#include "fader.h"
|
||||
#include "effect_chain.h"
|
||||
#include "effect_rack_view.h"
|
||||
#include "embed.h"
|
||||
#include "main_window.h"
|
||||
#include "lcd_spinbox.h"
|
||||
#include "gui_templates.h"
|
||||
|
||||
|
||||
struct fxChannel
|
||||
{
|
||||
fxChannel( model * _parent ) :
|
||||
m_fxChain( NULL ),
|
||||
m_used( FALSE ),
|
||||
m_peakLeft( 0.0f ),
|
||||
m_peakRight( 0.0f ),
|
||||
m_buffer( new surroundSampleFrame[
|
||||
engine::getMixer()->framesPerPeriod()] ),
|
||||
m_muteModel( FALSE, _parent ),
|
||||
m_soloModel( FALSE, _parent ),
|
||||
m_volumeModel( 1.0, 0.0, 2.0, 0.01, _parent ),
|
||||
m_lock()
|
||||
{
|
||||
engine::getMixer()->clearAudioBuffer( m_buffer,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
}
|
||||
|
||||
effectChain m_fxChain;
|
||||
bool m_used;
|
||||
float m_peakLeft;
|
||||
float m_peakRight;
|
||||
surroundSampleFrame * m_buffer;
|
||||
boolModel m_muteModel;
|
||||
boolModel m_soloModel;
|
||||
floatModel m_volumeModel;
|
||||
QMutex m_lock;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
fxMixer::fxMixer() :
|
||||
journallingObject(),
|
||||
model( NULL )
|
||||
{
|
||||
for( int i = 0; i < NUM_FX_CHANNELS+1; ++i )
|
||||
{
|
||||
m_fxChannels[i] = new fxChannel( this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fxMixer::~fxMixer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fxMixer::mixToChannel( const surroundSampleFrame * _buf, fx_ch_t _ch )
|
||||
{
|
||||
surroundSampleFrame * buf = m_fxChannels[_ch]->m_buffer;
|
||||
for( f_cnt_t f = 0; f < engine::getMixer()->framesPerPeriod(); ++f )
|
||||
{
|
||||
buf[f][0] += _buf[f][0];
|
||||
buf[f][1] += _buf[f][1];
|
||||
}
|
||||
m_fxChannels[_ch]->m_used = TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fxMixer::processChannel( fx_ch_t _ch )
|
||||
{
|
||||
if( m_fxChannels[_ch]->m_used || _ch == 0 )
|
||||
{
|
||||
const fpp_t f = engine::getMixer()->framesPerPeriod();
|
||||
m_fxChannels[_ch]->m_fxChain.startRunning();
|
||||
m_fxChannels[_ch]->m_fxChain.processAudioBuffer(
|
||||
m_fxChannels[_ch]->m_buffer, f );
|
||||
m_fxChannels[_ch]->m_peakLeft = engine::getMixer()->peakValueLeft( m_fxChannels[_ch]->m_buffer, f ) * m_fxChannels[_ch]->m_volumeModel.value();
|
||||
m_fxChannels[_ch]->m_peakRight = engine::getMixer()->peakValueRight( m_fxChannels[_ch]->m_buffer, f ) * m_fxChannels[_ch]->m_volumeModel.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fxChannels[_ch]->m_peakLeft =
|
||||
m_fxChannels[_ch]->m_peakRight = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fxMixer::prepareMasterMix( void )
|
||||
{
|
||||
engine::getMixer()->clearAudioBuffer( m_fxChannels[0]->m_buffer,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const surroundSampleFrame * fxMixer::masterMix( void )
|
||||
{
|
||||
surroundSampleFrame * buf = m_fxChannels[0]->m_buffer;
|
||||
for( int i = 1; i < NUM_FX_CHANNELS+1; ++i )
|
||||
{
|
||||
if( m_fxChannels[i]->m_used )
|
||||
{
|
||||
surroundSampleFrame * _buf = m_fxChannels[i]->m_buffer;
|
||||
for( f_cnt_t f = 0; f <
|
||||
engine::getMixer()->framesPerPeriod(); ++f )
|
||||
{
|
||||
buf[f][0] += _buf[f][0]*m_fxChannels[i]->m_volumeModel.value();
|
||||
buf[f][1] += _buf[f][1]*m_fxChannels[i]->m_volumeModel.value();
|
||||
}
|
||||
engine::getMixer()->clearAudioBuffer( _buf,
|
||||
engine::getMixer()->framesPerPeriod() );
|
||||
m_fxChannels[i]->m_used = FALSE;
|
||||
}
|
||||
}
|
||||
processChannel( 0 );
|
||||
for( f_cnt_t f = 0; f < engine::getMixer()->framesPerPeriod(); ++f )
|
||||
{
|
||||
buf[f][0] *= m_fxChannels[0]->m_volumeModel.value();
|
||||
buf[f][1] *= m_fxChannels[0]->m_volumeModel.value();
|
||||
}
|
||||
m_fxChannels[0]->m_peakLeft *= engine::getMixer()->masterGain();
|
||||
m_fxChannels[0]->m_peakRight *= engine::getMixer()->masterGain();
|
||||
return( buf );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fxMixer::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
{
|
||||
/* m_chordsEnabledModel.saveSettings( _doc, _this, "chord-enabled" );
|
||||
m_chordsModel.saveSettings( _doc, _this, "chord" );
|
||||
m_chordRangeModel.saveSettings( _doc, _this, "chordrange" );*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fxMixer::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
/* m_chordsEnabledModel.loadSettings( _this, "chord-enabled" );
|
||||
m_chordsModel.loadSettings( _this, "chord" );
|
||||
m_chordRangeModel.loadSettings( _this, "chordrange" );*/
|
||||
}
|
||||
|
||||
|
||||
class fxLine : public QWidget
|
||||
{
|
||||
public:
|
||||
fxLine( QWidget * _parent, fxMixerView * _mv ) :
|
||||
QWidget( _parent ),
|
||||
m_mv( _mv )
|
||||
{
|
||||
setFixedSize( 32, 200 );
|
||||
setAttribute( Qt::WA_OpaquePaintEvent, TRUE );
|
||||
}
|
||||
|
||||
virtual void setName( const QString & _name )
|
||||
{
|
||||
m_name = _name;
|
||||
}
|
||||
virtual void paintEvent( QPaintEvent * )
|
||||
{
|
||||
QPainter p( this );
|
||||
p.fillRect( rect(), QColor( 72, 76, 88 ) );
|
||||
/* p.setPen( QColor( 144, 152, 176 ) );
|
||||
p.drawLine( 0, 0, width()-1, 0 );
|
||||
p.drawLine( 0, 0, 0, height()-1 );
|
||||
p.setPen( QColor( 36, 38, 44 ) );
|
||||
p.drawLine( 0, height()-1, width()-1, height()-1 );
|
||||
p.drawLine( width()-1, 0, width()-1, height()-1 );*/
|
||||
p.setPen( QColor( 40, 42, 48 ) );
|
||||
p.drawRect( 0, 0, width()-2, height()-2 );
|
||||
p.setPen( QColor( 108, 114, 132 ) );
|
||||
p.drawRect( 1, 1, width()-2, height()-2 );
|
||||
p.setPen( QColor( 20, 24, 32 ) );
|
||||
p.drawRect( 0, 0, width()-1, height()-1 );
|
||||
|
||||
p.rotate( -90 );
|
||||
p.setPen( m_mv->currentFxLine() == this ?
|
||||
QColor( 0, 255, 0 ) : Qt::white );
|
||||
p.setFont( pointSizeF( font(), 7.5f ) );
|
||||
p.drawText( -70, 20, m_name );
|
||||
}
|
||||
|
||||
virtual void mousePressEvent( QMouseEvent * )
|
||||
{
|
||||
m_mv->setCurrentFxLine( this );
|
||||
}
|
||||
|
||||
virtual void mouseDoubleClickEvent( QMouseEvent * )
|
||||
{
|
||||
bool ok;
|
||||
QString new_name = QInputDialog::getText( this,
|
||||
fxMixerView::tr( "Rename FX channel" ),
|
||||
fxMixerView::tr( "Enter the new name for this "
|
||||
"FX channel" ),
|
||||
QLineEdit::Normal, m_name, &ok );
|
||||
if( ok && !new_name.isEmpty() )
|
||||
{
|
||||
m_name = new_name;
|
||||
update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
fxMixerView * m_mv;
|
||||
QString m_name;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
fxMixerView::fxMixerView() :
|
||||
QWidget(),
|
||||
modelView( NULL )
|
||||
{
|
||||
fxMixer * m = engine::getFxMixer();
|
||||
|
||||
QPalette pal = palette();
|
||||
pal.setColor( QPalette::Background, QColor( 72, 76, 88 ) );
|
||||
setPalette( pal );
|
||||
setAutoFillBackground( TRUE );
|
||||
|
||||
// setFixedHeight( 250+216 );
|
||||
setWindowTitle( tr( "FX-Mixer" ) );
|
||||
// setWindowIcon( embed::getIconPixmap( "fxmixer" ) );
|
||||
engine::getMainWindow()->workspace()->addSubWindow( this );
|
||||
parentWidget()->setAttribute( Qt::WA_DeleteOnClose, FALSE );
|
||||
QVBoxLayout * ml = new QVBoxLayout( this );
|
||||
ml->setMargin( 0 );
|
||||
ml->setSpacing( 0 );
|
||||
|
||||
QScrollArea * a = new QScrollArea( this );
|
||||
a->setFrameShape( QFrame::NoFrame );
|
||||
a->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
a->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
|
||||
a->setFixedHeight( 216 );
|
||||
ml->addWidget( a );
|
||||
|
||||
m_fxRackArea = new QWidget( this );
|
||||
m_fxRackArea->setFixedHeight( 250 );
|
||||
ml->addWidget( m_fxRackArea );
|
||||
ml->addStretch();
|
||||
|
||||
QWidget * base = new QWidget;
|
||||
QHBoxLayout * bl = new QHBoxLayout( base );
|
||||
bl->setSpacing( 0 );
|
||||
bl->setMargin( 0 );
|
||||
a->setWidget( base );
|
||||
|
||||
base->setFixedSize( (NUM_FX_CHANNELS+1)*33+6+10, 200 );
|
||||
pal = base->palette();
|
||||
pal.setColor( QPalette::Background, QColor( 72, 76, 88 ) );
|
||||
base->setPalette( pal );
|
||||
base->setAutoFillBackground( TRUE );
|
||||
|
||||
bl->addSpacing( 6 );
|
||||
for( int i = 0; i < NUM_FX_CHANNELS+1; ++i )
|
||||
{
|
||||
fxChannelView * cv = &m_fxChannelViews[i];
|
||||
cv->m_fxLine = new fxLine( base, this );
|
||||
bl->addWidget( cv->m_fxLine );
|
||||
if( i == 0 )
|
||||
{
|
||||
bl->addSpacing( 10 );
|
||||
cv->m_fxLine->setName( tr( "Master" ).arg( i ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
bl->addSpacing( 1 );
|
||||
cv->m_fxLine->setName( tr( "FX %1" ).arg( i ) );
|
||||
}
|
||||
lcdSpinBox * l = new lcdSpinBox( 2, cv->m_fxLine );
|
||||
l->model()->setRange( i, i );
|
||||
l->model()->setValue( i );
|
||||
l->update();
|
||||
cv->m_fader = new fader( &m->m_fxChannels[i]->m_volumeModel,
|
||||
cv->m_fxLine );
|
||||
cv->m_fader->move( 15-cv->m_fader->width()/2, 80 );
|
||||
cv->m_rackView = new effectRackView(
|
||||
&m->m_fxChannels[i]->m_fxChain, m_fxRackArea );
|
||||
cv->m_rackView->setFixedSize( 250, 250 );
|
||||
}
|
||||
|
||||
show();
|
||||
setCurrentFxLine( m_fxChannelViews[0].m_fxLine );
|
||||
|
||||
QTimer * t = new QTimer( this );
|
||||
connect( t, SIGNAL( timeout() ), this, SLOT( updateFaders() ) );
|
||||
t->start( 50 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fxMixerView::~fxMixerView()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fxMixerView::setCurrentFxLine( fxLine * _line )
|
||||
{
|
||||
m_currentFxLine = _line;
|
||||
for( int i = 0; i < NUM_FX_CHANNELS+1; ++i )
|
||||
{
|
||||
if( m_fxChannelViews[i].m_fxLine == _line )
|
||||
{
|
||||
m_fxChannelViews[i].m_rackView->show();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fxChannelViews[i].m_rackView->hide();
|
||||
}
|
||||
m_fxChannelViews[i].m_fxLine->update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void fxMixerView::updateFaders( void )
|
||||
{
|
||||
fxMixer * m = engine::getFxMixer();
|
||||
for( int i = 0; i < NUM_FX_CHANNELS+1; ++i )
|
||||
{
|
||||
const float opl = m_fxChannelViews[i].m_fader->getPeak_L();
|
||||
const float opr = m_fxChannelViews[i].m_fader->getPeak_R();
|
||||
const float fall_off = 1.1;
|
||||
if( m->m_fxChannels[i]->m_peakLeft > opl )
|
||||
{
|
||||
m_fxChannelViews[i].m_fader->setPeak_L(
|
||||
m->m_fxChannels[i]->m_peakLeft );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fxChannelViews[i].m_fader->setPeak_L( opl/fall_off );
|
||||
}
|
||||
if( m->m_fxChannels[i]->m_peakRight > opr )
|
||||
{
|
||||
m_fxChannelViews[i].m_fader->setPeak_R(
|
||||
m->m_fxChannels[i]->m_peakRight );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fxChannelViews[i].m_fader->setPeak_R( opr/fall_off );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "fx_mixer.moc"
|
||||
|
||||
#endif
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "mixer.h"
|
||||
#include "fx_mixer.h"
|
||||
#include "play_handle.h"
|
||||
#include "song.h"
|
||||
#include "templates.h"
|
||||
@@ -495,6 +496,7 @@ const surroundSampleFrame * mixer::renderNextBuffer( void )
|
||||
//printf("---------------------------next period\n");
|
||||
// if( criticalXRuns() == FALSE )
|
||||
{
|
||||
engine::getFxMixer()->prepareMasterMix();
|
||||
engine::getSong()->processNextBuffer();
|
||||
|
||||
lockPlayHandles();
|
||||
@@ -605,6 +607,14 @@ if( COND_NPH )
|
||||
}
|
||||
}
|
||||
}
|
||||
for( int i = 1; i < NUM_FX_CHANNELS+1; ++i )
|
||||
{
|
||||
engine::getFxMixer()->processChannel( i );
|
||||
}
|
||||
const surroundSampleFrame * buf =
|
||||
engine::getFxMixer()->masterMix();
|
||||
memcpy( m_writeBuf, buf, m_framesPerPeriod *
|
||||
sizeof( surroundSampleFrame ) );
|
||||
}
|
||||
|
||||
unlock();
|
||||
@@ -647,26 +657,6 @@ void mixer::clear( void )
|
||||
|
||||
|
||||
|
||||
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab,
|
||||
const f_cnt_t _frames,
|
||||
const f_cnt_t _offset )
|
||||
{
|
||||
memset( _ab+_offset, 0, sizeof( *_ab ) * _frames );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef DISABLE_SURROUND
|
||||
void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
|
||||
const f_cnt_t _frames,
|
||||
const f_cnt_t _offset )
|
||||
{
|
||||
memset( _ab+_offset, 0, sizeof( *_ab ) * _frames );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
|
||||
const fpp_t _frames,
|
||||
const f_cnt_t _offset,
|
||||
@@ -721,6 +711,59 @@ void FASTCALL mixer::bufferToPort( const sampleFrame * _buf,
|
||||
|
||||
|
||||
|
||||
void FASTCALL mixer::clearAudioBuffer( sampleFrame * _ab,
|
||||
const f_cnt_t _frames,
|
||||
const f_cnt_t _offset )
|
||||
{
|
||||
memset( _ab+_offset, 0, sizeof( *_ab ) * _frames );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef DISABLE_SURROUND
|
||||
void FASTCALL mixer::clearAudioBuffer( surroundSampleFrame * _ab,
|
||||
const f_cnt_t _frames,
|
||||
const f_cnt_t _offset )
|
||||
{
|
||||
memset( _ab+_offset, 0, sizeof( *_ab ) * _frames );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
float mixer::peakValueLeft( surroundSampleFrame * _ab, const f_cnt_t _frames )
|
||||
{
|
||||
float p = 0.0f;
|
||||
for( f_cnt_t f = 0; f < _frames; ++f )
|
||||
{
|
||||
if( _ab[f][0] > p )
|
||||
{
|
||||
p = _ab[f][0];
|
||||
}
|
||||
}
|
||||
return( p );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
float mixer::peakValueRight( surroundSampleFrame * _ab, const f_cnt_t _frames )
|
||||
{
|
||||
float p = 0.0f;
|
||||
for( f_cnt_t f = 0; f < _frames; ++f )
|
||||
{
|
||||
if( _ab[f][1] > p )
|
||||
{
|
||||
p = _ab[f][1];
|
||||
}
|
||||
}
|
||||
return( p );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void mixer::setHighQuality( bool _hq_on )
|
||||
{
|
||||
// don't delete the audio-device
|
||||
@@ -954,8 +997,7 @@ midiClient * mixer::tryMIDIClients( void )
|
||||
|
||||
|
||||
|
||||
void mixer::processBuffer( const surroundSampleFrame * _buf,
|
||||
fx_ch_t/* _fx_chnl */ )
|
||||
void mixer::processBuffer( const surroundSampleFrame * _buf, fx_ch_t _fx_chnl )
|
||||
{
|
||||
// TODO: process according effect-channel
|
||||
|
||||
@@ -968,22 +1010,7 @@ void mixer::processBuffer( const surroundSampleFrame * _buf,
|
||||
m_newBuffer[chnl] = TRUE;
|
||||
}
|
||||
}*/
|
||||
|
||||
static QMutex m;
|
||||
m.lock();
|
||||
for( fpp_t frame = 0; frame < m_framesPerPeriod; ++frame )
|
||||
{
|
||||
for( ch_cnt_t chnl = 0; chnl < m_audioDev->channels(); ++chnl )
|
||||
{
|
||||
m_writeBuf[frame][chnl] += _buf[frame][chnl];
|
||||
/*
|
||||
if( m_scaleClip )
|
||||
{
|
||||
scaleClip( frame, chnl );
|
||||
}*/
|
||||
}
|
||||
}
|
||||
m.unlock();
|
||||
engine::getFxMixer()->mixToChannel( _buf, _fx_chnl );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ instrumentTrack::instrumentTrack( trackContainer * _tc ) :
|
||||
m_volumeModel( DEFAULT_VOLUME, MIN_VOLUME, MAX_VOLUME,
|
||||
1.0f, this ),
|
||||
m_surroundAreaModel( this, this ),
|
||||
m_effectChannelModel( 1, 1, NUM_FX_CHANNELS, 1, this ),
|
||||
m_effectChannelModel( 0, 0, NUM_FX_CHANNELS, 1, this ),
|
||||
m_instrument( NULL ),
|
||||
m_soundShaping( this ),
|
||||
m_arpeggiator( this ),
|
||||
@@ -189,6 +189,7 @@ void instrumentTrack::processAudioBuffer( sampleFrame * _buf,
|
||||
}
|
||||
volumeVector v = m_surroundAreaModel.getVolumeVector( v_scale );
|
||||
|
||||
m_audioPort.setNextFxChannel( m_effectChannelModel.value() );
|
||||
engine::getMixer()->bufferToPort( _buf,
|
||||
( _n != NULL ) ? tMin<f_cnt_t>(
|
||||
_n->framesLeftForCurrentPeriod(), _frames ) :
|
||||
@@ -1162,8 +1163,8 @@ void instrumentTrackWindow::modelChanged( void )
|
||||
this, SLOT( updateInstrumentView() ),
|
||||
Qt::QueuedConnection );
|
||||
m_volumeKnob->setModel( &m_track->m_volumeModel );
|
||||
m_volumeKnob->setModel( &m_track->m_volumeModel );
|
||||
m_surroundArea->setModel( &m_track->m_surroundAreaModel );
|
||||
m_effectChannelNumber->setModel( &m_track->m_effectChannelModel );
|
||||
m_pianoView->setModel( &m_track->m_piano );
|
||||
|
||||
m_ssView->setModel( &m_track->m_soundShaping );
|
||||
|
||||
220
src/widgets/fader.cpp
Normal file
220
src/widgets/fader.cpp
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* fader.cpp - fader-widget used in mixer - partly taken from Hydrogen
|
||||
*
|
||||
* Copyright (c) 2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Hydrogen
|
||||
* Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
|
||||
*
|
||||
* http://www.hydrogen-music.org
|
||||
*
|
||||
* 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; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QPaintEvent>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
#include "fader.h"
|
||||
#include "embed.h"
|
||||
|
||||
|
||||
fader::fader( floatModel * _model, QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
floatModelView( _model ),
|
||||
m_model( _model ),
|
||||
m_fPeakValue_L( 0.0 ),
|
||||
m_fPeakValue_R( 0.0 ),
|
||||
m_fMinPeak( 0.01f ),
|
||||
m_fMaxPeak( 1.1 ),
|
||||
m_back( embed::getIconPixmap( "fader_background" ) ),
|
||||
m_leds( embed::getIconPixmap( "fader_leds" ) ),
|
||||
m_knob( embed::getIconPixmap( "fader_knob" ) )
|
||||
{
|
||||
setAttribute( Qt::WA_NoBackground );
|
||||
setMinimumSize( 23, 116 );
|
||||
setMaximumSize( 23, 116);
|
||||
resize( 23, 116 );
|
||||
setModel( _model );
|
||||
}
|
||||
|
||||
|
||||
|
||||
fader::~fader()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fader::mouseMoveEvent( QMouseEvent *ev )
|
||||
{
|
||||
float fVal = (float)( height() - ev->y() ) / (float)height();
|
||||
fVal = fVal * ( m_model->maxValue() - m_model->minValue() );
|
||||
|
||||
fVal = fVal + m_model->minValue();
|
||||
|
||||
m_model->setValue( fVal );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fader::mousePressEvent(QMouseEvent *ev)
|
||||
{
|
||||
mouseMoveEvent( ev );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fader::wheelEvent ( QWheelEvent *ev )
|
||||
{
|
||||
ev->accept();
|
||||
|
||||
if ( ev->delta() > 0 )
|
||||
{
|
||||
m_model->incValue( 5 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_model->incValue( -5 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Set peak value (0.0 .. 1.0)
|
||||
///
|
||||
void fader::setPeak_L( float fPeak )
|
||||
{
|
||||
if ( fPeak < m_fMinPeak ) {
|
||||
fPeak = m_fMinPeak;
|
||||
}
|
||||
else if ( fPeak > m_fMaxPeak ) {
|
||||
fPeak = m_fMaxPeak;
|
||||
}
|
||||
|
||||
if ( m_fPeakValue_L != fPeak) {
|
||||
m_fPeakValue_L = fPeak;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Set peak value (0.0 .. 1.0)
|
||||
///
|
||||
void fader::setPeak_R( float fPeak )
|
||||
{
|
||||
if ( fPeak < m_fMinPeak ) {
|
||||
fPeak = m_fMinPeak;
|
||||
}
|
||||
else if ( fPeak > m_fMaxPeak ) {
|
||||
fPeak = m_fMaxPeak;
|
||||
}
|
||||
|
||||
if ( m_fPeakValue_R != fPeak ) {
|
||||
m_fPeakValue_R = fPeak;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fader::paintEvent( QPaintEvent * ev)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
// background
|
||||
// painter.drawPixmap( rect(), m_back, QRect( 0, 0, 23, 116 ) );
|
||||
painter.drawPixmap( ev->rect(), m_back, ev->rect() );
|
||||
|
||||
|
||||
// peak leds
|
||||
//float fRange = abs( m_fMaxPeak ) + abs( m_fMinPeak );
|
||||
|
||||
float realPeak_L = m_fPeakValue_L - m_fMinPeak;
|
||||
//int peak_L = 116 - ( realPeak_L / fRange ) * 116.0;
|
||||
int peak_L = 116 - ( realPeak_L / ( m_fMaxPeak - m_fMinPeak ) ) * 116.0;
|
||||
|
||||
if ( peak_L > 116 ) {
|
||||
peak_L = 116;
|
||||
}
|
||||
painter.drawPixmap( QRect( 0, peak_L, 11, 116 - peak_L ), m_leds, QRect( 0, peak_L, 11, 116 - peak_L ) );
|
||||
|
||||
|
||||
float realPeak_R = m_fPeakValue_R - m_fMinPeak;
|
||||
int peak_R = 116 - ( realPeak_R / ( m_fMaxPeak - m_fMinPeak ) ) * 116.0;
|
||||
if ( peak_R > 116 ) {
|
||||
peak_R = 116;
|
||||
}
|
||||
painter.drawPixmap( QRect( 11, peak_R, 11, 116 - peak_R ), m_leds, QRect( 11, peak_R, 11, 116 - peak_R ) );
|
||||
|
||||
// knob
|
||||
static const uint knob_height = 29;
|
||||
static const uint knob_width = 15;
|
||||
|
||||
float fRange = m_model->maxValue() - m_model->minValue();
|
||||
|
||||
float realVal = m_model->value() - m_model->minValue();
|
||||
|
||||
// uint knob_y = (uint)( 116.0 - ( 86.0 * ( m_model->value() / fRange ) ) );
|
||||
uint knob_y = (uint)( 116.0 - ( 86.0 * ( realVal / fRange ) ) );
|
||||
|
||||
|
||||
painter.drawPixmap( QRect( 4, knob_y - knob_height, knob_width, knob_height), m_knob, QRect( 0, 0, knob_width, knob_height ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fader::setMaxPeak( float fMax )
|
||||
{
|
||||
m_fMaxPeak = fMax;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void fader::setMinPeak( float fMin )
|
||||
{
|
||||
m_fMinPeak = fMin;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include "fader.moc"
|
||||
|
||||
Reference in New Issue
Block a user