root/branches/jackMidi/libs/hydrogen/src/instrument.cpp @ 534

Revision 534, 8.0 KB (checked in by gabriel, 5 years ago)

Merge rev 428:439 from trunk

Conflicts:

libs/hydrogen/src/hydrogen.cpp

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22
23#include <hydrogen/instrument.h>
24#include <hydrogen/adsr.h>
25#include <hydrogen/sample.h>
26#include <hydrogen/Song.h>
27#include <hydrogen/LocalFileMng.h>
28#include <hydrogen/SoundLibrary.h>
29#include <hydrogen/audio_engine.h>
30
31#include <cassert>
32
33namespace H2Core
34{
35
36
37Instrument::Instrument( const QString& id, const QString& name, ADSR* adsr )
38                : Object( "Instrument" )
39                , __queued( 0 )
40                , __adsr( adsr )
41                , __muted( false )
42                , __name( name )
43                , __volume( 1.0 )
44                , __filter_resonance( 0.0 )
45                , __filter_cutoff( 1.0 )
46                , __random_pitch_factor( 0.0 )
47                , __id( id )
48                , __filter_active( false )
49                , __pan_l( 1.0 )
50                , __pan_r( 1.0 )
51                , __soloed( false )
52                , __active( true )
53                , __peak_l( 0.0 )
54                , __peak_r( 0.0 )
55                , __gain( 1.0 )
56                , __drumkit_name( "" )
57                , __mute_group( -1 )
58{
59        for ( unsigned nFX = 0; nFX < MAX_FX; ++nFX ) {
60                __fx_level[ nFX ] = 0.0;
61        }
62
63        for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; ++nLayer ) {
64                __layer_list[ nLayer ] = NULL;
65        }
66}
67
68
69
70Instrument::~Instrument()
71{
72        for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; ++nLayer ) {
73                delete __layer_list[ nLayer ];
74                __layer_list[ nLayer ] = NULL;
75        }
76        delete __adsr;
77        __adsr = NULL;
78}
79
80
81
82inline InstrumentLayer* Instrument::get_layer( int nLayer )
83{
84        if ( nLayer < 0 ) {
85                ERRORLOG( QString( "nLayer < 0 (nLayer=%1)" ).arg( nLayer ) );
86                return NULL;
87        }
88        if ( nLayer >= MAX_LAYERS ) {
89                ERRORLOG( QString( "nLayer > MAX_LAYERS (nLayer=%1)" ).arg( nLayer ) );
90                return NULL;
91        }
92
93        return __layer_list[ nLayer ];
94}
95
96
97
98void Instrument::set_layer( InstrumentLayer* pLayer, unsigned nLayer )
99{
100        if ( nLayer < MAX_LAYERS ) {
101                __layer_list[ nLayer ] = pLayer;
102        } else {
103                ERRORLOG( "nLayer > MAX_LAYER" );
104        }
105}
106
107void Instrument::set_adsr( ADSR* adsr )
108{
109        delete __adsr;
110        __adsr = adsr;
111}
112
113void Instrument::load_from_placeholder( Instrument* placeholder, bool is_live )
114{
115        LocalFileMng mgr;
116        QString path = mgr.getDrumkitDirectory( placeholder->get_drumkit_name() ) + placeholder->get_drumkit_name() + "/";
117        for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; ++nLayer ) {
118                InstrumentLayer *pNewLayer = placeholder->get_layer( nLayer );
119                if ( pNewLayer != NULL ) {
120                        // this is a 'placeholder sample:
121                        Sample *pNewSample = pNewLayer->get_sample();
122                       
123                        // now we load the actal data:
124                        Sample *pSample = Sample::load( path + pNewSample->get_filename() );
125                        InstrumentLayer *pOldLayer = this->get_layer( nLayer );
126
127                        if ( pSample == NULL ) {
128                                _ERRORLOG( "Error loading sample. Creating a new empty layer." );
129                                if ( is_live )
130                                        AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
131                               
132                                this->set_layer( NULL, nLayer );
133                               
134                                if ( is_live )
135                                        AudioEngine::get_instance()->unlock();
136                                delete pOldLayer;
137                                continue;
138                        }
139                        InstrumentLayer *pLayer = new InstrumentLayer( pSample );
140                        pLayer->set_start_velocity( pNewLayer->get_start_velocity() );
141                        pLayer->set_end_velocity( pNewLayer->get_end_velocity() );
142                        pLayer->set_gain( pNewLayer->get_gain() );
143
144                        if ( is_live )
145                                AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
146                       
147                        this->set_layer( pLayer, nLayer );      // set the new layer
148                       
149                        if ( is_live )
150                                AudioEngine::get_instance()->unlock();
151                        delete pOldLayer;               // delete the old layer
152
153                } else {
154                        InstrumentLayer *pOldLayer = this->get_layer( nLayer );
155                        if ( is_live )
156                                AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
157                       
158                        this->set_layer( NULL, nLayer );
159                       
160                        if ( is_live )
161                                AudioEngine::get_instance()->unlock();
162                        delete pOldLayer;               // delete the old layer
163                }
164
165        }
166        if ( is_live )
167                AudioEngine::get_instance()->lock( "Hydrogen::loadDrumkit" );
168       
169        // update instrument properties
170        this->set_id( placeholder->get_id() );
171        this->set_name( placeholder->get_name() );
172        this->set_pan_l( placeholder->get_pan_l() );
173        this->set_pan_r( placeholder->get_pan_r() );
174        this->set_volume( placeholder->get_volume() );
175        this->set_drumkit_name( placeholder->get_drumkit_name() );
176        this->set_muted( placeholder->is_muted() );
177        this->set_random_pitch_factor( placeholder->get_random_pitch_factor() );
178        this->set_adsr( new ADSR( *( placeholder->get_adsr() ) ) );
179        this->set_filter_active( placeholder->is_filter_active() );
180        this->set_filter_cutoff( placeholder->get_filter_cutoff() );
181        this->set_filter_resonance( placeholder->get_filter_resonance() );
182        this->set_mute_group( placeholder->get_mute_group() );
183       
184        if ( is_live )
185                AudioEngine::get_instance()->unlock();
186}
187
188Instrument * Instrument::create_empty()
189{
190        return new Instrument( "", "Empty Instrument", new ADSR() );
191}
192
193Instrument * Instrument::load_instrument(
194    const QString& drumkit_name,
195    const QString& instrument_name
196)
197{
198        Instrument * I = create_empty();
199        I->load_from_name( drumkit_name, instrument_name, false );
200        return I;
201}
202
203void Instrument::load_from_name(
204    const QString& drumkit_name,
205    const QString& instrument_name,
206    bool is_live
207)
208{
209        Instrument * pInstr = NULL;
210       
211        LocalFileMng mgr;
212        QString sDrumkitPath = mgr.getDrumkitDirectory( drumkit_name );
213
214        // find the drumkit
215        Drumkit *pDrumkitInfo = mgr.loadDrumkit( mgr.getDrumkitDirectory( drumkit_name ) + drumkit_name );
216        assert( pDrumkitInfo );
217
218        // find the instrument
219        InstrumentList *pInstrList = pDrumkitInfo->getInstrumentList();
220        for ( unsigned nInstr = 0; nInstr < pInstrList->get_size(); ++nInstr ) {
221                pInstr = pInstrList->get( nInstr );
222                if ( pInstr->get_name() == instrument_name ) {
223                        break;
224                }
225        }
226       
227        if ( pInstr != NULL ) {
228                load_from_placeholder( pInstr, is_live );
229        }
230        delete pDrumkitInfo;
231}
232
233
234
235// ::::
236
237
238InstrumentList::InstrumentList()
239                : Object( "InstrumentList" )
240{
241//      infoLog("INIT");
242}
243
244
245
246InstrumentList::~InstrumentList()
247{
248//      infoLog("DESTROY");
249        for ( unsigned int i = 0; i < m_list.size(); ++i ) {
250                delete m_list[i];
251        }
252}
253
254
255
256void InstrumentList::add( Instrument* newInstrument )
257{
258        m_list.push_back( newInstrument );
259        m_posmap[newInstrument] = m_list.size() - 1;
260}
261
262
263
264Instrument* InstrumentList::get( unsigned int pos )
265{
266        if ( pos >= m_list.size() ) {
267                ERRORLOG( QString( "pos > list.size(). pos = %1" ).arg( pos ) );
268                return NULL;
269        }
270        /*      else if ( pos < 0 ) {
271                        ERRORLOG( "pos < 0. pos = " + to_string(pos) );
272                        return NULL;
273                }*/
274        return m_list[pos];
275}
276
277
278
279/// Returns index of instrument in list, if instrument not found, returns -1
280int InstrumentList::get_pos( Instrument *pInstr )
281{
282        if ( m_posmap.find( pInstr ) == m_posmap.end() )
283                return -1;
284        return m_posmap[ pInstr ];
285}
286
287
288
289unsigned int InstrumentList::get_size()
290{
291        return m_list.size();
292}
293
294
295void InstrumentList::replace( Instrument* pNewInstr, unsigned nPos )
296{
297        if ( nPos >= m_list.size() ) {
298                ERRORLOG( QString( "Instrument index out of bounds in InstrumentList::replace. pos >= list.size() - %1 > %2" ).arg( nPos ).arg( m_list.size() ) );
299                return;
300        }
301        m_list.insert( m_list.begin() + nPos, pNewInstr );      // insert the new Instrument
302        // remove the old Instrument
303        m_list.erase( m_list.begin() + nPos + 1 );
304}
305
306
307void InstrumentList::del( int pos )
308{
309        assert( pos < ( int )m_list.size() );
310        assert( pos >= 0 );
311        m_list.erase( m_list.begin() + pos );
312}
313
314
315
316
317InstrumentLayer::InstrumentLayer( Sample *sample )
318                : Object( "InstrumentLayer" )
319                , __start_velocity( 0.0 )
320                , __end_velocity( 1.0 )
321                , __pitch( 0.0 )
322                , __gain( 1.0 )
323                , __sample( sample )
324{
325        //infoLog( "INIT" );
326}
327
328
329
330InstrumentLayer::~InstrumentLayer()
331{
332        delete __sample;
333        __sample = NULL;
334        //infoLog( "DESTROY" );
335}
336
337};
338
339
Note: See TracBrowser for help on using the browser.