]> git.tdb.fi Git - ext/openal.git/blob - core/buffer_storage.h
Import OpenAL Soft 1.23.1 sources
[ext/openal.git] / core / buffer_storage.h
1 #ifndef CORE_BUFFER_STORAGE_H
2 #define CORE_BUFFER_STORAGE_H
3
4 #include <atomic>
5
6 #include "albyte.h"
7 #include "alnumeric.h"
8 #include "alspan.h"
9 #include "ambidefs.h"
10
11
12 using uint = unsigned int;
13
14 /* Storable formats */
15 enum FmtType : unsigned char {
16     FmtUByte,
17     FmtShort,
18     FmtFloat,
19     FmtDouble,
20     FmtMulaw,
21     FmtAlaw,
22     FmtIMA4,
23     FmtMSADPCM,
24 };
25 enum FmtChannels : unsigned char {
26     FmtMono,
27     FmtStereo,
28     FmtRear,
29     FmtQuad,
30     FmtX51, /* (WFX order) */
31     FmtX61, /* (WFX order) */
32     FmtX71, /* (WFX order) */
33     FmtBFormat2D,
34     FmtBFormat3D,
35     FmtUHJ2, /* 2-channel UHJ, aka "BHJ", stereo-compatible */
36     FmtUHJ3, /* 3-channel UHJ, aka "THJ" */
37     FmtUHJ4, /* 4-channel UHJ, aka "PHJ" */
38     FmtSuperStereo, /* Stereo processed with Super Stereo. */
39 };
40
41 enum class AmbiLayout : unsigned char {
42     FuMa,
43     ACN,
44 };
45 enum class AmbiScaling : unsigned char {
46     FuMa,
47     SN3D,
48     N3D,
49     UHJ,
50 };
51
52 const char *NameFromFormat(FmtType type) noexcept;
53 const char *NameFromFormat(FmtChannels channels) noexcept;
54
55 uint BytesFromFmt(FmtType type) noexcept;
56 uint ChannelsFromFmt(FmtChannels chans, uint ambiorder) noexcept;
57 inline uint FrameSizeFromFmt(FmtChannels chans, FmtType type, uint ambiorder) noexcept
58 { return ChannelsFromFmt(chans, ambiorder) * BytesFromFmt(type); }
59
60 constexpr bool IsBFormat(FmtChannels chans) noexcept
61 { return chans == FmtBFormat2D || chans == FmtBFormat3D; }
62
63 /* Super Stereo is considered part of the UHJ family here, since it goes
64  * through similar processing as UHJ, both result in a B-Format signal, and
65  * needs the same consideration as BHJ (three channel result with only two
66  * channel input).
67  */
68 constexpr bool IsUHJ(FmtChannels chans) noexcept
69 { return chans == FmtUHJ2 || chans == FmtUHJ3 || chans == FmtUHJ4 || chans == FmtSuperStereo; }
70
71 /** Ambisonic formats are either B-Format or UHJ formats. */
72 constexpr bool IsAmbisonic(FmtChannels chans) noexcept
73 { return IsBFormat(chans) || IsUHJ(chans); }
74
75 constexpr bool Is2DAmbisonic(FmtChannels chans) noexcept
76 {
77     return chans == FmtBFormat2D || chans == FmtUHJ2 || chans == FmtUHJ3
78         || chans == FmtSuperStereo;
79 }
80
81
82 using CallbackType = int(*)(void*, void*, int);
83
84 struct BufferStorage {
85     CallbackType mCallback{nullptr};
86     void *mUserData{nullptr};
87
88     al::span<al::byte> mData;
89
90     uint mSampleRate{0u};
91     FmtChannels mChannels{FmtMono};
92     FmtType mType{FmtShort};
93     uint mSampleLen{0u};
94     uint mBlockAlign{0u};
95
96     AmbiLayout mAmbiLayout{AmbiLayout::FuMa};
97     AmbiScaling mAmbiScaling{AmbiScaling::FuMa};
98     uint mAmbiOrder{0u};
99
100     inline uint bytesFromFmt() const noexcept { return BytesFromFmt(mType); }
101     inline uint channelsFromFmt() const noexcept
102     { return ChannelsFromFmt(mChannels, mAmbiOrder); }
103     inline uint frameSizeFromFmt() const noexcept { return channelsFromFmt() * bytesFromFmt(); }
104
105     inline uint blockSizeFromFmt() const noexcept
106     {
107         if(mType == FmtIMA4) return ((mBlockAlign-1)/2 + 4) * channelsFromFmt();
108         if(mType == FmtMSADPCM) return ((mBlockAlign-2)/2 + 7) * channelsFromFmt();
109         return frameSizeFromFmt();
110     };
111
112     inline bool isBFormat() const noexcept { return IsBFormat(mChannels); }
113 };
114
115 #endif /* CORE_BUFFER_STORAGE_H */