#include "Synth.h" void SoundSequence::Put(double at, int i, double volume, double frequency, double duration, bool direct) { SoundEvent& e = At(at).Add(); e.frequency = (float)frequency; e.duration = (float)duration; e.volume = (float)volume; e.snd = &bank[i]; if(direct) { e.duration = (float)e.snd->op[0].duration; e.frequency = (float)e.snd->f; } } int SoundSequence::SoundIndex(const String& s) { int q = bank.Find(s); if(q < 0) { q = bank.GetCount(); bank.Add(s).Load(s); } return q; } void SoundSequence::Put(double at, const String& snd, double volume, double frequency, double duration, bool direct) { Put(at, SoundIndex(snd), volume, frequency, duration, direct); } const int SEQUENCER_CHANNEL_ID = -123; std::atomic sS; void PlaySequence(const SoundSequence& s) { s.at = s.cursor; sS = &s; } bool IsPlayingSequence() { return sS.load(); } void StopSequencer() { sS = NULL; StopChannels(SEQUENCER_CHANNEL_ID); } void PlayTempSequence(SoundSequence&& s) { static int ii; static SoundSequence h[2]; h[ii] = pick(s); PlaySequence(h[ii]); ii = !ii; } void Sequencer(int chunk_size) { static int ch; ch += chunk_size; if(ch < CHUNK_SIZE) return; ch -= CHUNK_SIZE; int PR = 10; const SoundSequence *ss = sS.load(); if(ss) { if(ss->at >= ss->event.GetCount()) { if(!IsNull(ss->loop) && ss->event.GetCount()) ss->at = ss->loop; else { sS = NULL; return; } } const Vector& e = ss->event[ss->at++]; for(const SoundEvent& s : e) { int ii = FindChannel(PR, 1, s.volume); if(ii >= 0) { Sound snd = *s.snd; if(s.frequency > 0) { snd.f = s.frequency; snd.op[0].volume *= s.volume / 100; snd.op[0].duration = s.duration; } SetChannel(ii, snd, 10, SEQUENCER_CHANNEL_ID); } } } }