1 ///
2 /// Class to abstract away details of audio output system is in use.
3 ///	@file		audiooutput.h - pianod2
4 ///	@author		Perette Barella
5 ///	@date		2015-02-26
6 ///	@copyright	Copyright (c) 2015-2017 Devious Fish. All rights reserved.
7 ///
8 
9 #pragma once
10 
11 #ifndef __pianod2__audiooutput__
12 #define __pianod2__audiooutput__
13 
14 #include <config.h>
15 
16 #include "fundamentals.h"
17 
18 /// Classes dealing with audio output drivers and decoding/playing audio files.
19 namespace Audio {
20     class LavGenericAdapter;
21 
22     enum SampleArrangement {
23         Native,
24         Big,
25         Little
26     };
27     enum SampleSignedness {
28         Signed,
29         Unsigned
30     };
31     /** Audio format, somewhat ripped off from libao */
32     struct AudioFormat {
33         int bits = 16; ///< Bits per sample *in a single channel*
34         int rate = 44100; ///< Samples per second *in a single channel*
35         int channels = 2;
36         SampleArrangement arrangement = SampleArrangement::Native;
37         SampleSignedness signedness = Signed;
38         SampleArrangement realArrangement () const;
39         bool isNativeArrangement () const;
40         /** Get the size of sample data.
41             @return Number of channels * sizeof (individual channel's sample). */
42         int sampleGroupSize () const {
43             assert ((bits & 0x07) == 0);
44             return channels * ((bits + 7) / 8);
45         };
46         static SampleArrangement nativeArrangement (int bits);
47     };
48 
strip_trailoptnull49     /// Exception for audio output problems.
50     class AudioException : public std::exception {
51     protected:
52         std::string reason;
53     public:
54         AudioException (const char *why = "") : reason (why) { };
55         AudioException (std::string why) : reason (why) { };
56         virtual const char *what() const noexcept override  { return reason.c_str(); };
57     };
58 
59 
60     /// Initialize the audio output libraries; uninitialize on destruction.
61     class Initializer {
62     public:
63         Initializer ();
64         ~Initializer ();
65     };
66 
67     /// Base audio output class (abstract).
68     class Output {
69     protected:
70         char bytes_per_sample_set; // Bytes/channel * number of channels
71     public:
72         virtual ~Output () { };
73         /** Play output.
74             @param buffer The samples, in packed (interleaved) format if multichannel.
75             @param number_of_bytes Size of the buffer; number of samples is determined
76             by the audio format set when opening the channel. */
77         virtual bool play (void *buffer, unsigned number_of_bytes) = 0;
78         inline char bytesPerSample() { return bytes_per_sample_set; };
79 
80         static bool isValidOutput (const AudioSettings &settings);
81         static bool outputCanCrossfade (const AudioSettings &settings);
82 
83         static Output *getOutput (const AudioSettings &settings,
84                                   const AudioFormat &format);
85         static void reportLibrariesAndVersions (int verbose);
86     };
87 }
88 
89 #endif /* defined(__pianod2__audiooutput__) */
90