hydrogen 1.2.3
InstrumentComponent.cpp
Go to the documentation of this file.
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 * Copyright(c) 2008-2024 The hydrogen development team [hydrogen-devel@lists.sourceforge.net]
5 *
6 * http://www.hydrogen-music.org
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
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
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see https://www.gnu.org/licenses
20 *
21 */
22
24
25#include <cassert>
26
28
29#include <core/Helpers/Xml.h>
31#include <core/License.h>
32
33#include <core/Basics/Adsr.h>
34#include <core/Basics/Sample.h>
35#include <core/Basics/Drumkit.h>
40
41namespace H2Core
42{
43
45
46InstrumentComponent::InstrumentComponent( int related_drumkit_componentID )
47 : __related_drumkit_componentID( related_drumkit_componentID )
48 , __gain( 1.0 )
49{
50 __layers.resize( m_nMaxLayers );
51 for ( int i = 0; i < m_nMaxLayers; i++ ) {
52 __layers[i] = nullptr;
53 }
54}
55
56InstrumentComponent::InstrumentComponent( std::shared_ptr<InstrumentComponent> other )
57 : __related_drumkit_componentID( other->__related_drumkit_componentID )
58 , __gain( other->__gain )
59{
60 __layers.resize( m_nMaxLayers );
61 for ( int i = 0; i < m_nMaxLayers; i++ ) {
62 std::shared_ptr<InstrumentLayer> other_layer = other->get_layer( i );
63 if ( other_layer ) {
64 __layers[i] = std::make_shared<InstrumentLayer>( other_layer );
65 } else {
66 __layers[i] = nullptr;
67 }
68 }
69}
70
72{
73 for ( int i = 0; i < m_nMaxLayers; i++ ) {
74 __layers[i] = nullptr;
75 }
76}
77
78void InstrumentComponent::set_layer( std::shared_ptr<InstrumentLayer> layer, int idx )
79{
80 assert( idx >= 0 && idx < m_nMaxLayers );
81 __layers[ idx ] = layer;
82}
83
85{
86 m_nMaxLayers = layers;
87}
88
93
94std::shared_ptr<InstrumentComponent> InstrumentComponent::load_from( XMLNode* pNode, const QString& sDrumkitPath, const License& drumkitLicense, bool bSilent )
95{
96 int nId = pNode->read_int( "component_id", EMPTY_INSTR_ID,
97 false, false, bSilent );
98 if ( nId == EMPTY_INSTR_ID ) {
99 return nullptr;
100 }
101
102 auto pInstrumentComponent = std::make_shared<InstrumentComponent>( nId );
103 pInstrumentComponent->set_gain( pNode->read_float( "gain", 1.0f,
104 true, false, bSilent ) );
105 XMLNode layer_node = pNode->firstChildElement( "layer" );
106 int nLayer = 0;
107 while ( ! layer_node.isNull() ) {
108 if ( nLayer >= m_nMaxLayers ) {
109 ERRORLOG( QString( "Layer #%1 >= m_nMaxLayers (%2). This as well as all further layers will be omitted." )
110 .arg( nLayer ).arg( m_nMaxLayers ) );
111 break;
112 }
113
114 auto pLayer = InstrumentLayer::load_from( &layer_node, sDrumkitPath,
115 drumkitLicense, bSilent );
116 if ( pLayer != nullptr ) {
117 pInstrumentComponent->set_layer( pLayer, nLayer );
118 nLayer++;
119 }
120 layer_node = layer_node.nextSiblingElement( "layer" );
121 }
122
123 return pInstrumentComponent;
124}
125
126void InstrumentComponent::save_to( XMLNode* node, int component_id, bool bRecentVersion, bool bFull )
127{
128 XMLNode component_node;
129 if ( bRecentVersion ) {
130 component_node = node->createNode( "instrumentComponent" );
131 component_node.write_int( "component_id", __related_drumkit_componentID );
132 component_node.write_float( "gain", __gain );
133 }
134 for ( int n = 0; n < m_nMaxLayers; n++ ) {
135 auto pLayer = get_layer( n );
136 if( pLayer != nullptr ) {
137 if( bRecentVersion ) {
138 pLayer->save_to( &component_node, bFull );
139 } else {
140 pLayer->save_to( node, bFull );
141 }
142 }
143 }
144}
145
146QString InstrumentComponent::toQString( const QString& sPrefix, bool bShort ) const {
147 QString s = Base::sPrintIndention;
148 QString sOutput;
149 if ( ! bShort ) {
150 sOutput = QString( "%1[InstrumentComponent]\n" ).arg( sPrefix )
151 .append( QString( "%1%2related_drumkit_componentID: %3\n" ).arg( sPrefix ).arg( s ).arg( __related_drumkit_componentID ) )
152 .append( QString( "%1%2gain: %3\n" ).arg( sPrefix ).arg( s ).arg( __gain ) )
153 .append( QString( "%1%2m_nMaxLayers: %3\n" ).arg( sPrefix ).arg( s ).arg( m_nMaxLayers ) )
154 .append( QString( "%1%2layers:\n" ).arg( sPrefix ).arg( s ) );
155
156 for ( auto ll : __layers ) {
157 if ( ll != nullptr ) {
158 sOutput.append( QString( "%1" ).arg( ll->toQString( sPrefix + s + s, bShort ) ) );
159 }
160 }
161 } else {
162 sOutput = QString( "[InstrumentComponent]" )
163 .append( QString( " related_drumkit_componentID: %1" ).arg( __related_drumkit_componentID ) )
164 .append( QString( ", gain: %1" ).arg( __gain ) )
165 .append( QString( ", m_nMaxLayers: %1" ).arg( m_nMaxLayers ) )
166 .append( QString( ", [layers:" ) );
167
168 for ( auto ll : __layers ) {
169 if ( ll != nullptr ) {
170 sOutput.append( QString( " [%1" ).arg( ll->toQString( sPrefix + s + s, bShort ).replace( "\n", "]" ) ) );
171 }
172 }
173
174 sOutput.append( "]\n" );
175
176 }
177
178 return sOutput;
179}
180
181std::vector<std::shared_ptr<InstrumentLayer>>::iterator InstrumentComponent::begin() {
182 return __layers.begin();
183}
184
185std::vector<std::shared_ptr<InstrumentLayer>>::iterator InstrumentComponent::end() {
186 return __layers.end();
187}
188
189};
190
191/* vim: set softtabstop=4 noexpandtab: */
#define EMPTY_INSTR_ID
Definition Instrument.h:34
#define ERRORLOG(x)
Definition Object.h:239
static QString sPrintIndention
String used to format the debugging string output of some core classes.
Definition Object.h:127
static std::shared_ptr< InstrumentComponent > load_from(XMLNode *pNode, const QString &sDrumkitPath, const License &drumkitLicense=License(), bool bSilent=false)
std::vector< std::shared_ptr< InstrumentLayer > > __layers
std::vector< std::shared_ptr< InstrumentLayer > >::iterator begin()
Iteration.
static int m_nMaxLayers
Maximum number of layers to be used in the Instrument editor.
InstrumentComponent(int related_drumkit_componentID)
static void setMaxLayers(int layers)
int __related_drumkit_componentID
Component ID of the drumkit.
std::vector< std::shared_ptr< InstrumentLayer > >::iterator end()
void set_layer(std::shared_ptr< InstrumentLayer > layer, int idx)
QString toQString(const QString &sPrefix="", bool bShort=true) const override
Formatted string version for debugging purposes.
std::shared_ptr< InstrumentLayer > get_layer(int idx)
void save_to(XMLNode *node, int component_id, bool bRecentVersion=true, bool bFull=false)
static std::shared_ptr< InstrumentLayer > load_from(XMLNode *pNode, const QString &sDrumkitPath, const License &drumkitLicense=License(), bool bSilent=false)
load an instrument layer from an XMLNode
Wrapper class to help Hydrogen deal with the license information specified in a drumkit.
Definition License.h:48
XMLNode is a subclass of QDomNode with read and write values methods.
Definition Xml.h:39
int read_int(const QString &node, int default_value, bool inexistent_ok=true, bool empty_ok=true, bool bSilent=false)
reads an integer stored into a child node
Definition Xml.cpp:170
float read_float(const QString &node, float default_value, bool inexistent_ok=true, bool empty_ok=true, bool bSilent=false)
reads a float stored into a child node
Definition Xml.cpp:139
void write_float(const QString &node, const float value)
write a float into a child node
Definition Xml.cpp:280
XMLNode createNode(const QString &name)
create a new XMLNode that has to be appended into de XMLDoc
Definition Xml.cpp:63
void write_int(const QString &node, const int value)
write an integer into a child node
Definition Xml.cpp:284