1 // Copyright 2004 "Gilles Degottex"
3 // This file is part of "Music"
5 // "Music" is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published by
7 // the Free Software Foundation; either version 2.1 of the License, or
8 // (at your option) any later version.
10 // "Music" is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #ifndef _Instrument_h_
21 #define _Instrument_h_
28 #include <CppAddons/Math.h>
35 #define MAX_NB_FREQ 24
37 #define MAX_RDM_HT -12
40 //! an abstract instrument
43 virtual vector< Math::polar<double> >* getFreqs(){return NULL;}
45 virtual double gen_value(int k, double phase=0.0)=0;
47 virtual ~Instrument(){}
50 //! an harmonic instrument
52 * une fondamentale choisie dans un interval et des composantes harmoniques
54 struct HarmInstrument : Instrument
58 vector< Math::polar<double> > m_freqs;
62 HarmInstrument(int dataBySecond, double AFreq, int nb_harm=int((rand()/RAND_MAX)*MAX_NB_HARM), int min_rdm_ht=-12, int max_rdm_ht=12)
63 : m_dataBySecond(dataBySecond)
66 , m_base_ht(int(min_rdm_ht+(rand()/RAND_MAX)*(max_rdm_ht-min_rdm_ht+1)))
67 , m_base_freq(h2f(m_base_ht, AFreq))
69 for(size_t i=0; i<m_freqs.size(); i++)
70 m_freqs[i] = Math::polar<double>(Random::s_random.nextDouble(), 2*Math::Pi*Random::s_random.nextDouble());
72 // s'il n'y a pas de composantes, ça ne sert à rien de choisir une amplitude au hazard pour la fondamentale
76 // la fondamentale doit avoir une amplitude minimale
77 m_freqs[0].mod = m_freqs[0].mod*0.8 + 0.2;
80 HarmInstrument(int dataBySecond, vector< Math::polar<double> >& freqs, double base_freq)
81 : m_dataBySecond(dataBySecond)
84 , m_base_freq(base_freq)
88 virtual vector< Math::polar<double> >* getFreqs(){return &m_freqs;}
90 virtual double gen_value(int k, double phase=0.0)
94 for(size_t i=0; i<m_freqs.size(); i++)
95 value += m_freqs[i].mod * sin(h2f(k, m_base_freq)*(i+1)*m_time+m_freqs[i].arg + phase);
97 m_time += 2*Math::Pi/m_dataBySecond;
103 inline ostream& operator<<(ostream& out, const HarmInstrument& instr)
105 cout << "HarmInstrument (mod:arg)" << endl;
106 for(size_t i=0; i<instr.m_freqs.size(); i++)
107 out << "\t" << instr.m_base_freq*(i+1) << " (" << instr.m_freqs[i].mod << ":" << instr.m_freqs[i].arg << ")" << endl;
112 /* basé sur un motif pré-enregistré
114 struct WaveInstrument : Instrument
116 vector<double> m_data;
123 WaveInstrument(int dataBySecond, double AFreq, const string& file_name)
125 , m_dataBySecond(dataBySecond)
128 ifstream file(file_name.c_str());
130 assert(file.is_open());
138 m_data.push_back(value);
145 WaveInstrument(int dataBySecond, double AFreq, const deque<double>& data)
146 : m_data(data.size())
148 , m_dataBySecond(dataBySecond)
151 for(size_t i=0; i<data.size(); i++)
155 WaveInstrument(int dataBySecond, double AFreq, const vector<double>& data)
158 , m_dataBySecond(dataBySecond)
163 virtual double gen_value(int k, double phase=0.0)
165 double f = h2f(k, m_AFreq);
167 int i = int(f*(m_time+phase)*m_data.size()/(2*Math::Pi))%m_data.size();
169 m_time += 2*Math::Pi/m_dataBySecond;
175 /* faux instrument: les composantes devraient toujours être des harmoniques
177 struct FreqInstrument : Instrument
179 static double get_freq(double lowest_freq, int i, double AFreq)
181 return h2f(int(f2h(lowest_freq, AFreq)+i), AFreq);
187 vector< Math::polar<double> > m_freqs;
188 double m_lowest_freq;
190 virtual vector< Math::polar<double> >* getFreqs(){return &m_freqs;}
192 FreqInstrument(int dataBySecond, double AFreq, double lowest_freq, int nb_freq=int((rand()/RAND_MAX)*MAX_NB_FREQ))
193 : m_dataBySecond(dataBySecond)
197 , m_lowest_freq(lowest_freq)
199 // cout << "FreqInstrument::FreqInstrument" << endl;
201 for(size_t i=0; i<m_freqs.size(); i++)
202 m_freqs[i] = Math::polar<double>((rand()/RAND_MAX), Math::Pi*(rand()/RAND_MAX));
204 // s'il n'y a pas de composantes, ça ne sert à rien de choisir une amplitude au hazard pour la fondamentale
205 if(m_freqs.size()==1)
206 m_freqs[0].mod = 1.0;
208 m_freqs[1].mod = 0.0; // TEMP
210 // la fondamentale doit avoir une amplitude minimale
211 m_freqs[0].mod = m_freqs[0].mod*0.8 + 0.2;
213 // rajoute un bruit sur la vitesse
214 double upper_freq = h2f(1, m_lowest_freq);
215 double lower_freq = h2f(-1, m_lowest_freq);
216 cout << "m_lowest_freq=" << m_lowest_freq << " upper_freq="<<upper_freq<<" lower_freq="<<lower_freq;
217 m_lowest_freq += (rand()/RAND_MAX)*(upper_freq-lower_freq)/16 - (m_lowest_freq-lower_freq)/16;
218 cout << " => " << m_lowest_freq << endl;
220 // cout << "/FreqInstrument::FreqInstrument" << endl;
223 FreqInstrument(int dataBySecond, double AFreq, vector< Math::polar<double> >& freqs, double lowest_freq)
224 : m_dataBySecond(dataBySecond)
228 , m_lowest_freq(lowest_freq)
232 virtual double gen_value(int k, double phase=0.0)
234 // cout << "FreqInstrument::gen_value" << endl;
238 for(size_t i=0; i<m_freqs.size(); i++)
239 value += m_freqs[i].mod * sin(get_freq(m_lowest_freq,i+k,m_AFreq)*m_time + m_freqs[i].arg);
241 m_time += 2*Math::Pi/m_dataBySecond;
247 inline ostream& operator<<(ostream& out, const FreqInstrument& instr)
249 cout << "FreqInstrument (mod:arg)" << endl;
250 for(size_t i=0; i<instr.m_freqs.size(); i++)
251 out << "\t" << FreqInstrument::get_freq(instr.m_lowest_freq,i,instr.m_AFreq) << " (" << instr.m_freqs[i].mod << ":" << instr.m_freqs[i].arg << ")" << endl;
258 #endif // _Instrument_h_