1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
//=============================================================================
// Zerberus
// Zample player
//
// Copyright (C) 2013 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __ZERBERUS_H__
#define __ZERBERUS_H__
#include <math.h>
#include <atomic>
// #include <mutex>
#include <list>
#include <memory>
#include <queue>
#include "synthesizer/synthesizer.h"
#include "synthesizer/event.h"
#include "synthesizer/midipatch.h"
#include "voice.h"
class Channel;
class ZInstrument;
enum class Trigger : char;
static const int MAX_VOICES = 512;
static const int MAX_CHANNEL = 256;
static const int MAX_TRIGGER = 512;
//---------------------------------------------------------
// VoiceFifo
//---------------------------------------------------------
class VoiceFifo {
std::queue<Voice*> buffer;
std::vector< std::unique_ptr<Voice> > voices;
public:
VoiceFifo() {
voices.resize(MAX_VOICES);
}
void init(Zerberus* z) {
for (int i = 0; i < MAX_VOICES; ++i) {
voices.push_back(std::unique_ptr<Voice>(new Voice(z)));
buffer.push(voices.back().get());
}
}
void push(Voice* v) {
buffer.push(v);
}
Voice* pop() {
Q_ASSERT(!buffer.empty());
Voice* v = buffer.front();
buffer.pop();
return v;
}
bool empty() const { return buffer.empty(); }
};
//---------------------------------------------------------
// Zerberus
//---------------------------------------------------------
class Zerberus : public Ms::Synthesizer {
static bool initialized;
static std::list<ZInstrument*> globalInstruments;
QList<Ms::MidiPatch*> patches;
double _masterTuning = 440.0;
std::atomic<bool> busy;
std::list<ZInstrument*> instruments;
Channel* _channel[MAX_CHANNEL];
int allocatedVoices = 0;
VoiceFifo freeVoices;
Voice* activeVoices = 0;
int _loadProgress = 0;
bool _loadWasCanceled = false;
QMutex mutex;
void programChange(int channel, int program);
void trigger(Channel*, int key, int velo, Trigger, int cc, int ccVal, double durSinceNoteOn);
void processNoteOff(Channel*, int pitch);
void processNoteOn(Channel* cp, int key, int velo);
public:
Zerberus();
~Zerberus();
virtual void process(unsigned frames, float*, float*, float*);
virtual void play(const Ms::PlayEvent& event);
bool loadInstrument(const QString&);
ZInstrument* instrument(int program) const;
Voice* getActiveVoices() { return activeVoices; }
Channel* channel(int n) { return _channel[n]; }
int loadProgress() { return _loadProgress; }
void setLoadProgress(int val) { _loadProgress = val; }
bool loadWasCanceled() { return _loadWasCanceled; }
void setLoadWasCanceled(bool status) { _loadWasCanceled = status; }
virtual void setMasterTuning(double val) { _masterTuning = val; }
virtual double masterTuning() const { return _masterTuning; }
double ct2hz(double c) const { return pow(2.0, (c-6900.0) / 1200.0) * masterTuning(); }
virtual const char* name() const;
virtual Ms::SynthesizerGroup state() const;
virtual bool setState(const Ms::SynthesizerGroup&);
virtual void allSoundsOff(int channel);
virtual void allNotesOff(int channel);
virtual bool addSoundFont(const QString&);
virtual bool removeSoundFont(const QString&);
virtual bool loadSoundFonts(const QStringList&);
virtual bool removeSoundFonts(const QStringList& fileNames);
QStringList soundFonts() const;
std::vector<Ms::SoundFontInfo> soundFontsInfo() const override;
virtual const QList<Ms::MidiPatch*>& getPatchInfo() const override { return patches; }
void updatePatchList();
virtual Ms::SynthesizerGui* gui();
static QFileInfoList sfzFiles();
};
#endif
|