5. Códigos Instruments (instrument, instrumentFM, instrumentFM2...) (2016)

Pràctica Español
Universidad Universidad Politécnica de Cataluña (UPC)
Grado Ingeniería de Sistemas Audiovisuales - 3º curso
Asignatura Procesado de Audio y Voz
Año del apunte 2016
Páginas 8
Fecha de subida 27/04/2016
Descargas 2
Subido por

Vista previa del texto

Práctica 5: Generación de música armónica Javier de la Rica instrument.cpp Instrument * get_instrument(const string &name, const string &parameters) { Instrument * pInst = 0; // cout << name << ": " << parameters << endl; if (name == "InstrumentDumb") { pInst = (Instrument *) new InstrumentDumb(parameters); } else if( name == "InstrumentSin"){ pInst = (Instrument *) new InstrumentSin(parameters); } else if( name == "InstrumentFM"){ pInst = (Instrument *) new InstrumentFM(parameters); } else if( name == "InstrumentFM2"){ pInst = (Instrument *) new InstrumentFM2(parameters); } return pInst; } Práctica 5: Generación de música armónica Javier de la Rica instrument_FM.cpp InstrumentFM::InstrumentFM(const std::string &param) : adsr(SamplingRate, param) { bActive = false; x.resize(BSIZE); /* You can use the class keyvalue to parse "param" and configure your instrument.
Take a Look at keyvalue.h */ KeyValue kv(param); if (!kv.to_float("l",l)) l = 1; //default value if (!kv.to_float("m",m)) m = 1; //default value } void InstrumentFM::command(long cmd, long note, long vel) { if (cmd == 9) { bActive = true; adsr.start(); phase1 = 0; phase2 = 0; float f0=440.0*pow(2,(((float)note-69.0)/12.0)); nota=f0/SamplingRate; velo=vel/128.0; step1 = 2 * M_PI * nota; step2 = 2 * M_PI *l*nota; I=m/(step2); } else if (cmd == 0 || cmd == 8) { Práctica 5: Generación de música armónica Javier de la Rica adsr.stop(); } } const vector<float> & InstrumentFM::synthesize() { if (!bActive) return x; if (!adsr.active()) { bActive = false; x.assign(x.size(), 0); return x; } for (int i=0; i < x.size() ; ++i) { x[i] = 0.3*velo*sin(phase1+I*sin(phase2)); phase1 += step1; phase2 += step2; while (phase1 > M_PI) phase1 -= 2*M_PI; while (phase2 > M_PI) phase2 -= 2*M_PI; } adsr(x); //apply envelope to x (and updates internal status of adsr) return x; } Práctica 5: Generación de música armónica Javier de la Rica instrument_FM2.cpp InstrumentFM2::InstrumentFM2(const std::string &param) : adsr(SamplingRate, param),adsr2 (SamplingRate) { bActive = false; x.resize(BSIZE); /* You can use the class keyvalue to parse "param" and configure your instrument.
Take a Look at keyvalue.h */ KeyValue kv(param); if (!kv.to_float("l",l)) l = 1; //default value if (!kv.to_float("m",m)) m = 1; //default value float a,d,s,r; kv.to_float("ADSR2_A",a); kv.to_float("ADSR2_D",d); kv.to_float("ADSR2_S",s); kv.to_float("ADSR2_R",r); adsr2.set(a,d,s,r); } void InstrumentFM2::command(long cmd, long note, long vel) { if (cmd == 9) { bActive = true; adsr.start(); adsr2.start(); Práctica 5: Generación de música armónica Javier de la Rica phase1 = 0; phase2 = 0; float f0=440.0*pow(2,(((float)note-69.0)/12.0)); nota=f0/SamplingRate; velo=vel/128.0; I=m/(step2); step1 = 2 * M_PI * nota; step2 = 2 * M_PI *l*nota; } else if (cmd == 0 || cmd == 8) { adsr.stop(); adsr2.stop(); } } const vector<float> & InstrumentFM2::synthesize() { if (!bActive) return x; if (!adsr.active()) { bActive = false; x.assign(x.size(), 0); return x; } vector <float> a2(x.size()); for(int j=0;j<a2.size();j++) a2[j]= 1; adsr2(a2); for (int i=0; i < x.size() ; ++i) { x[i] = 0.3*velo*sin(phase1+(I+a2[i])*sin(phase2)); Práctica 5: Generación de música armónica Javier de la Rica phase1 += step1; phase2 += step2; while (phase1 > M_PI) phase1 -= 2*M_PI; while (phase2 > M_PI) phase2 -= 2*M_PI; } adsr(x); //apply envelope to x (and updates internal status of adsr) return x; } Práctica 5: Generación de música armónica Javier de la Rica instrument_sin.cpp InstrumentSin::InstrumentSin(const std::string &param) : adsr(SamplingRate, param) { bActive = false; x.resize(BSIZE); KeyValue kv(param); int N; if (!kv.to_int("N",N)) N = 40; //default value //Create a tbl with a tone, fixed frequency tbl.resize(N); float phase = 0, step = 2 * M_PI /(float) N; index = 0; for (int i=0; i < N ; ++i) { tbl[i] = sin(phase); phase += step; } } void InstrumentSin::command(long cmd, long note, long vel) { if (cmd == 9) { bActive = true; adsr.start(); phase = 0; float f0=440.0*pow(2,(((float)note-69.0)/12.0)); nota=f0/SamplingRate; velo=vel/128.0; Práctica 5: Generación de música armónica Javier de la Rica step = 2 * M_PI * nota; } else if (cmd == 0 || cmd == 8) { adsr.stop(); } } const vector<float> & InstrumentSin::synthesize() { if (!bActive) return x; if (!adsr.active()) { bActive = false; x.assign(x.size(), 0); return x; } for (int i=0; i < x.size() ; ++i) { x[i] = 0.3*velo*sin(phase); phase += step; while (phase > 2*M_PI) phase -= 2*M_PI; } adsr(x); //apply envelope to x (and updates internal status of adsr) return x; } ...