new audio-mixing system and new VST-support-framework

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@25 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Tobias Doerffel
2005-11-30 10:19:11 +00:00
parent 7587d7c1f6
commit ab719618f7
179 changed files with 2844 additions and 1084 deletions

View File

@@ -1,4 +1,4 @@
if HAVE_LIBFST
if VST_SUPPORT
VESTIGE_SUBDIR=vestige
endif

View File

@@ -1,8 +1,9 @@
/*
* audio_file_processor.cpp - instrument for using audio-files
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public

View File

@@ -2,8 +2,9 @@
* audio_file_processor.h - declaration of class audioFileProcessor
* (instrument-plugin for using audio-files)
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public

View File

@@ -1,8 +1,9 @@
/*
* plucked_string_synth.cpp - instrument which uses the Karplus-Strong-algorithm
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public

View File

@@ -2,8 +2,9 @@
* plucked_string_sytn.h - declaration of class pluckedStringSynth which
* is a synth for plucked string-sounds
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public

View File

@@ -1,8 +1,9 @@
/*
* triple_oscillator.cpp - powerful instrument with three oscillators
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public

View File

@@ -2,8 +2,9 @@
* triple_oscillator.h - declaration of class tripleOscillator a powerful
* instrument-plugin with 3 oscillators
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public

View File

@@ -1,6 +1,5 @@
AUTOMAKE_OPTIONS = foreign 1.4
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/src/lib -I.
@@ -22,14 +21,19 @@ EMBEDDED_RESOURCES = $(wildcard *png)
EXTRA_DIST = $(EMBEDDED_RESOURCES)
CLEANFILES = $(MOC_FILES) ./embedded_resources.h
CLEANFILES = $(MOC_FILES) ./embedded_resources.h xfst.exe.so
pkglib_LTLIBRARIES = libvestige.la
libvestige_la_SOURCES = vestige.cpp vestige.h fstclient.cpp fstclient.h
$(libvestige_la_SOURCES): ./embedded_resources.h
pkglib_LTLIBRARIES= libvestige.la
libvestige_la_SOURCES = vestige.cpp vestige.h
# libvestige_la_LIBADD = -lfst
$(libvestige_la_SOURCES): ./embedded_resources.h
CC = winegcc
pkglib_PROGRAMS = xfst_server
xfst_server_SOURCES = fstserver.cpp fstcore.c fstserver.h communication.h
xfst_server_LDFLAGS = -mwindows -L/usr/X11R6/lib -lX11 -lpthread -o $(pkglib_PROGRAMS)
xfst_server_LINK = wineg++
nobase_pkglib_DATA = $(pkglib_PROGRAMS).exe.so

View File

@@ -0,0 +1,87 @@
#ifndef _COMMUNICATION_H
#define _COMMUNICATION_H
#include <unistd.h>
#include <string.h>
#include <string>
template<typename T>
inline T readValue( int _fd = 0 )
{
T i;
read( _fd, &i, sizeof( i ) );
return( i );
}
template<typename T>
inline void writeValue( const T & _i, int _fd = 1 )
{
write( _fd, &_i, sizeof( _i ) );
}
enum vstRemoteCommands
{
// client -> server
LOAD_VST_PLUGIN = 0,
CLOSE_VST_PLUGIN,
PROCESS = 10,
ENQUEUE_MIDI_EVENT = 11,
SET_SAMPLE_RATE = 20,
SET_BUFFER_SIZE,
GET_SHM_KEY_AND_SIZE,
GET_VST_VERSION = 30,
GET_NAME,
GET_VENDOR_STRING,
GET_PRODUCT_STRING,
// server -> client
SET_SHM_KEY_AND_SIZE = 100,
SET_INPUT_COUNT,
SET_OUTPUT_COUNT,
SET_XID,
INITIALIZATION_DONE,
FAILED_LOADING_PLUGIN,
QUIT_ACK,
GET_SAMPLE_RATE = 110,
GET_BUFFER_SIZE,
GET_BPM,
SET_VST_VERSION,
SET_NAME,
SET_VENDOR_STRING,
SET_PRODUCT_STRING,
PROCESS_DONE = 120,
DEBUG_MSG = 200,
UNDEFINED_CMD
} ;
static inline std::string readString( int _fd = 0 )
{
Sint16 len = readValue<Sint16>( _fd );
char * sc = new char[len];
read( _fd, sc, len );
std::string s( sc );
delete[] sc;
return( s );
}
static inline void writeString( const char * _str, int _fd = 1 )
{
int len = strlen( _str ) + 1;
writeValue<Sint16>( len, _fd );
write( _fd, _str, len );
}
#endif

View File

@@ -1,8 +1,9 @@
/*
* vestige.cpp - instrument-plugin for hosting VST-plugins
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -31,6 +32,7 @@
#include <QFileDialog>
#include <QFileInfo>
#include <QDir>
#include <QPushButton>
#include <QCursor>
#else
@@ -40,12 +42,12 @@
#include <qfiledialog.h>
#include <qfileinfo.h>
#include <qdir.h>
#include <qpushbutton.h>
#include <qcursor.h>
#endif
#include "vestige.h"
#include "channel_track.h"
#include "note_play_handle.h"
#include "buffer_allocator.h"
@@ -55,6 +57,7 @@
#include "pixmap_button.h"
#include "tooltip.h"
#include "spc_bg_hndl_widget.h"
#include "vestige.h"
#include "embed.cpp"
@@ -79,16 +82,13 @@ plugin::descriptor vestige_plugin_descriptor =
}
bool vestigeInstrument::s_initialized = FALSE;
bool vestigeInstrument::s_threadAdopted = FALSE;
QPixmap * vestigeInstrument::s_artwork = NULL;
vestigeInstrument::vestigeInstrument( channelTrack * _channel_track ) :
instrument( _channel_track, vestige_plugin_descriptor.public_name ),
specialBgHandlingWidget( PLUGIN_NAME::getIconPixmap( "artwork" ) ),
m_handle( NULL ),
m_fst( NULL )
m_plugin( NULL )
{
if( s_artwork == NULL )
{
@@ -126,15 +126,18 @@ vestigeInstrument::vestigeInstrument( channelTrack * _channel_track ) :
"clicking on this button, a file-open-dialog appears "
"and you can select your file." ) );
if( s_initialized == FALSE )
{
if( fst_init( fst_signal_handler ) )
{
// TODO: message-box
return;
}
s_initialized = TRUE;
}
m_toggleGUIButton = new QPushButton( tr( "Show/hide VST-GUI" ), this );
m_toggleGUIButton->setGeometry( 20, 120, 128, 24 );
connect( m_toggleGUIButton, SIGNAL( clicked() ), this,
SLOT( toggleGUI() ) );
#ifdef QT4
m_toggleGUIButton->setWhatsThis(
#else
QWhatsThis::add( m_toggleGUIButton,
#endif
tr( "Click here to show or hide the graphical user interface "
"(GUI) of your VST-plugin." ) );
// now we need a play-handle which cares for calling play()
instrumentPlayHandle * iph = new instrumentPlayHandle( this );
mixer::inst()->addPlayHandle( iph );
@@ -186,71 +189,36 @@ void vestigeInstrument::setParameter( const QString & _param,
{
closePlugin();
m_plugin = _value;
if( ( m_handle = fst_load(
#ifdef QT4
m_plugin.constData().toAscii()
#else
m_plugin.ascii()
#endif
) ) == NULL )
m_pluginDLL = _value;
m_plugin = new remoteVSTPlugin( m_pluginDLL );
if( m_plugin->failed() )
{
QMessageBox::information( this,
tr( "Failed loading plugin" ),
tr( "The VST-plugin %1 couldn't be "
"loaded for some reason." ).arg(
m_plugin ),
tr( "Failed loading VST-plugin" ),
tr( "The VST-plugin %1 could not "
"be loaded for some reason.\n"
"If it runs with other VST-"
"software under Linux, please "
"contact an LMMS-developer!"
).arg( m_pluginDLL ),
QMessageBox::Ok );
closePlugin();
return;
}
if( ( m_fst = fst_instantiate( m_handle, hostCallback,
this ) ) == NULL )
{
QMessageBox::information( this,
tr( "Failed instantiating plugin" ),
tr( "Couldn't create an instance of "
"VST-plugin %1 for some "
"reason." ).arg( m_plugin ),
QMessageBox::Ok );
fst_unload( m_handle );
m_handle = NULL;
return;
}
// set sample-rate and blocksize
m_fst->plugin->dispatcher( m_fst->plugin, effSetSampleRate, 0,
0, NULL, mixer::inst()->sampleRate() );
m_fst->plugin->dispatcher( m_fst->plugin, effSetBlockSize, 0,
mixer::inst()->framesPerAudioBuffer(),
NULL, 0.0f );
// set program to zero
m_fst->plugin->dispatcher( m_fst->plugin, effSetProgram, 0, 0,
NULL, 0.0f );
// resume
m_fst->plugin->dispatcher( m_fst->plugin, effMainsChanged, 0,
1, NULL, 0.0f );
/* if( fst_run_editor( m_fst ) )
{
printf( "VeSTige: cannot create editor\n" );
}*/
int vst_version = m_fst->plugin->dispatcher( m_fst->plugin,
effGetVstVersion, 0, 0,
NULL, 0.0f );
if( vst_version < 2 )
/* if( m_plugin->vstVersion() < 2000 )
{
QMessageBox::information( this,
tr( "VST-plugin too old" ),
tr( "The version of VST-plugin %1 "
"is smaller than 2, which "
"isn't supported." ).arg(
m_plugin ),
m_pluginDLL ),
QMessageBox::Ok );
closePlugin();
return;
}
/* printf("WID:%d %d\n", (int)fst_get_XID( m_fst ),
(int)QWidget::find( fst_get_XID( m_fst ) ) );*/
//printf("%d\n", m_fst->plugin->numParams);
}*/
m_plugin->showEditor();
update();
}
}
@@ -259,95 +227,16 @@ void vestigeInstrument::setParameter( const QString & _param,
void vestigeInstrument::play( void )
{
// the very first time, we have to adopt fst-thread
if( !s_threadAdopted )
{
fst_adopt_thread();
s_threadAdopted = TRUE;
}
if( m_handle == NULL || m_fst == NULL )
if( m_plugin == NULL )
{
return;
}
// first we gonna post all MIDI-events we enqueued so far
if( m_midiEvents.size() )
{
// since MIDI-events are not received immediately, we have
// to have them stored somewhere even after dispatcher-call,
// so we create static copies of the data and post them
static VstEvents events;
static vvector<VstMidiEvent> cur_events;
cur_events = m_midiEvents;
m_midiEvents.clear();
for( csize i = 0; i < cur_events.size(); ++i )
{
events.events[i] = (VstEvent *) &cur_events[i];
}
events.numEvents = cur_events.size();
printf( "VeSTige: posting %d events\n", cur_events.size());
events.reserved = 0;
m_fst->plugin->dispatcher( m_fst->plugin, effProcessEvents,
0, 0, &events, 0.0f );
}
// now we're ready to fetch sound from VST-plugin
const Uint32 frames = mixer::inst()->framesPerAudioBuffer();
int ch_in = m_fst->plugin->numInputs;
int ch_out = m_fst->plugin->numOutputs;
float * ins[ch_in];
float * outs[ch_out];
for( int i = 0; i < ch_in; ++i )
{
ins[i] = bufferAllocator::alloc<float>( frames );
}
for( int i = 0; i < ch_out; ++i )
{
outs[i] = bufferAllocator::alloc<float>( frames );
}
if( m_fst->plugin->flags & effFlagsCanReplacing )
{
m_fst->plugin->processReplacing( m_fst->plugin, ins, outs,
frames );
}
else
{
printf("normal process\n");
//mixer::inst()->clearAudioBuffer( buf, frames );
m_fst->plugin->process( m_fst->plugin, ins, outs, frames );
printf("normal process done\n");
}
for( int i = 0; i < ch_in; ++i )
{
bufferAllocator::free( ins[i] );
}
// got our data, now we just have to merge the 1/2 out-buffers
sampleFrame * buf = bufferAllocator::alloc<sampleFrame>( frames );
Uint8 chnls = tMax<Uint8>( ch_out, DEFAULT_CHANNELS );
if( chnls != DEFAULT_CHANNELS )
{
mixer::inst()->clearAudioBuffer( buf, frames );
}
for( Uint32 f = 0; f < frames; ++f )
{
for( Uint8 chnl = 0; chnl < chnls; ++chnl )
{
buf[f][chnl] = outs[chnl][f];
}
}
for( int i = 0; i < ch_out; ++i )
{
bufferAllocator::free( outs[i] );
}
m_plugin->process( NULL, buf );
getChannelTrack()->processAudioBuffer( buf, frames, NULL );
bufferAllocator::free( buf );
@@ -360,9 +249,9 @@ void vestigeInstrument::play( void )
void vestigeInstrument::playNote( notePlayHandle * _n )
{
if( _n->totalFramesPlayed() == 0 )
if( _n->totalFramesPlayed() == 0 && m_plugin != NULL )
{
enqueueEvent( midiEvent( NOTE_ON, 0, _n->key(),
m_plugin->enqueueMidiEvent( midiEvent( NOTE_ON, 0, _n->key(),
_n->getVolume() ), _n->framesAhead() );
}
}
@@ -372,7 +261,11 @@ void vestigeInstrument::playNote( notePlayHandle * _n )
void vestigeInstrument::deleteNotePluginData( notePlayHandle * _n )
{
enqueueEvent( midiEvent( NOTE_OFF, 0, _n->key(), 0 ) );
if( m_plugin != NULL )
{
m_plugin->enqueueMidiEvent( midiEvent( NOTE_OFF, 0, _n->key(),
0 ), 0 );
}
}
@@ -388,12 +281,12 @@ void vestigeInstrument::openPlugin( void )
#endif
QString dir;
if( m_plugin != "" )
if( m_pluginDLL != "" )
{
#ifdef QT4
dir = QFileInfo( m_plugin ).absolutePath();
dir = QFileInfo( m_pluginDLL ).absolutePath();
#else
dir = QFileInfo( m_plugin ).dirPath( TRUE );
dir = QFileInfo( m_pluginDLL ).dirPath( TRUE );
#endif
}
else
@@ -416,10 +309,10 @@ void vestigeInstrument::openPlugin( void )
ofd.addFilter( tr( "EXE-files (*.exe)" ) );
ofd.setSelectedFilter( tr( "DLL-files (*.dll)" ) );
#endif
if( m_plugin != "" )
if( m_pluginDLL != "" )
{
// select previously opened file
ofd.selectFile( QFileInfo( m_plugin ).fileName() );
ofd.selectFile( QFileInfo( m_pluginDLL ).fileName() );
}
if ( ofd.exec () == QDialog::Accepted )
@@ -435,6 +328,30 @@ void vestigeInstrument::openPlugin( void )
void vestigeInstrument::toggleGUI( void )
{
if( m_plugin == NULL )
{
return;
}
QWidget * w = m_plugin->pluginWidget();
if( w == NULL )
{
return;
}
if( w->isHidden() )
{
w->show();
}
else
{
w->hide();
}
}
void vestigeInstrument::paintEvent( QPaintEvent * )
{
#ifdef QT4
@@ -448,12 +365,9 @@ void vestigeInstrument::paintEvent( QPaintEvent * )
p.drawPixmap( 0, 0, *s_artwork );
QString plugin_name = ( m_handle != NULL && m_fst != NULL ) ?
QString( m_handle->name ) + " " +
QString::number( m_fst->plugin->dispatcher(
m_fst->plugin,
effGetVendorVersion,
0, 0, NULL, 0.0f ) ):
QString plugin_name = ( m_plugin ) ?
QString( m_plugin->name() )
:
tr( "No VST-plugin loaded" );
QFont f = p.font();
f.setBold( TRUE );
@@ -462,15 +376,13 @@ void vestigeInstrument::paintEvent( QPaintEvent * )
p.drawText( 20, 80, plugin_name );
if( m_handle != NULL && m_fst != NULL )
if( m_plugin != NULL )
{
p.setPen( QColor( 64, 128, 64 ) );
f.setBold( FALSE );
p.setFont( pointSize<8>( f ) );
char buf[1024];
m_fst->plugin->dispatcher( m_fst->plugin, effGetVendorString,
0, 0, buf, 0 );
p.drawText( 20, 94, tr( "by" ) + " " + QString( buf ) );
p.drawText( 20, 94, tr( "by" ) + " " +
m_plugin->vendorString() );
}
#ifndef QT4
bitBlt( this, rect().topLeft(), &pm );
@@ -482,364 +394,8 @@ void vestigeInstrument::paintEvent( QPaintEvent * )
void vestigeInstrument::closePlugin( void )
{
if( m_fst != NULL && m_handle != NULL )
{
//fst_destroy_editor( m_fst );
printf( "closing VST-plugin" );
fst_close( m_fst );
printf( "unloading VST-plugin" );
fst_unload( m_handle );
m_fst = NULL;
m_handle = NULL;
}
}
void vestigeInstrument::enqueueEvent( const midiEvent & _e,
Uint32 _frames_ahead )
{
if( m_handle == NULL || m_fst == NULL )
{
return;
}
VstMidiEvent event;
event.type = kVstMidiType;
event.byteSize = 24;
event.deltaFrames = _frames_ahead;
event.flags = 0;
event.detune = 0;
event.noteLength = 0;
event.noteOffset = 0;
event.noteOffVelocity = 0;
event.reserved1 = 0;
event.reserved2 = 0;
event.midiData[0] = _e.m_type + _e.m_channel;
event.midiData[1] = _e.key();
event.midiData[2] = _e.velocity();
event.midiData[3] = 0;
m_midiEvents.push_back( event );
}
#define DEBUG_CALLBACKS
#ifdef DEBUG_CALLBACKS
#define SHOW_CALLBACK printf
#else
#define SHOW_CALLBACK(...)
#endif
long vestigeInstrument::hostCallback( AEffect * _effect, long _opcode,
long _index, long _value, void * _ptr,
float _opt )
{
static VstTimeInfo _timeInfo;
SHOW_CALLBACK( "host-callback, opcode = %d", (int) _opcode );
switch( _opcode )
{
case audioMasterAutomate:
SHOW_CALLBACK( "amc: audioMasterAutomate\n" );
// index, value, returns 0
_effect->setParameter( _effect, _index, _opt );
return( 0 );
case audioMasterVersion:
SHOW_CALLBACK( "amc: audioMasterVersion\n" );
// vst version, currently 2 (0 for older)
return( 2 );
case audioMasterCurrentId:
SHOW_CALLBACK( "amc: audioMasterCurrentId\n" );
// returns the unique id of a plug that's currently
// loading
return( 0 );
case audioMasterIdle:
SHOW_CALLBACK ("amc: audioMasterIdle\n");
// call application idle routine (this will
// call effEditIdle for all open editors too)
_effect->dispatcher( _effect, effEditIdle, 0, 0, NULL,
0.0f );
return( 0 );
case audioMasterPinConnected:
SHOW_CALLBACK( "amc: audioMasterPinConnected\n" );
// inquire if an input or output is beeing connected;
// index enumerates input or output counting from zero:
// value is 0 for input and != 0 otherwise. note: the
// return value is 0 for <true> such that older versions
// will always return true.
return( 1 );
case audioMasterWantMidi:
SHOW_CALLBACK( "amc: audioMasterWantMidi\n" );
// <value> is a filter which is currently ignored
return( 0 );
case audioMasterGetTime:
SHOW_CALLBACK( "amc: audioMasterGetTime\n" );
// returns const VstTimeInfo* (or 0 if not supported)
// <value> should contain a mask indicating which
// fields are required (see valid masks above), as some
// items may require extensive conversions
memset( &_timeInfo, 0, sizeof( _timeInfo ) );
//tstate = jack_transport_query (jackvst->client, &jack_pos);
_timeInfo.samplePos = 0;
_timeInfo.sampleRate = mixer::inst()->sampleRate();
_timeInfo.flags = 0;
_timeInfo.tempo = songEditor::inst()->getBPM();
_timeInfo.timeSigNumerator = 4;//(long) floor (jack_pos.beats_per_bar);
_timeInfo.timeSigDenominator = 4;//(long) floor (jack_pos.beat_type);
_timeInfo.flags |= (kVstBarsValid|kVstTempoValid);
// if (tstate == JackTransportRolling) {
_timeInfo.flags |= kVstTransportPlaying;
// }
return( (long)&_timeInfo );
case audioMasterProcessEvents:
SHOW_CALLBACK( "amc: audioMasterProcessEvents\n" );
// VstEvents* in <ptr>
return( 0 );
case audioMasterSetTime:
SHOW_CALLBACK( "amc: audioMasterSetTime\n" );
// VstTimenfo* in <ptr>, filter in <value>, not
// supported
case audioMasterTempoAt:
SHOW_CALLBACK( "amc: audioMasterTempoAt\n" );
// returns tempo (in bpm * 10000) at sample frame
// location passed in <value>
return( 0 );
case audioMasterGetNumAutomatableParameters:
SHOW_CALLBACK( "amc: audioMasterGetNumAutomatable"
"Parameters\n" );
return( 0 );
case audioMasterGetParameterQuantization:
SHOW_CALLBACK( "amc: audioMasterGetParameter\n"
"Quantization\n" );
// returns the integer value for +1.0 representation,
// or 1 if full single float precision is maintained
// in automation. parameter index in <value> (-1: all,
// any)
return( 0 );
case audioMasterIOChanged:
SHOW_CALLBACK( "amc: audioMasterIOChanged\n" );
// numInputs and/or numOutputs has changed
return( 0 );
case audioMasterNeedIdle:
SHOW_CALLBACK( "amc: audioMasterNeedIdle\n" );
// plug needs idle calls (outside its editor window)
return( 0 );
case audioMasterSizeWindow:
// TODO using lmms-main-window-size
SHOW_CALLBACK( "amc: audioMasterSizeWindow\n" );
// index: width, value: height
return( 0 );
case audioMasterGetSampleRate:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetSampleRate\n" );
return( 0 );
case audioMasterGetBlockSize:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetBlockSize\n" );
return( 0 );
case audioMasterGetInputLatency:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetInputLatency\n" );
return( 0 );
case audioMasterGetOutputLatency:
// TODO using mixer-call
SHOW_CALLBACK( "amc: audioMasterGetOutputLatency\n" );
return( 0 );
case audioMasterGetPreviousPlug:
SHOW_CALLBACK( "amc: audioMasterGetPreviousPlug\n" );
// input pin in <value> (-1: first to come), returns
// cEffect*
return( 0 );
case audioMasterGetNextPlug:
SHOW_CALLBACK( "amc: audioMasterGetNextPlug\n" );
// output pin in <value> (-1: first to come), returns
// cEffect*
return( 0 );
case audioMasterWillReplaceOrAccumulate:
SHOW_CALLBACK( "amc: audioMasterWillReplaceOr"
"Accumulate\n" );
// returns: 0: not supported, 1: replace, 2: accumulate
return( 0 );
case audioMasterGetCurrentProcessLevel:
SHOW_CALLBACK( "amc: audioMasterGetCurrentProcess"
"Level\n" );
// returns: 0: not supported,
// 1: currently in user thread (gui)
// 2: currently in audio thread (where process is
// called)
// 3: currently in 'sequencer' thread (midi, timer etc)
// 4: currently offline processing and thus in user
// thread
// other: not defined, but probably pre-empting user
// thread.
return( 0 );
case audioMasterGetAutomationState:
SHOW_CALLBACK( "amc: audioMasterGetAutomationState\n" );
// returns 0: not supported, 1: off, 2:read, 3:write,
// 4:read/write offline
return( 0 );
case audioMasterOfflineStart:
SHOW_CALLBACK( "amc: audioMasterOfflineStart\n" );
return( 0 );
case audioMasterOfflineRead:
SHOW_CALLBACK( "amc: audioMasterOfflineRead\n" );
// ptr points to offline structure, see below.
// return 0: error, 1 ok
return( 0 );
case audioMasterOfflineWrite:
SHOW_CALLBACK( "amc: audioMasterOfflineWrite\n" );
// same as read
return( 0 );
case audioMasterOfflineGetCurrentPass:
SHOW_CALLBACK( "amc: audioMasterOfflineGetCurrent"
"Pass\n" );
return( 0 );
case audioMasterOfflineGetCurrentMetaPass:
SHOW_CALLBACK( "amc: audioMasterOfflineGetCurrentMeta"
"Pass\n");
return( 0 );
case audioMasterSetOutputSampleRate:
SHOW_CALLBACK( "amc: audioMasterSetOutputSample"
"Rate\n" );
// for variable i/o, sample rate in <opt>
return( 0 );
case audioMasterGetSpeakerArrangement:
SHOW_CALLBACK( "amc: audioMasterGetSpeaker"
"Arrangement\n" );
// (long)input in <value>, output in <ptr>
return( 0 );
case audioMasterGetVendorString:
SHOW_CALLBACK( "amc: audioMasterGetVendorString\n" );
// fills <ptr> with a string identifying the vendor
// (max 64 char)
strcpy( (char *) _ptr, "LAD");
return( 0 );
case audioMasterGetProductString:
SHOW_CALLBACK( "amc: audioMasterGetProductString\n" );
// fills <ptr> with a string with product name
// (max 64 char)
strcpy( (char *) _ptr, "VeSTige" );
return( 0 );
case audioMasterGetVendorVersion:
SHOW_CALLBACK( "amc: audioMasterGetVendorVersion\n" );
// TODO
// returns vendor-specific version
return( 1000 );
case audioMasterVendorSpecific:
SHOW_CALLBACK( "amc: audioMasterVendorSpecific\n" );
// no definition, vendor specific handling
return( 0 );
case audioMasterSetIcon:
SHOW_CALLBACK( "amc: audioMasterSetIcon\n" );
// TODO
// void* in <ptr>, format not defined yet
return( 0 );
case audioMasterCanDo:
SHOW_CALLBACK( "amc: audioMasterCanDo\n" );
// string in ptr, see below
return( 0 );
case audioMasterGetLanguage:
SHOW_CALLBACK( "amc: audioMasterGetLanguage\n" );
// TODO
// see enum
return( 0 );
case audioMasterOpenWindow:
SHOW_CALLBACK( "amc: audioMasterOpenWindow\n" );
// TODO
// returns platform specific ptr
return( 0 );
case audioMasterCloseWindow:
SHOW_CALLBACK( "amc: audioMasterCloseWindow\n" );
// TODO
// close window, platform specific handle in <ptr>
return( 0 );
case audioMasterGetDirectory:
SHOW_CALLBACK( "amc: audioMasterGetDirectory\n" );
// TODO
// get plug directory, FSSpec on MAC, else char*
return( 0 );
case audioMasterUpdateDisplay:
SHOW_CALLBACK( "amc: audioMasterUpdateDisplay\n" );
// something has changed, update 'multi-fx' display
_effect->dispatcher( _effect, effEditIdle, 0, 0, NULL,
0.0f );
return( 0 );
case audioMasterBeginEdit:
SHOW_CALLBACK( "amc: audioMasterBeginEdit\n" );
// begin of automation session (when mouse down),
// parameter index in <index>
return( 0 );
case audioMasterEndEdit:
SHOW_CALLBACK( "amc: audioMasterEndEdit\n" );
// end of automation session (when mouse up),
// parameter index in <index>
return( 0 );
case audioMasterOpenFileSelector:
SHOW_CALLBACK( "amc: audioMasterOpenFileSelector\n" );
// open a fileselector window with VstFileSelect*
// in <ptr>
return( 0 );
default:
SHOW_CALLBACK( "VST master dispatcher: undefed: "
"%d, %d\n", (int) _opcode,
effKeysRequired );
break;
}
return( 0 );
delete m_plugin;
m_plugin = NULL;
}

View File

@@ -1,8 +1,9 @@
/*
* vestige.h - instrument VeSTige for hosting VST-plugins
*
* Linux MultiMedia Studio
* Copyright (c) 2004-2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
* Copyright (c) 2005 Tobias Doerffel <tobydox/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -30,7 +31,7 @@
#ifdef QT4
#include <QVector>
#include <qvector>
#else
@@ -39,13 +40,13 @@
#endif
#include <fst.h>
#include <vst/aeffectx.h>
#include "fstclient.h"
#include "spc_bg_hndl_widget.h"
class pixmapButton;
class QPushButton;
class remoteVSTPlugin;
class QPixmap;
@@ -74,6 +75,7 @@ public:
protected slots:
void openPlugin( void );
void toggleGUI( void );
protected:
@@ -83,25 +85,16 @@ protected:
private:
void closePlugin( void );
void enqueueEvent( const midiEvent & _e, Uint32 _frames_ahead = 0 );
static long hostCallback( AEffect *, long, long, long, void *, float );
static bool s_initialized;
static bool s_threadAdopted;
static QPixmap * s_artwork;
FSTHandle * m_handle;
FST * m_fst;
vvector<VstMidiEvent> m_midiEvents;
remoteVSTPlugin * m_plugin;
pixmapButton * m_openPluginButton;
QPushButton * m_toggleGUIButton;
QString m_plugin;
QString m_pluginDLL;
} ;