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