rendered paste body
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<wave_period> 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<wave_period> periods;
unsigned int sample_rate;
};