1 /*******************************************************************************
2 *                         Goggles Audio Player Library                         *
3 ********************************************************************************
4 *           Copyright (C) 2010-2021 by Sander Jansen. All Rights Reserved      *
5 *                               ---                                            *
6 * This program is free software: you can redistribute it and/or modify         *
7 * it under the terms of the GNU General Public License as published by         *
8 * the Free Software Foundation, either version 3 of the License, or            *
9 * (at your option) any later version.                                          *
10 *                                                                              *
11 * This program is distributed in the hope that it will be useful,              *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of               *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                *
14 * GNU General Public License for more details.                                 *
15 *                                                                              *
16 * You should have received a copy of the GNU General Public License            *
17 * along with this program.  If not, see http://www.gnu.org/licenses.           *
18 ********************************************************************************/
19 #ifndef AUDIOFORMAT_H
20 #define AUDIOFORMAT_H
21 
22 namespace ap {
23 
24 
25 struct ReplayGain{
26   FXdouble album      = NAN;
27   FXdouble album_peak = NAN;
28   FXdouble track      = NAN;
29   FXdouble track_peak = NAN;
30 
emptyReplayGain31   FXbool empty() const { return isnan(album) && isnan(track); }
32 
resetReplayGain33   void reset() { album=NAN; album_peak=NAN; track=NAN; track_peak=NAN; }
34   };
35 
36 
37 namespace Codec {
38 
39   enum {
40     Invalid   = 0,
41     PCM       = 1,
42     FLAC      = 2,
43     Vorbis    = 3,
44     MPEG      = 4,
45     AAC       = 5,
46     Opus      = 6,
47     ALAC      = 7,
48     DCA       = 8,
49     A52       = 9
50     };
51 
52   extern const FXchar * name(FXuchar codec);
53   }
54 
55 
56 namespace Channel {
57   const FXuint None        =  0u;
58   const FXuint Mono        =  1u;
59   const FXuint FrontLeft   =  2u;
60   const FXuint FrontRight  =  3u;
61   const FXuint FrontCenter =  4u;
62   const FXuint BackLeft    =  5u;
63   const FXuint BackRight   =  6u;
64   const FXuint BackCenter  =  7u;
65   const FXuint SideLeft    =  8u;
66   const FXuint SideRight   =  9u;
67   const FXuint LFE         = 10u;
68   const FXuint Reserved    = 15u; // Max 4 bits
69   }
70 
71 
72 
73 #define AP_CMAP1(c1)                      (c1)
74 #define AP_CMAP2(c1,c2)                   (c1|(c2<<4))
75 #define AP_CMAP3(c1,c2,c3)                (c1|(c2<<4)|(c3<<8))
76 #define AP_CMAP4(c1,c2,c3,c4)             (c1|(c2<<4)|(c3<<8)|(c4<<12))
77 #define AP_CMAP5(c1,c2,c3,c4,c5)          (c1|(c2<<4)|(c3<<8)|(c4<<12)|(c5<<16))
78 #define AP_CMAP6(c1,c2,c3,c4,c5,c6)       (c1|(c2<<4)|(c3<<8)|(c4<<12)|(c5<<16)|(c6<<20))
79 #define AP_CMAP7(c1,c2,c3,c4,c5,c6,c7)    (c1|(c2<<4)|(c3<<8)|(c4<<12)|(c5<<16)|(c6<<20)|(c7<<24))
80 #define AP_CMAP8(c1,c2,c3,c4,c5,c6,c7,c8) (c1|(c2<<4)|(c3<<8)|(c4<<12)|(c5<<16)|(c6<<20)|(c7<<24)|(c8<<28))
81 
82 
83 
84 
85 
86 namespace Format {
87 
88 enum {
89 
90   /// Mask and shift definitions
91   Type_Mask         = 7,
92   Type_Shift        = 0,
93   Order_Mask        = 1,
94   Order_Shift       = 3,
95   Bits_Mask         = 31,
96   Bits_Shift        = 8,
97   Pack_Mask         = 7,
98   Pack_Shift        = 13,
99 
100   /// Data type (xxxx xxxx xxxx x111)
101   Signed            = 0,
102   Unsigned          = 1,
103   Float             = 2,
104   IEC958            = 3,
105   Format_Reserved_1 = 4,
106   Format_Reserved_2 = 5,
107   Format_Reserved_3 = 6,
108   Format_Reserved_4 = 7,
109 
110   /// Byte Order (xxxx xxxx xxxx 1xxx)
111   Little            = ( 0 << Order_Shift),
112   Big               = ( 1 << Order_Shift),
113 #if FOX_BIGENDIAN == 1
114   Native            = Big,
115   Other             = Little,
116 #else
117   Native            = Little,
118   Other             = Big,
119 #endif
120 
121   /// Bits per sample  (xxx1 1111 xxxx xxxx)
122   Bits_8            = ( 7 << Bits_Shift),
123   Bits_16           = (15 << Bits_Shift),
124   Bits_24           = (23 << Bits_Shift),
125   Bits_32           = (31 << Bits_Shift),
126 
127   /// Bytes per sample (111x xxxx xxxx xxxx)
128   Pack_1            = ( 0 << Pack_Shift),
129   Pack_2            = ( 1 << Pack_Shift),
130   Pack_3            = ( 2 << Pack_Shift),
131   Pack_4            = ( 3 << Pack_Shift),
132   Pack_Reserved_1   = ( 4 << Pack_Shift),
133   Pack_Reserved_2   = ( 5 << Pack_Shift),
134   Pack_Reserved_3   = ( 6 << Pack_Shift),
135   Pack_8            = ( 7 << Pack_Shift),
136 
137 
138   //// Input Formats
139   Unknown           = 0,
140   WAV               = 1,
141   OGG               = 2,
142   FLAC              = 3,
143   MP3               = 4,
144   MP4               = 5,
145   AAC               = 6,
146   M3U               = 7,
147   PLS               = 8,
148   XSPF              = 9,
149   AIFF              = 10,
150   Matroska          = 11
151   };
152 
153 }
154 
155 enum {
156   AP_FORMAT_S8          = ( Format::Signed   | Format::Native | Format::Bits_8  | Format::Pack_1 ),
157   AP_FORMAT_U8          = ( Format::Unsigned | Format::Native | Format::Bits_8  | Format::Pack_1 ),
158 
159   AP_FORMAT_S16         = ( Format::Signed   | Format::Native | Format::Bits_16 | Format::Pack_2 ),
160   AP_FORMAT_S16_OTHER   = ( Format::Signed   | Format::Other  | Format::Bits_16 | Format::Pack_2 ),
161 
162   AP_FORMAT_S16_LE      = ( Format::Signed   | Format::Little | Format::Bits_16 | Format::Pack_2 ),
163   AP_FORMAT_S16_BE      = ( Format::Signed   | Format::Big    | Format::Bits_16 | Format::Pack_2 ),
164 
165   AP_FORMAT_FLOAT       = ( Format::Float    | Format::Native | Format::Bits_32 | Format::Pack_4 ),
166   AP_FORMAT_FLOAT_OTHER = ( Format::Float    | Format::Other  | Format::Bits_32 | Format::Pack_4 ),
167   AP_FORMAT_FLOAT_LE    = ( Format::Float    | Format::Little | Format::Bits_32 | Format::Pack_4 ),
168   AP_FORMAT_FLOAT_BE    = ( Format::Float    | Format::Big    | Format::Bits_32 | Format::Pack_4 ),
169 
170   AP_FORMAT_S24         = ( Format::Signed   | Format::Native | Format::Bits_24 | Format::Pack_4 ),
171   AP_FORMAT_S24_LE      = ( Format::Signed   | Format::Little | Format::Bits_24 | Format::Pack_4 ),
172   AP_FORMAT_S24_BE      = ( Format::Signed   | Format::Big    | Format::Bits_24 | Format::Pack_4 ),
173 
174   AP_FORMAT_S24_3       = ( Format::Signed   | Format::Native | Format::Bits_24 | Format::Pack_3 ),
175   AP_FORMAT_S24_3LE     = ( Format::Signed   | Format::Little | Format::Bits_24 | Format::Pack_3 ),
176   AP_FORMAT_S24_3BE     = ( Format::Signed   | Format::Big    | Format::Bits_24 | Format::Pack_3 ),
177 
178   AP_FORMAT_S32         = ( Format::Signed   | Format::Native | Format::Bits_32 | Format::Pack_4 ),
179   AP_FORMAT_S32_LE      = ( Format::Signed   | Format::Little | Format::Bits_32 | Format::Pack_4 ),
180   AP_FORMAT_S32_BE      = ( Format::Signed   | Format::Big    | Format::Bits_32 | Format::Pack_4 ),
181 
182 
183   AP_CHANNELMAP_MONO    = ( Channel::Mono ),
184   AP_CHANNELMAP_STEREO  = AP_CMAP2(Channel::FrontLeft,Channel::FrontRight)
185   };
186 
187 
188 extern FXuint ap_format_from_extension(const FXString & extension);
189 extern FXuint ap_format_from_mime(const FXString & mime);
190 extern FXuint ap_format_from_buffer(const FXchar * buffer,FXival size);
191 extern const FXchar * ap_format_name(FXuint name);
192 
193 
194 class GMAPI AudioFormat {
195 public:
196   FXuint   rate       = 0;
197   FXushort format     = 0;
198   FXuchar  channels   = 0;
199   FXuint   channelmap = 0;  // up to 8 channels
200 public:
201   AudioFormat() = default;
202 
203   void setBits(FXushort bps);
204 
205   void setChannels(FXuchar channels);
206 
207   void set(FXushort datatype,FXushort bps,FXushort pack,FXuint rate,FXuchar channels,FXuint map=0);
208 
209   void set(FXushort format,FXuint rate,FXuchar channels,FXuint map=0);
210 
undefined()211   FXbool undefined() const { return ((rate==0) && (format==0) && (channels==0)); }
212 
set()213   FXbool set() const { return (rate!=0) && (format!=0) && (channels!=0); }
214 
channeltype(FXuint c)215   FXuchar channeltype(FXuint c) const { return (FXuchar)((channelmap>>(c<<2))&0xF); }
216 
byteorder()217   FXuchar byteorder() const {
218     return (format>>Format::Order_Shift)&Format::Order_Mask;
219     }
220 
datatype()221   FXuchar datatype() const {
222     return format&Format::Type_Mask;
223     }
224 
bps()225   FXuchar bps() const {
226     return 1+((format>>Format::Bits_Shift)&Format::Bits_Mask);
227     }
228 
packing()229   FXuchar packing() const {
230     return 1+((format>>Format::Pack_Shift)&Format::Pack_Mask);
231     }
232 
framesize()233   FXint framesize() const {
234     return (FXint)channels * (FXint)packing();
235     }
236 
237   /* Swap byte order. Return true if succesfull */
238   FXbool swap();
239 
240   /* Change to compatible format */
241   FXbool compatible();
242 
243   void debug() const;
244 
245   FXString debug_format() const;
246 
247   void reset();
248   };
249 
250 extern GMAPI FXbool operator!=(const AudioFormat& s1,const AudioFormat& s2);
251 extern GMAPI FXbool operator==(const AudioFormat& s1,const AudioFormat& s2);
252 
253 }
254 #endif
255