-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathopus++.h
More file actions
172 lines (136 loc) · 4.83 KB
/
opus++.h
File metadata and controls
172 lines (136 loc) · 4.83 KB
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
/* This is free and unencumbered software released into the public domain. */
#ifndef OPUSXX_H
#define OPUSXX_H
/**
* <opus++.h> - Public domain C++11 wrapper for the libopus <opus.h> interface.
*
* @author Arto Bendiken
*/
#ifndef __cplusplus
#error "<opus++.h> requires a C++ compiler"
#endif
#if __cplusplus < 201402L
#error "<opus++.h> requires a C++14 compiler (CXXFLAGS='-std=c++14')"
#endif
////////////////////////////////////////////////////////////////////////////////
#include <opus.h> /* for libopus */
#include <assert.h> /* for assert() */
#include <memory> /* for std::unique_ptr */
////////////////////////////////////////////////////////////////////////////////
namespace opus {
class error;
class encoder;
class decoder;
}
////////////////////////////////////////////////////////////////////////////////
/**
* @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__errorcodes.html
*/
class opus::error : public std::runtime_error {
protected:
int _code;
public:
explicit error(int code) noexcept
: _code{code}, runtime_error{""} {}
int code() const noexcept {
return _code;
}
virtual const char* what() const noexcept override {
switch (_code) {
case OPUS_ALLOC_FAIL:
return "memory allocation has failed";
case OPUS_BAD_ARG:
return "one or more invalid/out of range arguments";
case OPUS_BUFFER_TOO_SMALL:
return "not enough bytes allocated in the buffer";
case OPUS_INTERNAL_ERROR:
return "an internal error was detected";
case OPUS_INVALID_PACKET:
return "the compressed data passed is corrupted";
case OPUS_INVALID_STATE:
return "an encoder or decoder structure is invalid or already freed";
case OPUS_OK:
return "no error";
case OPUS_UNIMPLEMENTED:
return "invalid/unsupported request number";
default:
assert(_code);
return "unknown error from libopus";
}
}
};
////////////////////////////////////////////////////////////////////////////////
/**
* @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__encoder.html
*/
class opus::encoder {
public:
using handle_ptr = std::unique_ptr<OpusEncoder, void(*)(OpusEncoder*)>;
protected:
// @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__encoder.html#ga5f4c05b4b51cdffec5a55dbf17bbfa1c
handle_ptr _handle{nullptr, ::opus_encoder_destroy};
public:
// @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__encoder.html#gaa89264fd93c9da70362a0c9b96b9ca88
static encoder create(const int frequency,
const int channels,
const int application = OPUS_APPLICATION_AUDIO) {
int error;
OpusEncoder* const handle = ::opus_encoder_create(frequency, channels, application, &error);
if (error != OPUS_OK) throw opus::error{error};
assert(handle != nullptr);
return encoder{handle};
}
explicit encoder() noexcept = default;
explicit encoder(OpusEncoder* const handle) noexcept
: _handle{handle, ::opus_encoder_destroy} {}
const OpusEncoder* handle() const noexcept {
return _handle.get();
}
OpusEncoder* handle() noexcept {
return _handle.get();
}
OpusEncoder* release() noexcept {
return _handle.release();
}
void reset(OpusEncoder* const handle) noexcept {
_handle.reset(handle);
}
};
////////////////////////////////////////////////////////////////////////////////
/**
* @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__decoder.html
*/
class opus::decoder {
public:
using handle_ptr = std::unique_ptr<OpusDecoder, void(*)(OpusDecoder*)>;
protected:
// @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__decoder.html#gafebf4cb3c29c9317cac385446a76e36e
handle_ptr _handle{nullptr, ::opus_decoder_destroy};
public:
// @see https://mf4.xiph.org/jenkins/view/opus/job/opus/ws/doc/html/group__opus__decoder.html#ga753f6fe0b699c81cfd47d70c8e15a0bd
static decoder create(const int frequency,
const int channels) {
int error;
OpusDecoder* const handle = ::opus_decoder_create(frequency, channels, &error);
if (error != OPUS_OK) throw opus::error{error};
assert(handle != nullptr);
return decoder{handle};
}
explicit decoder() noexcept = default;
explicit decoder(OpusDecoder* const handle) noexcept
: _handle{handle, ::opus_decoder_destroy} {}
const OpusDecoder* handle() const noexcept {
return _handle.get();
}
OpusDecoder* handle() noexcept {
return _handle.get();
}
OpusDecoder* release() noexcept {
return _handle.release();
}
void reset(OpusDecoder* const handle) noexcept {
_handle.reset(handle);
}
};
////////////////////////////////////////////////////////////////////////////////
#endif /* OPUSXX_H */