mirror of
https://github.com/AxioDL/amuse.git
synced 2025-08-05 19:55:47 +00:00
210 lines
4.9 KiB
C++
210 lines
4.9 KiB
C++
#include "amuse/Voice.hpp"
|
|
#include "amuse/Submix.hpp"
|
|
#include "amuse/IBackendVoice.hpp"
|
|
#include "amuse/AudioGroup.hpp"
|
|
#include "amuse/dsp.h"
|
|
#include <string.h>
|
|
|
|
namespace amuse
|
|
{
|
|
|
|
void Voice::_destroy()
|
|
{
|
|
Entity::_destroy();
|
|
if (m_submix)
|
|
m_submix->m_activeVoices.erase(this);
|
|
}
|
|
|
|
Voice::Voice(Engine& engine, const AudioGroup& group, int vid, bool emitter, Submix* smx)
|
|
: Entity(engine, group), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
|
{
|
|
if (m_submix)
|
|
m_submix->m_activeVoices.insert(this);
|
|
}
|
|
|
|
Voice::Voice(Engine& engine, const AudioGroup& group, ObjectId oid, int vid, bool emitter, Submix* smx)
|
|
: Entity(engine, group, oid), m_vid(vid), m_emitter(emitter), m_submix(smx)
|
|
{
|
|
if (m_submix)
|
|
m_submix->m_activeVoices.insert(this);
|
|
}
|
|
|
|
bool Voice::_checkSamplePos()
|
|
{
|
|
if (m_curSamplePos >= m_lastSamplePos)
|
|
{
|
|
if (m_curSample->first.m_loopLengthSamples)
|
|
{
|
|
/* Turn over looped sample */
|
|
m_curSamplePos = m_curSample->first.m_loopStartSample;
|
|
m_prev1 = m_curSample->second.m_hist1;
|
|
m_prev2 = m_curSample->second.m_hist2;
|
|
}
|
|
else
|
|
{
|
|
/* Notify sample end */
|
|
m_state.sampleEndNotify(*this);
|
|
m_curSample = nullptr;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Voice::_doKeyOff()
|
|
{
|
|
}
|
|
|
|
size_t Voice::supplyAudio(size_t samples, int16_t* data)
|
|
{
|
|
uint32_t samplesRem = samples;
|
|
if (m_curSample)
|
|
{
|
|
uint32_t block = m_curSamplePos / 14;
|
|
uint32_t rem = m_curSamplePos % 14;
|
|
|
|
if (rem)
|
|
{
|
|
uint32_t decSamples = DSPDecompressFrameRanged(data, m_curSampleData + 8 * block,
|
|
m_curSample->second.m_coefs,
|
|
&m_prev1, &m_prev2, rem,
|
|
std::min(samplesRem,
|
|
m_lastSamplePos - block * 14));
|
|
m_curSamplePos += decSamples;
|
|
samplesRem -= decSamples;
|
|
data += decSamples;
|
|
}
|
|
|
|
if (_checkSamplePos())
|
|
{
|
|
if (samplesRem)
|
|
memset(data, 0, sizeof(int16_t) * samplesRem);
|
|
return samples;
|
|
}
|
|
|
|
while (samplesRem)
|
|
{
|
|
block = m_curSamplePos / 14;
|
|
uint32_t decSamples = DSPDecompressFrame(data, m_curSampleData + 8 * block,
|
|
m_curSample->second.m_coefs,
|
|
&m_prev1, &m_prev2,
|
|
std::min(samplesRem,
|
|
m_lastSamplePos - block * 14));
|
|
m_curSamplePos += decSamples;
|
|
samplesRem -= decSamples;
|
|
data += decSamples;
|
|
|
|
if (_checkSamplePos())
|
|
{
|
|
if (samplesRem)
|
|
memset(data, 0, sizeof(int16_t) * samplesRem);
|
|
return samples;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
memset(data, 0, sizeof(int16_t) * samples);
|
|
|
|
return samples;
|
|
}
|
|
|
|
Voice* Voice::startChildMacro(int8_t addNote, ObjectId macroId, int macroStep)
|
|
{
|
|
}
|
|
|
|
bool Voice::loadSoundMacro(ObjectId macroId, int macroStep, bool pushPc)
|
|
{
|
|
}
|
|
|
|
void Voice::keyOff()
|
|
{
|
|
if (m_sustained)
|
|
m_sustainKeyOff = true;
|
|
else
|
|
_doKeyOff();
|
|
}
|
|
|
|
void Voice::message(int32_t val)
|
|
{
|
|
}
|
|
|
|
void Voice::startSample(int16_t sampId, int32_t offset)
|
|
{
|
|
m_curSample = m_audioGroup.getSample(sampId);
|
|
if (m_curSample)
|
|
{
|
|
m_backendVoice->stop();
|
|
m_backendVoice->resetSampleRate(m_curSample->first.m_sampleRate);
|
|
m_backendVoice->start();
|
|
m_curSamplePos = offset;
|
|
m_curSampleData = m_audioGroup.getSampleData(m_curSample->first.m_sampleOff);
|
|
m_prev1 = 0;
|
|
m_prev2 = 0;
|
|
m_lastSamplePos = m_curSample->first.m_loopLengthSamples ?
|
|
(m_curSample->first.m_loopStartSample + m_curSample->first.m_loopLengthSamples) :
|
|
m_curSample->first.m_numSamples;
|
|
}
|
|
}
|
|
|
|
void Voice::stopSample()
|
|
{
|
|
m_backendVoice->stop();
|
|
m_curSample = nullptr;
|
|
}
|
|
|
|
void Voice::setVolume(float vol)
|
|
{
|
|
}
|
|
|
|
void Voice::setPanning(float pan)
|
|
{
|
|
}
|
|
|
|
void Voice::setSurroundPanning(float span)
|
|
{
|
|
}
|
|
|
|
void Voice::setPitchKey(int32_t cents)
|
|
{
|
|
}
|
|
|
|
void Voice::setModulation(float mod)
|
|
{
|
|
}
|
|
|
|
void Voice::setPedal(bool pedal)
|
|
{
|
|
if (m_sustained && !pedal && m_sustainKeyOff)
|
|
{
|
|
m_sustainKeyOff = false;
|
|
_doKeyOff();
|
|
}
|
|
m_sustained = pedal;
|
|
}
|
|
|
|
void Voice::setDoppler(float doppler)
|
|
{
|
|
}
|
|
|
|
void Voice::setReverbVol(float rvol)
|
|
{
|
|
}
|
|
|
|
void Voice::setAdsr(ObjectId adsrId)
|
|
{
|
|
}
|
|
|
|
void Voice::setPitchFrequency(uint32_t hz, uint16_t fine)
|
|
{
|
|
}
|
|
|
|
void Voice::setPitchAdsr(ObjectId adsrId, int32_t cents)
|
|
{
|
|
}
|
|
|
|
void Voice::setPitchWheelRange(int8_t up, int8_t down)
|
|
{
|
|
}
|
|
|
|
}
|