AudioJack: do not use QVector in processCallback()
[lmms.git] / plugins / zynaddsubfx / LocalZynAddSubFx.cpp
blob34663c2c3b294c297d6bdcc8fbc25d485c5962e1
1 /*
2 * LocalZynAddSubFx.cpp - local implementation of ZynAddSubFx plugin
4 * Copyright (c) 2009-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
25 #include <lmmsconfig.h>
27 #include "LocalZynAddSubFx.h"
29 #include "src/Input/NULLMidiIn.h"
30 #include "src/Misc/Master.h"
31 #include "src/Misc/Dump.h"
34 int LocalZynAddSubFx::s_instanceCount = 0;
37 LocalZynAddSubFx::LocalZynAddSubFx()
39 for( int i = 0; i < NumKeys; ++i )
41 m_runningNotes[i] = 0;
44 if( s_instanceCount == 0 )
46 #ifdef LMMS_BUILD_WIN32
47 // (non-portable) initialization of statically linked pthread library
48 pthread_win32_process_attach_np();
49 pthread_win32_thread_attach_np();
50 #endif
52 initConfig();
54 OSCIL_SIZE = config.cfg.OscilSize;
56 srand( time( NULL ) );
57 denormalkillbuf = new REALTYPE[SOUND_BUFFER_SIZE];
58 for( int i = 0; i < SOUND_BUFFER_SIZE; ++i )
60 denormalkillbuf[i] = (RND-0.5)*1e-16;
63 ++s_instanceCount;
65 m_master = new Master();
66 m_master->swaplr = 0;
72 LocalZynAddSubFx::~LocalZynAddSubFx()
74 delete m_master;
76 if( --s_instanceCount == 0 )
78 delete[] denormalkillbuf;
85 void LocalZynAddSubFx::initConfig()
87 config.init();
89 config.cfg.GzipCompression = 0;
95 void LocalZynAddSubFx::setSampleRate( int _sampleRate )
97 SAMPLE_RATE = _sampleRate;
103 void LocalZynAddSubFx::setBufferSize( int _bufferSize )
105 SOUND_BUFFER_SIZE = _bufferSize;
111 void LocalZynAddSubFx::saveXML( const std::string & _filename )
113 char * name = strdup( _filename.c_str() );
114 m_master->saveXML( name );
115 free( name );
121 void LocalZynAddSubFx::loadXML( const std::string & _filename )
123 char * f = strdup( _filename.c_str() );
125 pthread_mutex_lock( &m_master->mutex );
126 m_master->defaults();
127 m_master->loadXML( f );
128 pthread_mutex_unlock( &m_master->mutex );
130 m_master->applyparameters();
132 unlink( f );
133 free( f );
139 void LocalZynAddSubFx::loadPreset( const std::string & _filename, int _part )
141 char * f = strdup( _filename.c_str() );
143 pthread_mutex_lock( &m_master->mutex );
144 m_master->part[_part]->defaultsinstrument();
145 m_master->part[_part]->loadXMLinstrument( f );
146 pthread_mutex_unlock( &m_master->mutex );
148 m_master->applyparameters();
150 free( f );
156 void LocalZynAddSubFx::setPresetDir( const std::string & _dir )
158 m_presetsDir = _dir;
159 for( int i = 0; i < MAX_BANK_ROOT_DIRS; ++i )
161 if( config.cfg.bankRootDirList[i] == NULL )
163 config.cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE];
164 strcpy( config.cfg.bankRootDirList[i], m_presetsDir.c_str() );
165 break;
167 else if( strcmp( config.cfg.bankRootDirList[i],
168 m_presetsDir.c_str() ) == 0 )
170 break;
178 void LocalZynAddSubFx::setLmmsWorkingDir( const std::string & _dir )
180 if( config.workingDir != NULL )
182 free( config.workingDir );
184 config.workingDir = strdup( _dir.c_str() );
186 initConfig();
191 void LocalZynAddSubFx::processMidiEvent( const midiEvent & _e )
193 // all functions are called while m_master->mutex is held
194 static NULLMidiIn midiIn;
196 switch( _e.m_type )
198 case MidiNoteOn:
199 if( _e.velocity() > 0 )
201 if( _e.key() <= 0 || _e.key() >= 128 )
203 break;
205 if( m_runningNotes[_e.key()] > 0 )
207 m_master->NoteOff( 0, _e.key() );
209 ++m_runningNotes[_e.key()];
210 m_master->NoteOn( 0, _e.key(), _e.velocity() );
211 break;
213 case MidiNoteOff:
214 if( _e.key() <= 0 || _e.key() >= 128 )
216 break;
218 if( --m_runningNotes[_e.key()] <= 0 )
220 m_master->NoteOff( 0, _e.key() );
222 break;
223 case MidiPitchBend:
224 m_master->SetController( 0, C_pitchwheel,
225 _e.m_data.m_param[0] +
226 _e.m_data.m_param[1]*128-8192 );
227 break;
228 case MidiControlChange:
229 m_master->SetController( 0,
230 midiIn.getcontroller( _e.m_data.m_param[0] ),
231 _e.m_data.m_param[1] );
232 break;
233 default:
234 break;
241 void LocalZynAddSubFx::processAudio( sampleFrame * _out )
243 REALTYPE outputl[SOUND_BUFFER_SIZE];
244 REALTYPE outputr[SOUND_BUFFER_SIZE];
246 m_master->AudioOut( outputl, outputr );
248 for( int f = 0; f < SOUND_BUFFER_SIZE; ++f )
250 _out[f][0] = outputl[f];
251 _out[f][1] = outputr[f];