steroEnhancer, Vibed, and separated Graph widget

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/branches/lmms-mv@699 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Paul Giblock
2008-02-22 08:09:34 +00:00
parent 3e29f447a9
commit 5313f32c56
22 changed files with 1380 additions and 1293 deletions

View File

@@ -11,7 +11,7 @@ AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="stereoenhancer"
$(MOC) -o $@ $<
MOC_FILES = ./stereoenhancer_control_dialog.moc
MOC_FILES = ./stereoenhancer_controls.moc
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
EMBEDDED_RESOURCES = $(wildcard *png)
@@ -31,6 +31,8 @@ pkglib_LTLIBRARIES= libstereoenhancer.la
libstereoenhancer_la_SOURCES = stereo_enhancer.cpp \
stereo_enhancer.h \
stereoenhancer_control_dialog.cpp \
stereoenhancer_control_dialog.h
stereoenhancer_control_dialog.h \
stereoenhancer_controls.cpp \
stereoenhancer_controls.h
$(libstereoenhancer_la_SOURCES): ./embedded_resources.h

View File

@@ -51,11 +51,13 @@ plugin::descriptor stereoenhancer_plugin_descriptor =
stereoEnhancerEffect::stereoEnhancerEffect(
model * _parent,
const descriptor::subPluginFeatures::key * _key ) :
effect( &stereoenhancer_plugin_descriptor, _key ),
effect( &stereoenhancer_plugin_descriptor, _parent, _key ),
m_seFX( effectLib::stereoEnhancer<>( 0.0f ) ),
m_delayBuffer( new surroundSampleFrame[DEFAULT_BUFFER_SIZE] ),
m_currFrame( 0 )
m_currFrame( 0 ),
m_bbControls( this )
{
// TODO: Make m_delayBuffer customizable?
}
@@ -89,7 +91,7 @@ bool FASTCALL stereoEnhancerEffect::processAudioBuffer( surroundSampleFrame * _b
int frameIndex = 0;
if( isBypassed() || !isRunning () )
if( !isEnabled() || !isRunning() )
{
return( FALSE );
}
@@ -123,7 +125,7 @@ bool FASTCALL stereoEnhancerEffect::processAudioBuffer( surroundSampleFrame * _b
_buf[f][ch] = getDryLevel() * _buf[f][ch] +
getWetLevel() *
s[ch%DEFAULT_CHANNELS];
out_sum += _buf[f][ch]*_buf[f][ch];
out_sum += _buf[f][ch]*_buf[f][ch];
}
// Update currFrame
@@ -170,9 +172,9 @@ extern "C"
{
// neccessary for getting instance out of shared lib
plugin * lmms_plugin_main( void * _data )
plugin * lmms_plugin_main( model * _parent, void * _data )
{
return( new stereoEnhancerEffect(
return( new stereoEnhancerEffect( _parent,
static_cast<const plugin::descriptor::subPluginFeatures::key *>(
_data ) ) );
}

View File

@@ -32,43 +32,36 @@
#include "effect_lib.h"
#include "engine.h"
#include "main_window.h"
#include "stereoenhancer_control_dialog.h"
#include "stereoenhancer_controls.h"
class stereoEnhancerEffect : public effect
{
public:
stereoEnhancerEffect( const descriptor::subPluginFeatures::key * _key );
stereoEnhancerEffect( model * parent,
const descriptor::subPluginFeatures::key * _key );
virtual ~stereoEnhancerEffect();
virtual bool FASTCALL processAudioBuffer( surroundSampleFrame * _buf,
const fpp_t _frames );
inline virtual QString nodeName( void ) const
const fpp_t _frames );
virtual effectControls * getControls( void )
{
return( "stereoenhancereffect" );
return( &m_bbControls );
}
virtual inline effectControlDialog * createControlDialog( track * )
{
return( new stereoEnhancerControlDialog(
engine::getMainWindow()->workspace(),
this ) );
}
void clearMyBuffer();
private:
//effectLib::monoToStereoAdaptor<effectLib::stereoEnhancer<> > m_seFX;
effectLib::stereoEnhancer<> m_seFX;
surroundSampleFrame * m_delayBuffer;
int m_currFrame;
stereoEnhancerControls m_bbControls;
friend class stereoEnhancerControlDialog;
friend class stereoEnhancerControls;
} ;
#endif

View File

@@ -23,68 +23,27 @@
*/
#ifndef QT3
#include <QtGui/QLayout>
#include <QtGui/QMdiArea>
#else
#include <qlayout.h>
#endif
#include "stereo_enhancer.h"
#include "knob.h"
#include "stereoenhancer_control_dialog.h"
#include "stereoenhancer_controls.h"
stereoEnhancerControlDialog::stereoEnhancerControlDialog( QMdiArea * _parent,
stereoEnhancerEffect * _eff ) :
effectControlDialog( _parent, _eff ),
m_effect( _eff )
stereoEnhancerControlDialog::stereoEnhancerControlDialog(
stereoEnhancerControls * _controls ) :
effectControlDialog( _controls )
{
QHBoxLayout * l = new QHBoxLayout( this );
m_widthKnob = new knob( knobBright_26, this, tr( "Width" ), NULL );
m_widthKnob->setRange( 0.0f, 180.0f, 1.0f );
m_widthKnob->setInitValue( 0.0f );
m_widthKnob->setLabel( tr( "WIDE" ) );
m_widthKnob->setHintText( tr( "Width:" ) + " ", "samples" );
connect( m_widthKnob, SIGNAL( valueChanged( float ) ),
this, SLOT( changeWideCoeff( void ) ) );
knob * widthKnob = new knob( knobBright_26, this, tr( "Width" ) );
widthKnob->setModel( &_controls->m_widthModel );
widthKnob->setLabel( tr( "WIDE" ) );
widthKnob->setHintText( tr( "Width:" ) + " ", "samples" );
l->addWidget( m_widthKnob );
l->addWidget( widthKnob );
changeWideCoeff();
this->setLayout(l);
}
void stereoEnhancerControlDialog::changeWideCoeff( void )
{
m_effect->m_seFX.setWideCoeff( m_widthKnob->value() );
}
void FASTCALL stereoEnhancerControlDialog::loadSettings(
const QDomElement & _this )
{
m_widthKnob->setValue( _this.attribute( "width" ).toFloat() );
}
void FASTCALL stereoEnhancerControlDialog::saveSettings( QDomDocument & _doc,
QDomElement & _this )
{
_this.setAttribute( "width", m_widthKnob->value() );
}
#include "stereoenhancer_control_dialog.moc"

View File

@@ -27,42 +27,18 @@
#include "effect_control_dialog.h"
class knob;
class stereoEnhancerEffect;
class QMdiArea;
class stereoEnhancerControls;
class stereoEnhancerControlDialog : public effectControlDialog
{
Q_OBJECT
public:
stereoEnhancerControlDialog( QMdiArea * _parent, stereoEnhancerEffect * _eff );
stereoEnhancerControlDialog( stereoEnhancerControls * _controls );
virtual ~stereoEnhancerControlDialog()
{
}
virtual void FASTCALL saveSettings( QDomDocument & _doc,
QDomElement & _parent );
virtual void FASTCALL loadSettings( const QDomElement & _this );
inline virtual QString nodeName( void ) const
{
return( "stereoenhancercontrols" );
}
};
virtual ch_cnt_t getControlCount( void )
{
return( 1 );
}
private slots:
void changeWideCoeff( void );
private:
stereoEnhancerEffect * m_effect;
knob * m_widthKnob;
} ;
#endif

View File

@@ -0,0 +1,68 @@
/*
* stereoenhancer_controls.cpp - control-dialog for stereoenhancer-effect
*
* Copyright (c) 2006-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 "stereoenhancer_controls.h"
#include "stereo_enhancer.h"
#include "automatable_model_templates.h"
stereoEnhancerControls::stereoEnhancerControls( stereoEnhancerEffect * _eff ) :
effectControls( _eff ),
m_effect( _eff ),
m_widthModel(0.0f, 0.0f, 180.0f, 1.0f)
{
connect( &m_widthModel, SIGNAL( dataChanged( void ) ),
this, SLOT( changeWideCoeff( void ) ) );
changeWideCoeff();
}
void stereoEnhancerControls::changeWideCoeff( void )
{
m_effect->m_seFX.setWideCoeff( m_widthModel.value() );
}
void FASTCALL stereoEnhancerControls::loadSettings(
const QDomElement & _this )
{
m_widthModel.setValue( _this.attribute( "width" ).toFloat() );
}
void FASTCALL stereoEnhancerControls::saveSettings( QDomDocument & _doc,
QDomElement & _this )
{
_this.setAttribute( "width", m_widthModel.value() );
}
#include "stereoenhancer_controls.moc"

View File

@@ -0,0 +1,74 @@
/*
* stereoenhancer_controls.h - controls for stereoEnhancer-effect
*
* 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.
*
*/
#ifndef _STEREO_ENHANCER_CONTROLS_H
#define _STEREO_ENHANCER_CONTROLS_H
#include "effect_controls.h"
#include "stereoenhancer_control_dialog.h"
#include "knob.h"
class stereoEnhancerEffect;
class stereoEnhancerControls : public effectControls
{
Q_OBJECT
public:
stereoEnhancerControls( stereoEnhancerEffect( * _eff ) );
virtual ~stereoEnhancerControls()
{
}
virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent );
virtual void loadSettings( const QDomElement & _this );
inline virtual QString nodeName( void ) const
{
return( "stereoenhancercontrols" );
}
virtual ch_cnt_t getControlCount( void )
{
return( 1 );
}
virtual effectControlDialog * createView( void )
{
return new stereoEnhancerControlDialog( this );
}
private slots:
void changeWideCoeff( void );
private:
stereoEnhancerEffect * m_effect;
knobModel m_widthModel;
friend class stereoEnhancerControlDialog;
} ;
#endif /*_STEREO_ENHANCER_CONTROLS_H*/

View File

@@ -11,7 +11,7 @@ AM_CXXFLAGS := $(AM_CXXFLAGS) $(QT_CXXFLAGS) -DPLUGIN_NAME="vibedstrings"
$(MOC) -o $@ $<
MOC_FILES = ./vibed.moc ./graph.moc ./impulse_editor.moc ./nine_button_selector.moc
MOC_FILES = ./vibed.moc ./nine_button_selector.moc
BUILT_SOURCES = $(MOC_FILES) ./embedded_resources.h
EMBEDDED_RESOURCES = $(wildcard *png)
@@ -30,15 +30,11 @@ pkglib_LTLIBRARIES= libvibedstrings.la
libvibedstrings_la_SOURCES = vibed.cpp \
vibed.h \
graph.cpp \
graph.h \
vibrating_string.cpp \
vibrating_string.h \
nine_button_selector.cpp \
nine_button_selector.h \
string_container.cpp \
string_container.h \
impulse_editor.cpp \
impulse_editor.h \
nine_button_selector.cpp \
nine_button_selector.h
string_container.h
$(libvibedstrings_la_SOURCES): ./embedded_resources.h

View File

@@ -1,227 +0,0 @@
/*
* graph.cpp - a QT widget for displaying and manipulating waveforms
*
* Copyright (c) 2006-2007 Andreas Brandmaier <andy/at/brandmaier/dot/de>
*
* 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/QPaintEvent>
#include <QtGui/QFontMetrics>
#include <QtGui/QPainter>
#include "graph.h"
#include "string_pair_drag.h"
#include "sample_buffer.h"
#include <iostream>
#include <cstdlib>
using namespace std;
graph::graph( QWidget * _parent ) :
QWidget( _parent )
{
m_mouseDown = false;
setFixedSize( 132, 104 );
setAcceptDrops( TRUE );
}
graph::~graph()
{
}
void graph::setForeground( const QPixmap &_pixmap )
{
m_foreground = _pixmap;
}
void graph::setSamplePointer( float * _pointer, int _length )
{
samplePointer = _pointer;
sampleLength = _length;
update();
}
void graph::loadSampleFromFile( const QString & _filename )
{
// zero sample_shape
for (int i = 0; i < sampleLength; i++)
{
samplePointer[i] = 0;
}
// load user shape
sampleBuffer buffer( _filename );
// copy buffer data
sampleLength = min( sampleLength, static_cast<int>(buffer.frames()) );
for ( int i = 0; i < sampleLength; i++ )
{
samplePointer[i] = (float)*buffer.data()[i];
}
}
void graph::mouseMoveEvent ( QMouseEvent * _me )
{
// get position
int x = _me->x();
int y = _me->y();
// avoid mouse leaps
int diff = x - m_lastCursorX;
if( diff >= 1 )
{
x = m_lastCursorX + 1;
}
else if( diff <= 1 )
{
x = m_lastCursorX - 1;
}
else
{
x = m_lastCursorX;
}
changeSampleAt( x, y );
// update mouse
m_lastCursorX = x;
}
void graph::mousePressEvent( QMouseEvent * _me )
{
if( _me->button() == Qt::LeftButton )
{
// toggle mouse state
m_mouseDown = true;
// get position
int x = _me->x();
int y = _me->y();
changeSampleAt( x,y );
// toggle mouse state
m_mouseDown = true;
setCursor( Qt::BlankCursor );
m_lastCursorX = x;
}
}
void graph::changeSampleAt(int _x, int _y)
{
// consider border of background image
_x -= 2;
_y -= 2;
// boundary check
if (_x < 0) { return; }
if (_x > sampleLength) { return; }
if (_y < 0) { return; }
if (_y >= 100) { return; }
_y = 100 - _y;
// change sample shape
samplePointer[_x] = (_y-50.0)/50.0;
emit sampleChanged();
}
void graph::mouseReleaseEvent( QMouseEvent * _me )
{
if( _me->button() == Qt::LeftButton )
{
// toggle mouse state
m_mouseDown = false;
setCursor( Qt::ArrowCursor );
update();
}
}
void graph::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.setPen( QColor( 0xFF, 0xAA, 0x00 ) );
p.drawLine( 1+sampleLength, 2, 1+sampleLength, 102);
float xscale = 128.0 / sampleLength;
for (int i=0; i < sampleLength-1; i++)
{
p.drawLine(2+static_cast<int>(i*xscale),
2+static_cast<int>(-samplePointer[i]*50) + 50,
2+static_cast<int>((i+1)*xscale),
2+static_cast<int>(-samplePointer[i+1]*50 + 50)
);
}
// draw Pointer
if (m_mouseDown) {
QPoint cursor = mapFromGlobal( QCursor::pos() );
p.setPen( QColor( 0xAA, 0xFF, 0x00 ) );
p.drawLine( 2, cursor.y(), 130, cursor.y() );
p.drawLine( cursor.x(), 2, cursor.x(), 102 );
}
p.drawPixmap( 0, 0, m_foreground );
}
void graph::dropEvent( QDropEvent * _de )
{
QString type = stringPairDrag::decodeKey( _de );
QString value = stringPairDrag::decodeValue( _de );
if( type == "samplefile" )
{
loadSampleFromFile( value );
_de->accept();
}
}
void graph::dragEnterEvent( QDragEnterEvent * _dee )
{
if( stringPairDrag::processDragEnterEvent( _dee,
QString( "samplefile" ) ) == FALSE )
{
_dee->ignore();
}
}
#include "graph.moc"

View File

@@ -1,72 +0,0 @@
/*
* graph.h - a QT widget for displaying and manipulating waveforms
*
* Copyright (c) 2006-2007 Andreas Brandmaier <andy/at/brandmaier/dot/de>
*
* 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.
*
*/
#ifndef _GRAPH_H
#define _GRAPH_H
#include <QtGui/QWidget>
#include <QtGui/QPixmap>
#include <QtGui/QCursor>
class graph : public QWidget
{
Q_OBJECT
public:
graph( QWidget * _parent );
virtual ~graph();
void setSamplePointer( float * pointer, int length );
void setForeground( const QPixmap & _pixmap );
void loadSampleFromFile( const QString & _filename );
signals:
void sampleSizeChanged( float f );
void sampleChanged( void );
protected:
virtual void paintEvent( QPaintEvent * _pe );
virtual void dropEvent( QDropEvent * _de );
virtual void dragEnterEvent( QDragEnterEvent * _dee );
virtual void mousePressEvent( QMouseEvent * _me );
virtual void mouseMoveEvent( QMouseEvent * _me );
virtual void mouseReleaseEvent( QMouseEvent * _me );
private:
void changeSampleAt(int _x, int _y);
QPixmap m_foreground;
float *samplePointer;
int sampleLength;
bool m_mouseDown;
int m_lastCursorX;
} ;
#endif

View File

@@ -1,471 +0,0 @@
/*
* impulse_editor.cpp - graphic waveform editor
*
* Copyright (c) 2006-2007 Danny McRae <khjklujn/at/yahoo/com>
*
* 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 "impulse_editor.h"
#include <Qt/QtXml>
#include <QtCore/QMap>
#include <QtCore/QPoint>
#include <QtGui/QWhatsThis>
#include "caption_menu.h"
#include "embed.h"
#include "engine.h"
#include "oscillator.h"
#include "song_editor.h"
#include "tooltip.h"
#include "vibed.h"
impulseEditor::impulseEditor( QWidget * _parent, int _x, int _y, track * _track,
Uint32 _len ) :
QWidget( _parent ),
m_sampleLength( _len ),
m_normalizeFactor( 1.0f ),
m_forward( TRUE )
{
setFixedSize( 153, 124 );
m_base = QPixmap::grabWidget( _parent, _x, _y );
setAutoFillBackground( TRUE );
QPalette pal = palette();
pal.setBrush( backgroundRole(), m_base );
setPalette( pal );
m_graph = new graph( this );
m_graph->setForeground( PLUGIN_NAME::getIconPixmap( "wavegraph4" ) );
m_graph->move( 0, 0 );
m_graph->setCursor( QCursor( Qt::CrossCursor ) );
toolTip::add( m_graph, tr ( "Draw your own waveform here "
"by dragging your mouse onto this graph" ) );
connect( m_graph, SIGNAL ( sampleChanged( void ) ),
this, SLOT ( sampleChanged( void ) ) );
m_sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ), _track );
m_sinWaveBtn->move( 136, 3 );
m_sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
"sin_wave_active" ) );
m_sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"sin_wave_inactive" ) );
m_sinWaveBtn->setChecked( TRUE );
toolTip::add( m_sinWaveBtn,
tr( "Click here if you want a sine-wave for "
"current oscillator." ) );
connect( m_sinWaveBtn, SIGNAL (clicked ( void ) ),
this, SLOT ( sinWaveClicked( void ) ) );
m_triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ),
_track );
m_triangleWaveBtn->move( 136, 20 );
m_triangleWaveBtn->setActiveGraphic(
embed::getIconPixmap( "triangle_wave_active" ) );
m_triangleWaveBtn->setInactiveGraphic(
embed::getIconPixmap( "triangle_wave_inactive" ) );
toolTip::add( m_triangleWaveBtn,
tr( "Click here if you want a triangle-wave "
"for current oscillator." ) );
connect( m_triangleWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( triangleWaveClicked( void ) ) );
m_sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ), _track );
m_sawWaveBtn->move( 136, 37 );
m_sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
"saw_wave_active" ) );
m_sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"saw_wave_inactive" ) );
toolTip::add( m_sawWaveBtn,
tr( "Click here if you want a saw-wave for "
"current oscillator." ) );
connect( m_sawWaveBtn, SIGNAL (clicked ( void ) ),
this, SLOT ( sawWaveClicked( void ) ) );
m_sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ), _track );
m_sqrWaveBtn->move( 136, 54 );
m_sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
"square_wave_active" ) );
m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"square_wave_inactive" ) );
toolTip::add( m_sqrWaveBtn,
tr( "Click here if you want a square-wave for "
"current oscillator." ) );
connect( m_sqrWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( sqrWaveClicked( void ) ) );
m_whiteNoiseWaveBtn = new pixmapButton( this, tr( "White noise wave" ),
_track );
m_whiteNoiseWaveBtn->move( 136, 71 );
m_whiteNoiseWaveBtn->setActiveGraphic(
embed::getIconPixmap( "white_noise_wave_active" ) );
m_whiteNoiseWaveBtn->setInactiveGraphic(
embed::getIconPixmap( "white_noise_wave_inactive" ) );
toolTip::add( m_whiteNoiseWaveBtn,
tr( "Click here if you want a white-noise for "
"current oscillator." ) );
connect( m_whiteNoiseWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( noiseWaveClicked( void ) ) );
m_usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ),
_track );
m_usrWaveBtn->move( 136, 88 );
m_usrWaveBtn->setActiveGraphic( embed::getIconPixmap(
"usr_wave_active" ) );
m_usrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"usr_wave_inactive" ) );
toolTip::add( m_usrWaveBtn,
tr( "Click here if you want a user-defined "
"wave-shape for current oscillator." ) );
connect( m_usrWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( usrWaveClicked( void ) ) );
m_smoothBtn = new pixmapButton( this, tr( "Smooth" ), _track );
m_smoothBtn->move( 3, 108 );
m_smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"smooth_active" ) );
m_smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"smooth_inactive" ) );
m_smoothBtn->setChecked( FALSE );
toolTip::add( m_smoothBtn,
tr( "Click here to smooth waveform." ) );
connect( m_smoothBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( smoothClicked( void ) ) );
m_normalizeBtn = new pixmapButton( this, tr( "Normalize" ), _track );
m_normalizeBtn->move( 20, 108 );
m_normalizeBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"normalize_active" ) );
m_normalizeBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"normalize_inactive" ) );
m_normalizeBtn->setChecked( FALSE );
toolTip::add( m_normalizeBtn,
tr( "Click here to normalize waveform." ) );
connect( m_normalizeBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( normalizeClicked( void ) ) );
m_state = new ledCheckBox( "", this, tr( "Enable waveform" ), _track );
m_state->move( 136, 109 );
m_state->setChecked( TRUE );
toolTip::add( m_state,
tr( "Click here to enable/disable waveform." ) );
m_sampleShape = new float[m_sampleLength];
m_graph->setSamplePointer( m_sampleShape, m_sampleLength );
m_lastBtn = m_sinWaveBtn;
emit( sawWaveClicked() );
move( _x, _y );
}
impulseEditor::~impulseEditor()
{
}
void impulseEditor::sinWaveClicked( void )
{
m_lastBtn->setChecked( FALSE);
m_lastBtn = m_sinWaveBtn;
m_lastBtn->setChecked( TRUE );
// generate a Sinus wave using static oscillator-method
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = oscillator::sinSample( i /
static_cast<float>( m_sampleLength ) );
}
sampleChanged();
}
void impulseEditor::triangleWaveClicked( void )
{
m_lastBtn->setChecked( FALSE);
m_lastBtn = m_triangleWaveBtn;
m_lastBtn->setChecked( TRUE );
// generate a Triangle wave using static oscillator-method
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = oscillator::triangleSample( i /
static_cast<float>( m_sampleLength ) );
}
sampleChanged();
}
void impulseEditor::sawWaveClicked( void )
{
m_lastBtn->setChecked( FALSE);
m_lastBtn = m_sawWaveBtn;
m_lastBtn->setChecked( TRUE );
// generate a Saw wave using static oscillator-method
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = oscillator::sawSample( i /
static_cast<float>( m_sampleLength ) );
}
sampleChanged();
}
void impulseEditor::sqrWaveClicked( void )
{
m_lastBtn->setChecked( FALSE);
m_lastBtn = m_sqrWaveBtn;
m_lastBtn->setChecked( TRUE );
// generate a Sqr wave using static oscillator-method
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = oscillator::squareSample( i /
static_cast<float>( m_sampleLength ) );
}
sampleChanged();
}
void impulseEditor::noiseWaveClicked( void )
{
m_lastBtn->setChecked( FALSE);
m_lastBtn = m_whiteNoiseWaveBtn;
m_lastBtn->setChecked( TRUE );
// generate a Noise wave using static oscillator-method
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = oscillator::noiseSample( i /
static_cast<float>( m_sampleLength ) );
}
sampleChanged();
}
void impulseEditor::usrWaveClicked( void )
{
m_lastBtn->setChecked( FALSE );
m_lastBtn = m_usrWaveBtn;
m_lastBtn->setChecked( TRUE );
// zero sample_shape
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = 0;
}
// load user shape
sampleBuffer buffer;
QString af = buffer.openAudioFile();
if( af != "" )
{
buffer.setAudioFile( af );
// copy buffer data
if( m_sampleLength < static_cast<Uint32>( buffer.frames() ) )
{
m_sampleLength = m_sampleLength;
}
else
{
m_sampleLength = static_cast<int>( buffer.frames() );
}
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = static_cast<float>(
buffer.data()[0][i] );
}
}
sampleChanged();
}
void impulseEditor::smoothClicked( void )
{
m_smoothBtn->setChecked( TRUE );
m_smoothBtn->update();
float* temp = new float[m_sampleLength];
memcpy( temp, m_sampleShape, sizeof( float ) * m_sampleLength );
// Smoothing
m_sampleShape[0] = temp[0] / 2.0f;
for( Uint32 i = 1; i < m_sampleLength - 1; i++ )
{
m_sampleShape[i] = ( temp[i - 1] +
temp[i] +
temp[i + 1] ) / 3.0f;
}
m_sampleShape[m_sampleLength - 1] = temp[m_sampleLength - 1] / 2.0f;
m_forward = FALSE;
// Clean up
delete[] temp;
// paint
update();
m_graph->update();
engine::getSongEditor()->setModified();
m_smoothBtn->setChecked( FALSE );
m_smoothBtn->update();
}
void impulseEditor::normalizeClicked( void )
{
m_normalizeBtn->setChecked( TRUE );
m_normalizeBtn->update();
float max = 0.0001f;
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
if( fabsf(m_sampleShape[i]) > max && m_sampleShape[i] != 0.0f )
{
max = fabs( m_sampleShape[i] );
}
}
m_normalizeFactor = max;
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] /= m_normalizeFactor;
}
update();
m_graph->update();
engine::getSongEditor()->setModified();
m_normalizeBtn->setChecked( FALSE );
m_normalizeBtn->update();
}
void impulseEditor::sampleChanged()
{
// analyze
float max = 0.0001f;
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
if( fabsf(m_sampleShape[i]) > max && m_sampleShape[i] != 0.0f )
{
max = fabs( m_sampleShape[i] );
}
}
m_normalizeFactor = max;
// update
if( m_graph != NULL )
{
m_graph->update();
}
engine::getSongEditor()->setModified();
}
void impulseEditor::setOn( bool _on )
{
if( _on )
{
m_state->setChecked( TRUE );
}
else
{
m_state->setChecked( FALSE );
}
}
void impulseEditor::contextMenuEvent( QContextMenuEvent * )
{
captionMenu contextMenu( accessibleName() );
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
this, SLOT( displayHelp() ) );
contextMenu.exec( QCursor::pos() );
}
void impulseEditor::displayHelp( void )
{
QWhatsThis::showText( mapToGlobal( rect().bottomRight() ),
whatsThis() );
}
void FASTCALL impulseEditor::setValues( float * _shape )
{
for( Uint32 i = 0; i < m_sampleLength; i++ )
{
m_sampleShape[i] = _shape[i];
}
}
#include "impulse_editor.moc"

View File

@@ -1,88 +0,0 @@
/*
* impulse_editor.cpp - graphic waveform editor
*
* Copyright (c) 2006-2007 Danny McRae <khjklujn/at/yahoo/com>
*
* 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.
*
*/
#ifndef _IMPULSE_EDITOR_H
#define _IMPULSE_EDITOR_H
#include <QtGui/QWidget>
#include <QtGui/QPixmap>
#include <QtGui/QCursor>
#include "config.h"
#include "types.h"
#include "graph.h"
#include "pixmap_button.h"
#include "led_checkbox.h"
class impulseEditor: public QWidget
{
Q_OBJECT
public:
impulseEditor( QWidget *parent, int _x, int _y, track * _track,
Uint32 _len = 128 );
~impulseEditor();
inline float * getValues() { return( m_sampleShape ); };
inline bool isOn() { return( m_state->isChecked() ); };
void FASTCALL setValues( float * _shape );
public slots:
void sinWaveClicked( void );
void triangleWaveClicked( void );
void sawWaveClicked( void );
void sqrWaveClicked( void );
void noiseWaveClicked( void );
void usrWaveClicked( void );
void smoothClicked( void );
void normalizeClicked( void );
void sampleChanged();
void setOn( bool _on );
void contextMenuEvent( QContextMenuEvent * );
void displayHelp( void );
private:
graph * m_graph;
pixmapButton * m_sinWaveBtn;
pixmapButton * m_triangleWaveBtn;
pixmapButton * m_sqrWaveBtn;
pixmapButton * m_sawWaveBtn;
pixmapButton * m_whiteNoiseWaveBtn;
pixmapButton * m_usrWaveBtn;
pixmapButton * m_smoothBtn;
pixmapButton * m_normalizeBtn;
pixmapButton * m_lastBtn;
ledCheckBox * m_state;
float * m_sampleShape;
Uint32 m_sampleLength;
float m_normalizeFactor;
bool m_forward;
QPixmap m_base;
};
#endif

View File

@@ -51,10 +51,9 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
QPixmap _button8_off,
Uint8 _default,
Uint32 _x, Uint32 _y,
QWidget * _parent,
track * _track ):
QWidget * _parent ):
QWidget( _parent ),
m_selected( _default )
autoModelView( new nineButtonSelectorModel(0, 8, _default, 1, NULL, TRUE ) )
{
setFixedSize( 50, 50 );
m_base = QPixmap::grabWidget( _parent, _x, _y );
@@ -65,7 +64,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
pal.setBrush( backgroundRole(), m_base );
setPalette( pal );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 1, 1 );
m_button->setActiveGraphic( _button0_on );
m_button->setInactiveGraphic( _button0_off );
@@ -74,7 +73,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button0Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 18, 1 );
m_button->setActiveGraphic( _button1_on );
m_button->setInactiveGraphic( _button1_off );
@@ -83,7 +82,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button1Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 35, 1 );
m_button->setActiveGraphic( _button2_on );
m_button->setInactiveGraphic( _button2_off );
@@ -92,7 +91,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button2Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 1, 18 );
m_button->setActiveGraphic( _button3_on );
m_button->setInactiveGraphic( _button3_off );
@@ -101,7 +100,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button3Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 18, 18 );
m_button->setActiveGraphic( _button4_on );
m_button->setInactiveGraphic( _button4_off );
@@ -110,7 +109,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button4Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 35, 18 );
m_button->setActiveGraphic( _button5_on );
m_button->setInactiveGraphic( _button5_off );
@@ -119,7 +118,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button5Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 1, 35 );
m_button->setActiveGraphic( _button6_on );
m_button->setInactiveGraphic( _button6_off );
@@ -128,7 +127,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button6Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 18, 35 );
m_button->setActiveGraphic( _button7_on );
m_button->setInactiveGraphic( _button7_off );
@@ -137,7 +136,7 @@ nineButtonSelector::nineButtonSelector( QPixmap _button0_on,
this, SLOT ( button7Clicked( void ) ) );
m_buttons.append( m_button );
m_button = new pixmapButton( this, NULL, _track );
m_button = new pixmapButton( this, NULL );
m_button->move( 35, 35 );
m_button->setActiveGraphic( _button8_on );
m_button->setInactiveGraphic( _button8_off );
@@ -231,22 +230,29 @@ void nineButtonSelector::button8Clicked( void )
setSelected( 8 );
}
void nineButtonSelector::modelChanged( void )
{
printf("Model Changed %d", model()->value());
updateButton( model()->value() );
}
void FASTCALL nineButtonSelector::setSelected( Uint8 _new_button )
{
m_selected = _new_button;
m_lastBtn->setChecked( FALSE );
m_lastBtn = m_buttons[m_selected];
m_lastBtn->setChecked( TRUE );
emit nineButtonSelection( m_selected );
model()->setValue(_new_button);
updateButton( _new_button );
}
void FASTCALL nineButtonSelector::updateButton( Uint8 _new_button )
{
m_lastBtn->setChecked( FALSE );
m_lastBtn->update();
m_lastBtn = m_buttons[_new_button];
m_lastBtn->setChecked( TRUE );
m_lastBtn->update();
emit nineButtonSelection( _new_button );
}
void nineButtonSelector::contextMenuEvent( QContextMenuEvent * )
{

View File

@@ -29,12 +29,14 @@
#include "pixmap_button.h"
class nineButtonSelector: public QWidget
class nineButtonSelector: public QWidget , public intModelView
{
Q_OBJECT
public:
nineButtonSelector( QPixmap _button1_on,
nineButtonSelector( QPixmap _button0_on,
QPixmap _button0_off,
QPixmap _button1_on,
QPixmap _button1_off,
QPixmap _button2_on,
QPixmap _button2_off,
@@ -50,15 +52,16 @@ public:
QPixmap _button7_off,
QPixmap _button8_on,
QPixmap _button8_off,
QPixmap _button9_on,
QPixmap _button9_off,
Uint8 _default,
Uint32 _x, Uint32 _y,
QWidget * _parent,
track * _track );
QWidget * _parent);
~nineButtonSelector();
inline Uint8 getSelected() { return( m_selected ); };
// inline Uint8 getSelected() {
// return( castModel<nineButtonSelectorModel>()->value() );
// };
protected:
void FASTCALL setSelected( Uint8 _new_button );
public slots:
@@ -78,11 +81,18 @@ signals:
void nineButtonSelection( Uint8 );
private:
virtual void modelChanged( void );
void updateButton( Uint8 );
QList<pixmapButton *> m_buttons;
pixmapButton * m_button;
pixmapButton * m_lastBtn;
QPixmap m_base;
Uint8 m_selected;
};
typedef nineButtonSelector::autoModel nineButtonSelectorModel;
#endif

View File

@@ -45,7 +45,7 @@ stringContainer::stringContainer(const float _pitch,
void stringContainer::addString(Uint8 _harm,
const float _pick,
const float _pickup,
float * _impluse,
const float * _impulse,
const float _randomize,
const float _string_loss,
const float _detune,
@@ -90,7 +90,7 @@ void stringContainer::addString(Uint8 _harm,
m_strings.append( new vibratingString( m_pitch * harm,
_pick,
_pickup,
_impluse,
const_cast<float*>(_impulse),
m_bufferLength,
m_sampleRate,
_oversample,

View File

@@ -43,7 +43,7 @@ public:
void addString( Uint8 _harm,
const float _pick,
const float _pickup,
float * _impluse,
const float * _impluse,
const float _randomize,
const float _string_loss,
const float _detune,

View File

@@ -23,22 +23,22 @@
*/
#include "vibed.h"
#include <Qt/QtXml>
#include <QtCore/QMap>
#include <QtGui/QWhatsThis>
#include "base64.h"
#include "caption_menu.h"
#include "vibed.h"
#include "automatable_model_templates.h"
#include "engine.h"
#include "instrument_track.h"
#include "knob.h"
#include "note_play_handle.h"
#include "tooltip.h"
#include "base64.h"
#include "caption_menu.h"
#include "oscillator.h"
#include "string_container.h"
#include "templates.h"
#include "tooltip.h"
#include "volume.h"
#include "volume_knob.h"
@@ -48,13 +48,13 @@
extern "C"
{
plugin::descriptor vibedstrings_plugin_descriptor =
{
STRINGIFY_PLUGIN_NAME( PLUGIN_NAME ),
"Vibed",
QT_TRANSLATE_NOOP( "pluginBrowser",
"Vibrating string modeler" ),
"Vibrating string modeler" ),
"Danny McRae <khjklujn/at/yahoo/com>",
0x0100,
plugin::Instrument,
@@ -66,258 +66,58 @@ plugin::descriptor vibedstrings_plugin_descriptor =
vibed::vibed( instrumentTrack * instrument_track ) :
instrument( instrument_track, &vibedstrings_plugin_descriptor ),
m_sampleLength( 128 )
instrument( instrument_track, &vibedstrings_plugin_descriptor )
{
setAutoFillBackground( TRUE );
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
"artwork" ) );
setPalette( pal );
knobModel * knob;
boolModel * led;
nineButtonSelectorModel * harmonic;
graphModel * graphTmp;
for( Uint8 harm = 0; harm < 9; harm++ )
{
m_editor = new impulseEditor( this, 76, 21, instrument_track );
m_editor->setAccessibleName( tr( "Impulse Editor" ) );
m_editor->setOn( FALSE );
m_editor->hide();
m_editors.append( m_editor );
m_editor->setWhatsThis( tr(
"The waveform editor provides control over the initial state or impulse "
"that is used to start the string vibrating. The buttons to the right of "
"the graph will initialize the waveform to the selected type. The '?' "
"button will load a waveform from a file--only the first 128 samples "
"will be loaded.\n\n"
knob = new knobModel( DEFAULT_VOLUME, MIN_VOLUME, MAX_VOLUME, 1.0f, this );
m_volumeKnobs.append( knob );
"The waveform can also be drawn in the graph.\n\n"
knob = new knobModel( 0.0f, 0.0f, 0.05f, 0.001f, this );
m_stiffnessKnobs.append( knob );
"The 'S' button will smooth the waveform.\n\n"
knob = new knobModel( 0.0f, 0.0f, 0.05f, 0.001f, this );
m_stiffnessKnobs.append( knob );
"The 'N' button will normalize the waveform.") );
knob = new knobModel( 0.0f, 0.0f, 0.05f, 0.005f, this );
m_pickKnobs.append( knob );
m_volumeKnob = new volumeKnob( knobBright_26, this,
tr( "Volume" ), instrument_track );
m_volumeKnob->setRange( MIN_VOLUME, MAX_VOLUME, 1.0f );
m_volumeKnob->setInitValue( DEFAULT_VOLUME );
m_volumeKnob->move( 103, 142 );
m_volumeKnob->setHintText( tr( "Volume:" ) + " ", "" );
m_volumeKnob->hide();
m_volumeKnobs.append( m_volumeKnob );
m_volumeKnob->setWhatsThis( tr( "The 'V' knob sets the volume "
"of the selected string." ) );
m_stiffnessKnob = new knob( knobBright_26, this,
tr( "String stiffness" ),
instrument_track );
m_stiffnessKnob->setRange( 0.0f, 0.05f, 0.001f );
m_stiffnessKnob->setInitValue( 0.0f );
m_stiffnessKnob->move( 129, 142 );
m_stiffnessKnob->setHintText( tr( "String stiffness:" ) +
" ", "" );
m_stiffnessKnob->hide();
m_stiffnessKnobs.append( m_stiffnessKnob );
m_stiffnessKnob->setWhatsThis( tr(
"The 'S' knob sets the stiffness of the selected string. The stiffness "
"of the string affects how long the string will ring out. The lower "
"the setting, the longer the string will ring." ) );
m_pickKnob = new knob( knobBright_26, this,
tr( "Pick position" ),
instrument_track );
m_pickKnob->setRange( 0.0f, 0.5f, 0.005f );
m_pickKnob->setInitValue( 0.0f );
m_pickKnob->move( 153, 142 );
m_pickKnob->setHintText( tr( "Pick position:" ) + " ", "" );
m_pickKnob->hide();
m_pickKnobs.append( m_pickKnob );
m_pickKnob->setWhatsThis( tr(
"The 'P' knob sets the position where the selected string will be 'picked'. "
"The lower the setting the closer the pick is to the bridge." ) );
m_pickupKnob = new knob( knobBright_26, this,
tr( "Pickup position" ),
instrument_track );
m_pickupKnob->setRange( 0.0f, 0.5f, 0.005f );
m_pickupKnob->setInitValue( 0.05f );
m_pickupKnob->move( 177, 142 );
m_pickupKnob->setHintText( tr( "Pickup position:" ) +
" ", "" );
m_pickupKnob->hide();
m_pickupKnobs.append( m_pickupKnob );
m_pickupKnob->setWhatsThis( tr(
"The 'PU' knob sets the position where the vibrations will be monitored "
"for the selected string. The lower the setting, the closer the "
"pickup is to the bridge." ) );
knob = new knobModel( 0.05f, 0.0f, 0.05f, 0.005f, this );
m_pickupKnobs.append( knob );
m_panKnob = new knob( knobBright_26, this, tr( "Pan" ),
instrument_track );
m_panKnob->setRange( -1.0f, 1.0f, 0.01f );
m_panKnob->setInitValue( 0.0f );
m_panKnob->move( 105, 187 );
m_panKnob->setHintText( tr( "Pan:" ) + " ", "" );
m_panKnob->hide();
m_panKnobs.append( m_panKnob );
m_panKnob->setWhatsThis( tr(
"The Pan knob determines the location of the selected string in the stereo "
"field." ) );
m_detuneKnob = new knob( knobBright_26, this, tr( "Detune" ),
instrument_track );
m_detuneKnob->setRange( -0.1f, 0.1f, 0.001f );
m_detuneKnob->setInitValue( 0.0f );
m_detuneKnob->move( 150, 187 );
m_detuneKnob->setHintText( tr( "Detune:" ) + " ", "" );
m_detuneKnob->hide();
m_detuneKnobs.append( m_detuneKnob );
m_detuneKnob->setWhatsThis( tr(
"The Detune knob modifies the pitch of the selected string. Settings less "
"than zero will cause the string to sound flat. Settings greater than zero "
"will cause the string to sound sharp." ) );
m_randomKnob = new knob( knobBright_26, this, tr( "Fuzziness" ),
instrument_track );
m_randomKnob->setRange( 0.0f, 0.75f, 0.01f );
m_randomKnob->setInitValue( 0.0f );
m_randomKnob->move( 194, 187 );
m_randomKnob->setHintText( tr( "Fuzziness:" ) +
" ", "" );
m_randomKnob->hide();
m_randomKnobs.append( m_randomKnob );
m_randomKnob->setWhatsThis( tr(
"The Slap knob adds a bit of fuzz to the selected string which is most "
"apparent during the attack, though it can also be used to make the string "
"sound more 'metallic'.") );
knob = new knobModel( 0.0f, -1.0f, 1.0f, 0.01f, this );
m_panKnobs.append( knob );
m_lengthKnob = new knob( knobBright_26, this, tr( "Length" ),
instrument_track );
m_lengthKnob->setRange( 1, 16, 1 );
m_lengthKnob->setInitValue( 1 );
m_lengthKnob->move( 23, 193 );
m_lengthKnob->setHintText( tr( "Length:" ) +
" ", "" );
m_lengthKnob->hide();
m_lengthKnobs.append( m_lengthKnob );
m_lengthKnob->setWhatsThis( tr(
"The Length knob sets the length of the selected string. Longer strings "
"will both ring longer and sound brighter, however, they will also eat up "
"more CPU cycles." ) );
knob = new knobModel( 0.0f, -0.1f, 0.1f, 0.001f, this );
m_detuneKnobs.append( knob );
m_impulse = new ledCheckBox( "", this, tr( "Impulse" ),
instrument_track );
m_impulse->move( 23, 94 );
m_impulse->setChecked( FALSE );
toolTip::add( m_impulse,
tr( "Impulse or initial state" ) );
m_impulse->hide();
m_impulses.append( m_impulse );
m_impulse->setWhatsThis( tr(
"The 'Imp' selector determines whether the waveform in the graph is to be "
"treated as an impulse imparted to the string by the pick or the initial "
"state of the string." ) );
knob = new knobModel( 0.0f, 0.0f, 0.75f, 0.01f, this );
m_randomKnobs.append( knob );
knob = new knobModel( 1, 1, 16, 1, this );
m_lengthKnobs.append( knob );
led = new boolModel( FALSE, this );
m_impulses.append( led );
led = new boolModel( harm==0, this );
m_powerButtons.append( led );
harmonic = new nineButtonSelectorModel( 2, 0, 8, 1, this );
m_harmonics.append( harmonic );
graphTmp = new graphModel( -1.0, 1.0, m_sampleLength, this );
graphTmp->setWaveToSine();
m_graphs.append( graphTmp );
m_harmonic = new nineButtonSelector(
PLUGIN_NAME::getIconPixmap( "button_-2_on" ),
PLUGIN_NAME::getIconPixmap( "button_-2_off" ),
PLUGIN_NAME::getIconPixmap( "button_-1_on" ),
PLUGIN_NAME::getIconPixmap( "button_-1_off" ),
PLUGIN_NAME::getIconPixmap( "button_f_on" ),
PLUGIN_NAME::getIconPixmap( "button_f_off" ),
PLUGIN_NAME::getIconPixmap( "button_2_on" ),
PLUGIN_NAME::getIconPixmap( "button_2_off" ),
PLUGIN_NAME::getIconPixmap( "button_3_on" ),
PLUGIN_NAME::getIconPixmap( "button_3_off" ),
PLUGIN_NAME::getIconPixmap( "button_4_on" ),
PLUGIN_NAME::getIconPixmap( "button_4_off" ),
PLUGIN_NAME::getIconPixmap( "button_5_on" ),
PLUGIN_NAME::getIconPixmap( "button_5_off" ),
PLUGIN_NAME::getIconPixmap( "button_6_on" ),
PLUGIN_NAME::getIconPixmap( "button_6_off" ),
PLUGIN_NAME::getIconPixmap( "button_7_on" ),
PLUGIN_NAME::getIconPixmap( "button_7_off" ),
2,
21, 127,
this,
NULL );
m_harmonic->setAccessibleName( tr( "Octave" ) );
m_harmonic->hide();
m_harmonics.append( m_harmonic );
m_harmonic->setWhatsThis( tr(
"The Octave selector is used to choose which harmonic of the note the "
"string will ring at. For example, '-2' means the string will ring two "
"octaves below the fundamental, 'F' means the string will ring at the "
"fundamental, and '6' means the string will ring six octaves above the "
"fundamental." ) );
}
m_stringSelector = new nineButtonSelector(
PLUGIN_NAME::getIconPixmap( "button_1_on" ),
PLUGIN_NAME::getIconPixmap( "button_1_off" ),
PLUGIN_NAME::getIconPixmap( "button_2_on" ),
PLUGIN_NAME::getIconPixmap( "button_2_off" ),
PLUGIN_NAME::getIconPixmap( "button_3_on" ),
PLUGIN_NAME::getIconPixmap( "button_3_off" ),
PLUGIN_NAME::getIconPixmap( "button_4_on" ),
PLUGIN_NAME::getIconPixmap( "button_4_off" ),
PLUGIN_NAME::getIconPixmap( "button_5_on" ),
PLUGIN_NAME::getIconPixmap( "button_5_off" ),
PLUGIN_NAME::getIconPixmap( "button_6_on" ),
PLUGIN_NAME::getIconPixmap( "button_6_off" ),
PLUGIN_NAME::getIconPixmap( "button_7_on" ),
PLUGIN_NAME::getIconPixmap( "button_7_off" ),
PLUGIN_NAME::getIconPixmap( "button_8_on" ),
PLUGIN_NAME::getIconPixmap( "button_8_off" ),
PLUGIN_NAME::getIconPixmap( "button_9_on" ),
PLUGIN_NAME::getIconPixmap( "button_9_off" ),
0,
21, 39,
this,
NULL );
m_stringSelector->setAccessibleName( tr( "String" ) );
connect( m_stringSelector, SIGNAL( nineButtonSelection( Uint8 ) ),
this, SLOT( showString( Uint8 ) ) );
m_stringSelector->setWhatsThis( tr(
"The String selector is used to choose which string the controls are "
"editting. A Vibed instrument can contain up to nine independently "
"vibrating strings. The LED in the lower right corner of the "
"waveform editor indicates whether the selected string is active." ) );
m_pickKnob = m_pickKnobs[0];
m_pickupKnob = m_pickupKnobs[0];
m_stiffnessKnob = m_stiffnessKnobs[0];
m_volumeKnob = m_volumeKnobs[0];
m_panKnob = m_panKnobs[0];
m_detuneKnob = m_detuneKnobs[0];
m_randomKnob = m_randomKnobs[0];
m_lengthKnob = m_lengthKnobs[0];
m_editor = m_editors[0];
m_impulse = m_impulses[0];
m_harmonic = m_harmonics[0];
m_editor->setOn( TRUE );
showString( 0 );
setWhatsThis( tr(
"Vibed models up to nine independently vibrating strings. The 'String' "
"selector allows you to choose which string is being edited. The 'Imp' " "selector chooses whether the graph represents an impulse or the initial "
"state of the string. The 'Octave' selector chooses which harmonic the "
"string should vibrate at.\n\n"
"The graph allows you to control the initial state or impulse used to set the "
"string in motion.\n\n"
"The 'V' knob controls the volume. The 'S' knob controls the string's "
"stiffness. The 'P' knob controls the pick position. The 'PU' knob "
"controls the pickup position.\n\n"
"'Pan' and 'Detune' hopefully don't need explanation. The 'Slap' knob "
"adds a bit of fuzz to the sound of the string.\n\n"
"The 'Length' knob controls the length of the string.\n\n"
"The LED in the lower right corner of the waveform editor determines "
"whether the string is active in the current instrument." ) );
}
@@ -333,6 +133,7 @@ vibed::~vibed()
void vibed::saveSettings( QDomDocument & _doc,
QDomElement & _this )
{
QString name;
// Save plugin version
@@ -341,9 +142,10 @@ void vibed::saveSettings( QDomDocument & _doc,
for( Uint8 i = 0; i < 9; i++ )
{
name = "active" + QString::number( i );
_this.setAttribute( name, QString::number(
m_editors[i]->isOn() ) );
if( m_editors[i]->isOn() )
_this.setAttribute( name, QString::number(
m_powerButtons[i]->value() ) );
if( m_powerButtons[i]->value() )
{
name = "volume" + QString::number( i );
m_volumeKnobs[i]->saveSettings( _doc, _this, name );
@@ -358,8 +160,7 @@ void vibed::saveSettings( QDomDocument & _doc,
m_pickupKnobs[i]->saveSettings( _doc, _this, name );
name = "octave" + QString::number( i );
_this.setAttribute( name, QString::number(
m_harmonics[i]->getSelected() ) );
m_harmonics[i]->saveSettings( _doc, _this, name );
name = "length" + QString::number( i );
m_lengthKnobs[i]->saveSettings( _doc, _this, name );
@@ -375,13 +176,14 @@ void vibed::saveSettings( QDomDocument & _doc,
name = "impulse" + QString::number( i );
m_impulses[i]->saveSettings( _doc, _this, name );
QString sampleString;
base64::encode(
(const char *)m_editors[i]->getValues(),
128 * sizeof(float), sampleString );
base64::encode(
(const char *)m_graphs[i]->samples(),
m_sampleLength * sizeof(float),
sampleString );
name = "graph" + QString::number( i );
_this.setAttribute( name, sampleString );
_this.setAttribute( name, sampleString );
}
}
@@ -389,17 +191,17 @@ void vibed::saveSettings( QDomDocument & _doc,
void vibed::loadSettings( const QDomElement & _this )
{
QString name;
for( Uint8 i = 0; i < 9; i++ )
{
name = "active" + QString::number( i );
m_editors[i]->setOn( _this.attribute( name ).toInt() );
m_powerButtons[i]->setValue( _this.attribute( name ).toInt() );
if( m_editors[i]->isOn() &&
if( m_powerButtons[i]->value() &&
_this.hasAttribute( "volume" + QString::number( i ) ) )
{
name = "volume" + QString::number( i );
@@ -415,8 +217,7 @@ void vibed::loadSettings( const QDomElement & _this )
m_pickupKnobs[i]->loadSettings( _this, name );
name = "octave" + QString::number( i );
m_harmonics[i]->setSelected(
_this.attribute( name ).toInt() );
m_harmonics[i]->loadSettings( _this, name );
name = "length" + QString::number( i );
m_lengthKnobs[i]->loadSettings( _this, name );
@@ -437,11 +238,13 @@ void vibed::loadSettings( const QDomElement & _this )
float * shp = 0;
base64::decode( _this.attribute( "graph" +
QString::number( i ) ),
(char * *) &shp, &size );
(char * *) &shp,
&size );
// TODO: check whether size == 128 * sizeof( float ),
// otherwise me might and up in a segfault
m_editors[i]->setValues( shp );
m_graphs[i]->setSamples( shp );
delete[] shp;
// TODO: do one of the following to avoid
// "uninitialized" wave-shape-buttongroup
@@ -452,7 +255,7 @@ void vibed::loadSettings( const QDomElement & _this )
}
}
update();
// update();
}
@@ -471,25 +274,25 @@ void vibed::playNote( notePlayHandle * _n, bool )
if ( _n->totalFramesPlayed() == 0 || _n->m_pluginData == NULL )
{
_n->m_pluginData = new stringContainer( _n->frequency(),
engine::getMixer()->sampleRate(),
m_sampleLength );
engine::getMixer()->sampleRate(),
m_sampleLength );
for( Uint8 i = 0; i < 9; ++i )
{
if( m_editors[i]->isOn() )
if( m_powerButtons[i]->value() )
{
static_cast<stringContainer*>(
_n->m_pluginData )->addString(
m_harmonics[i]->getSelected(),
m_harmonics[i]->value(),
m_pickKnobs[i]->value(),
m_pickupKnobs[i]->value(),
m_editors[i]->getValues(),
m_graphs[i]->samples(),
m_randomKnobs[i]->value(),
m_stiffnessKnobs[i]->value(),
m_detuneKnobs[i]->value(),
static_cast<int>(
m_lengthKnobs[i]->value() ),
m_impulses[i]->isChecked(),
m_impulses[i]->value(),
i );
}
}
@@ -497,8 +300,8 @@ void vibed::playNote( notePlayHandle * _n, bool )
const fpp_t frames = _n->framesLeftForCurrentPeriod();
stringContainer * ps = static_cast<stringContainer *>(
_n->m_pluginData );
_n->m_pluginData );
sampleFrame * buf = new sampleFrame[frames];
for( fpp_t i = 0; i < frames; ++i )
@@ -538,77 +341,421 @@ void vibed::deleteNotePluginData( notePlayHandle * _n )
}
void vibed::showString( Uint8 _string )
pluginView * vibed::instantiateView( QWidget * _parent )
{
m_pickKnob->hide();
m_pickupKnob->hide();
m_stiffnessKnob->hide();
m_volumeKnob->hide();
m_panKnob->hide();
m_detuneKnob->hide();
m_randomKnob->hide();
m_lengthKnob->hide();
m_editor->hide();
m_impulse->hide();
m_harmonic->hide();
// TODO: first assign, then show - avoids that we have to index vector
// (or list or whatever) twice
// something like
// ( m_editor = m_editors[_string] )->show()
// would be even better ;-)
m_editors[_string]->show();
m_volumeKnobs[_string]->show();
m_stiffnessKnobs[_string]->show();
m_pickKnobs[_string]->show();
m_pickupKnobs[_string]->show();
m_panKnobs[_string]->show();
m_detuneKnobs[_string]->show();
m_randomKnobs[_string]->show();
m_lengthKnobs[_string]->show();
m_impulses[_string]->show();
m_impulses[_string]->update();
m_harmonics[_string]->show();
m_pickKnob = m_pickKnobs[_string];
m_pickupKnob = m_pickupKnobs[_string];
m_stiffnessKnob = m_stiffnessKnobs[_string];
m_volumeKnob = m_volumeKnobs[_string];
m_panKnob = m_panKnobs[_string];
m_detuneKnob = m_detuneKnobs[_string];
m_randomKnob = m_randomKnobs[_string];
m_lengthKnob = m_lengthKnobs[_string];
m_editor = m_editors[_string];
m_impulse = m_impulses[_string];
m_harmonic = m_harmonics[_string];
return( new vibedView( this, _parent ) );
}
void vibed::contextMenuEvent( QContextMenuEvent * )
vibedView::vibedView( instrument * _instrument,
QWidget * _parent ) :
instrumentView( _instrument, _parent )
{
setAutoFillBackground( TRUE );
QPalette pal;
pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap(
"artwork" ) );
setPalette( pal );
m_volumeKnob = new volumeKnob( knobBright_26, this, tr( "Volume" ) );
m_volumeKnob->move( 103, 142 );
m_volumeKnob->setHintText( tr( "Volume:" ) + " ", "" );
m_volumeKnob->setWhatsThis( tr( "The 'V' knob sets the volume "
"of the selected string." ) );
m_stiffnessKnob = new knob( knobBright_26, this,
tr( "String stiffness" ) );
m_stiffnessKnob->move( 129, 142 );
m_stiffnessKnob->setHintText( tr( "String stiffness:" ) +
" ", "" );
m_stiffnessKnob->setWhatsThis( tr(
"The 'S' knob sets the stiffness of the selected string. The stiffness "
"of the string affects how long the string will ring out. The lower "
"the setting, the longer the string will ring." ) );
m_pickKnob = new knob( knobBright_26, this,
tr( "Pick position" ) );
m_pickKnob->move( 153, 142 );
m_pickKnob->setHintText( tr( "Pick position:" ) + " ", "" );
m_pickKnob->setWhatsThis( tr(
"The 'P' knob sets the position where the selected string will be 'picked'. "
"The lower the setting the closer the pick is to the bridge." ) );
m_pickupKnob = new knob( knobBright_26, this,
tr( "Pickup position" ) );
m_pickupKnob->move( 177, 142 );
m_pickupKnob->setHintText( tr( "Pickup position:" ) +
" ", "" );
m_pickupKnob->setWhatsThis( tr(
"The 'PU' knob sets the position where the vibrations will be monitored "
"for the selected string. The lower the setting, the closer the "
"pickup is to the bridge." ) );
m_panKnob = new knob( knobBright_26, this, tr( "Pan" ) );
m_panKnob->move( 105, 187 );
m_panKnob->setHintText( tr( "Pan:" ) + " ", "" );
m_panKnob->setWhatsThis( tr(
"The Pan knob determines the location of the selected string in the stereo "
"field." ) );
m_detuneKnob = new knob( knobBright_26, this, tr( "Detune" ) );
m_detuneKnob->move( 150, 187 );
m_detuneKnob->setHintText( tr( "Detune:" ) + " ", "" );
m_detuneKnob->setWhatsThis( tr(
"The Detune knob modifies the pitch of the selected string. Settings less "
"than zero will cause the string to sound flat. Settings greater than zero "
"will cause the string to sound sharp." ) );
m_randomKnob = new knob( knobBright_26, this, tr( "Fuzziness" ) );
m_randomKnob->move( 194, 187 );
m_randomKnob->setHintText( tr( "Fuzziness:" ) +
" ", "" );
m_randomKnob->setWhatsThis( tr(
"The Slap knob adds a bit of fuzz to the selected string which is most "
"apparent during the attack, though it can also be used to make the string "
"sound more 'metallic'.") );
m_lengthKnob = new knob( knobBright_26, this, tr( "Length" ) );
m_lengthKnob->move( 23, 193 );
m_lengthKnob->setHintText( tr( "Length:" ) +
" ", "" );
m_lengthKnob->setWhatsThis( tr(
"The Length knob sets the length of the selected string. Longer strings "
"will both ring longer and sound brighter, however, they will also eat up "
"more CPU cycles." ) );
m_impulse = new ledCheckBox( "", this, tr( "Impulse" ) );
m_impulse->move( 23, 94 );
toolTip::add( m_impulse,
tr( "Impulse or initial state" ) );
m_impulse->setWhatsThis( tr(
"The 'Imp' selector determines whether the waveform in the graph is to be "
"treated as an impulse imparted to the string by the pick or the initial "
"state of the string." ) );
m_harmonic = new nineButtonSelector(
PLUGIN_NAME::getIconPixmap( "button_-2_on" ),
PLUGIN_NAME::getIconPixmap( "button_-2_off" ),
PLUGIN_NAME::getIconPixmap( "button_-1_on" ),
PLUGIN_NAME::getIconPixmap( "button_-1_off" ),
PLUGIN_NAME::getIconPixmap( "button_f_on" ),
PLUGIN_NAME::getIconPixmap( "button_f_off" ),
PLUGIN_NAME::getIconPixmap( "button_2_on" ),
PLUGIN_NAME::getIconPixmap( "button_2_off" ),
PLUGIN_NAME::getIconPixmap( "button_3_on" ),
PLUGIN_NAME::getIconPixmap( "button_3_off" ),
PLUGIN_NAME::getIconPixmap( "button_4_on" ),
PLUGIN_NAME::getIconPixmap( "button_4_off" ),
PLUGIN_NAME::getIconPixmap( "button_5_on" ),
PLUGIN_NAME::getIconPixmap( "button_5_off" ),
PLUGIN_NAME::getIconPixmap( "button_6_on" ),
PLUGIN_NAME::getIconPixmap( "button_6_off" ),
PLUGIN_NAME::getIconPixmap( "button_7_on" ),
PLUGIN_NAME::getIconPixmap( "button_7_off" ),
2,
21, 127,
this );
m_harmonic->setAccessibleName( tr( "Octave" ) );
m_harmonic->setWhatsThis( tr(
"The Octave selector is used to choose which harmonic of the note the "
"string will ring at. For example, '-2' means the string will ring two "
"octaves below the fundamental, 'F' means the string will ring at the "
"fundamental, and '6' means the string will ring six octaves above the "
"fundamental." ) );
m_stringSelector = new nineButtonSelector(
PLUGIN_NAME::getIconPixmap( "button_1_on" ),
PLUGIN_NAME::getIconPixmap( "button_1_off" ),
PLUGIN_NAME::getIconPixmap( "button_2_on" ),
PLUGIN_NAME::getIconPixmap( "button_2_off" ),
PLUGIN_NAME::getIconPixmap( "button_3_on" ),
PLUGIN_NAME::getIconPixmap( "button_3_off" ),
PLUGIN_NAME::getIconPixmap( "button_4_on" ),
PLUGIN_NAME::getIconPixmap( "button_4_off" ),
PLUGIN_NAME::getIconPixmap( "button_5_on" ),
PLUGIN_NAME::getIconPixmap( "button_5_off" ),
PLUGIN_NAME::getIconPixmap( "button_6_on" ),
PLUGIN_NAME::getIconPixmap( "button_6_off" ),
PLUGIN_NAME::getIconPixmap( "button_7_on" ),
PLUGIN_NAME::getIconPixmap( "button_7_off" ),
PLUGIN_NAME::getIconPixmap( "button_8_on" ),
PLUGIN_NAME::getIconPixmap( "button_8_off" ),
PLUGIN_NAME::getIconPixmap( "button_9_on" ),
PLUGIN_NAME::getIconPixmap( "button_9_off" ),
0,
21, 39,
this);
m_graph = new graph( this );
m_graph->setAccessibleName( tr( "Impulse Editor" ) );
m_graph->setForeground( PLUGIN_NAME::getIconPixmap( "wavegraph4" ) );
m_graph->move( 76, 21 );
m_graph->resize(132, 104);
m_graph->setWhatsThis( tr(
"The waveform editor provides control over the initial state or impulse "
"that is used to start the string vibrating. The buttons to the right of "
"the graph will initialize the waveform to the selected type. The '?' "
"button will load a waveform from a file--only the first 128 samples "
"will be loaded.\n\n"
"The waveform can also be drawn in the graph.\n\n"
"The 'S' button will smooth the waveform.\n\n"
"The 'N' button will normalize the waveform.") );
setWhatsThis( tr(
"Vibed models up to nine independently vibrating strings. The 'String' "
"selector allows you to choose which string is being edited. The 'Imp' " "selector chooses whether the graph represents an impulse or the initial "
"state of the string. The 'Octave' selector chooses which harmonic the "
"string should vibrate at.\n\n"
"The graph allows you to control the initial state or impulse used to set the "
"string in motion.\n\n"
"The 'V' knob controls the volume. The 'S' knob controls the string's "
"stiffness. The 'P' knob controls the pick position. The 'PU' knob "
"controls the pickup position.\n\n"
"'Pan' and 'Detune' hopefully don't need explanation. The 'Slap' knob "
"adds a bit of fuzz to the sound of the string.\n\n"
"The 'Length' knob controls the length of the string.\n\n"
"The LED in the lower right corner of the waveform editor determines "
"whether the string is active in the current instrument." ) );
m_power = new ledCheckBox( "", this, tr( "Enable waveform" ) );
m_power->move( 212, 130 );
toolTip::add( m_power,
tr( "Click here to enable/disable waveform." ) );
// String selector is not a part of the model
m_stringSelector->setAccessibleName( tr( "String" ) );
m_stringSelector->setWhatsThis( tr(
"The String selector is used to choose which string the controls are "
"editting. A Vibed instrument can contain up to nine independently "
"vibrating strings. The LED in the lower right corner of the "
"waveform editor indicates whether the selected string is active." ) );
connect( m_stringSelector, SIGNAL( nineButtonSelection( Uint8 ) ),
this, SLOT( showString( Uint8 ) ) );
showString( 0 );
// Get current graph-model
graphModel * gModel = m_graph->model();
m_sinWaveBtn = new pixmapButton( this, tr( "Sine wave" ) );
m_sinWaveBtn->move( 212, 24 );
m_sinWaveBtn->setActiveGraphic( embed::getIconPixmap(
"sin_wave_active" ) );
m_sinWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"sin_wave_inactive" ) );
toolTip::add( m_sinWaveBtn,
tr( "Click here if you want a sine-wave for "
"current oscillator." ) );
connect( m_sinWaveBtn, SIGNAL (clicked ( void ) ),
this, SLOT ( sinWaveClicked( void ) ) );
m_triangleWaveBtn = new pixmapButton( this, tr( "Triangle wave" ) );
m_triangleWaveBtn->move( 212, 41 );
m_triangleWaveBtn->setActiveGraphic(
embed::getIconPixmap( "triangle_wave_active" ) );
m_triangleWaveBtn->setInactiveGraphic(
embed::getIconPixmap( "triangle_wave_inactive" ) );
toolTip::add( m_triangleWaveBtn,
tr( "Click here if you want a triangle-wave "
"for current oscillator." ) );
connect( m_triangleWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( triangleWaveClicked( ) ) );
m_sawWaveBtn = new pixmapButton( this, tr( "Saw wave" ) );
m_sawWaveBtn->move( 212, 58 );
m_sawWaveBtn->setActiveGraphic( embed::getIconPixmap(
"saw_wave_active" ) );
m_sawWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"saw_wave_inactive" ) );
toolTip::add( m_sawWaveBtn,
tr( "Click here if you want a saw-wave for "
"current oscillator." ) );
connect( m_sawWaveBtn, SIGNAL (clicked ( void ) ),
this, SLOT ( sawWaveClicked( void ) ) );
m_sqrWaveBtn = new pixmapButton( this, tr( "Square wave" ) );
m_sqrWaveBtn->move( 212, 75 );
m_sqrWaveBtn->setActiveGraphic( embed::getIconPixmap(
"square_wave_active" ) );
m_sqrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"square_wave_inactive" ) );
toolTip::add( m_sqrWaveBtn,
tr( "Click here if you want a square-wave for "
"current oscillator." ) );
connect( m_sqrWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( sqrWaveClicked( void ) ) );
m_whiteNoiseWaveBtn = new pixmapButton( this, tr( "White noise wave" ) );
m_whiteNoiseWaveBtn->move( 212, 92 );
m_whiteNoiseWaveBtn->setActiveGraphic(
embed::getIconPixmap( "white_noise_wave_active" ) );
m_whiteNoiseWaveBtn->setInactiveGraphic(
embed::getIconPixmap( "white_noise_wave_inactive" ) );
toolTip::add( m_whiteNoiseWaveBtn,
tr( "Click here if you want a white-noise for "
"current oscillator." ) );
connect( m_whiteNoiseWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( noiseWaveClicked( void ) ) );
m_usrWaveBtn = new pixmapButton( this, tr( "User defined wave" ) );
m_usrWaveBtn->move( 212, 109 );
m_usrWaveBtn->setActiveGraphic( embed::getIconPixmap(
"usr_wave_active" ) );
m_usrWaveBtn->setInactiveGraphic( embed::getIconPixmap(
"usr_wave_inactive" ) );
toolTip::add( m_usrWaveBtn,
tr( "Click here if you want a user-defined "
"wave-shape for current oscillator." ) );
connect( m_usrWaveBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( usrWaveClicked( void ) ) );
m_smoothBtn = new pixmapButton( this, tr( "Smooth" ) );
m_smoothBtn->move( 79, 129 );
m_smoothBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"smooth_active" ) );
m_smoothBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"smooth_inactive" ) );
m_smoothBtn->setChecked( FALSE );
toolTip::add( m_smoothBtn,
tr( "Click here to smooth waveform." ) );
connect( m_smoothBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( smoothClicked( void ) ) );
m_normalizeBtn = new pixmapButton( this, tr( "Normalize" ) );
m_normalizeBtn->move( 96, 129 );
m_normalizeBtn->setActiveGraphic( PLUGIN_NAME::getIconPixmap(
"normalize_active" ) );
m_normalizeBtn->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
"normalize_inactive" ) );
m_normalizeBtn->setChecked( FALSE );
toolTip::add( m_normalizeBtn,
tr( "Click here to normalize waveform." ) );
connect( m_normalizeBtn, SIGNAL ( clicked ( void ) ),
this, SLOT ( normalizeClicked( void ) ) );
}
void vibedView::modelChanged( void )
{
showString( 0 );
}
void vibedView::showString( Uint8 _string )
{
vibed * v = castModel<vibed>();
m_pickKnob->setModel( v->m_pickKnobs[_string] );
m_pickupKnob->setModel( v->m_pickupKnobs[_string] );
m_stiffnessKnob->setModel( v->m_stiffnessKnobs[_string] );
m_volumeKnob->setModel( v->m_volumeKnobs[_string] );
m_panKnob->setModel( v->m_panKnobs[_string] );
m_detuneKnob->setModel( v->m_detuneKnobs[_string] );
m_randomKnob->setModel( v->m_randomKnobs[_string] );
m_lengthKnob->setModel( v->m_lengthKnobs[_string] );
m_graph->setModel( v->m_graphs[_string] );
m_impulse->setModel( v->m_impulses[_string] );
m_harmonic->setModel( v->m_harmonics[_string] );
m_power->setModel( v->m_powerButtons[_string] );
}
void vibedView::sinWaveClicked( void )
{
m_graph->model()->setWaveToSine();
engine::getSongEditor()->setModified();
}
void vibedView::triangleWaveClicked( void )
{
m_graph->model()->setWaveToTriangle();
engine::getSongEditor()->setModified();
}
void vibedView::sawWaveClicked( void )
{
m_graph->model()->setWaveToSaw();
engine::getSongEditor()->setModified();
}
void vibedView::sqrWaveClicked( void )
{
m_graph->model()->setWaveToSquare();
engine::getSongEditor()->setModified();
}
void vibedView::noiseWaveClicked( void )
{
m_graph->model()->setWaveToNoise();
engine::getSongEditor()->setModified();
}
void vibedView::usrWaveClicked( void )
{
// TODO: load file
//m_graph->model()->setWaveToUser();
//engine::getSongEditor()->setModified();
}
void vibedView::smoothClicked( void )
{
m_graph->model()->smooth();
engine::getSongEditor()->setModified();
}
void vibedView::normalizeClicked( void )
{
m_graph->model()->normalize();
engine::getSongEditor()->setModified();
}
void vibedView::contextMenuEvent( QContextMenuEvent * )
{
captionMenu contextMenu( publicName() );
contextMenu.addAction( embed::getIconPixmap( "help" ), tr( "&Help" ),
this, SLOT( displayHelp() ) );
this, SLOT( displayHelp() ) );
contextMenu.exec( QCursor::pos() );
}
void vibed::displayHelp( void )
void vibedView::displayHelp( void )
{
QWhatsThis::showText( mapToGlobal( rect().bottomRight() ),
whatsThis() );
whatsThis() );
}
extern "C"
{

View File

@@ -24,56 +24,91 @@
#define _VIBED_STRINGS_H
#include "instrument.h"
#include "instrument_view.h"
#include "sample_buffer.h"
#include "graph.h"
#include "knob.h"
#include "pixmap_button.h"
#include "led_checkbox.h"
#include "impulse_editor.h"
#include "lcd_spinbox.h"
#include "volume_knob.h"
#include "nine_button_selector.h"
class knob;
class vibedView;
class notePlayHandle;
class volumeKnob;
class vibed : public instrument
{
Q_OBJECT
public:
vibed( instrumentTrack * _channel_track );
virtual ~vibed();
virtual void FASTCALL playNote( notePlayHandle * _n,
bool _try_parallelizing );
bool _try_parallelizing );
virtual void FASTCALL deleteNotePluginData( notePlayHandle * _n );
virtual void FASTCALL saveSettings( QDomDocument & _doc,
QDomElement & _parent );
QDomElement & _parent );
virtual void FASTCALL loadSettings( const QDomElement & _this );
virtual QString nodeName( void ) const;
virtual pluginView * instantiateView( QWidget * _parent );
private:
QList<knobModel*> m_pickKnobs;
QList<knobModel*> m_pickupKnobs;
QList<knobModel*> m_stiffnessKnobs;
QList<knobModel*> m_volumeKnobs;
QList<knobModel*> m_panKnobs;
QList<knobModel*> m_detuneKnobs;
QList<knobModel*> m_randomKnobs;
QList<knobModel*> m_lengthKnobs;
QList<boolModel*> m_powerButtons;
QList<graphModel*> m_graphs;
QList<boolModel*> m_impulses;
QList<nineButtonSelectorModel*> m_harmonics;
static const int m_sampleLength = 128;
friend class vibedView;
} ;
class vibedView : public instrumentView
{
Q_OBJECT
public:
vibedView( instrument * _instrument,
QWidget * _parent );
virtual ~vibedView() {};
public slots:
void showString( Uint8 _string );
void contextMenuEvent( QContextMenuEvent * );
void displayHelp( void );
protected slots:
void sinWaveClicked( void );
void triangleWaveClicked( void );
void sawWaveClicked( void );
void sqrWaveClicked( void );
void noiseWaveClicked( void );
void usrWaveClicked( void );
void smoothClicked( void );
void normalizeClicked( void );
private:
QList<knob*> m_pickKnobs;
QList<knob*> m_pickupKnobs;
QList<knob*> m_stiffnessKnobs;
QList<volumeKnob*> m_volumeKnobs;
QList<knob*> m_panKnobs;
QList<knob*> m_detuneKnobs;
QList<knob*> m_randomKnobs;
QList<knob*> m_lengthKnobs;
QList<impulseEditor*> m_editors;
QList<ledCheckBox*> m_impulses;
QList<nineButtonSelector*> m_harmonics;
virtual void modelChanged( void );
// String-related
knob * m_pickKnob;
knob * m_pickupKnob;
knob * m_stiffnessKnob;
@@ -82,15 +117,25 @@ private:
knob * m_detuneKnob;
knob * m_randomKnob;
knob * m_lengthKnob;
impulseEditor * m_editor;
nineButtonSelector * m_stringSelector;
graph * m_graph;
nineButtonSelector * m_harmonic;
ledCheckBox * m_impulse;
int m_sampleLength;
} ;
ledCheckBox * m_power;
// Not in model
nineButtonSelector * m_stringSelector;
pixmapButton * m_smoothBtn;
pixmapButton * m_normalizeBtn;
// From impulse editor
pixmapButton * m_sinWaveBtn;
pixmapButton * m_triangleWaveBtn;
pixmapButton * m_sqrWaveBtn;
pixmapButton * m_sawWaveBtn;
pixmapButton * m_whiteNoiseWaveBtn;
pixmapButton * m_usrWaveBtn;
};
#endif