mirror of https://github.com/AxioDL/amuse.git
148 lines
5.5 KiB
C++
148 lines
5.5 KiB
C++
#ifndef __AMUSE_BOO_BACKEND_HPP__
|
|
#define __AMUSE_BOO_BACKEND_HPP__
|
|
|
|
#include <boo/audiodev/IAudioVoiceEngine.hpp>
|
|
#include <boo/audiodev/IAudioSubmix.hpp>
|
|
#include <boo/audiodev/IMIDIReader.hpp>
|
|
#include <boo/audiodev/MIDIDecoder.hpp>
|
|
#include "IBackendVoice.hpp"
|
|
#include "IBackendSubmix.hpp"
|
|
#include "IBackendVoiceAllocator.hpp"
|
|
#include <mutex>
|
|
#include <list>
|
|
|
|
namespace amuse
|
|
{
|
|
|
|
/** Backend voice implementation for boo mixer */
|
|
class BooBackendVoice : public IBackendVoice
|
|
{
|
|
friend class BooBackendVoiceAllocator;
|
|
Voice& m_clientVox;
|
|
struct VoiceCallback : boo::IAudioVoiceCallback
|
|
{
|
|
BooBackendVoice& m_parent;
|
|
void preSupplyAudio(boo::IAudioVoice& voice, double dt);
|
|
size_t supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data);
|
|
void routeAudio(size_t frames, size_t channels, double dt, int busId, int16_t* in, int16_t* out);
|
|
void routeAudio(size_t frames, size_t channels, double dt, int busId, int32_t* in, int32_t* out);
|
|
void routeAudio(size_t frames, size_t channels, double dt, int busId, float* in, float* out);
|
|
VoiceCallback(BooBackendVoice& parent) : m_parent(parent) {}
|
|
} m_cb;
|
|
boo::ObjToken<boo::IAudioVoice> m_booVoice;
|
|
|
|
public:
|
|
BooBackendVoice(boo::IAudioVoiceEngine& engine, Voice& clientVox, double sampleRate, bool dynamicPitch);
|
|
void resetSampleRate(double sampleRate);
|
|
|
|
void resetChannelLevels();
|
|
void setChannelLevels(IBackendSubmix* submix, const float coefs[8], bool slew);
|
|
void setPitchRatio(double ratio, bool slew);
|
|
void start();
|
|
void stop();
|
|
};
|
|
|
|
/** Backend submix implementation for boo mixer */
|
|
class BooBackendSubmix : public IBackendSubmix
|
|
{
|
|
friend class BooBackendVoiceAllocator;
|
|
friend class BooBackendVoice;
|
|
Submix& m_clientSmx;
|
|
struct SubmixCallback : boo::IAudioSubmixCallback
|
|
{
|
|
BooBackendSubmix& m_parent;
|
|
bool canApplyEffect() const;
|
|
void applyEffect(int16_t* audio, size_t frameCount, const boo::ChannelMap& chanMap, double sampleRate) const;
|
|
void applyEffect(int32_t* audio, size_t frameCount, const boo::ChannelMap& chanMap, double sampleRate) const;
|
|
void applyEffect(float* audio, size_t frameCount, const boo::ChannelMap& chanMap, double sampleRate) const;
|
|
void resetOutputSampleRate(double sampleRate);
|
|
SubmixCallback(BooBackendSubmix& parent) : m_parent(parent) {}
|
|
} m_cb;
|
|
boo::ObjToken<boo::IAudioSubmix> m_booSubmix;
|
|
|
|
public:
|
|
BooBackendSubmix(boo::IAudioVoiceEngine& engine, Submix& clientSmx, bool mainOut, int busId);
|
|
void setSendLevel(IBackendSubmix* submix, float level, bool slew);
|
|
double getSampleRate() const;
|
|
SubmixFormat getSampleFormat() const;
|
|
};
|
|
|
|
/** Backend MIDI event reader for controlling sequencer with external hardware / software */
|
|
class BooBackendMIDIReader : public IMIDIReader, public boo::IMIDIReader
|
|
{
|
|
friend class BooBackendVoiceAllocator;
|
|
protected:
|
|
Engine& m_engine;
|
|
std::unordered_map<std::string, std::unique_ptr<boo::IMIDIIn>> m_midiIns;
|
|
std::unique_ptr<boo::IMIDIIn> m_virtualIn;
|
|
boo::MIDIDecoder m_decoder;
|
|
|
|
bool m_useLock;
|
|
std::list<std::pair<double, std::vector<uint8_t>>> m_queue;
|
|
std::mutex m_midiMutex;
|
|
void _MIDIReceive(std::vector<uint8_t>&& bytes, double time);
|
|
|
|
public:
|
|
~BooBackendMIDIReader();
|
|
BooBackendMIDIReader(Engine& engine, bool useLock);
|
|
|
|
void addMIDIIn(const char* name);
|
|
void removeMIDIIn(const char* name);
|
|
bool hasMIDIIn(const char* name) const;
|
|
void setVirtualIn(bool v);
|
|
bool hasVirtualIn() const;
|
|
|
|
void pumpReader(double dt);
|
|
|
|
void noteOff(uint8_t chan, uint8_t key, uint8_t velocity);
|
|
void noteOn(uint8_t chan, uint8_t key, uint8_t velocity);
|
|
void notePressure(uint8_t chan, uint8_t key, uint8_t pressure);
|
|
void controlChange(uint8_t chan, uint8_t control, uint8_t value);
|
|
void programChange(uint8_t chan, uint8_t program);
|
|
void channelPressure(uint8_t chan, uint8_t pressure);
|
|
void pitchBend(uint8_t chan, int16_t pitch);
|
|
|
|
void allSoundOff(uint8_t chan);
|
|
void resetAllControllers(uint8_t chan);
|
|
void localControl(uint8_t chan, bool on);
|
|
void allNotesOff(uint8_t chan);
|
|
void omniMode(uint8_t chan, bool on);
|
|
void polyMode(uint8_t chan, bool on);
|
|
|
|
void sysex(const void* data, size_t len);
|
|
void timeCodeQuarterFrame(uint8_t message, uint8_t value);
|
|
void songPositionPointer(uint16_t pointer);
|
|
void songSelect(uint8_t song);
|
|
void tuneRequest();
|
|
|
|
void startSeq();
|
|
void continueSeq();
|
|
void stopSeq();
|
|
|
|
void reset();
|
|
};
|
|
|
|
/** Backend voice allocator implementation for boo mixer */
|
|
class BooBackendVoiceAllocator : public IBackendVoiceAllocator, public boo::IAudioVoiceEngineCallback
|
|
{
|
|
friend class BooBackendMIDIReader;
|
|
protected:
|
|
boo::IAudioVoiceEngine& m_booEngine;
|
|
Engine* m_cbInterface = nullptr;
|
|
|
|
public:
|
|
BooBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine);
|
|
std::unique_ptr<IBackendVoice> allocateVoice(Voice& clientVox, double sampleRate, bool dynamicPitch);
|
|
std::unique_ptr<IBackendSubmix> allocateSubmix(Submix& clientSmx, bool mainOut, int busId);
|
|
std::vector<std::pair<std::string, std::string>> enumerateMIDIDevices();
|
|
std::unique_ptr<IMIDIReader> allocateMIDIReader(Engine& engine);
|
|
void setCallbackInterface(Engine* engine);
|
|
AudioChannelSet getAvailableSet();
|
|
void setVolume(float vol);
|
|
void on5MsInterval(boo::IAudioVoiceEngine& engine, double dt);
|
|
void onPumpCycleComplete(boo::IAudioVoiceEngine& engine);
|
|
};
|
|
}
|
|
|
|
#endif // __AMUSE_BOO_BACKEND_HPP__
|