CUGL 1.2
Cornell University Game Library
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
CUAudioScheduler.h
1 //
2 // CUAudioScheduler.h
3 // Cornell University Game Library (CUGL)
4 //
5 // Thie module provides an audio graph node for scheduling different audio
6 // nodes. When combined with AudioPlayer, this provides a classic player
7 // node such as you might find in AVFoundation. However, by generalizing
8 // this concept, we are able to schedule arbitrary audio patches as well.
9 //
10 // CUGL MIT License:
11 //
12 // This software is provided 'as-is', without any express or implied
13 // warranty. In no event will the authors be held liable for any damages
14 // arising from the use of this software.
15 //
16 // Permission is granted to anyone to use this software for any purpose,
17 // including commercial applications, and to alter it and redistribute it
18 // freely, subject to the following restrictions:
19 //
20 // 1. The origin of this software must not be misrepresented; you must not
21 // claim that you wrote the original software. If you use this software
22 // in a product, an acknowledgment in the product documentation would be
23 // appreciated but is not required.
24 //
25 // 2. Altered source versions must be plainly marked as such, and must not
26 // be misrepresented as being the original software.
27 //
28 // 3. This notice may not be removed or altered from any source distribution.
29 //
30 // Author: Walker White
31 // Version: 11/20/18
32 //
33 #ifndef __CU_AUDIO_SEQUENCER_H__
34 #define __CU_AUDIO_SEQUENCER_H__
35 #include <SDL/SDL.h>
36 #include "CUAudioNode.h"
37 #include "CUAudioPlayer.h"
38 #include <functional>
39 #include <deque>
40 
41 namespace cugl {
42  namespace audio {
43 
44 #pragma mark -
45 #pragma mark Audio Node Queue
46 
62 private:
68  struct Entry {
70  std::shared_ptr<AudioNode> value;
72  Sint32 loops;
74  Entry* next;
75 
87  Entry(const std::shared_ptr<AudioNode>& node, Sint32 loop) :
88  value(node), loops(loop), next(nullptr) { }
89  };
90 
92  Entry* _first;
94  std::atomic<Entry*> _divide;
96  std::atomic<Entry*> _last;
97 
98 
99 public:
100 #pragma mark Constructors
101 
104  AudioNodeQueue();
105 
109  ~AudioNodeQueue();
110 
111 
112 #pragma mark Queue Methods
113 
120  bool empty() const { return _divide == _last; }
121 
135  void push(const std::shared_ptr<AudioNode>& node, Sint32 loops=0);
136 
151  bool peek(std::shared_ptr<AudioNode>& node, Sint32& loop) const;
152 
167  bool pop(std::shared_ptr<AudioNode>& node, Sint32& loop);
168 
182  bool fill(std::deque<std::shared_ptr<AudioNode>>& container) const;
183 
189  void clear();
190 };
191 
192 
193 #pragma mark -
194 #pragma mark Sequencer Node
195 
219 class AudioScheduler : public AudioNode {
220 private:
222  std::shared_ptr<AudioNode> _current;
224  std::shared_ptr<AudioNode> _previous;
226  std::atomic<Sint32> _loops;
228  std::atomic<Uint32> _overlap;
230  float* _buffer;
231 
233  AudioNodeQueue _queue;
234 
236  std::atomic<Uint32> _qsize;
238  std::atomic<Uint32> _qskip;
239 
241  std::deque<std::shared_ptr<AudioNode>> _memory;
243  Sint64 _mempos;
244 
245 public:
246 #pragma mark Constructors
247 
253  AudioScheduler();
254 
258  ~AudioScheduler();
259 
272  virtual bool init() override;
273 
286  virtual bool init(Uint8 channels, Uint32 rate) override;
287 
294  virtual void dispose() override;
295 
312  static std::shared_ptr<AudioScheduler> alloc(Uint8 channels, Uint32 rate) {
313  std::shared_ptr<AudioScheduler> result = std::make_shared<AudioScheduler>();
314  return (result->init(channels, rate) ? result : nullptr);
315  }
316 
317 #pragma mark Queue Management
318 
341  void play(const std::shared_ptr<AudioNode>& node, Sint32 loop = 0);
342 
367  void append(const std::shared_ptr<AudioNode>& node, Sint32 loop = 0);
368 
377  std::shared_ptr<AudioNode> getCurrent() const;
378 
387  std::deque<std::shared_ptr<AudioNode>> getTail() const;
388 
396  Uint32 getTailSize() const;
397 
413  void clear(bool force=false);
414 
421  void trim(Sint32 size = -1);
422 
436  void skip(Uint32 n=0);
437 
446  bool isPlaying();
447 
466  double getOverlap() const;
467 
486  void setOverlap(double time);
487 
488 #pragma mark Playback Sequencing
489 
503  Sint32 getLoops() const;
504 
519  void setLoops(Sint32 loop);
520 
521  // TODO: Add cross-fade support
522 
523 
524 #pragma mark Overriden Methods
525 
543  virtual Uint32 read(float* buffer, Uint32 frames) override;
544 
565  virtual bool mark() override;
566 
578  virtual bool unmark() override;
579 
593  virtual bool reset() override;
594 
620  virtual Sint64 advance(Uint32 frames) override;
621 
637  virtual Sint64 getPosition() const override;
638 
665  virtual Sint64 setPosition(Uint32 position) override;
666 
685  virtual double getElapsed() const override;
686 
713  virtual double setElapsed(double time) override;
714 
715 #pragma mark Scheduling Helpers
716 private:
735  std::shared_ptr<AudioNode> acquire(Sint32& loop, Uint32 skip=0, Action action=Action::COMPLETE);
736 };
737  }
738 }
739 
740 #endif /* __CU_AUDIO_SEQUENCER_H__ */
void play(const std::shared_ptr< AudioNode > &node, Sint32 loop=0)
void append(const std::shared_ptr< AudioNode > &node, Sint32 loop=0)
virtual bool reset() override
bool empty() const
Definition: CUAudioScheduler.h:120
void setOverlap(double time)
virtual bool mark() override
virtual bool init() override
Definition: CUAudioScheduler.h:61
bool peek(std::shared_ptr< AudioNode > &node, Sint32 &loop) const
void setLoops(Sint32 loop)
virtual Uint32 read(float *buffer, Uint32 frames) override
Definition: CUAction.h:70
void trim(Sint32 size=-1)
Uint32 getTailSize() const
void push(const std::shared_ptr< AudioNode > &node, Sint32 loops=0)
Definition: CUAudioNode.h:93
void clear(bool force=false)
virtual double setElapsed(double time) override
std::deque< std::shared_ptr< AudioNode > > getTail() const
virtual Sint64 advance(Uint32 frames) override
virtual bool unmark() override
static std::shared_ptr< AudioScheduler > alloc(Uint8 channels, Uint32 rate)
Definition: CUAudioScheduler.h:312
virtual void dispose() override
double getOverlap() const
virtual Sint64 setPosition(Uint32 position) override
bool pop(std::shared_ptr< AudioNode > &node, Sint32 &loop)
Definition: CUAudioScheduler.h:219
virtual Sint64 getPosition() const override
Definition: CUAction.h:51
std::shared_ptr< AudioNode > getCurrent() const
bool fill(std::deque< std::shared_ptr< AudioNode >> &container) const
virtual double getElapsed() const override