00001
00002
00003
00004
00005
00006
00007
00008
00010
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00028
00029 #include <Nsound/Buffer.h>
00030 #include <Nsound/Generator.h>
00031 #include <Nsound/RngTausworthe.h>
00032
00033 #include <cmath>
00034 #include <string.h>
00035 #include <iostream>
00036
00037 using namespace Nsound;
00038
00039 using std::cout;
00040 using std::cerr;
00041 using std::endl;
00042
00043 #define M_2PI (2.0*M_PI)
00044
00045 #define CERR_HEADER __FILE__ << ":" << __LINE__ << ": "
00046
00048
00050 Generator::
00051 Generator()
00052 :
00053 last_frequency_(0.0),
00054 position_(0.0),
00055 sample_rate_(0.0),
00056 sample_time_(0.0),
00057 t_(0.0),
00058 waveform_(NULL),
00059 rng_(NULL),
00060 buzz_max_harmonics_(0),
00061 buzz_position_(),
00062 chorus_is_on_(false),
00063 chorus_n_voices_(0),
00064 chorus_position_(),
00065 chorus_factor_(),
00066 sync_is_master_(false),
00067 sync_is_slave_(false),
00068 sync_count_(0),
00069 sync_vector_(),
00070 sync_slaves_()
00071 {
00072 };
00073
00075
00077 Generator::
00078 Generator(const float64 & sample_rate)
00079 :
00080 last_frequency_(0.0),
00081 position_(0.0),
00082 sample_rate_(0.0),
00083 sample_time_(0.0),
00084 t_(0.0),
00085 waveform_(NULL),
00086 rng_(NULL),
00087 buzz_max_harmonics_(0),
00088 buzz_position_(),
00089 chorus_is_on_(false),
00090 chorus_n_voices_(0),
00091 chorus_position_(),
00092 chorus_factor_(),
00093 sync_is_master_(false),
00094 sync_is_slave_(false),
00095 sync_count_(0),
00096 sync_vector_(),
00097 sync_slaves_()
00098 {
00099 ctor(sample_rate);
00100 }
00101
00103
00105 Generator::
00106 Generator(const std::string & wave_filename)
00107 :
00108 last_frequency_(0.0),
00109 position_(0.0),
00110 sample_rate_(0.0),
00111 sample_time_(0.0),
00112 t_(0.0),
00113 waveform_(NULL),
00114 rng_(NULL),
00115 buzz_max_harmonics_(0),
00116 buzz_position_(),
00117 chorus_is_on_(false),
00118 chorus_n_voices_(0),
00119 chorus_position_(),
00120 chorus_factor_(),
00121 sync_is_master_(false),
00122 sync_is_slave_(false),
00123 sync_count_(0),
00124 sync_vector_(),
00125 sync_slaves_()
00126 {
00127 Buffer b(wave_filename);
00128 ctor(b.getLength(), b);
00129 }
00130
00132
00134 Generator::
00135 Generator(const float64 & sample_rate, const Buffer & waveform)
00136 :
00137 last_frequency_(0.0),
00138 position_(0.0),
00139 sample_rate_(0.0),
00140 sample_time_(0.0),
00141 t_(0.0),
00142 waveform_(NULL),
00143 rng_(NULL),
00144 buzz_max_harmonics_(0),
00145 buzz_position_(),
00146 chorus_is_on_(false),
00147 chorus_n_voices_(0),
00148 chorus_position_(),
00149 chorus_factor_(),
00150 sync_is_master_(false),
00151 sync_is_slave_(false),
00152 sync_count_(0),
00153 sync_vector_(),
00154 sync_slaves_()
00155 {
00156 ctor(sample_rate, waveform);
00157 }
00158
00160
00162 Generator::
00163 Generator(const Generator & gen)
00164 :
00165 last_frequency_(0.0),
00166 position_(0.0),
00167 sample_rate_(0.0),
00168 sample_time_(0.0),
00169 t_(0.0),
00170 waveform_(NULL),
00171 rng_(NULL),
00172 buzz_max_harmonics_(0),
00173 buzz_position_(),
00174 chorus_is_on_(false),
00175 chorus_n_voices_(0),
00176 chorus_position_(),
00177 chorus_factor_(),
00178 sync_is_master_(false),
00179 sync_is_slave_(false),
00180 sync_count_(0),
00181 sync_vector_(),
00182 sync_slaves_()
00183 {
00184
00185 *this = gen;
00186 }
00187
00189
00191 Generator::
00192 ~Generator()
00193 {
00194 delete waveform_;
00195 delete rng_;
00196 };
00197
00199
00201 void
00202 Generator::
00203 ctor(const float64 & sample_rate)
00204 {
00205 sample_rate_ = sample_rate;
00206 sample_time_ = 1.0 / sample_rate_;
00207 waveform_ = NULL;
00208 rng_ = new RngTausworthe();
00209 }
00210
00212
00214 void
00215 Generator::
00216 ctor(const float64 & sample_rate, const Buffer & waveform)
00217 {
00218 if(waveform.getLength() != sample_rate)
00219 {
00220 cerr << ERROR_HEADER << "waveform.getLength() != sample_rate ("
00221 << waveform.getLength()
00222 << " != "
00223 << sample_rate
00224 << ")"
00225 << endl;
00226
00227 ctor(sample_rate);
00228 }
00229 else
00230 {
00231 sample_rate_ = sample_rate;
00232 sample_time_ = 1.0 / sample_rate_;
00233 waveform_ = new Buffer(waveform);
00234 rng_ = new RngTausworthe();
00235 }
00236 }
00237
00239 void
00240 Generator::
00241 addSlaveSync(Generator & slave)
00242 {
00243 sync_is_master_ = true;
00244 slave.sync_is_slave_ = true;
00245
00246
00247 std::vector<Generator *>::iterator itor = sync_slaves_.begin();
00248 std::vector<Generator *>::iterator end = sync_slaves_.end();
00249
00250 boolean is_found = false;
00251
00252 while(itor != end)
00253 {
00254 if(*itor == &slave) is_found = true;
00255
00256 ++itor;
00257 }
00258
00259 if(!is_found) sync_slaves_.push_back(&slave);
00260
00261 reset();
00262 }
00263
00265 void
00266 Generator::
00267 buzzInit(const uint32 & max_harmonics)
00268 {
00269 buzz_max_harmonics_ = max_harmonics;
00270 reset();
00271 }
00272
00274 float64
00275 Generator::
00276 buzz(
00277 const float64 & frequency,
00278 const float64 & n_harmonics,
00279 const float64 & phase_offset)
00280 {
00281
00282
00283 float64 n = static_cast<int32>(n_harmonics);
00284
00285 n = fabs(n);
00286 if(n < 1.0) n = 1.0;
00287
00288 float64 two_n_plus_1 = 2.0 * n + 1.0;
00289 float64 scale = static_cast<float64>(0.5) / n;
00290
00291 float64 sign = 1.0;
00292 for(int i = 0; i < n; ++i) sign = -sign;
00293
00294 float64 phase = fabs(phase_offset / static_cast<float64>(2.0));
00295
00296 while(phase >= 0.5) phase -= 0.5;
00297
00298 position_ += (phase - last_frequency_) * sample_rate_;
00299
00300 last_frequency_ = phase;
00301
00302 float64 y;
00303
00304 while(position_ >= sample_rate_) position_ -= sample_rate_;
00305
00306 float64 denom = (*waveform_)[static_cast<int32>(position_ + 0.5)] * sign;
00307
00308 if(fabs(denom) > 1e-12)
00309 {
00310 float64 up_phase = position_ * two_n_plus_1;
00311 while(up_phase >= sample_rate_) up_phase -= sample_rate_;
00312
00313 float64 num = (*waveform_)[static_cast<int32>(up_phase)];
00314
00315 y = (num / denom - static_cast<float64>(1.0)) * scale;
00316 }
00317 else
00318 {
00319 y = 1.0;
00320 }
00321
00322 position_ += 0.5*frequency;
00323
00324 return y;
00325 }
00326
00328 Buffer
00329 Generator::
00330 buzz(
00331 const float64 & duration,
00332 const float64 & frequency,
00333 const float64 & n_harmonics,
00334 const float64 & phase_offset)
00335 {
00336 buzzInit(static_cast<uint32>(n_harmonics));
00337
00338 int32 n_samples = static_cast<int32>(duration * sample_rate_);
00339
00340 Buffer y(n_samples);
00341
00342 for(int i = 0; i < n_samples; ++i)
00343 {
00344 y << buzz(frequency, n_harmonics, phase_offset+0.5);
00345 }
00346
00347 return y;
00348 }
00349
00351 Buffer
00352 Generator::
00353 buzz(
00354 const float64 & duration,
00355 const Buffer & frequencies,
00356 const Buffer & n_harmonics,
00357 const Buffer & phase_offset)
00358 {
00359 buzzInit(static_cast<uint32>(n_harmonics.getMax()));
00360
00361 int32 n_samples = static_cast<int32>(duration * sample_rate_);
00362
00363 Buffer::circular_iterator f = frequencies.cbegin();
00364 Buffer::circular_iterator n = n_harmonics.cbegin();
00365 Buffer::circular_iterator p = phase_offset.cbegin();
00366
00367 Buffer y(n_samples);
00368
00369 for(int32 i = 0; i < n_samples; ++i, ++f, ++n, ++p)
00370 {
00371 y << buzz(*f, *n, *p+0.5);
00372 }
00373
00374 return y;
00375 }
00376
00378 void
00379 Generator::
00380 setChorus(const uint32 n_voices, const float64 & amount)
00381 {
00382 if(n_voices == 0)
00383 {
00384 chorus_is_on_ = false;
00385 return;
00386 }
00387
00388 chorus_is_on_ = true;
00389
00390 chorus_n_voices_ = n_voices;
00391
00392 chorus_factor_.clear();
00393 chorus_position_.clear();
00394
00395 for(uint32 i = 0; i < chorus_n_voices_; ++i)
00396 {
00397 chorus_factor_.push_back(1.0 + rng_->get(-amount, amount));
00398
00399 chorus_position_.push_back(0.0);
00400 }
00401
00402 reset();
00403 }
00404
00406 Buffer
00407 Generator::
00408 drawDecay(const float64 & duration, const float64 & alpha) const
00409 {
00410 if(duration <= 0.0) return Buffer();
00411
00412 Buffer t = drawLine(duration, 0.0, 1.0);
00413
00414 t *= -alpha;
00415
00416 t.exp();
00417
00418 return t;
00419 }
00420
00422 Buffer
00423 Generator::
00424 drawGaussian(
00425 const float64 & duration,
00426 const float64 & mu,
00427 const float64 & sigma,
00428 const boolean & normalize) const
00429 {
00430 if(duration <= 0.0) return Buffer();
00431
00432 float64 variance = sigma * sigma;
00433
00434 Buffer g = drawLine(duration, 0.0, duration);
00435
00436 g -= mu;
00437
00438 g *= g;
00439
00440 g /= (2.0 * variance);
00441
00442 g *= -1.0;
00443
00444 g.exp();
00445
00446 g /= ::sqrt(M_2PI * variance);
00447
00448 if(normalize) g.normalize();
00449
00450 return g;
00451 }
00452
00454 Buffer
00455 Generator::
00456 drawFatGaussian(
00457 const float64 & duration,
00458 const float64 & pass_band_percent) const
00459 {
00460 if(duration <= 0.0) return Buffer();
00461
00462 if(pass_band_percent <= 0.0)
00463 {
00464 std::cerr
00465 << CERR_HEADER
00466 << "drawFatGaussian(): Warning: creating all zero Buffer!"
00467 << std::endl;
00468
00469 return drawLine(duration, 0.0, 0.0);
00470 }
00471
00472 else if(pass_band_percent >= 1.0)
00473 {
00474 std::cerr
00475 << CERR_HEADER
00476 << "drawFatGaussian(): Warning: creating all 1.0 Buffer!"
00477 << std::endl;
00478
00479 return drawLine(duration, 1.0, 1.0);
00480 }
00481
00482 float64 pass_band_time = duration * pass_band_percent;
00483
00484 float64 gauss_time = duration - pass_band_time;
00485
00486 float64 h_gauss_time = gauss_time / 2.0;
00487
00488
00489
00490
00491 float64 sigma = 0.275 * h_gauss_time;
00492
00493 Buffer y;
00494
00495 y << drawGaussian(h_gauss_time, h_gauss_time, sigma)
00496 << drawLine(pass_band_time, 1.0, 1.0)
00497 << drawGaussian(h_gauss_time, 0.0, sigma);
00498
00499 return y;
00500 }
00501
00503 Buffer
00504 Generator::
00505 drawLine(
00506 const float64 & duration,
00507 const float64 & y1,
00508 const float64 & y2) const
00509 {
00510 if(duration <= 0.0) return Buffer();
00511
00512 Buffer buffer;
00513
00514 float64 n_samples = duration * sample_rate_;
00515
00516 float64 slope = (y2 - y1) / n_samples;
00517
00518 float64 current_sample = y1;
00519
00520 for(uint32 i = 0; i < static_cast<uint32>(n_samples+0.5); ++i)
00521 {
00522 buffer << current_sample;
00523 current_sample += slope;
00524 }
00525
00526 return buffer;
00527 }
00528
00530 Buffer
00531 Generator::
00532 drawParabola(
00533 const float64 & duration,
00534 const float64 & y1,
00535 const float64 & x2,
00536 const float64 & y2,
00537 const float64 & y3) const
00538 {
00539 if(duration <= 0.0) return Buffer();
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 if (x2 >= duration)
00570 {
00571 std::cerr
00572 << CERR_HEADER
00573 << "drawParabola(): x2 > duration"
00574 << std::endl;
00575
00576 return Buffer();
00577 }
00578
00579 float64 x3 = duration;
00580
00581 float64 C = y1;
00582
00583 float64 B = ( x2*x2*(y3 - y1) + x3*x3*(y1 - y2) ) / ( x2*x3*(x2 - x3) );
00584
00585 float64 A = (y2 - y1 - B*x2) / (x2*x2);
00586
00587 Buffer t = drawLine(duration, 0.0, duration);
00588
00589 return A*t*t + B*t + C;
00590 }
00591
00593 Buffer
00594 Generator::
00595 drawSine(
00596 const float64 & duration,
00597 const float64 & frequency)
00598 {
00599 if(duration <= 0.0) return Buffer();
00600
00601 t_ = 0.0;
00602
00603 Buffer y;
00604
00605 uint64 n_samples = static_cast<uint64>(duration * sample_rate_ + 0.5);
00606
00607 for(uint64 i = 0; i < n_samples; ++i)
00608 {
00609 y << drawSine2(frequency, 0.0);
00610 }
00611
00612 return y;
00613 }
00614
00616 Buffer
00617 Generator::
00618 drawSine(
00619 const float64 & duration,
00620 const Buffer & frequency)
00621 {
00622 if(duration <= 0.0) return Buffer();
00623
00624 t_ = 0.0;
00625
00626 Buffer y;
00627
00628 uint64 n_samples = static_cast<uint64>(duration * sample_rate_ + 0.5);
00629
00630 Buffer::circular_iterator f = frequency.cbegin();
00631
00632 for(uint64 i = 0; i < n_samples; ++i)
00633 {
00634 y << drawSine2(*f, 0.0);
00635 ++f;
00636 }
00637
00638 return y;
00639 }
00640
00642 Buffer
00643 Generator::
00644 drawSine2(
00645 const float64 & duration,
00646 const float64 & frequency,
00647 const float64 & phase)
00648 {
00649 if(duration <= 0.0) return Buffer();
00650
00651 t_ = 0.0;
00652
00653 Buffer y;
00654
00655 uint64 n_samples = static_cast<uint64>(duration * sample_rate_ + 0.5);
00656
00657 for(uint64 i = 0; i < n_samples; ++i)
00658 {
00659 y << drawSine2(frequency, phase);
00660 }
00661
00662 return y;
00663 }
00664
00666 Buffer
00667 Generator::
00668 drawSine2(
00669 const float64 & duration,
00670 const Buffer & frequency,
00671 const Buffer & phase)
00672 {
00673 if(duration <= 0.0) return Buffer();
00674
00675 t_ = 0.0;
00676
00677 Buffer y;
00678
00679 uint64 n_samples = static_cast<uint64>(duration * sample_rate_ + 0.5);
00680
00681 Buffer::circular_iterator f = frequency.cbegin();
00682 Buffer::circular_iterator p = phase.cbegin();
00683
00684 for(uint64 i = 0; i < n_samples; ++i)
00685 {
00686 y << drawSine2(*f, *p);
00687 ++f;
00688 ++p;
00689 }
00690
00691 return y;
00692 }
00693
00695 Buffer
00696 Generator::
00697 drawSine2(
00698 const float64 & duration,
00699 const Buffer & frequency,
00700 const float64 & phase)
00701 {
00702 Buffer p(1);
00703 p << phase;
00704
00705 return drawSine2(duration, frequency, p);
00706 }
00707
00709 Buffer
00710 Generator::
00711 drawSine2(
00712 const float64 & duration,
00713 const float64 & frequency,
00714 const Buffer & phase)
00715 {
00716 Buffer f(1);
00717 f << frequency;
00718
00719 return drawSine2(duration, f, phase);
00720 }
00721
00723 float64
00724 Generator::
00725 drawSine2(const float64 & frequency, const float64 & phase)
00726 {
00727 float64 f = 0.0;
00728 float64 sample = 0.0;
00729
00730 if(chorus_is_on_)
00731 {
00732 for(uint32 i = 0; i < chorus_n_voices_; ++i)
00733 {
00734 f = M_2PI * chorus_position_[i] * sample_time_ + M_PI * phase;
00735 sample += ::sin(f);
00736 chorus_position_[i] += frequency * chorus_factor_[i];
00737 }
00738 sample /= static_cast<float64>(chorus_n_voices_);
00739 }
00740 else
00741 {
00742 sample = ::sin(M_2PI * t_ * sample_time_ + M_PI * phase);
00743 t_ += frequency;
00744 }
00745
00746 return sample;
00747 }
00748
00750 float64
00751 Generator::
00752 drawSine(const float64 & frequency)
00753 {
00754 return drawSine2(frequency, 0.0);
00755 }
00756
00757
00759 Buffer
00760 Generator::
00761 drawWindow(const float64 & duration, WindowType type) const
00762 {
00763 switch(type)
00764 {
00765 case BARTLETT: return drawWindowBartlett(duration);
00766 case BLACKMAN: return drawWindowBlackman(duration);
00767 case BLACKMAN_HARRIS: return drawWindowBlackmanHarris(duration);
00768 case GAUSSIAN: return drawGaussian(duration, duration/2.0, 1.0);
00769 case GAUSSIAN_05: return drawFatGaussian(duration, 0.05);
00770 case GAUSSIAN_10: return drawFatGaussian(duration, 0.10);
00771 case GAUSSIAN_15: return drawFatGaussian(duration, 0.15);
00772 case GAUSSIAN_20: return drawFatGaussian(duration, 0.20);
00773 case GAUSSIAN_25: return drawFatGaussian(duration, 0.25);
00774 case GAUSSIAN_30: return drawFatGaussian(duration, 0.30);
00775 case GAUSSIAN_33: return drawFatGaussian(duration, 0.3333);
00776 case GAUSSIAN_35: return drawFatGaussian(duration, 0.35);
00777 case GAUSSIAN_40: return drawFatGaussian(duration, 0.40);
00778 case GAUSSIAN_45: return drawFatGaussian(duration, 0.45);
00779 case GAUSSIAN_50: return drawFatGaussian(duration, 0.50);
00780 case GAUSSIAN_55: return drawFatGaussian(duration, 0.55);
00781 case GAUSSIAN_60: return drawFatGaussian(duration, 0.60);
00782 case GAUSSIAN_65: return drawFatGaussian(duration, 0.65);
00783 case GAUSSIAN_66: return drawFatGaussian(duration, 0.6666);
00784 case GAUSSIAN_70: return drawFatGaussian(duration, 0.70);
00785 case GAUSSIAN_75: return drawFatGaussian(duration, 0.75);
00786 case GAUSSIAN_80: return drawFatGaussian(duration, 0.80);
00787 case GAUSSIAN_85: return drawFatGaussian(duration, 0.85);
00788 case GAUSSIAN_90: return drawFatGaussian(duration, 0.90);
00789 case GAUSSIAN_95: return drawFatGaussian(duration, 0.95);
00790 case GAUSSIAN_99: return drawFatGaussian(duration, 0.9999);
00791 case HAMMING: return drawWindowHamming(duration);
00792 case HANNING: return drawWindowHanning(duration);
00793 case KAISER: return drawWindowKaiser(duration);
00794 case NUTTALL: return drawWindowNuttall(duration);
00795 case PARZEN: return drawWindowParzen(duration);
00796 case RECTANGULAR: return drawWindowRectangular(duration);
00797 }
00798
00799 return drawWindowRectangular(duration);
00800 }
00801
00803 static
00804 void
00805 cosinewindow(
00806 Buffer & win,
00807 const float64 & a0,
00808 const float64 & a1,
00809 const float64 & a2,
00810 const float64 & a3)
00811 {
00812 int32 n = win.getLength();
00813 for(int32 i = 0; i < n; ++i)
00814 {
00815 win[i] *= a0
00816 - a1 * ::cos(2.0 * M_PI * i / n)
00817 + a2 * ::cos(4.0 * M_PI * i / n)
00818 - a3 * ::cos(6.0 * M_PI * i / n);
00819 }
00820 }
00821
00823 Buffer
00824 Generator::
00825 drawWindowBartlett(const float64 & duration) const
00826 {
00827 Buffer window = drawLine(duration, 1.0, 1.0);
00828
00829 int32 n = static_cast<int32>(duration * sample_rate_);
00830
00831 float64 n_over_2 = static_cast<float64>(n / 2);
00832
00833 for(int32 i = 0; i < n / 2; ++i)
00834 {
00835 float64 t = static_cast<float64>(i) / n_over_2;
00836 window[i] *= t;
00837 window[i + n/2] *= 1.0 - t;
00838 }
00839
00840 return window;
00841 }
00842
00844 Buffer
00845 Generator::
00846 drawWindowBlackman(const float64 & duration) const
00847 {
00848 Buffer window = drawLine(duration, 1.0, 1.0);
00849
00850 cosinewindow(window, 0.42, 0.50, 0.08, 0.00);
00851
00852 return window;
00853 }
00854
00856 Buffer
00857 Generator::
00858 drawWindowBlackmanHarris(const float64 & duration) const
00859 {
00860 Buffer window = drawLine(duration, 1.0, 1.0);
00861
00862 cosinewindow(window, 0.35875, 0.48829, 0.14128, 0.01168);
00863
00864 return window;
00865 }
00866
00867
00869 Buffer
00870 Generator::
00871 drawWindowHamming(const float64 & duration) const
00872 {
00873 Buffer window = drawLine(duration, 1.0, 1.0);
00874
00875 cosinewindow(window, 0.54, 0.46, 0.00, 0.00);
00876
00877 return window;
00878 }
00879
00881 Buffer
00882 Generator::
00883 drawWindowHanning(const float64 & duration) const
00884 {
00885 Buffer window = drawLine(duration, 1.0, 1.0);
00886
00887 cosinewindow(window, 0.50, 0.50, 0.00, 0.00);
00888
00889 return window;
00890 }
00891
00893
00894
00895
00896
00897
00898
00899
00900
00901 float64
00902 bessel_i0(const float64 & x)
00903 {
00904 const float64 p1 = 1.0,
00905 p2 = 3.5156229,
00906 p3 = 3.0899424,
00907 p4 = 1.2067492,
00908 p5 = 0.2659732,
00909 p6 = 3.60768e-2,
00910 p7 = 4.5813e-3;
00911
00912 const float64 q1 = 0.39894228,
00913 q2 = 1.328592e-2,
00914 q3 = 2.25319e-3,
00915 q4 = -1.57565e-3,
00916 q5 = 9.16281e-3,
00917 q6 = -2.057706e-2,
00918 q7 = 2.635537e-2,
00919 q8 = -1.647633e-2,
00920 q9 = 3.92377e-3;
00921
00922 float64 ax = ::fabs(x);
00923
00924 float64 y = 0.0,
00925 result = 0.0;
00926
00927 if (ax < 3.75)
00928 {
00929 y = ::pow(x / 3.75, 2);
00930 result = p1+y*(p2+y*(p3+y*(p4+y*(p5+y*(p6+y*p7)))));
00931 }
00932 else
00933 {
00934 y = 3.75 / ax;
00935 result = (::exp(ax) / ::sqrt(ax))
00936 * (q1+y*(q2+y*(q3+y*(q4+y*(q5+y*(q6+y*(q7+y*(q8+y*q9))))))));
00937 }
00938 return result;
00939 }
00940
00941
00943 Buffer
00944 Generator::
00945 drawWindowKaiser(const float64 & duration, const float64 & beta) const
00946 {
00947 Buffer window = drawLine(duration, 0.0, 0.0);
00948
00949 int32 n_samples = window.getLength();
00950 float64 f_n_samples = float64(n_samples);
00951
00952 float64 b = ::fabs(beta);
00953
00954 if(b < 1.0)
00955 {
00956 b = 1.0;
00957 }
00958
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 float64 alpha = f_n_samples / 2.0;
00972
00973 float64 denominator = bessel_i0(b);
00974
00975 for(int32 i = 0 ; i < n_samples; ++i)
00976 {
00977 float64 temp = (float64(i) - alpha) / alpha;
00978 temp *= temp;
00979
00980 window[i] = bessel_i0( b * ::sqrt(1.0 - temp)) / denominator;
00981 }
00982
00983 return window;
00984 }
00985
00987 Buffer
00988 Generator::
00989 drawWindowNuttall(const float64 & duration) const
00990 {
00991 Buffer window = drawLine(duration, 1.0, 1.0);
00992
00993 cosinewindow(window, 0.3635819, 0.4891775, 0.1365995, 0.0106411);
00994
00995 return window;
00996 }
00997
00999 Buffer
01000 Generator::
01001 drawWindowParzen(const float64 & duration) const
01002 {
01003 Buffer window = drawLine(duration, 1.0, 1.0);
01004
01005 int32 n = static_cast<int32>(duration * sample_rate_);
01006
01007 int32 N = n -1;
01008
01009 float64 Nf = static_cast<float64>(N);
01010
01011 for(int32 i = 0; i < N / 4; ++i)
01012 {
01013 float64 m = 2 * ::pow(1.0 - (Nf / 2 - i) / (Nf / 2), 3.0);
01014 window[i] *= m;
01015 window[N - i] *= m;
01016 }
01017
01018 for(int32 i = N/4; i <= N/2; ++i)
01019 {
01020 int32 wn = i - N/2;
01021 float64 m = 1.0
01022 - 6.0 * ::pow(wn / (Nf/2),2.0)
01023 * (1.0 - ::fabs(wn) / (Nf/2));
01024
01025 window[i] *= m;
01026 window[N-i] *= m;
01027 }
01028
01029 return window;
01030 }
01031
01033 Buffer
01034 Generator::
01035 drawWindowRectangular(const float64 & duration) const
01036 {
01037 return drawLine(duration, 1.0, 1.0);
01038 }
01039
01041 float64
01042 Generator::
01043 generate(const float64 & frequency)
01044 {
01045 return generate2(frequency, 0.0);
01046 }
01047
01049 float64
01050 Generator::
01051 generate2(const float64 & frequency, const float64 & phase)
01052 {
01053 if(waveform_ == NULL) return 0.0;
01054
01055 ++sync_count_;
01056
01057 if(sync_is_slave_ && !sync_vector_.empty())
01058 {
01059 uint32 sync_count = sync_vector_.front();
01060
01061 if(sync_count_ == sync_count)
01062 {
01063 sync_vector_.erase(sync_vector_.begin());
01064 position_ = 0;
01065 }
01066 }
01067
01068
01069 float64 ph = (phase * sample_rate_ / 2.0);
01070 float64 position2 = position_ + ph + 0.5;
01071
01072
01073 while(position2 >= sample_rate_)
01074 {
01075 position2 -= sample_rate_;
01076 }
01077
01078 while(position2 < 0.0)
01079 {
01080 position2 += sample_rate_;
01081 }
01082
01083 float64 sample = 0.0;
01084
01085 if(chorus_is_on_)
01086 {
01087 for(uint32 i = 0; i < chorus_n_voices_; ++i)
01088 {
01089 float64 pos = chorus_position_[i]
01090 + chorus_factor_[i] * frequency
01091 + ph
01092 + 0.5;
01093
01094
01095 while(pos >= sample_rate_) pos -= sample_rate_;
01096 while(pos < 0) pos += sample_rate_;
01097
01098 sample += (*waveform_)[static_cast<uint64>(pos)];
01099
01100 chorus_position_[i] += frequency * chorus_factor_[i];
01101 }
01102
01103 sample /= static_cast<float64>(chorus_n_voices_);
01104 }
01105 else
01106 {
01107 sample = (*waveform_)[static_cast<uint64>(position2)];
01108 }
01109
01110 position_ += frequency;
01111
01112 return sample;
01113 }
01114
01116 Buffer
01117 Generator::
01118 generate(
01119 const float64 & duration,
01120 const float64 & frequency,
01121 bool reset_first)
01122 {
01123 if(duration <= 0.0) return Buffer();
01124
01125 if(reset_first)
01126 {
01127 reset();
01128 }
01129
01130 Buffer buffer;
01131
01132 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01133
01134 for(uint64 i = 0; i < n_samples; ++i)
01135 {
01136 buffer << generate(frequency);
01137 }
01138
01139 return buffer;
01140 }
01141
01143 Buffer
01144 Generator::
01145 generate2(
01146 const float64 & duration,
01147 const float64 & frequency,
01148 const float64 & phase,
01149 bool reset_first)
01150 {
01151 if(duration <= 0.0) return Buffer();
01152
01153 if(reset_first)
01154 {
01155 reset();
01156 }
01157
01158 Buffer buffer;
01159
01160 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01161
01162 for(uint64 i = 0; i < n_samples; ++i)
01163 {
01164 buffer << generate2(frequency, phase);
01165 }
01166
01167 return buffer;
01168 }
01169
01171 Buffer
01172 Generator::
01173 generate(
01174 const float64 & duration,
01175 const Buffer & frequencies,
01176 bool reset_first)
01177 {
01178 if(duration <= 0.0) return Buffer();
01179
01180 if(reset_first)
01181 {
01182 reset();
01183 }
01184
01185 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01186
01187 Buffer y(n_samples);
01188
01189 Buffer::circular_iterator freq = frequencies.cbegin();
01190
01191 for(uint64 i = 0; i < n_samples; ++i, ++freq)
01192 {
01193 y << generate(*freq);
01194 }
01195
01196 return y;
01197 }
01198
01200 Buffer
01201 Generator::
01202 generate2(
01203 const float64 & duration,
01204 const float64 & frequency,
01205 const Buffer & phase,
01206 bool reset_first)
01207 {
01208 if(duration <= 0.0) return Buffer();
01209
01210 if(reset_first)
01211 {
01212 reset();
01213 }
01214
01215 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01216
01217 Buffer y(n_samples);
01218
01219 Buffer::circular_iterator p = phase.cbegin();
01220
01221 for(uint64 i = 0; i < n_samples; ++i, ++p)
01222 {
01223 y << generate2(frequency,*p);
01224 }
01225
01226 return y;
01227 }
01228
01230 Buffer
01231 Generator::
01232 generate2(
01233 const float64 & duration,
01234 const Buffer & frequencies,
01235 const float64 & phase,
01236 bool reset_first)
01237 {
01238 if(duration <= 0.0) return Buffer();
01239
01240 if(reset_first)
01241 {
01242 reset();
01243 }
01244
01245 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01246
01247 Buffer y(n_samples);
01248
01249 Buffer::circular_iterator f = frequencies.cbegin();
01250
01251 for(uint64 i = 0; i < n_samples; ++i, ++f)
01252 {
01253 y << generate2(*f, phase);
01254 }
01255
01256 return y;
01257 }
01258
01260 Buffer
01261 Generator::
01262 generate2(
01263 const float64 & duration,
01264 const Buffer & frequencies,
01265 const Buffer & phase,
01266 bool reset_first)
01267 {
01268 if(duration <= 0.0) return Buffer();
01269
01270 if(reset_first)
01271 {
01272 reset();
01273 }
01274
01275 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01276
01277 Buffer y(n_samples);
01278
01279 Buffer::circular_iterator f = frequencies.cbegin();
01280 Buffer::circular_iterator p = phase.cbegin();
01281
01282 for(uint64 i = 0; i < n_samples; ++i, ++f, ++p)
01283 {
01284 y << generate2(*f,*p);
01285 }
01286
01287 return y;
01288 }
01289
01291 Generator &
01292 Generator::
01293 operator=(const Generator & rhs)
01294 {
01295
01296 if(this == &rhs)
01297 {
01298 return *this;
01299 }
01300
01301 last_frequency_ = rhs.last_frequency_;
01302 position_ = rhs.position_;
01303 sample_rate_ = rhs.sample_rate_;
01304 sample_time_ = rhs.sample_time_;
01305 t_ = rhs.t_;
01306
01307 if(waveform_ != NULL && rhs.waveform_ != NULL)
01308 {
01309 *waveform_ = *rhs.waveform_;
01310 }
01311 else if(waveform_ == NULL && rhs.waveform_ != NULL)
01312 {
01313 waveform_ = new Buffer(*rhs.waveform_);
01314 }
01315 else if(waveform_ != NULL && rhs.waveform_ == NULL)
01316 {
01317 delete waveform_;
01318 waveform_ = NULL;
01319 }
01320
01321 *rng_ = *rhs.rng_;
01322
01323 buzz_max_harmonics_ = rhs.buzz_max_harmonics_;
01324 buzz_position_ = rhs.buzz_position_;
01325
01326 chorus_is_on_ = rhs.chorus_is_on_;
01327 chorus_n_voices_ = rhs.chorus_n_voices_;
01328 chorus_position_ = rhs.chorus_position_;
01329 chorus_factor_ = rhs.chorus_factor_;
01330
01331 sync_is_master_ = rhs.sync_is_master_;
01332 sync_is_slave_ = rhs.sync_is_slave_;
01333 sync_count_ = rhs.sync_count_;
01334 sync_vector_ = rhs.sync_vector_;
01335 sync_slaves_ = rhs.sync_slaves_;
01336
01337 return *this;
01338 }
01339
01341 void
01342 Generator::
01343 removeSlaveSync(Generator & slave)
01344 {
01345 slave.sync_is_slave_ = false;
01346
01347 std::vector<Generator *>::iterator itor = sync_slaves_.begin();
01348 std::vector<Generator *>::iterator end = sync_slaves_.end();
01349
01350 while(*itor != (&slave))
01351 {
01352 ++itor;
01353 }
01354
01355 if(*itor == (&slave))
01356 {
01357 sync_slaves_.erase(itor);
01358 }
01359
01360 reset();
01361 }
01362
01363
01365 void
01366 Generator::
01367 reset()
01368 {
01369 position_ = 0.0;
01370 last_frequency_ = -1.0;
01371 sync_count_ = 0;
01372 t_ = 0.0;
01373
01374 buzz_position_.reserve(buzz_max_harmonics_);
01375
01376 for(uint32 i = 0; i < buzz_max_harmonics_; ++i)
01377 {
01378 buzz_position_[i] = 0.0;
01379 }
01380
01381 for(uint32 i = 0; i < chorus_n_voices_; ++i)
01382 {
01383 chorus_position_[i] = 0.0;
01384 }
01385
01386 for(uint32 i = 0; i < sync_slaves_.size(); ++i)
01387 {
01388 sync_slaves_[i]->sync_vector_.clear();
01389 }
01390 }
01391
01393 void
01394 Generator::
01395 setSeed(const uint32 seed)
01396 {
01397 rng_->setSeed(seed);
01398 }
01399
01401 Buffer
01402 Generator::
01403 silence(const float64 & duration) const
01404 {
01405 if(duration <= 0.0) return Buffer();
01406
01407 return drawLine(duration,0.0,0.0);
01408 }
01409
01411 float64
01412 Generator::
01413 tell() const
01414 {
01415 return position_ / sample_rate_;
01416 }
01417
01418
01420 Buffer
01421 Generator::
01422 whiteNoise(const float64 & duration) const
01423 {
01424 if(duration <= 0.0) return Buffer();
01425
01426 Buffer buffer;
01427
01428 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01429
01430 for(uint64 i = 0; i < n_samples; ++i)
01431 {
01432 buffer << rng_->get(-1.0f,1.0f);
01433 }
01434
01435 return buffer;
01436 }
01437
01439 Buffer
01440 Generator::
01441 gaussianNoise(
01442 const float64 & duration,
01443 const float64 & mu,
01444 const float64 & sigma) const
01445 {
01446 if(duration <= 0.0) return Buffer();
01447
01448 Buffer buffer;
01449
01450 uint32 n_samples = static_cast<uint32>(std::ceil(duration * sample_rate_));
01451
01452
01453
01454 uint32 i = 0;
01455 while(true)
01456 {
01457 float64 f = 0.0;
01458 float64 x1 = 0.0;
01459 float64 x2 = 0.0;
01460 float64 r2 = 0.0;
01461
01462 while(r2 == 0.0 || r2 >= 1.0)
01463 {
01464 x1 = rng_->get(-1.0f, 1.0f);
01465 x2 = rng_->get(-1.0f, 1.0f);
01466 r2 = x1 * x1 + x2 * x2;
01467 }
01468
01469 f = ::sqrt(-2.0 * ::log(r2) / r2);
01470
01471 buffer << mu + sigma * f * x1;
01472
01473 ++i;
01474
01475 if(i >= n_samples)
01476 {
01477 break;
01478 }
01479
01480 buffer << mu + sigma * f * x2;
01481
01482 ++i;
01483
01484 if(i >= n_samples)
01485 {
01486 break;
01487 }
01488 }
01489
01490 return buffer;
01491 }
01492
01494 Buffer
01495 Generator::
01496 tanh(const float64 & duration) const
01497 {
01498 if(duration <= 0.0) return Buffer();
01499
01500 Buffer buffer;
01501
01502 uint64 n_samples = static_cast<uint64>(std::ceil(duration * sample_rate_));
01503
01504 float64 step = (2.0 * M_PI) / n_samples;
01505
01506 float64 x = -1.0 * M_PI;
01507
01508 for(uint64 i = 0; i < n_samples; ++i)
01509 {
01510 buffer << std::tanh(x);
01511 x += step;
01512 }
01513
01514 return buffer;
01515 }