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 _ScoreGenerator_h_
21 #define _ScoreGenerator_h_
30 #include <CppAddons/Math.h>
31 #include <CppAddons/Random.h>
32 //#include <CppAddons/String.h>
35 #include "Instrument.h"
40 //! generate a randomly generated score with \ref Instrument
42 * \param buffer the outputed wave
43 * \param score the corresponding outputed score
44 * \param instrs the instruments
45 * \param lenght lenght of the score in seconds : R+*
46 * \param dataBySecond number of data by second : ~{11000, 22000, 44100}
47 * \param AFreq frequency of the A3 : ~440.0
48 * \param minHT minimum halftone : Z // TODO <0
49 * \param maxHT maximum halftone : Z
50 * \param nbNotes maximum number of notes in lenght : N*
51 * \param nbInstr maximum number of instruments played at the same time : N*
53 inline void GenerateScoreFromInstruments(
54 deque<double>& buffer,
55 vector< vector<int> >& score,
56 vector<Instrument*>& instrs,
65 int size = int(lenght*dataBySecond);
66 int nbHT = maxHT-minHT+1;
67 int note_size = size / nbNotes;
68 // cout << "AFreq=" << AFreq << " dataBySecond=" << dataBySecond << endl;
69 // cout << "nbNotes=" << nbNotes << " lenght=" << lenght << " minHT=" << minHT << " maxHT=" << maxHT << endl;
70 // cout << "size=" << size << " nbHT=" << nbHT << endl;
72 // TODO compute upHT so every harm are present in the range of minHT maxHT
74 // for(int i=0; i<instrs.size(); i++)
76 // if(instrs[i]->getFreqs()!=NULL)
78 // int n = instrs[i]->getFreqs()->size();
79 // maxNbHarm = std::max(maxNbHarm, n);
82 // int upHT = (int)f2h(AFreq*(maxNbHarm+1), AFreq);
83 // if(upHT>maxHT-minHT) throw string("not enough HT for covering all harmonics");
84 // cout << upHT << endl;
86 // cout << "make score ... " << instrs.size() << endl;
88 if(score.size()!=(size_t)(nbNotes*note_size))
89 score.resize(nbNotes*note_size);
91 assert((size_t)nbInstr<=instrs.size());
93 for(int i=0; i<nbNotes; i++)
95 vector<int> hs(instrs.size());
96 vector< Math::polar<double> > ps(instrs.size());
97 vector<bool> play(instrs.size());
98 for(size_t w=0; w<play.size(); w++) play[w] = false;
100 while(count_playing<nbInstr)
102 int index = int(Random::s_random.nextDouble()*play.size());
109 for(size_t v=0; v<hs.size(); v++)
113 // hs[v] = minHT+g_random.nextInt(maxHT-minHT+1);
114 // hs[v] = minHT+g_random.nextInt(maxHT-minHT-upHT+1);
115 // TODO !!!!!!!!!!!!!!
116 // int up = (int)f2h(AFreq*(instrs[v]->getFreqs()->size()), AFreq);
117 // int up = instrs[v]->getFreqs()->size();
119 // cout << "up=" << up << endl;
120 // assert(up<maxHT-minHT);
121 hs[v] = minHT+Random::s_random.nextInt(maxHT-minHT-up+1);
122 // hs[v] = minHT+g_random.nextInt(maxHT-minHT+1);
123 ps[v] = Math::polar<double>(Random::s_random.nextDouble()/nbInstr, Random::s_random.nextDouble()*2*Math::Pi);
124 // ps[v] = Math::polar<double>(1.0/nbInstr, g_random.nextDouble()*2*Math::Pi);
125 // cout << "halftone choosen " << hs[v] << endl;
128 // cout << ps[v].mod << " ";
132 // if(i==5)hs[0]=-12;
135 // for(int v=0; v<hs.size(); v++)
136 // cout << "halftone choosen " << hs[v] << " play=" << play[v] << endl;
138 for(int j=0; j<note_size; j++)
141 for(size_t v=0; v<instrs.size(); v++)
143 buff += ps[v].mod*instrs[v]->gen_value(hs[v], ps[v].arg);
145 buffer.push_back(buff);
147 vector<int> score_at(nbHT);
148 for(size_t h=0; h<score_at.size(); h++)
151 for(size_t v=0; v<instrs.size(); v++)
152 if(play[v] && ps[v].mod>0.05) // TODO 0.1: note is here if we hear it !
153 score_at[hs[v]-minHT]++;
161 //! generate a randomly generated sinusoid score
163 * \param buffer the outputed wave
164 * \param score the outputed score
165 * \param lenght lenght of the score in seconds : R+*
166 * \param dataBySecond number of data by second : ~{11000, 22000, 44100}
167 * \param AFreq frequency of the A3 : ~440.0
168 * \param minHT minimum halftone : Z // TODO <0
169 * \param maxHT maximum halftone : Z
170 * \param nbNotes number of notes in lenght : N*
171 * \param nbVoice number of voices : N*
173 inline void GenerateScore( deque<double>& buffer,
174 vector< vector<int> >& score,
183 int size = int(lenght*dataBySecond);
184 int nbHT = maxHT-minHT+1;
185 int note_size = size / nbNotes;
186 // cout << "AFreq=" << AFreq << " dataBySecond=" << dataBySecond << endl;
187 // cout << "nbNotes=" << nbNotes << " lenght=" << lenght << " minHT=" << minHT << " maxHT=" << maxHT << endl;
188 // cout << "size=" << size << " nbHT=" << nbHT << " nbVoice=" << nbVoice << endl;
190 // cout << "make score ... \t\t" << flush;
192 for(int i=0; i<nbNotes; i++)
194 vector<int> hs(nbVoice);
195 for(size_t v=0; v<hs.size(); v++)
197 hs[v] = minHT+Random::s_random.nextInt(maxHT-minHT+1);
198 // cout << "halftone choosen " << hs[v] << endl;
201 vector<double> decals(nbVoice);
202 for(size_t v=0; v<decals.size(); v++)
203 decals[v] = Random::s_random.nextDouble()*Math::Pi/2;
204 // decals[v] = g_random.nextDouble()*2*Math::Pi;
206 // cout << "halftone selected=" << h << " freq=" << freq << endl;
207 for(int j=0; j<note_size; j++)
210 for(size_t v=0; v<hs.size(); v++)
211 buff += sin( ((2.0*Math::Pi)/dataBySecond)*h2f(hs[v], AFreq)*double(j) + decals[v]);
213 // int index = i*note_size+j;
214 // add data index and wav value
216 buffer.push_back(buff);
217 // add score halftones (solution)
218 vector<int> score_at(nbHT);
219 for(int vh=0; vh<nbHT; vh++)
222 for(size_t v=0; v<hs.size(); v++)
227 score.push_back(score_at);
228 // n = String::undoable_out_percent(cout, 100.0f*index/size, n);
231 // String::undoable_out_clear(cout, n);
232 // cout << "done " << endl;
237 #endif // _ScoreGenerator_h_