mirror of
https://github.com/LMMS/lmms.git
synced 2026-03-11 10:36:36 -04:00
ZynAddSubFX: lots of cleanups in RemotePlugin implementation
Moved all ZynAddSubFX instance related functions and variables into RemoteZynAddSubFX class so there're no globals anymore. Also removed some unused headers and ZynAddSubFX' main.c. Additionally make use of full 80 chars/line with ts=4.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* remote_zynaddsubfx.cpp - ZynAddSubFX-embedding plugin
|
||||
*
|
||||
* Copyright (c) 2008-2009 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
|
||||
@@ -22,40 +22,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <lmmsconfig.h>
|
||||
#include <queue>
|
||||
|
||||
#define BUILD_REMOTE_PLUGIN_CLIENT
|
||||
#include "engine.h"
|
||||
#include "instrument_play_handle.h"
|
||||
#include "note_play_handle.h"
|
||||
#include "note.h"
|
||||
#include "RemotePlugin.h"
|
||||
#include "remote_zynaddsubfx.h"
|
||||
|
||||
|
||||
std::string __presets_dir;
|
||||
|
||||
#define main unused_main
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
#define ATOM(x) (x)
|
||||
#endif
|
||||
#include "src/main.C"
|
||||
|
||||
#undef main
|
||||
#include "src/Misc/Master.h"
|
||||
#include "src/Misc/Util.h"
|
||||
#include "src/Misc/Dump.h"
|
||||
#include "src/UI/MasterUI.h"
|
||||
|
||||
#include <FL/x.H>
|
||||
|
||||
static pthread_t __gui_thread_handle;
|
||||
static pthread_mutex_t __gui_mutex;
|
||||
static std::queue<RemotePluginClient::message> __gui_messages;
|
||||
|
||||
|
||||
class RemoteZynAddSubFX : public RemotePluginClient
|
||||
{
|
||||
public:
|
||||
RemoteZynAddSubFX( int _shm_in, int _shm_out ) :
|
||||
RemotePluginClient( _shm_in, _shm_out )
|
||||
RemotePluginClient( _shm_in, _shm_out ),
|
||||
m_guiSleepTime( 100 ),
|
||||
m_guiExit( false )
|
||||
{
|
||||
for( int i = 0; i < NumKeys; ++i )
|
||||
{
|
||||
@@ -80,17 +69,29 @@ public:
|
||||
OscilGen::tmpsmps = new REALTYPE[OSCIL_SIZE];
|
||||
newFFTFREQS( &OscilGen::outoscilFFTfreqs, OSCIL_SIZE/2 );
|
||||
|
||||
master = new Master();
|
||||
master->swaplr = 0;
|
||||
m_master = new Master();
|
||||
m_master->swaplr = 0;
|
||||
|
||||
pthread_mutex_init( &m_guiMutex, NULL );
|
||||
pthread_create( &m_guiThreadHandle, NULL, guiThread, this );
|
||||
|
||||
}
|
||||
|
||||
virtual ~RemoteZynAddSubFX()
|
||||
{
|
||||
delete master;
|
||||
m_guiExit = true;
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
Sleep( m_guiSleepTime * 2 );
|
||||
#else
|
||||
usleep( m_guiSleepTime * 2 * 1000 );
|
||||
#endif
|
||||
|
||||
delete m_master;
|
||||
|
||||
delete[] denormalkillbuf;
|
||||
delete[] OscilGen::tmpsmps;
|
||||
deleteFFTFREQS( &OscilGen::outoscilFFTfreqs );
|
||||
pthread_mutex_destroy( &m_guiMutex );
|
||||
}
|
||||
|
||||
virtual void updateSampleRate()
|
||||
@@ -103,9 +104,19 @@ public:
|
||||
SOUND_BUFFER_SIZE = bufferSize();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
message m;
|
||||
while( ( m = receiveMessage() ).id != IdQuit )
|
||||
{
|
||||
pthread_mutex_lock( &m_master->mutex );
|
||||
processMessage( m );
|
||||
pthread_mutex_unlock( &m_master->mutex );
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool processMessage( const message & _m )
|
||||
{
|
||||
bool gui_message = false;
|
||||
switch( _m.id )
|
||||
{
|
||||
case IdQuit:
|
||||
@@ -115,50 +126,47 @@ public:
|
||||
case IdHideUI:
|
||||
case IdLoadSettingsFromFile:
|
||||
case IdLoadPresetFromFile:
|
||||
gui_message = true;
|
||||
pthread_mutex_lock( &m_guiMutex );
|
||||
m_guiMessages.push( _m );
|
||||
pthread_mutex_unlock( &m_guiMutex );
|
||||
break;
|
||||
|
||||
case IdSaveSettingsToFile:
|
||||
{
|
||||
char * name = strdup( _m.getString().c_str() );
|
||||
master->saveXML( name );
|
||||
m_master->saveXML( name );
|
||||
free( name );
|
||||
sendMessage( IdSaveSettingsToFile );
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
case IdZasfPresetDirectory:
|
||||
__presets_dir = _m.getString();
|
||||
for( int i = 0; i < MAX_BANK_ROOT_DIRS; ++i )
|
||||
{
|
||||
if( config.cfg.bankRootDirList[i] == NULL )
|
||||
{
|
||||
config.cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE];
|
||||
strcpy(config.cfg.bankRootDirList[i], __presets_dir.c_str() );
|
||||
break;
|
||||
}
|
||||
else if( strcmp( config.cfg.bankRootDirList[i],
|
||||
__presets_dir.c_str() ) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_presetsDir = _m.getString();
|
||||
for( int i = 0; i < MAX_BANK_ROOT_DIRS; ++i )
|
||||
{
|
||||
if( config.cfg.bankRootDirList[i] == NULL )
|
||||
{
|
||||
config.cfg.bankRootDirList[i] =
|
||||
new char[MAX_STRING_SIZE];
|
||||
strcpy( config.cfg.bankRootDirList[i],
|
||||
m_presetsDir.c_str() );
|
||||
break;
|
||||
}
|
||||
else if( strcmp( config.cfg.bankRootDirList[i],
|
||||
m_presetsDir.c_str() ) == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return RemotePluginClient::processMessage( _m );
|
||||
}
|
||||
if( gui_message )
|
||||
{
|
||||
pthread_mutex_lock( &__gui_mutex );
|
||||
__gui_messages.push( _m );
|
||||
pthread_mutex_unlock( &__gui_mutex );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// all functions are called while master->mutex is held
|
||||
// all functions are called while m_master->mutex is held
|
||||
virtual void processMidiEvent( const midiEvent & _e,
|
||||
const f_cnt_t /* _offset */ )
|
||||
{
|
||||
@@ -175,11 +183,10 @@ public:
|
||||
}
|
||||
if( m_runningNotes[_e.key()] > 0 )
|
||||
{
|
||||
master->NoteOff( 0, _e.key() );
|
||||
m_master->NoteOff( 0, _e.key() );
|
||||
}
|
||||
++m_runningNotes[_e.key()];
|
||||
master->NoteOn( 0, _e.key(),
|
||||
_e.velocity() );
|
||||
m_master->NoteOn( 0, _e.key(), _e.velocity() );
|
||||
break;
|
||||
}
|
||||
case MidiNoteOff:
|
||||
@@ -189,19 +196,18 @@ public:
|
||||
}
|
||||
if( --m_runningNotes[_e.key()] <= 0 )
|
||||
{
|
||||
master->NoteOff( 0, _e.key() );
|
||||
m_master->NoteOff( 0, _e.key() );
|
||||
}
|
||||
break;
|
||||
case MidiPitchBend:
|
||||
master->SetController( 0,
|
||||
C_pitchwheel,
|
||||
_e.m_data.m_param[0] +
|
||||
_e.m_data.m_param[1]*128-8192 );
|
||||
m_master->SetController( 0, C_pitchwheel,
|
||||
_e.m_data.m_param[0] +
|
||||
_e.m_data.m_param[1]*128-8192 );
|
||||
break;
|
||||
case MidiControlChange:
|
||||
master->SetController( 0,
|
||||
midiIn.getcontroller( _e.m_data.m_param[0] ),
|
||||
_e.m_data.m_param[1] );
|
||||
m_master->SetController( 0,
|
||||
midiIn.getcontroller( _e.m_data.m_param[0] ),
|
||||
_e.m_data.m_param[1] );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -214,49 +220,61 @@ public:
|
||||
REALTYPE outputl[SOUND_BUFFER_SIZE];
|
||||
REALTYPE outputr[SOUND_BUFFER_SIZE];
|
||||
|
||||
master->AudioOut( outputl, outputr );
|
||||
m_master->AudioOut( outputl, outputr );
|
||||
|
||||
for( fpp_t f = 0; f < SOUND_BUFFER_SIZE; ++f )
|
||||
for( int f = 0; f < SOUND_BUFFER_SIZE; ++f )
|
||||
{
|
||||
_out[f][0] = outputl[f];
|
||||
_out[f][1] = outputr[f];
|
||||
}
|
||||
}
|
||||
|
||||
static void * guiThread( void * _arg );
|
||||
|
||||
|
||||
private:
|
||||
std::string m_presetsDir;
|
||||
|
||||
const int m_guiSleepTime;
|
||||
int m_runningNotes[NumKeys];
|
||||
Master * m_master;
|
||||
|
||||
pthread_t m_guiThreadHandle;
|
||||
pthread_mutex_t m_guiMutex;
|
||||
std::queue<RemotePluginClient::message> m_guiMessages;
|
||||
bool m_guiExit;
|
||||
|
||||
} ;
|
||||
|
||||
static RemoteZynAddSubFX * __remote_zasf = NULL;
|
||||
static int __exit = 0;
|
||||
|
||||
|
||||
void * guiThread( void * )
|
||||
void * RemoteZynAddSubFX::guiThread( void * _arg )
|
||||
{
|
||||
int e;
|
||||
ui = NULL;
|
||||
MasterUI * ui = NULL;
|
||||
|
||||
while( !__exit )
|
||||
RemoteZynAddSubFX * _this = static_cast<RemoteZynAddSubFX *>( _arg );
|
||||
Master * master = _this->m_master;
|
||||
|
||||
while( !_this->m_guiExit )
|
||||
{
|
||||
if( ui )
|
||||
{
|
||||
Fl::wait( 0.1 );
|
||||
Fl::wait( _this->m_guiSleepTime / 1000.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
Sleep( 100 );
|
||||
Sleep( _this->m_guiSleepTime );
|
||||
#else
|
||||
usleep( 100*1000 );
|
||||
usleep( _this->m_guiSleepTime*1000 );
|
||||
#endif
|
||||
}
|
||||
pthread_mutex_lock( &__gui_mutex );
|
||||
while( __gui_messages.size() )
|
||||
pthread_mutex_lock( &_this->m_guiMutex );
|
||||
while( _this->m_guiMessages.size() )
|
||||
{
|
||||
RemotePluginClient::message m = __gui_messages.front();
|
||||
__gui_messages.pop();
|
||||
RemotePluginClient::message m = _this->m_guiMessages.front();
|
||||
_this->m_guiMessages.pop();
|
||||
switch( m.id )
|
||||
{
|
||||
case IdShowUI:
|
||||
@@ -275,21 +293,20 @@ void * guiThread( void * )
|
||||
switch( config.cfg.UserInterfaceMode )
|
||||
{
|
||||
case 0:
|
||||
ui->selectuiwindow->hide();
|
||||
break;
|
||||
ui->selectuiwindow->hide();
|
||||
break;
|
||||
case 1:
|
||||
ui->masterwindow->hide();
|
||||
break;
|
||||
ui->masterwindow->hide();
|
||||
break;
|
||||
case 2:
|
||||
ui->simplemasterwindow->hide();
|
||||
break;
|
||||
ui->simplemasterwindow->hide();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IdLoadSettingsFromFile:
|
||||
{
|
||||
char * f = strdup( m.getString().
|
||||
c_str() );
|
||||
char * f = strdup( m.getString().c_str() );
|
||||
pthread_mutex_lock( &master->mutex );
|
||||
master->defaults();
|
||||
master->loadXML( f );
|
||||
@@ -299,16 +316,14 @@ void * guiThread( void * )
|
||||
unlink( f );
|
||||
free( f );
|
||||
pthread_mutex_lock( &master->mutex );
|
||||
__remote_zasf->sendMessage(
|
||||
IdLoadSettingsFromFile );
|
||||
_this->sendMessage( IdLoadSettingsFromFile );
|
||||
pthread_mutex_unlock( &master->mutex );
|
||||
break;
|
||||
}
|
||||
|
||||
case IdLoadPresetFromFile:
|
||||
{
|
||||
char * f = strdup( m.getString().
|
||||
c_str() );
|
||||
char * f = strdup( m.getString().c_str() );
|
||||
pthread_mutex_lock( &master->mutex );
|
||||
const int npart = ui ?
|
||||
ui->npartcounter->value()-1 : 0;
|
||||
@@ -324,8 +339,7 @@ void * guiThread( void * )
|
||||
}
|
||||
free( f );
|
||||
pthread_mutex_lock( &master->mutex );
|
||||
__remote_zasf->sendMessage(
|
||||
IdLoadPresetFromFile );
|
||||
_this->sendMessage( IdLoadPresetFromFile );
|
||||
pthread_mutex_unlock( &master->mutex );
|
||||
break;
|
||||
}
|
||||
@@ -334,10 +348,12 @@ void * guiThread( void * )
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock( &__gui_mutex );
|
||||
pthread_mutex_unlock( &_this->m_guiMutex );
|
||||
}
|
||||
Fl::flush();
|
||||
|
||||
delete ui;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -358,30 +374,14 @@ int main( int _argc, char * * _argv )
|
||||
pthread_win32_thread_attach_np();
|
||||
#endif
|
||||
|
||||
pthread_mutex_init( &__gui_mutex, NULL );
|
||||
|
||||
__remote_zasf = new RemoteZynAddSubFX( atoi( _argv[1] ), atoi( _argv[2] ) );
|
||||
RemoteZynAddSubFX * remoteZASF =
|
||||
new RemoteZynAddSubFX( atoi( _argv[1] ), atoi( _argv[2] ) );
|
||||
|
||||
pthread_create( &__gui_thread_handle, NULL, guiThread, NULL );
|
||||
remoteZASF->run();
|
||||
|
||||
RemotePluginClient::message m;
|
||||
while( ( m = __remote_zasf->receiveMessage() ).id != IdQuit )
|
||||
{
|
||||
pthread_mutex_lock( &master->mutex );
|
||||
__remote_zasf->processMessage( m );
|
||||
pthread_mutex_unlock( &master->mutex );
|
||||
}
|
||||
delete remoteZASF;
|
||||
|
||||
__exit = 1;
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
Sleep( 200 );
|
||||
#else
|
||||
usleep( 200*1000 );
|
||||
#endif
|
||||
|
||||
delete __remote_zasf;
|
||||
|
||||
pthread_mutex_destroy( &__gui_mutex );
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
pthread_win32_thread_detach_np();
|
||||
@@ -392,5 +392,3 @@ int main( int _argc, char * * _argv )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,783 +0,0 @@
|
||||
/*
|
||||
ZynAddSubFX - a software synthesizer
|
||||
|
||||
main.c - Main file of the synthesizer
|
||||
Copyright (C) 2002-2005 Nasca Octavian Paul
|
||||
Author: Nasca Octavian Paul
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License
|
||||
as published by the Free Software Foundation.
|
||||
|
||||
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 (version 2 or later) for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License (version 2)
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef OS_LINUX
|
||||
#include <getopt.h>
|
||||
#elif OS_WINDOIWS
|
||||
#include <winbase.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "Misc/Master.h"
|
||||
#include "Misc/Util.h"
|
||||
#include "Misc/Dump.h"
|
||||
extern Dump dump;
|
||||
|
||||
#ifdef ALSAMIDIIN
|
||||
#include "Input/ALSAMidiIn.h"
|
||||
#endif
|
||||
|
||||
#ifdef OSSMIDIIN
|
||||
#include "Input/OSSMidiIn.h"
|
||||
#endif
|
||||
|
||||
#if (defined(NONEMIDIIN)||defined(VSTMIDIIN))
|
||||
#include "Input/NULLMidiIn.h"
|
||||
#endif
|
||||
|
||||
#ifdef WINMIDIIN
|
||||
#include "Input/WINMidiIn.h"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
#include "UI/MasterUI.h"
|
||||
MasterUI *ui;
|
||||
#endif
|
||||
|
||||
pthread_t thr1,thr2,thr3,thr4;
|
||||
Master *master;
|
||||
int swaplr=0;//1 for left-right swapping
|
||||
bool usejackit=false;
|
||||
|
||||
#ifdef JACKAUDIOOUT
|
||||
#include "Output/JACKaudiooutput.h"
|
||||
#endif
|
||||
|
||||
#ifdef JACK_RTAUDIOOUT
|
||||
#include "Output/JACKaudiooutput.h"
|
||||
#endif
|
||||
|
||||
#ifdef PAAUDIOOUT
|
||||
#include "Output/PAaudiooutput.h"
|
||||
#endif
|
||||
|
||||
#ifdef OSSAUDIOOUT
|
||||
#include "Output/OSSaudiooutput.h"
|
||||
OSSaudiooutput *audioout;
|
||||
#endif
|
||||
|
||||
#ifdef USE_LASH
|
||||
#include "Misc/LASHClient.h"
|
||||
LASHClient *lash;
|
||||
#endif
|
||||
|
||||
MidiIn *Midi;
|
||||
int Pexitprogram=0;//if the UI set this to 1, the program will exit
|
||||
|
||||
/*
|
||||
* Try to get the realtime priority
|
||||
*/
|
||||
void set_realtime(){
|
||||
#ifdef OS_LINUX
|
||||
sched_param sc;
|
||||
|
||||
sc.sched_priority=50;
|
||||
#ifndef LMMS_BUILD_APPLE
|
||||
//if you want get "sched_setscheduler undeclared" from compilation, you can safely remove the folowing line
|
||||
sched_setscheduler(0,SCHED_FIFO,&sc);
|
||||
#endif
|
||||
// if (err==0) printf("Real-time");
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Midi input thread
|
||||
*/
|
||||
#if !(defined(WINMIDIIN)||defined(VSTMIDIIN))
|
||||
void *thread1(void *arg){
|
||||
MidiCmdType cmdtype;
|
||||
unsigned char cmdchan,note,vel;
|
||||
int cmdparams[MP_MAX_BYTES];
|
||||
|
||||
set_realtime();
|
||||
while (Pexitprogram==0){
|
||||
Midi->getmidicmd(cmdtype,cmdchan,cmdparams);
|
||||
note=cmdparams[0];
|
||||
vel=cmdparams[1];
|
||||
|
||||
pthread_mutex_lock(&master->mutex);
|
||||
|
||||
if ((cmdtype==MidiNoteON)&&(note!=0)) master->NoteOn(cmdchan,note,vel);
|
||||
if ((cmdtype==MidiNoteOFF)&&(note!=0)) master->NoteOff(cmdchan,note);
|
||||
if (cmdtype==MidiController) master->SetController(cmdchan,cmdparams[0],cmdparams[1]);
|
||||
|
||||
pthread_mutex_unlock(&master->mutex);
|
||||
};
|
||||
|
||||
return(0);
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Wave output thread (for OSS AUDIO out)
|
||||
*/
|
||||
#if defined(OSSAUDIOOUT)
|
||||
//!(defined(JACKAUDIOOUT)||defined(JACK_RTAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT))
|
||||
|
||||
void *thread2(void *arg){
|
||||
REALTYPE outputl[SOUND_BUFFER_SIZE];
|
||||
REALTYPE outputr[SOUND_BUFFER_SIZE];
|
||||
|
||||
set_realtime();
|
||||
while (Pexitprogram==0){
|
||||
pthread_mutex_lock(&master->mutex);
|
||||
master->AudioOut(outputl,outputr);
|
||||
pthread_mutex_unlock(&master->mutex);
|
||||
|
||||
#ifndef NONEAUDIOOUT
|
||||
audioout->OSSout(outputl,outputr);
|
||||
#endif
|
||||
|
||||
/** / int i,x,x2;
|
||||
REALTYPE xx,xx2;
|
||||
|
||||
short int xsmps[SOUND_BUFFER_SIZE*2];
|
||||
for (i=0;i<SOUND_BUFFER_SIZE;i++){//output to stdout
|
||||
xx=-outputl[i]*32767;
|
||||
xx2=-outputr[i]*32767;
|
||||
if (xx<-32768) xx=-32768;
|
||||
if (xx>32767) xx=32767;
|
||||
if (xx2<-32768) xx2=-32768;
|
||||
if (xx2>32767) xx2=32767;
|
||||
x=(short int) xx;
|
||||
x2=(short int) xx2;
|
||||
xsmps[i*2]=x;xsmps[i*2+1]=x2;
|
||||
};
|
||||
write(1,&xsmps,SOUND_BUFFER_SIZE*2*2);
|
||||
|
||||
/ * */
|
||||
};
|
||||
return(0);
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* User Interface thread
|
||||
*/
|
||||
|
||||
|
||||
void *thread3(void *arg){
|
||||
#ifndef DISABLE_GUI
|
||||
ui->showUI();
|
||||
while (Pexitprogram==0) {
|
||||
#ifdef USE_LASH
|
||||
std::string filename;
|
||||
switch (lash->checkevents(filename)) {
|
||||
case LASHClient::Save:
|
||||
ui->do_save_master(const_cast<char*>(filename.c_str()));
|
||||
lash->confirmevent(LASHClient::Save);
|
||||
break;
|
||||
case LASHClient::Restore:
|
||||
ui->do_load_master(const_cast<char*>(filename.c_str()));
|
||||
lash->confirmevent(LASHClient::Restore);
|
||||
break;
|
||||
case LASHClient::Quit:
|
||||
Pexitprogram = 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
Fl::wait();
|
||||
}
|
||||
#endif
|
||||
return(0);
|
||||
};
|
||||
|
||||
/*
|
||||
* Sequencer thread (test)
|
||||
*/
|
||||
void *thread4(void *arg){
|
||||
while (Pexitprogram==0){
|
||||
int type,par1,par2,again,midichan;
|
||||
for (int ntrack=0;ntrack<NUM_MIDI_TRACKS;ntrack++){
|
||||
if (master->seq.play==0) break;
|
||||
do{
|
||||
again=master->seq.getevent(ntrack,&midichan,&type,&par1,&par2);
|
||||
// printf("ntrack=%d again=%d\n",ntrack,again);
|
||||
if (type>0) {
|
||||
// printf("%d %d %d %d %d\n",type,midichan,chan,par1,par2);
|
||||
|
||||
// if (cmdtype==MidiController) master->SetController(cmdchan,cmdparams[0],cmdparams[1]);
|
||||
|
||||
|
||||
|
||||
pthread_mutex_lock(&master->mutex);
|
||||
if (type==1){//note_on or note_off
|
||||
if (par2!=0) master->NoteOn(midichan,par1,par2);
|
||||
else master->NoteOff(midichan,par1);
|
||||
};
|
||||
pthread_mutex_unlock(&master->mutex);
|
||||
};
|
||||
} while (again>0);
|
||||
|
||||
};
|
||||
//if (!realtime player) atunci fac asta
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
#ifdef OS_LINUX
|
||||
usleep(1000);
|
||||
#elif OS_WINDOWS
|
||||
Sleep(1);
|
||||
#endif
|
||||
};
|
||||
|
||||
return(0);
|
||||
};
|
||||
|
||||
/*
|
||||
* Program initialisation
|
||||
*/
|
||||
|
||||
|
||||
void initprogram(){
|
||||
#ifndef JACKAUDIOOUT
|
||||
#ifndef JACK_RTAUDIOOUT
|
||||
fprintf(stderr,"\nSample Rate = \t\t%d\n",SAMPLE_RATE);
|
||||
#endif
|
||||
#endif
|
||||
fprintf(stderr,"Sound Buffer Size = \t%d samples\n",SOUND_BUFFER_SIZE);
|
||||
fprintf(stderr,"Internal latency = \t%.1f ms\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE);
|
||||
fprintf(stderr,"ADsynth Oscil.Size = \t%d samples\n",OSCIL_SIZE);
|
||||
|
||||
fflush(stderr);
|
||||
srand(time(NULL));
|
||||
denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE];
|
||||
for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=(RND-0.5)*1e-16;
|
||||
|
||||
OscilGen::tmpsmps=new REALTYPE[OSCIL_SIZE];
|
||||
newFFTFREQS(&OscilGen::outoscilFFTfreqs,OSCIL_SIZE/2);
|
||||
|
||||
master=new Master();
|
||||
master->swaplr=swaplr;
|
||||
|
||||
#if defined(JACKAUDIOOUT)
|
||||
if (usejackit) {
|
||||
bool tmp=JACKaudiooutputinit(master);
|
||||
#if defined(OSSAUDIOOUT)
|
||||
if (!tmp) printf("\nUsing OSS instead.\n");
|
||||
#else
|
||||
if (!tmp) exit(1);
|
||||
#endif
|
||||
usejackit=tmp;
|
||||
};
|
||||
#endif
|
||||
#if defined(OSSAUDIOOUT)
|
||||
if (!usejackit) audioout=new OSSaudiooutput();
|
||||
else audioout=NULL;
|
||||
#endif
|
||||
|
||||
#ifdef JACK_RTAUDIOOUT
|
||||
JACKaudiooutputinit(master);
|
||||
#endif
|
||||
#ifdef PAAUDIOOUT
|
||||
PAaudiooutputinit(master);
|
||||
#endif
|
||||
|
||||
#ifdef ALSAMIDIIN
|
||||
Midi=new ALSAMidiIn();
|
||||
#endif
|
||||
#ifdef OSSMIDIIN
|
||||
Midi=new OSSMidiIn();
|
||||
#endif
|
||||
#if (defined(NONEMIDIIN)||(defined(VSTMIDIIN)))
|
||||
Midi=new NULLMidiIn();
|
||||
#endif
|
||||
#ifndef DISABLE_GUI
|
||||
ui=new MasterUI(master,&Pexitprogram);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Program exit
|
||||
*/
|
||||
void exitprogram(){
|
||||
pthread_mutex_lock(&master->mutex);
|
||||
#ifdef OSSAUDIOOUT
|
||||
delete(audioout);
|
||||
#endif
|
||||
#ifdef JACKAUDIOOUT
|
||||
if (usejackit) JACKfinish();
|
||||
#endif
|
||||
#ifdef JACK_RTAUDIOOUT
|
||||
JACKfinish();
|
||||
#endif
|
||||
#ifdef PAAUDIOOUT
|
||||
PAfinish();
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_GUI
|
||||
delete(ui);
|
||||
#endif
|
||||
delete(Midi);
|
||||
delete(master);
|
||||
|
||||
#ifdef USE_LASH
|
||||
delete(lash);
|
||||
#endif
|
||||
|
||||
// pthread_mutex_unlock(&master->mutex);
|
||||
delete [] denormalkillbuf;
|
||||
delete [] OscilGen::tmpsmps;
|
||||
deleteFFTFREQS(&OscilGen::outoscilFFTfreqs);
|
||||
|
||||
};
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
#define ARGSIZE 100
|
||||
char winoptarguments[ARGSIZE];
|
||||
char getopt(int argc, char *argv[], const char *shortopts, int *index){
|
||||
winoptarguments[0]=0;
|
||||
char result=0;
|
||||
|
||||
if (*index>=argc) return(-1);
|
||||
|
||||
if (strlen(argv[*index])==2)
|
||||
if (argv[*index][0]=='-') {
|
||||
result=argv[*index][1];
|
||||
if (*index+1<argc) {
|
||||
snprintf(winoptarguments,ARGSIZE,"%s",argv[*index+1]);
|
||||
};
|
||||
};
|
||||
(*index)++;
|
||||
return(result);
|
||||
};
|
||||
int opterr=0;
|
||||
#undef ARGSIZE
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef VSTAUDIOOUT
|
||||
int main(int argc, char *argv[]){
|
||||
|
||||
#ifdef USE_LASH
|
||||
lash = new LASHClient(&argc, &argv);
|
||||
#endif
|
||||
|
||||
config.init();
|
||||
dump.startnow();
|
||||
int noui=0;
|
||||
#ifdef JACKAUDIOOUT
|
||||
usejackit=true;//use jack by default
|
||||
#endif
|
||||
fprintf(stderr,"%s","\nZynAddSubFX - Copyright (c) 2002-2008 Nasca Octavian Paul and others\n");
|
||||
fprintf(stderr,"Compiled: %s %s\n",__DATE__,__TIME__);
|
||||
fprintf(stderr,"%s","This program is free software (GNU GPL v.2 or later) and \n it comes with ABSOLUTELY NO WARRANTY.\n\n");
|
||||
#ifdef OS_LINUX
|
||||
if (argc==1) fprintf(stderr,"%s","Try 'zynaddsubfx --help' for command-line options.\n");
|
||||
#else
|
||||
if (argc==1) fprintf(stderr,"%s","Try 'zynaddsubfx -h' for command-line options.\n");
|
||||
#endif
|
||||
/* Get the settings from the Config*/
|
||||
SAMPLE_RATE=config.cfg.SampleRate;
|
||||
SOUND_BUFFER_SIZE=config.cfg.SoundBufferSize;
|
||||
OSCIL_SIZE=config.cfg.OscilSize;
|
||||
swaplr=config.cfg.SwapStereo;
|
||||
|
||||
/* Parse command-line options */
|
||||
#ifdef OS_LINUX
|
||||
struct option opts[]={
|
||||
{"load",2,NULL,'l'},
|
||||
{"load-instrument",2,NULL,'L'},
|
||||
{"sample-rate",2,NULL,'r'},
|
||||
{"buffer-size",2,NULL,'b'},
|
||||
{"oscil-size",2,NULL,'o'},
|
||||
{"dump",2,NULL,'D'},
|
||||
{"swap",2,NULL,'S'},
|
||||
{"no-gui",2,NULL,'U'},
|
||||
{"not-use-jack",2,NULL,'A'},
|
||||
{"dummy",2,NULL,'Y'},
|
||||
{"help",2,NULL,'h'},
|
||||
{0,0,0,0}
|
||||
};
|
||||
#endif
|
||||
opterr=0;
|
||||
int option_index=0,opt,exitwithhelp=0;
|
||||
|
||||
char loadfile[1001];ZERO(loadfile,1001);
|
||||
char loadinstrument[1001];ZERO(loadinstrument,1001);
|
||||
|
||||
while (1){
|
||||
#ifdef OS_LINUX
|
||||
opt=getopt_long(argc,argv,"l:L:r:b:o:hSDUAY",opts,&option_index);
|
||||
char *optarguments=optarg;
|
||||
#else
|
||||
opt=getopt(argc,argv,"l:L:r:b:o:hSDUAY",&option_index);
|
||||
char *optarguments=&winoptarguments[0];
|
||||
#endif
|
||||
|
||||
if (opt==-1) break;
|
||||
|
||||
int tmp;
|
||||
switch(opt){
|
||||
case 'h':exitwithhelp=1;
|
||||
break;
|
||||
case 'Y':/* this command a dummy command (has NO effect)
|
||||
and is used because I need for NSIS installer
|
||||
(NSIS sometimes forces a command line for a
|
||||
program, even if I don't need that; eg. when
|
||||
I want to add a icon to a shortcut.
|
||||
*/
|
||||
break;
|
||||
case 'U':noui=1;
|
||||
break;
|
||||
case 'A':
|
||||
#ifdef JACKAUDIOOUT
|
||||
#ifdef OSSAUDIOOUT
|
||||
usejackit=false;
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case 'l':tmp=0;
|
||||
if (optarguments!=NULL) {
|
||||
snprintf(loadfile,1000,"%s",optarguments);
|
||||
};
|
||||
break;
|
||||
case 'L':tmp=0;
|
||||
if (optarguments!=NULL) {
|
||||
snprintf(loadinstrument,1000,"%s",optarguments);
|
||||
};
|
||||
break;
|
||||
case 'r':tmp=0;
|
||||
if (optarguments!=NULL) tmp=atoi(optarguments);
|
||||
if (tmp>=4000) {
|
||||
SAMPLE_RATE=tmp;
|
||||
} else {
|
||||
fprintf(stderr,"ERROR:Incorrect sample rate %s .\n",optarguments);
|
||||
exit(1);
|
||||
};
|
||||
break;
|
||||
case 'b':tmp=0;
|
||||
if (optarguments!=NULL) tmp=atoi(optarguments);
|
||||
if (tmp>=2) {
|
||||
SOUND_BUFFER_SIZE=tmp;
|
||||
} else {
|
||||
fprintf(stderr,"ERROR:Incorrect buffer size %s .\n",optarguments);
|
||||
exit(1);
|
||||
};
|
||||
break;
|
||||
case 'o':tmp=0;
|
||||
if (optarguments!=NULL) tmp=atoi(optarguments);
|
||||
OSCIL_SIZE=tmp;
|
||||
if (OSCIL_SIZE<MAX_AD_HARMONICS*2) OSCIL_SIZE=MAX_AD_HARMONICS*2;
|
||||
OSCIL_SIZE=(int) pow(2,ceil(log (OSCIL_SIZE-1.0)/log(2.0)));
|
||||
if (tmp!=OSCIL_SIZE) fprintf(stderr,"\nOSCIL_SIZE is wrong (must me 2^n) or too small. Adjusting to %d.\n",OSCIL_SIZE);
|
||||
break;
|
||||
case 'S':swaplr=1;
|
||||
break;
|
||||
case 'D':dump.startnow();
|
||||
break;
|
||||
case '?':fprintf(stderr,"%s","ERROR:Bad option or parameter.\n\n");
|
||||
exitwithhelp=1;
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
if (exitwithhelp!=0) {
|
||||
fprintf(stderr,"%s","Usage: zynaddsubfx [OPTION]\n\n");
|
||||
fprintf(stderr,"%s"," -h , --help \t\t\t\t display command-line help and exit\n");
|
||||
fprintf(stderr,"%s"," -l file, --load=FILE\t\t\t loads a .xmz file\n");
|
||||
fprintf(stderr,"%s"," -L file, --load-instrument=FILE\t\t loads a .xiz file\n");
|
||||
fprintf(stderr,"%s"," -r SR, --sample-rate=SR\t\t set the sample rate SR\n");
|
||||
fprintf(stderr,"%s"," -b BS, --buffer-size=SR\t\t set the buffer size (granularity)\n");
|
||||
fprintf(stderr,"%s"," -o OS, --oscil-size=OS\t\t set the ADsynth oscil. size\n");
|
||||
fprintf(stderr,"%s"," -S , --swap\t\t\t\t swap Left <--> Right\n");
|
||||
fprintf(stderr,"%s"," -D , --dump\t\t\t\t Dumps midi note ON/OFF commands\n");
|
||||
fprintf(stderr,"%s"," -U , --no-gui\t\t\t\t Run ZynAddSubFX without user interface\n");
|
||||
#ifdef JACKAUDIOOUT
|
||||
#ifdef OSSAUDIOOUT
|
||||
fprintf(stderr,"%s"," -A , --not-use-jack\t\t\t Use OSS/ALSA instead of JACK\n");
|
||||
#endif
|
||||
#endif
|
||||
#ifdef OS_WINDOWS
|
||||
fprintf(stderr,"%s","\nWARNING: On Windows systems, only short comandline parameters works.\n");
|
||||
fprintf(stderr,"%s"," eg. instead '--buffer-size=512' use '-b 512'\n");
|
||||
#endif
|
||||
fprintf(stderr,"%s","\n\n");
|
||||
return(0);
|
||||
};
|
||||
|
||||
//---------
|
||||
|
||||
initprogram();
|
||||
|
||||
#ifdef USE_LASH
|
||||
#ifdef ALSAMIDIIN
|
||||
ALSAMidiIn* alsamidi = dynamic_cast<ALSAMidiIn*>(Midi);
|
||||
if (alsamidi)
|
||||
lash->setalsaid(alsamidi->getalsaid());
|
||||
#endif
|
||||
#ifdef JACKAUDIOOUT
|
||||
lash->setjackname(JACKgetname());
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (strlen(loadfile)>1){
|
||||
int tmp=master->loadXML(loadfile);
|
||||
if (tmp<0) {
|
||||
fprintf(stderr,"ERROR:Could not load master file %s .\n",loadfile);
|
||||
exit(1);
|
||||
} else {
|
||||
master->applyparameters();
|
||||
#ifndef DISABLE_GUI
|
||||
if (noui==0) ui->refresh_master_ui();
|
||||
#endif
|
||||
printf("Master file loaded.\n");
|
||||
};
|
||||
};
|
||||
|
||||
if (strlen(loadinstrument)>1){
|
||||
int loadtopart=0;
|
||||
int tmp=master->part[loadtopart]->loadXMLinstrument(loadinstrument);
|
||||
if (tmp<0) {
|
||||
fprintf(stderr,"ERROR:Could not load instrument file %s .\n",loadinstrument);
|
||||
exit(1);
|
||||
} else {
|
||||
master->part[loadtopart]->applyparameters();
|
||||
#ifndef DISABLE_GUI
|
||||
if (noui==0) ui->refresh_master_ui();
|
||||
#endif
|
||||
printf("Instrument file loaded.\n");
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#if !(defined(NONEMIDIIN)||defined(WINMIDIIN)||defined(VSTMIDIIN))
|
||||
pthread_create(&thr1,NULL,thread1,NULL);
|
||||
#endif
|
||||
|
||||
#ifdef OSSAUDIOOUT
|
||||
//!(defined(JACKAUDIOOUT)||defined(JACK_RTAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT))
|
||||
if (!usejackit) pthread_create(&thr2,NULL,thread2,NULL);
|
||||
#endif
|
||||
|
||||
/*It is not working and I don't know why
|
||||
//drop the suid-root permisions
|
||||
#if !(defined(JACKAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT)|| (defined (WINMIDIIN)) )
|
||||
setuid(getuid());
|
||||
seteuid(getuid());
|
||||
// setreuid(getuid(),getuid());
|
||||
// setregid(getuid(),getuid());
|
||||
#endif
|
||||
*/
|
||||
if (noui==0) pthread_create(&thr3,NULL,thread3,NULL);
|
||||
|
||||
pthread_create(&thr4,NULL,thread4,NULL);
|
||||
#ifdef WINMIDIIN
|
||||
InitWinMidi(master);
|
||||
#endif
|
||||
|
||||
while (Pexitprogram==0){
|
||||
#ifdef OS_LINUX
|
||||
usleep(100000);
|
||||
#elif OS_WINDOWS
|
||||
Sleep(100);
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef WINMIDIIN
|
||||
StopWinMidi();
|
||||
#endif
|
||||
|
||||
exitprogram();
|
||||
return(0);
|
||||
};
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#include "Output/VSTaudiooutput.h"
|
||||
|
||||
#define main main_plugin
|
||||
extern "C" __declspec(dllexport) AEffect *main_plugin(audioMasterCallback audioMaster);
|
||||
|
||||
int instances=-1;
|
||||
|
||||
AEffect *main (audioMasterCallback audioMaster){
|
||||
// if (audioMaster(0,audioMasterVersion,0,0,0,0)!=0) {
|
||||
// return(0);
|
||||
// };
|
||||
|
||||
if (instances==-1){
|
||||
Midi=new NULLMidiIn();
|
||||
denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE];
|
||||
for (int i=0;i<SOUND_BUFFER_SIZE;i++) denormalkillbuf[i]=(RND-0.5)*1e-16;
|
||||
instances=0;
|
||||
};
|
||||
|
||||
if (instances!=0) return(0);//don't allow multiple instances
|
||||
|
||||
AudioEffect *sintetizator=new VSTSynth(audioMaster);
|
||||
|
||||
return sintetizator->getAeffect();
|
||||
};
|
||||
|
||||
void* hInstance;
|
||||
BOOL WINAPI DllMain (HINSTANCE hInst,DWORD dwReason,LPVOID lpvReserved){
|
||||
hInstance=hInst;
|
||||
return(1);
|
||||
};
|
||||
|
||||
void *thread(void *arg){
|
||||
VSTSynth *vs=(VSTSynth *) arg;
|
||||
|
||||
/* FILE *a=fopen("aaaa1","a");
|
||||
fprintf(a,"%lx %lx %lx -i=%d\n",vs,0,vs->vmaster,instances);
|
||||
fflush(a);fclose(a);
|
||||
*/
|
||||
|
||||
vs->ui=new MasterUI(vs->vmaster,&vs->Pexitprogram);
|
||||
|
||||
/* a=fopen("aaaa1","a");
|
||||
fprintf(a,"%lx %lx %lx\n",vs,vs->ui->master,vs->vmaster);
|
||||
fflush(a);fclose(a);
|
||||
*/
|
||||
|
||||
vs->ui->showUI();
|
||||
|
||||
/* a=fopen("aaaa1","a");
|
||||
fprintf(a,"%lx %lx %lx\n",vs,vs->ui,vs->vmaster);
|
||||
fflush(a);fclose(a);
|
||||
*/
|
||||
|
||||
while (vs->Pexitprogram==0) Fl::wait(0.01);
|
||||
|
||||
delete(vs->ui);
|
||||
Fl::wait(0.01);
|
||||
|
||||
/* a=fopen("aaaa1","a");
|
||||
fprintf(a,"EXIT\n");
|
||||
fflush(a);fclose(a);
|
||||
*/
|
||||
|
||||
|
||||
pthread_exit(0);
|
||||
return(0);
|
||||
};
|
||||
|
||||
//Parts of the VSTSynth class
|
||||
VSTSynth::VSTSynth (audioMasterCallback audioMaster):AudioEffectX(audioMaster,1,0){
|
||||
instances++;
|
||||
|
||||
if (audioMaster){
|
||||
setNumInputs(0);
|
||||
setNumOutputs(2);
|
||||
setUniqueID('ZASF');
|
||||
canProcessReplacing();
|
||||
// hasVu(false);
|
||||
// hasClip(false);
|
||||
|
||||
isSynth(true);
|
||||
|
||||
programsAreChunks(true);
|
||||
|
||||
};
|
||||
|
||||
|
||||
SAMPLE_RATE=config.cfg.SampleRate;
|
||||
SOUND_BUFFER_SIZE=config.cfg.SoundBufferSize;
|
||||
OSCIL_SIZE=config.cfg.OscilSize;
|
||||
swaplr=config.cfg.SwapStereo;
|
||||
this->Pexitprogram=0;
|
||||
|
||||
this->vmaster=new Master();
|
||||
this->vmaster->swaplr=swaplr;
|
||||
|
||||
|
||||
// FILE *a=fopen("aaaa0","a");
|
||||
// fprintf(a,"%lx %lx %lx\n",this,this->ui,this->ui->masterwindow);
|
||||
// fflush(a);fclose(a);
|
||||
|
||||
pthread_create(&this->thr,NULL,thread,this);
|
||||
|
||||
// suspend();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
VSTSynth::~VSTSynth(){
|
||||
this->Pexitprogram=1;
|
||||
|
||||
Sleep(200);//wait the thread to finish
|
||||
|
||||
// pthread_mutex_lock(&vmaster->mutex);
|
||||
|
||||
|
||||
delete(this->vmaster);
|
||||
|
||||
instances--;
|
||||
};
|
||||
|
||||
long VSTSynth::processEvents(VstEvents *events){
|
||||
for (int i=0;i<events->numEvents;i++){
|
||||
|
||||
//debug stuff
|
||||
// FILE *a=fopen("events","a");
|
||||
// fprintf(a,"%lx\n",events->events[i]->type);
|
||||
// fflush(a);fclose(a);
|
||||
|
||||
if ((events->events[i])->type != kVstMidiType) continue;
|
||||
VstMidiEvent *ev= (VstMidiEvent*) events->events[i];
|
||||
unsigned char *data= (unsigned char *)ev->midiData;
|
||||
int status=data[0]/16;
|
||||
int cmdchan=data[0]&0x0f;
|
||||
int cntl;
|
||||
|
||||
pthread_mutex_lock(&vmaster->mutex);
|
||||
switch(status){
|
||||
case 0x8:vmaster->NoteOff(cmdchan,data[1]&0x7f);
|
||||
break;
|
||||
case 0x9:if (data[2]==0) vmaster->NoteOff(cmdchan,data[1]&0x7f);
|
||||
else vmaster->NoteOn(cmdchan,data[1]&0x7f,data[2]&0x7f);
|
||||
break;
|
||||
case 0xB: cntl=Midi->getcontroller(data[1]&0x7f);
|
||||
vmaster->SetController(cmdchan,cntl,data[2]&0x7f);
|
||||
break;
|
||||
case 0xE: vmaster->SetController(cmdchan,C_pitchwheel,data[1]+data[2]*(long int) 128-8192);
|
||||
break;
|
||||
};
|
||||
pthread_mutex_unlock(&vmaster->mutex);
|
||||
|
||||
};
|
||||
|
||||
return(1);
|
||||
};
|
||||
|
||||
long VSTSynth::getChunk(void** data,bool isPreset){
|
||||
int size=0;
|
||||
size=vmaster->getalldata((char **)data);
|
||||
return((long)size);
|
||||
};
|
||||
|
||||
long VSTSynth::setChunk(void *data,long size,bool isPreset){
|
||||
vmaster->putalldata((char*)data,size);
|
||||
return(0);
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user