mirror of https://github.com/AxioDL/amuse.git
Timing and pitch fixes
This commit is contained in:
parent
93b9c93ea4
commit
5245a41567
|
@ -204,7 +204,10 @@ struct AppCallback : boo::IApplicationCallback
|
|||
{
|
||||
m_setupId = setupId;
|
||||
if (m_seq)
|
||||
m_seq->allOff();
|
||||
{
|
||||
m_seq->stopSong();
|
||||
m_seq->kill();
|
||||
}
|
||||
m_seq = m_engine->seqPlay(m_groupId, setupId, nullptr);
|
||||
m_seq->setVolume(m_volume * VOL_FACTOR);
|
||||
|
||||
|
@ -291,7 +294,7 @@ struct AppCallback : boo::IApplicationCallback
|
|||
UpdateSongDisplay();
|
||||
}
|
||||
|
||||
m_engine->pumpEngine(1.0 / 60.0);
|
||||
m_engine->pumpEngine();
|
||||
|
||||
size_t voxCount;
|
||||
if (m_seq)
|
||||
|
@ -377,7 +380,7 @@ struct AppCallback : boo::IApplicationCallback
|
|||
UpdateSFXDisplay();
|
||||
}
|
||||
|
||||
m_engine->pumpEngine(1.0 / 60.0);
|
||||
m_engine->pumpEngine();
|
||||
|
||||
if (m_vox && m_vox->state() == amuse::VoiceState::Dead)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine);
|
||||
std::unique_ptr<IBackendVoice> allocateVoice(Voice& clientVox, double sampleRate, bool dynamicPitch);
|
||||
std::unique_ptr<IBackendSubmix> allocateSubmix(Submix& clientSmx);
|
||||
void register5MsCallback(std::function<void(double)>&& callback);
|
||||
AudioChannelSet getAvailableSet();
|
||||
void pumpAndMixVoices();
|
||||
};
|
||||
|
|
|
@ -50,6 +50,7 @@ class Engine
|
|||
std::list<Submix>::iterator _destroySubmix(Submix* smx);
|
||||
std::list<Submix>::iterator _removeSubmix(Submix* smx);
|
||||
void _bringOutYourDead();
|
||||
void _5MsCallback(double dt);
|
||||
public:
|
||||
~Engine();
|
||||
Engine(IBackendVoiceAllocator& backend);
|
||||
|
@ -58,7 +59,7 @@ public:
|
|||
IBackendVoiceAllocator& getBackend() {return m_backend;}
|
||||
|
||||
/** Update all active audio entities and fill OS audio buffers as needed */
|
||||
void pumpEngine(double dt);
|
||||
void pumpEngine();
|
||||
|
||||
/** Add audio group data pointers to engine; must remain resident! */
|
||||
const AudioGroup* addAudioGroup(const AudioGroupData& data);
|
||||
|
|
|
@ -24,8 +24,8 @@ private:
|
|||
double m_decayTime = 0.0; /**< Time of decay in seconds */
|
||||
double m_sustainFactor = 1.0; /**< Evaluated sustain percentage */
|
||||
double m_releaseTime = 0.0; /**< Time of release in seconds */
|
||||
double m_releaseStartFactor; /**< Level at whenever release event occurs */
|
||||
double m_curTime; /**< Current time of envelope stage in seconds */
|
||||
double m_releaseStartFactor = 0.0; /**< Level at whenever release event occurs */
|
||||
double m_curTime = 0.0; /**< Current time of envelope stage in seconds */
|
||||
public:
|
||||
void reset(const ADSR* adsr);
|
||||
void reset(const ADSRDLS* adsr, int8_t note, int8_t vel);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __AMUSE_IBACKENDVOICEALLOCATOR_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
namespace amuse
|
||||
{
|
||||
|
@ -39,6 +40,9 @@ public:
|
|||
|
||||
/** Amuse flushes voice samples to the backend this way */
|
||||
virtual void pumpAndMixVoices()=0;
|
||||
|
||||
/** Amuse may request callbacks 200-updates-per-second virtually */
|
||||
virtual void register5MsCallback(std::function<void(double dt)>&& callback)=0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -127,6 +127,9 @@ public:
|
|||
/** Play MIDI arrangement */
|
||||
void playSong(const unsigned char* arrData, bool dieOnEnd=true);
|
||||
|
||||
/** Stop current MIDI arrangement */
|
||||
void stopSong(bool now=false);
|
||||
|
||||
/** Set total volume of sequencer */
|
||||
void setVolume(float vol);
|
||||
|
||||
|
|
|
@ -115,6 +115,11 @@ std::unique_ptr<IBackendSubmix> BooBackendVoiceAllocator::allocateSubmix(Submix&
|
|||
return std::make_unique<BooBackendSubmix>(m_booEngine, clientSmx);
|
||||
}
|
||||
|
||||
void BooBackendVoiceAllocator::register5MsCallback(std::function<void(double)>&& callback)
|
||||
{
|
||||
m_booEngine.register5MsCallback(std::move(callback));
|
||||
}
|
||||
|
||||
AudioChannelSet BooBackendVoiceAllocator::getAvailableSet()
|
||||
{
|
||||
return AudioChannelSet(m_booEngine.getAvailableSet());
|
||||
|
|
|
@ -25,7 +25,9 @@ Engine::~Engine()
|
|||
|
||||
Engine::Engine(IBackendVoiceAllocator& backend)
|
||||
: m_backend(backend)
|
||||
{}
|
||||
{
|
||||
backend.register5MsCallback(std::bind(&Engine::_5MsCallback, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
std::pair<AudioGroup*, const SongGroupIndex*> Engine::_findSongGroup(int groupId) const
|
||||
{
|
||||
|
@ -152,12 +154,15 @@ void Engine::_bringOutYourDead()
|
|||
}
|
||||
}
|
||||
|
||||
/** Update all active audio entities and fill OS audio buffers as needed */
|
||||
void Engine::pumpEngine(double dt)
|
||||
void Engine::_5MsCallback(double dt)
|
||||
{
|
||||
for (std::shared_ptr<Sequencer>& seq : m_activeSequencers)
|
||||
seq->advance(dt);
|
||||
}
|
||||
|
||||
/** Update all active audio entities and fill OS audio buffers as needed */
|
||||
void Engine::pumpEngine()
|
||||
{
|
||||
m_backend.pumpAndMixVoices();
|
||||
_bringOutYourDead();
|
||||
|
||||
|
@ -321,7 +326,8 @@ std::shared_ptr<Voice> Engine::fxStart(int sfxId, float vol, float pan, Submix*
|
|||
if (!grp)
|
||||
return nullptr;
|
||||
|
||||
std::shared_ptr<Voice> ret = _allocateVoice(*grp, std::get<1>(search->second), 32000.0, true, false, smx);
|
||||
std::shared_ptr<Voice> ret = _allocateVoice(*grp, std::get<1>(search->second),
|
||||
32000.0, true, false, smx);
|
||||
if (!ret->loadSoundObject(SBig(entry->objId), 0, 1000.f, entry->defKey, entry->defVel, 0))
|
||||
{
|
||||
_destroyVoice(ret.get());
|
||||
|
@ -345,7 +351,8 @@ std::shared_ptr<Emitter> Engine::addEmitter(const Vector3f& pos, const Vector3f&
|
|||
if (!grp)
|
||||
return nullptr;
|
||||
|
||||
std::shared_ptr<Voice> vox = _allocateVoice(*grp, std::get<1>(search->second), 32000.0, true, true, smx);
|
||||
std::shared_ptr<Voice> vox = _allocateVoice(*grp, std::get<1>(search->second),
|
||||
32000.0, true, true, smx);
|
||||
m_activeEmitters.emplace(m_activeEmitters.end(), new Emitter(*this, *grp, std::move(vox)));
|
||||
Emitter& ret = *m_activeEmitters.back();
|
||||
if (!ret.getVoice()->loadSoundObject(entry->objId, 0, 1000.f, entry->defKey, entry->defVel, 0))
|
||||
|
|
|
@ -409,6 +409,13 @@ void Sequencer::playSong(const unsigned char* arrData, bool dieOnEnd)
|
|||
m_state = SequencerState::Playing;
|
||||
}
|
||||
|
||||
void Sequencer::stopSong(bool now)
|
||||
{
|
||||
allOff(now);
|
||||
m_arrData = nullptr;
|
||||
m_state = SequencerState::Interactive;
|
||||
}
|
||||
|
||||
void Sequencer::ChannelState::setVolume(float vol)
|
||||
{
|
||||
m_curVol = vol;
|
||||
|
|
|
@ -190,7 +190,7 @@ bool SongState::Channel::advance(Sequencer& seq, int32_t ticks)
|
|||
m_lastPitchTick = nextTick;
|
||||
remPitchTicks -= (nextTick - pitchTick);
|
||||
pitchTick = nextTick;
|
||||
seq.setPitchWheel(m_midiChan, clamp(-1.f, m_lastPitchVal / 8192.f, 1.f));
|
||||
seq.setPitchWheel(m_midiChan, clamp(-1.f, m_lastPitchVal / 32768.f, 1.f));
|
||||
continue;
|
||||
}
|
||||
remPitchTicks -= (nextTick - pitchTick);
|
||||
|
|
|
@ -224,7 +224,8 @@ bool Voice::_advanceSample(int16_t& samp, int32_t& newPitch)
|
|||
}
|
||||
|
||||
/* Factor in ADSR envelope state */
|
||||
float totalVol = m_userVol * m_curVol * m_volAdsr.nextSample(m_sampleRate) * (m_state.m_curVel / 127.f);
|
||||
float adsr = m_volAdsr.nextSample(m_sampleRate);
|
||||
float totalVol = m_userVol * m_curVol * adsr * (m_state.m_curVel / 127.f);
|
||||
|
||||
/* Apply tremolo */
|
||||
if (m_state.m_tremoloSel && (m_tremoloScale || m_tremoloModScale))
|
||||
|
|
Loading…
Reference in New Issue