File: zerberus.h

package info (click to toggle)
musescore3 3.2.3%2Bdfsg2-11
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 210,672 kB
  • sloc: cpp: 291,093; xml: 200,238; sh: 3,779; ansic: 1,447; python: 393; makefile: 240; perl: 82; pascal: 79
file content (145 lines) | stat: -rw-r--r-- 4,383 bytes parent folder | download | duplicates (5)
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