CyberMatris port for Miyoo Mini Plus
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

125 lines
3.0 KiB

#pragma once
#include <SDL2/SDL.h>
#include <mutex>
#include <vector>
enum class WaveType {
SINE,
SQUARE,
TRIANGLE,
NOISE
};
enum class ChordType {
AM,
E7,
DM,
F,
G,
C
};
struct Envelope {
float attackTime = 0.005f; // seconds
float decayTime = 0.05f; // seconds
float sustainLevel = 0.7f; // 0.0 to 1.0
float releaseTime = 0.12f; // seconds
};
struct Voice {
bool active = false;
WaveType wave = WaveType::SQUARE;
float frequency = 0.0f;
float phase = 0.0f;
float volume = 0.12f;
float pan = 0.5f; // 0.0 (left) to 1.0 (right)
// Envelope tracking
Envelope adsr;
float age = 0.0f; // duration active (seconds)
float releaseAge = 0.0f; // duration in release phase (seconds)
bool releasing = false;
// Frequency sweeps (for sound effects)
float startFreq = 0.0f;
float targetFreq = 0.0f;
float sweepDuration = 0.0f;
float sweepAge = 0.0f;
// Vibrato
float vibratoFreq = 0.0f; // LFO speed (Hz)
float vibratoDepth = 0.0f; // pitch variation depth
};
enum class SFXType {
MOVE,
ROTATE,
LAND,
LINE_CLEAR,
TETRIS_CLEAR,
LEVEL_UP,
GAME_OVER
};
class Synth {
public:
Synth();
~Synth();
bool init();
void playBGM(bool play);
void triggerSFX(SFXType type);
void stopAllSFX();
// Thread-safe copy of visualizer buffer for the GPU renderer
std::vector<float> getVisualizerBuffer();
// SDL Audio Callback
void audioCallback(Uint8* stream, int len);
private:
static void audioCallbackWrapper(void* userdata, Uint8* stream, int len);
SDL_AudioDeviceID mAudioDevice = 0;
bool mBGMEnabled = false;
std::mutex mMutex;
// 8 Dedicated voices:
// Voice 0: BGM Lead (Square)
// Voice 1: BGM Harmony / Echo (Pulse)
// Voice 2: BGM Bass (Triangle)
// Voice 3: BGM Drums / Noise (Noise/Triangle)
// Voice 4, 5, 6, 7: Dedicated SFX voices
static constexpr int NUM_VOICES = 8;
Voice mVoices[NUM_VOICES];
// Sequencer state
int mBPM = 138;
float mSecsPerTick = 0.0f; // Seconds per eighth note tick
float mTickTimer = 0.0f;
int mCurrentTick = 0;
// Pattern-based Sequencer
static constexpr int NUM_PATTERNS = 6;
uint8_t mPatternLead[NUM_PATTERNS][64];
uint8_t mPatternBass[NUM_PATTERNS][64];
ChordType mPatternChords[NUM_PATTERNS][8]; // 8 bars per pattern
// Dynamic Playlist (4 patterns per cycle)
int mPlaylist[4];
void shufflePlaylist();
// Visualizer Oscilloscope Ring Buffer
static constexpr int VIS_BUFFER_SIZE = 512;
float mVisBuffer[VIS_BUFFER_SIZE];
int mVisWritePos = 0;
void initSequencer();
void updateSequencer(float dt);
void updateVoice(Voice& voice, float dt);
float generateSample(Voice& voice);
// Helper to start BGM notes
void triggerMusicNote(int voiceIdx, uint8_t midiNote, WaveType wave, float duration, float pan = 0.5f, float volume = 0.1f);
};