mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
136 lines
2.9 KiB
C++
136 lines
2.9 KiB
C++
#ifndef _Synth_Synth_h
|
|
#define _Synth_Synth_h
|
|
|
|
#include <Core/Core.h>
|
|
|
|
using namespace Upp;
|
|
|
|
enum FORMS {
|
|
WAVEFORM_SIN = 0,
|
|
WAVEFORM_SQUARE = 1,
|
|
WAVEFORM_TRIANGLE = 2,
|
|
WAVEFORM_SAWTOOTH = 3,
|
|
|
|
WAVEFORM_FIRSTSAMPLE = 4,
|
|
WAVEFORM_SAXOPHONE = WAVEFORM_FIRSTSAMPLE,
|
|
WAVEFORM_VIOLIN = 5,
|
|
WAVEFORM_DOUBLEBASS = 6,
|
|
WAVEFORM_BANJO = 7,
|
|
WAVEFORM_TRUMPET = 8,
|
|
WAVEFORM_LASTSAMPLE = 8,
|
|
|
|
WAVEFORM_BROWN = 100,
|
|
WAVEFORM_WHITE = 101,
|
|
};
|
|
|
|
struct FMOP {
|
|
double duration = 99000;
|
|
double volume = 0;
|
|
|
|
double f = 1;
|
|
double fdrift = 0;
|
|
|
|
double attack = 100;
|
|
double decay = 100;
|
|
double sustain = 100;
|
|
double release = 100;
|
|
|
|
int waveform = WAVEFORM_SIN;
|
|
|
|
String Save() const;
|
|
const char *Load(const char *s);
|
|
};
|
|
|
|
#define OPCOUNT 5
|
|
|
|
struct Sound {
|
|
double f = 440;
|
|
FMOP op[OPCOUNT];
|
|
double pan = 0.5;
|
|
|
|
String Save() const;
|
|
void Load(const char *s);
|
|
|
|
Sound();
|
|
};
|
|
|
|
struct SoundGen {
|
|
struct FMOPGen : FMOP {
|
|
int p;
|
|
double v;
|
|
double n;
|
|
double *wave_tab;
|
|
|
|
void Start() { v = 1e-3; p = 0; n = 0; }
|
|
void Comp();
|
|
String ToString() const;
|
|
|
|
double Evaluate(int t, double mf, double mod, double& current_volume);
|
|
};
|
|
|
|
int serial;
|
|
int param_serial;
|
|
int id;
|
|
int priority;
|
|
double f = 440;
|
|
float lpan = 0.5f;
|
|
float rpan = 0.5f;
|
|
int t;
|
|
int delay;
|
|
FMOPGen op[OPCOUNT];
|
|
float feedback[8192];
|
|
double current_volume = 0;
|
|
double lfo_mod = 0;
|
|
|
|
void Start(const Sound& s);
|
|
float Get();
|
|
String ToString() const;
|
|
};
|
|
|
|
#define CHUNK_SIZE 512
|
|
#define NUM_CHANNELS 20
|
|
|
|
void InitSoundSynth(bool initsdl = true);
|
|
void CloseSoundSynth(bool exitsdl = true);
|
|
|
|
void SetChannel(int chi, const Sound& c, int priority = INT_MAX, int id = 0);
|
|
void SetChannelVolume(int chi, double volume);
|
|
void StopChannelById(int id);
|
|
int FindChannel(int priority, int from, double new_volume);
|
|
void StopChannels(int id);
|
|
|
|
void SetGlobalVolume(float vol);
|
|
|
|
struct SoundEvent : Moveable<SoundEvent> {
|
|
Sound *snd;
|
|
float duration;
|
|
float frequency;
|
|
float volume;
|
|
};
|
|
|
|
struct SoundSequence {
|
|
mutable int at = 0;
|
|
int cursor = 0;
|
|
int loop = Null;
|
|
ArrayMap<String, Sound> bank;
|
|
Vector<Vector<SoundEvent>> event;
|
|
|
|
int GetAt(double at) { return (int)(at * 44100 / 512); }
|
|
Vector<SoundEvent>& At(double at) { return event.At(GetAt(at)); }
|
|
void LoopAt(double at) { loop = GetAt(at); }
|
|
int SoundIndex(const String& s);
|
|
void Put(double at, int i,
|
|
double volume, double freqency, double duration, bool direct = false);
|
|
void Put(double at, const String& snd,
|
|
double volume, double freqency, double duration, bool direct = false);
|
|
};
|
|
|
|
void PlaySequence(const SoundSequence& s);
|
|
void PlayTempSequence(SoundSequence&& s);
|
|
|
|
void StopSequencer();
|
|
bool IsPlayingSequence();
|
|
|
|
SoundSequence ParseQSF(const String& data);
|
|
|
|
#endif
|