# Amuse: include/amuse/Voice.hpp Source File

Voice.hpp
#ifndef __AMUSE_VOICE_HPP__
#define __AMUSE_VOICE_HPP__
#include <stdint.h>
#include <stdlib.h>
#include <memory>
#include <list>
#include "SoundMacroState.hpp"
#include "Entity.hpp"
#include "AudioGroupSampleDirectory.hpp"
#include "AudioGroup.hpp"
#include "Envelope.hpp"
namespace amuse
{
class IBackendVoice;
class Submix;
struct Keymap;
struct LayerMapping;
enum class VoiceState
{
Playing,
KeyOff,
Dead
};
class Voice : public Entity
{
friend class Engine;
friend class Sequencer;
friend class SoundMacroState;
int m_vid;
bool m_emitter;
Submix* m_submix = nullptr;
std::list<std::shared_ptr<Voice>>::iterator m_engineIt;
std::unique_ptr<IBackendVoice> m_backendVoice;
SoundMacroState m_state;
SoundMacroState::EventTrap m_keyoffTrap;
SoundMacroState::EventTrap m_sampleEndTrap;
SoundMacroState::EventTrap m_messageTrap;
std::list<int32_t> m_messageQueue;
std::list<std::shared_ptr<Voice>> m_childVoices;
uint8_t m_keygroup = 0;
enum class SampleFormat : uint8_t
{
DSP,
IMA,
PCM
};
const Sample* m_curSample = nullptr;
const unsigned char* m_curSampleData = nullptr;
SampleFormat m_curFormat;
uint32_t m_curSamplePos = 0;
uint32_t m_lastSamplePos = 0;
int16_t m_prev1 = 0;
int16_t m_prev2 = 0;
double m_sampleRate = 32000.0;
double m_voiceTime;
VoiceState m_voxState = VoiceState::Dead;
bool m_sustained = false;
bool m_sustainKeyOff = false;
uint8_t m_curAftertouch = 0;
float m_userVol = 1.f;
float m_curVol;
float m_curReverbVol;
float m_curPan;
float m_curSpan;
float m_curPitchWheel = 0.f;
int32_t m_pitchWheelUp;
int32_t m_pitchWheelDown;
int32_t m_pitchWheelVal;
int32_t m_curPitch;
bool m_pitchDirty;
Envelope m_volAdsr;
double m_envelopeTime;
double m_envelopeDur;
float m_envelopeStart;
float m_envelopeEnd;
const Curve* m_envelopeCurve;
bool m_pitchEnv = false;
Envelope m_pitchAdsr;
int32_t m_pitchEnvRange;
uint32_t m_pitchSweep1;
uint32_t m_pitchSweep2;
int16_t m_pitchSweep1Add;
int16_t m_pitchSweep2Add;
uint8_t m_pitchSweep1Times;
uint8_t m_pitchSweep2Times;
uint8_t m_pitchSweep1It;
uint8_t m_pitchSweep2It;
float m_panningTime;
float m_panningDur;
uint8_t m_panPos;
uint8_t m_panWidth;
float m_spanningTime;
float m_spanningDur;
uint8_t m_spanPos;
uint8_t m_spanWidth;
int32_t m_vibratoLevel;
int32_t m_vibratoModLevel;
float m_vibratoPeriod;
bool m_vibratoModWheel;
float m_tremoloScale;
float m_tremoloModScale;
float m_lfoPeriods[2];
std::unique_ptr<int8_t[]> m_ctrlValsSelf;
int8_t* m_extCtrlVals = nullptr;
void _destroy();
void _reset();
bool _checkSamplePos();
void _doKeyOff();
void _macroKeyOff();
void _macroSampleEnd();
bool _advanceSample(int16_t& samp, int32_t& curPitch);
void _setTotalPitch(int32_t cents, bool slew);
bool _isRecursivelyDead();
void _bringOutYourDead();
std::shared_ptr<Voice> _findVoice(int vid, std::weak_ptr<Voice> thisPtr);
std::unique_ptr<int8_t[]>& _ensureCtrlVals();
std::shared_ptr<Voice> _allocateVoice(double sampleRate, bool dynamicPitch);
std::list<std::shared_ptr<Voice>>::iterator _destroyVoice(Voice* voice);
bool _loadSoundMacro(const unsigned char* macroData, int macroStep, double ticksPerSec,
uint8_t midiKey, uint8_t midiVel, uint8_t midiMod, bool pushPc=false);
bool _loadKeymap(const Keymap* keymap, int macroStep, double ticksPerSec,
uint8_t midiKey, uint8_t midiVel, uint8_t midiMod, bool pushPc=false);
bool _loadLayer(const std::vector<const LayerMapping*>& layer, int macroStep, double ticksPerSec,
uint8_t midiKey, uint8_t midiVel, uint8_t midiMod, bool pushPc=false);
std::shared_ptr<Voice> _startChildMacro(ObjectId macroId, int macroStep, double ticksPerSec,
uint8_t midiKey, uint8_t midiVel, uint8_t midiMod, bool pushPc=false);
public:
~Voice();
Voice(Engine& engine, const AudioGroup& group, int groupId, int vid, bool emitter, Submix* smx);
Voice(Engine& engine, const AudioGroup& group, int groupId, ObjectId oid, int vid, bool emitter, Submix* smx);
size_t supplyAudio(size_t frames, int16_t* data);
Submix* getSubmix() {return m_submix;}
VoiceState state() const {return m_voxState;}
int vid() const {return m_vid;}
int maxVid() const;
std::shared_ptr<Voice> startChildMacro(int8_t addNote, ObjectId macroId, int macroStep);
bool loadSoundObject(ObjectId objectId, int macroStep, double ticksPerSec,
uint8_t midiKey, uint8_t midiVel, uint8_t midiMod,
bool pushPc=false);
void keyOff();
void message(int32_t val);
void startSample(int16_t sampId, int32_t offset);
void stopSample();
void setVolume(float vol);
void setPan(float pan);
void setSurroundPan(float span);
void startEnvelope(double dur, float vol, const Curve* envCurve);
void startFadeIn(double dur, float vol, const Curve* envCurve);
void startPanning(double dur, uint8_t panPos, uint8_t panWidth);
void startSpanning(double dur, uint8_t spanPos, uint8_t spanWidth);
void setPitchKey(int32_t cents);
void setPedal(bool pedal);
void setDoppler(float doppler);
void setVibrato(int32_t level, int32_t modLevel, float period);
void setMod2VibratoRange(int32_t modLevel);
void setTremolo(float tremoloScale, float tremoloModScale);
void setLFO1Period(float period) {m_lfoPeriods[0] = period;}
void setLFO2Period(float period) {m_lfoPeriods[1] = period;}
void setPitchSweep1(uint8_t times, int16_t add);
void setPitchSweep2(uint8_t times, int16_t add);
void setReverbVol(float rvol);
void setAdsr(ObjectId adsrId, bool dls);
void setPitchFrequency(uint32_t hz, uint16_t fine);
void setPitchAdsr(ObjectId adsrId, int32_t cents);
void setPitchWheel(float pitchWheel);
void setPitchWheelRange(int8_t up, int8_t down);
void setAftertouch(uint8_t aftertouch);
void setKeygroup(uint8_t kg) {m_keygroup = kg;}
uint8_t getLastNote() const {return m_state.m_initKey;}
void notifyCtrlChange(uint8_t ctrl, int8_t val);
int8_t getCtrlValue(uint8_t ctrl) const
{
if (!m_extCtrlVals)
{
if (m_ctrlValsSelf)
m_ctrlValsSelf[ctrl];
return 0;
}
return m_extCtrlVals[ctrl];
}
void setCtrlValue(uint8_t ctrl, int8_t val)
{
if (!m_extCtrlVals)
{
std::unique_ptr<int8_t[]>& vals = _ensureCtrlVals();
vals[ctrl] = val;
}
else
m_extCtrlVals[ctrl] = val;
notifyCtrlChange(ctrl, val);
}
int8_t getModWheel() const {return getCtrlValue(1);}
void installCtrlValues(int8_t* cvs)
{
m_ctrlValsSelf.reset();
m_extCtrlVals = cvs;
}
int8_t getPitchWheel() const {return m_curPitchWheel * 127;}
int8_t getAftertouch() const {return m_curAftertouch;}
size_t getTotalVoices() const;
};
}
#endif // __AMUSE_VOICE_HPP__
amuse::Voice::getAftertouch
int8_t getAftertouch() const
Definition: Voice.hpp:308
amuse::Voice::getModWheel
int8_t getModWheel() const
Definition: Voice.hpp:295
amuse::AudioGroup
Definition: AudioGroup.hpp:16
amuse::Voice::getPitchWheel
int8_t getPitchWheel() const
Definition: Voice.hpp:305
amuse
Definition: AudioGroup.hpp:8
amuse::Voice::setLFO2Period
void setLFO2Period(float period)
Definition: Voice.hpp:232
amuse::Voice::setKeygroup
void setKeygroup(uint8_t kg)
Definition: Voice.hpp:262
amuse::Voice::installCtrlValues
void installCtrlValues(int8_t *cvs)
Definition: Voice.hpp:298
amuse::Voice
Definition: Voice.hpp:30
amuse::Submix
Definition: Submix.hpp:20
amuse::Voice::getLastNote
uint8_t getLastNote() const
Definition: Voice.hpp:265
amuse::Voice::getSubmix
Submix * getSubmix()
Definition: Voice.hpp:158
amuse::Keymap
Definition: AudioGroupPool.hpp:70
amuse::Voice::setCtrlValue
void setCtrlValue(uint8_t ctrl, int8_t val)
Definition: Voice.hpp:282
amuse::Voice::vid
int vid() const
Definition: Voice.hpp:164
amuse::Voice::setLFO1Period
void setLFO1Period(float period)
Definition: Voice.hpp:229
amuse::Engine
Definition: Engine.hpp:23
amuse::SoundMacroState
Definition: SoundMacroState.hpp:14
amuse::Envelope
Definition: Envelope.hpp:10
amuse::Entity
Definition: Entity.hpp:18
amuse::Voice::getCtrlValue
int8_t getCtrlValue(uint8_t ctrl) const
Definition: Voice.hpp:270
amuse::Voice::state
VoiceState state() const
Definition: Voice.hpp:161
amuse::Sequencer
Definition: Sequencer.hpp:27