wip: oscillator class
This commit is contained in:
8
inc/Note.h
Normal file
8
inc/Note.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct Note {
|
||||||
|
std::string& name;
|
||||||
|
int length;
|
||||||
|
}
|
||||||
38
inc/Oscillator.h
Normal file
38
inc/Oscillator.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
#include<vector>
|
||||||
|
#include "OscillatorType.h"
|
||||||
|
|
||||||
|
typedef float (Oscillator::*OscFunction)(void);
|
||||||
|
typedef float (Oscillator::*DtFunction)(float);
|
||||||
|
|
||||||
|
class Oscillator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
OscillatorType m_osc;
|
||||||
|
float m_freq;
|
||||||
|
float m_volume;
|
||||||
|
float m_phase;
|
||||||
|
float m_phase_dt;
|
||||||
|
OscFunction m_osc_function;
|
||||||
|
DtFunction m_dt_function;
|
||||||
|
void sine_osc_phase_incr();
|
||||||
|
void saw_osc_phase_incr();
|
||||||
|
float calc_saw_phase_delta(float freq);
|
||||||
|
float calc_sine_phase_delta(float freq);
|
||||||
|
float sawosc();
|
||||||
|
float triangleosc();
|
||||||
|
float squareosc();
|
||||||
|
float sign(float v);
|
||||||
|
float sineosc();
|
||||||
|
public:
|
||||||
|
Oscillator(OscillatorType osc, float freq, float volume);
|
||||||
|
~Oscillator();
|
||||||
|
OscillatorType GetType() { return m_osc; }
|
||||||
|
void SetType(OscillatorType osc);
|
||||||
|
float GetVolume() { return m_volume; }
|
||||||
|
void SetVolume(float volume) { m_volume = volume; }
|
||||||
|
float GetFreq() { return m_freq; }
|
||||||
|
void SetFreq(float freq);
|
||||||
|
void Reset();
|
||||||
|
float GenerateSample(float duration);
|
||||||
|
};
|
||||||
7
inc/OscillatorType.h
Normal file
7
inc/OscillatorType.h
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#pragma once
|
||||||
|
typedef enum {
|
||||||
|
Sine,
|
||||||
|
Triangle,
|
||||||
|
Saw,
|
||||||
|
Square
|
||||||
|
} OscillatorType;
|
||||||
16
inc/Settings.h
Normal file
16
inc/Settings.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define SAMPLE_RATE 48000.f
|
||||||
|
#define BPM 120.f
|
||||||
|
#define BEAT_DURATION 60.f/BPM
|
||||||
|
#define PITCH_STANDARD 440.f
|
||||||
|
#define VOLUME 0.5f
|
||||||
|
#define ATTACK_MS 100.f
|
||||||
|
#define STREAM_BUFFER_SIZE 4096
|
||||||
|
|
||||||
|
#define SYNTH_PI 3.1415926535f
|
||||||
|
#define SYNTH_VOLUME 0.5f
|
||||||
|
|
||||||
|
#define WINDOW_WIDTH 640
|
||||||
|
#define WINDOW_HEIGHT 480
|
||||||
|
#define OSCILLATOR_PANEL_WIDTH 200
|
||||||
103
src/Oscillator.cpp
Normal file
103
src/Oscillator.cpp
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
#include "Oscillator.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#define TWO_PI 2*SYNTH_PI
|
||||||
|
|
||||||
|
Oscillator::Oscillator(OscillatorType osc, float freq, float volume)
|
||||||
|
{
|
||||||
|
SetType(osc);
|
||||||
|
m_freq = freq;
|
||||||
|
m_volume = volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
Oscillator::~Oscillator()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oscillator::Reset()
|
||||||
|
{
|
||||||
|
m_volume = 0;
|
||||||
|
m_phase = 0;
|
||||||
|
m_phase_dt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oscillator::SetType(OscillatorType osc)
|
||||||
|
{
|
||||||
|
m_osc = osc;
|
||||||
|
switch (m_osc) {
|
||||||
|
case Sine:
|
||||||
|
m_osc_function = &sineosc;
|
||||||
|
m_dt_function = &calc_sine_phase_delta;
|
||||||
|
break;
|
||||||
|
case Triangle:
|
||||||
|
m_osc_function = &triangleosc;
|
||||||
|
m_dt_function = &calc_saw_phase_delta;
|
||||||
|
break;
|
||||||
|
case Square:
|
||||||
|
m_osc_function = &squareosc;
|
||||||
|
m_dt_function = &calc_sine_phase_delta;
|
||||||
|
break;
|
||||||
|
case Saw:
|
||||||
|
m_osc_function = &sawosc;
|
||||||
|
m_dt_function = &calc_saw_phase_delta;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oscillator::SetFreq(float freq)
|
||||||
|
{
|
||||||
|
m_freq = freq;
|
||||||
|
m_phase = 0;
|
||||||
|
m_phase_dt = m_dt_function(freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::GenerateSample(float duration)
|
||||||
|
{
|
||||||
|
return m_osc_function() * m_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oscillator::sine_osc_phase_incr() {
|
||||||
|
m_phase += m_phase_dt;
|
||||||
|
if (m_phase >= TWO_PI)
|
||||||
|
m_phase -= TWO_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Oscillator::saw_osc_phase_incr() {
|
||||||
|
m_phase += m_phase_dt;
|
||||||
|
if (m_phase >= 1.0f)
|
||||||
|
m_phase -= 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::calc_saw_phase_delta(float freq) {
|
||||||
|
return freq / SAMPLE_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::calc_sine_phase_delta(float freq) {
|
||||||
|
return (TWO_PI * freq) / SAMPLE_RATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::sineosc() {
|
||||||
|
float result = sinf(m_phase);
|
||||||
|
sine_osc_phase_incr();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::sign(float v) {
|
||||||
|
return (v > 0.0) ? 1.f : -1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::squareosc() {
|
||||||
|
return sign(sineosc());
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::triangleosc() {
|
||||||
|
float result = 1.f - fabsf(m_phase - 0.5f) * 4.f;
|
||||||
|
saw_osc_phase_incr();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Oscillator::sawosc() {
|
||||||
|
float result = m_phase * 2.f - 1.f;
|
||||||
|
saw_osc_phase_incr();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user