class wave { public: wave(unsigned int sr=22050) { sample_rate = sr; } // Frequency is in hertz // Amplitude is in seconds // Duration is in seconds void resonate(double frequency, double amplitude, double duration, double octave, waveform wf) { frequency /= pow(2.0, octave); // Frequency is periods-per-second, and duration is in seconds. int total_periods = frequency * duration; if(!total_periods) total_periods = 1; int total_samples = total_periods * (sample_rate/frequency); int samples_per_period = total_samples / total_periods; double seconds_per_sample = duration / total_samples; wave_period source_period; switch(wf) // Generate a source period by the waveform. { case sawtooth_wave: { double incrementor = amplitude / samples_per_period/2; for(int j=-samples_per_period/2; j < samples_per_period/2; ++j) { int sample_buf = incrementor*j; source_period.push_back(sample_buf); } } break; case square_wave: { double incrementor = amplitude / samples_per_period/2; for(int j=-samples_per_period/2; j < samples_per_period/2; ++j) { int sample_buf = incrementor*j; source_period.push_back(sample_buf); } } break; case sine_wave: { std::vector periods; double incrementor = amplitude / samples_per_period; for(int j=0; j < samples_per_period; ++j) { static const double pi = 3.14159265358979323846; static const double rad360 = 360.0*(pi/180.0); double t = seconds_per_sample*j; int sample_buf = amplitude*sin(2*pi*frequency*t); source_period.push_back(sample_buf); } } break; } // Duplicate the source period to fulfill duration. periods.insert(periods.end(), total_periods, source_period); } std::vector periods; unsigned int sample_rate; };