opusenc.h 13.6 KB
Newer Older
Jean-Marc Valin's avatar
Jean-Marc Valin committed
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
/* Copyright (c) 2017 Jean-Marc Valin */
/*
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
26 27 28 29

#if !defined(_opusenc_h)
# define _opusenc_h (1)

Jean-Marc Valin's avatar
Jean-Marc Valin committed
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
/**\mainpage
   \section Introduction

   This is the documentation for the <tt>libopusenc</tt> C API.

   The <tt>libopusenc</tt> package provides a convenient high-level API for
   encoding Ogg Opus files.

   \section Organization

   The main API is divided into several sections:
   - \ref encoding
   - \ref comments
   - \ref encoder_ctl
   - \ref callbacks
   - \ref error_codes

   \section Overview

   The <tt>libopusfile</tt> API provides an easy way to encode Ogg Opus files using
   <tt>libopus</tt>.
*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
52 53 54 55 56

# if defined(__cplusplus)
extern "C" {
# endif

57
#include <opus.h>
58

Jean-Marc Valin's avatar
Jean-Marc Valin committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72
#ifndef OPE_EXPORT
# if defined(WIN32)
#  if defined(OPE_BUILD) && defined(DLL_EXPORT)
#   define OPE_EXPORT __declspec(dllexport)
#  else
#   define OPE_EXPORT
#  endif
# elif defined(__GNUC__) && defined(OPE_BUILD)
#  define OPE_EXPORT __attribute__ ((visibility ("default")))
# else
#  define OPE_EXPORT
# endif
#endif

Jean-Marc Valin's avatar
Jean-Marc Valin committed
73 74 75 76 77 78 79 80 81 82 83
/**\defgroup error_codes Error Codes*/
/*@{*/
/**\name List of possible error codes
   Many of the functions in this library return a negative error code when a
    function fails.
   This list provides a brief explanation of the common errors.
   See each individual function for more details on what a specific error code
    means in that context.*/
/*@{*/


Jean-Marc Valin's avatar
Jean-Marc Valin committed
84 85 86 87
/* Bump this when we change the API. */
/** API version for this header. Can be used to check for features at compile time. */
#define OPE_API_VERSION 0

88
#define OPE_OK 0
89 90
/* Based on the relevant libopus code minus 10. */
#define OPE_BAD_ARG -11
Jean-Marc Valin's avatar
Jean-Marc Valin committed
91
#define OPE_INTERNAL_ERROR -13
92 93 94 95 96 97
#define OPE_UNIMPLEMENTED -15
#define OPE_ALLOC_FAIL -17

/* Specific to libopusenc. */
#define OPE_CANNOT_OPEN -30
#define OPE_TOO_LATE -31
98
#define OPE_UNRECOVERABLE -32
99 100
#define OPE_INVALID_PICTURE -33
#define OPE_INVALID_ICON -34
Jean-Marc Valin's avatar
Jean-Marc Valin committed
101 102
/*@}*/
/*@}*/
103

104

105
/* These are the "raw" request values -- they should usually not be used. */
106 107 108 109 110 111 112 113 114
#define OPE_SET_DECISION_DELAY_REQUEST      14000
#define OPE_GET_DECISION_DELAY_REQUEST      14001
#define OPE_SET_MUXING_DELAY_REQUEST        14002
#define OPE_GET_MUXING_DELAY_REQUEST        14003
#define OPE_SET_COMMENT_PADDING_REQUEST     14004
#define OPE_GET_COMMENT_PADDING_REQUEST     14005
#define OPE_SET_SERIALNO_REQUEST            14006
#define OPE_GET_SERIALNO_REQUEST            14007
#define OPE_SET_PACKET_CALLBACK_REQUEST     14008
115
/*#define OPE_GET_PACKET_CALLBACK_REQUEST     14009*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
116 117
#define OPE_SET_HEADER_GAIN_REQUEST         14010
#define OPE_GET_HEADER_GAIN_REQUEST         14011
118

Jean-Marc Valin's avatar
Jean-Marc Valin committed
119 120 121 122 123 124 125 126
/**\defgroup encoder_ctl Encoding Options*/
/*@{*/

/**\name Control parameters

   Macros for setting encoder options.*/
/*@{*/

127 128 129 130
#define OPE_SET_DECISION_DELAY(x) OPE_SET_DECISION_DELAY_REQUEST, __opus_check_int(x)
#define OPE_GET_DECISION_DELAY(x) OPE_GET_DECISION_DELAY_REQUEST, __opus_check_int_ptr(x)
#define OPE_SET_MUXING_DELAY(x) OPE_SET_MUXING_DELAY_REQUEST, __opus_check_int(x)
#define OPE_GET_MUXING_DELAY(x) OPE_GET_MUXING_DELAY_REQUEST, __opus_check_int_ptr(x)
131 132
#define OPE_SET_COMMENT_PADDING(x) OPE_SET_COMMENT_PADDING_REQUEST, __opus_check_int(x)
#define OPE_GET_COMMENT_PADDING(x) OPE_GET_COMMENT_PADDING_REQUEST, __opus_check_int_ptr(x)
133 134
#define OPE_SET_SERIALNO(x) OPE_SET_SERIALNO_REQUEST, __opus_check_int(x)
#define OPE_GET_SERIALNO(x) OPE_GET_SERIALNO_REQUEST, __opus_check_int_ptr(x)
135
/* FIXME: Add type-checking macros to these. */
136
#define OPE_SET_PACKET_CALLBACK(x,u) OPE_SET_PACKET_CALLBACK_REQUEST, (x), (u)
137
/*#define OPE_GET_PACKET_CALLBACK(x,u) OPE_GET_PACKET_CALLBACK_REQUEST, (x), (u)*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
138 139
#define OPE_SET_HEADER_GAIN(x,u) OPE_SET_HEADER_GAIN_REQUEST, __opus_check_int(x)
#define OPE_GET_HEADER_GAIN(x,u) OPE_GET_HEADER_GAIN_REQUEST, __opus_check_int_ptr(x)
Jean-Marc Valin's avatar
Jean-Marc Valin committed
140 141 142 143 144 145 146
/*@}*/
/*@}*/

/**\defgroup callbacks Callback Functions */
/*@{*/

/**\name Callback functions
147

Jean-Marc Valin's avatar
Jean-Marc Valin committed
148 149 150 151
   These are the callbacks that can be implemented for an encoder.*/
/*@{*/

/** Called for writing a page. */
152
typedef int (*ope_write_func)(void *user_data, const unsigned char *ptr, opus_int32 len);
153

Jean-Marc Valin's avatar
Jean-Marc Valin committed
154
/** Called for closing a stream. */
155 156
typedef int (*ope_close_func)(void *user_data);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
157
/** Called on every packet encoded (including header). */
158
typedef int (*ope_packet_func)(void *user_data, const unsigned char *packet_ptr, opus_int32 packet_len, opus_uint32 flags);
159

Jean-Marc Valin's avatar
Jean-Marc Valin committed
160
/** Callback functions for accessing the stream. */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
161
typedef struct {
Jean-Marc Valin's avatar
Jean-Marc Valin committed
162
  /** Callback for writing to the stream. */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
163
  ope_write_func write;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
164
  /** Callback for closing the stream. */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
165 166
  ope_close_func close;
} OpusEncCallbacks;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
167 168
/*@}*/
/*@}*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
169

Jean-Marc Valin's avatar
Jean-Marc Valin committed
170 171 172
/** Opaque comments struct. */
typedef struct OggOpusComments OggOpusComments;

173
/** Opaque encoder struct. */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
174 175
typedef struct OggOpusEnc OggOpusEnc;

Jean-Marc Valin's avatar
Jean-Marc Valin committed
176 177 178 179 180 181 182 183
/**\defgroup comments Comments Handling */
/*@{*/

/**\name Functions for handling comments

   These functions make it possible to add comments and pictures to Ogg Opus files.*/
/*@{*/

Jean-Marc Valin's avatar
Jean-Marc Valin committed
184 185
/** Create a new comments object. 
    \return Newly-created comments object. */
186
OPE_EXPORT OggOpusComments *ope_comments_create(void);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
187

Jean-Marc Valin's avatar
Jean-Marc Valin committed
188 189 190
/** Create a deep copy of a comments object.
    \param comments Comments object to copy
    \return Deep copy of input. */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
191 192
OPE_EXPORT OggOpusComments *ope_comments_copy(OggOpusComments *comments);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
193 194
/** Destroys a comments object. 
    \param comments Comments object to destroy*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
195 196
OPE_EXPORT void ope_comments_destroy(OggOpusComments *comments);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
197 198 199
/** Add a comment. 
    \param[in,out] comments Where to add the comments
    \param         tag      Tag for the comment (must not contain = char)
Jean-Marc Valin's avatar
Jean-Marc Valin committed
200
    \param         val      Value for the tag
Jean-Marc Valin's avatar
Jean-Marc Valin committed
201 202
    \return Error code
 */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
203 204
OPE_EXPORT int ope_comments_add(OggOpusComments *comments, const char *tag, const char *val);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
205 206 207 208 209
/** Add a comment as a single tag=value string. 
    \param[in,out] comments    Where to add the comments
    \param         tag_and_val string of the form tag=value (must contain = char)
    \return Error code
 */
210 211
OPE_EXPORT int ope_comments_add_string(OggOpusComments *comments, const char *tag_and_val);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
212
/** Add a picture. 
Jean-Marc Valin's avatar
Jean-Marc Valin committed
213 214 215 216
    \param[in,out] comments     Where to add the comments
    \param         filename     File name for the picture
    \param         picture_type Type of picture (-1 for default)
    \param         description  Description (NULL means no comment)
Jean-Marc Valin's avatar
Jean-Marc Valin committed
217 218
    \return Error code
 */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
219
OPE_EXPORT int ope_comments_add_picture(OggOpusComments *comments, const char *filename, int picture_type, const char *description);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
220

Jean-Marc Valin's avatar
Jean-Marc Valin committed
221 222 223 224 225 226 227 228 229 230
/*@}*/
/*@}*/

/**\defgroup encoding Encoding */
/*@{*/

/**\name Functions for encoding Ogg Opus files

   These functions make it possible to encode Ogg Opus files.*/
/*@{*/
Jean-Marc Valin's avatar
Jean-Marc Valin committed
231

Jean-Marc Valin's avatar
Jean-Marc Valin committed
232 233 234 235 236 237 238 239 240
/** Create a new OggOpus file.
    \param path       Path where to create the file
    \param comments   Comments associated with the stream
    \param rate       Input sampling rate (48 kHz is faster)
    \param channels   Number of channels
    \param family     Mapping family (0 for mono/stereo, 1 for surround)
    \param[out] error Error code (NULL if no error is to be returned)
    \return Newly-created encoder.
    */
241
OPE_EXPORT OggOpusEnc *ope_encoder_create_file(const char *path, OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
242

Jean-Marc Valin's avatar
Jean-Marc Valin committed
243 244 245 246 247 248 249 250 251 252
/** Create a new OggOpus stream to be handled using callbacks
    \param callbacks  Callback functions
    \param user_data  Pointer to be associated with the stream and passed to the callbacks
    \param comments   Comments associated with the stream
    \param rate       Input sampling rate (48 kHz is faster)
    \param channels   Number of channels
    \param family     Mapping family (0 for mono/stereo, 1 for surround)
    \param[out] error Error code (NULL if no error is to be returned)
    \return Newly-created encoder.
    */
253
OPE_EXPORT OggOpusEnc *ope_encoder_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
254
    OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
255

Jean-Marc Valin's avatar
Jean-Marc Valin committed
256 257 258 259 260 261 262 263 264
/** Create a new OggOpus stream to be used along with.ope_encoder_get_page().
  This is mostly useful for muxing with other streams.
    \param comments   Comments associated with the stream
    \param rate       Input sampling rate (48 kHz is faster)
    \param channels   Number of channels
    \param family     Mapping family (0 for mono/stereo, 1 for surround)
    \param[out] error Error code (NULL if no error is to be returned)
    \return Newly-created encoder.
    */
265
OPE_EXPORT OggOpusEnc *ope_encoder_create_pull(OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
266

267 268 269 270 271 272 273 274 275 276 277
/** Deferred initialization of the encoder to force an explicit channel mapping.
    \param[in,out] enc         Encoder
    \param family              Mapping family (0 for mono/stereo, 1 for surround)
    \param streams             Total number of streams
    \param coupled_streams     Number of coupled streams
    \param mapping             Channel mapping
    \return Error code
 */
OPE_EXPORT int ope_encoder_deferred_init_with_mapping(OggOpusEnc *enc, int family, int streams, 
    int coupled_streams, const unsigned char *mapping);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
278 279 280 281 282
/** Add/encode any number of float samples to the stream.
    \param[in,out] enc         Encoder
    \param pcm                 Floating-point PCM values in the +/-1 range (interleaved if multiple channels)
    \param samples_per_channel Number of samples for each channel
    \return Error code*/
283
OPE_EXPORT int ope_encoder_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
284

Jean-Marc Valin's avatar
Jean-Marc Valin committed
285 286 287 288 289
/** Add/encode any number of 16-bit linear samples to the stream.
    \param[in,out] enc         Encoder
    \param pcm                 Linear 16-bit PCM values in the [-32768,32767] range (interleaved if multiple channels)
    \param samples_per_channel Number of samples for each channel
    \return Error code*/
290
OPE_EXPORT int ope_encoder_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
291

Jean-Marc Valin's avatar
Jean-Marc Valin committed
292 293 294 295 296 297
/** Get the next page from the stream (only if using ope_encoder_create_pull()).
    \param[in,out] enc Encoder
    \param[out] page   Next available encoded page
    \param[out] len    Size (in bytes) of the page returned
    \param flush       If non-zero, forces a flush of the page (if any data avaiable)
    \return 1 if there is a page available, 0 if not. */
298
OPE_EXPORT int ope_encoder_get_page(OggOpusEnc *enc, unsigned char **page, opus_int32 *len, int flush);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
299

Jean-Marc Valin's avatar
Jean-Marc Valin committed
300 301 302 303
/** Finalizes the stream, but does not deallocate the object.
    \param[in,out] enc Encoder
    \return Error code
 */
304
OPE_EXPORT int ope_encoder_drain(OggOpusEnc *enc);
305

Jean-Marc Valin's avatar
Jean-Marc Valin committed
306 307 308
/** Deallocates the obect. Make sure to ope_drain() first.
    \param[in,out] enc Encoder
 */
309
OPE_EXPORT void ope_encoder_destroy(OggOpusEnc *enc);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
310

Jean-Marc Valin's avatar
Jean-Marc Valin committed
311 312 313 314 315
/** Ends the stream and create a new stream within the same file.
    \param[in,out] enc Encoder
    \param comments   Comments associated with the stream
    \return Error code
 */
316
OPE_EXPORT int ope_encoder_chain_current(OggOpusEnc *enc, OggOpusComments *comments);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
317

Jean-Marc Valin's avatar
Jean-Marc Valin committed
318 319 320 321 322 323
/** Ends the stream and create a new file.
    \param[in,out] enc Encoder
    \param path        Path where to write the new file
    \param comments    Comments associated with the stream
    \return Error code
 */
324
OPE_EXPORT int ope_encoder_continue_new_file(OggOpusEnc *enc, const char *path, OggOpusComments *comments);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
325

Jean-Marc Valin's avatar
Jean-Marc Valin committed
326 327 328 329 330 331
/** Ends the stream and create a new file (callback-based).
    \param[in,out] enc Encoder
    \param user_data   Pointer to be associated with the new stream and passed to the callbacks
    \param comments    Comments associated with the stream
    \return Error code
 */
332
OPE_EXPORT int ope_encoder_continue_new_callbacks(OggOpusEnc *enc, void *user_data, OggOpusComments *comments);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
333

Jean-Marc Valin's avatar
Jean-Marc Valin committed
334 335 336 337
/** Write out the header now rather than wait for audio to begin.
    \param[in,out] enc Encoder
    \return Error code
 */
338
OPE_EXPORT int ope_encoder_flush_header(OggOpusEnc *enc);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
339

Jean-Marc Valin's avatar
Jean-Marc Valin committed
340 341 342 343 344
/** Sets encoder options.
    \param[in,out] enc Encoder
    \param request     Use a request macro
    \return Error code
 */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
345
OPE_EXPORT int ope_encoder_ctl(OggOpusEnc *enc, int request, ...);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
346

Jean-Marc Valin's avatar
Jean-Marc Valin committed
347
/** Converts a libopusenc error code into a human readable string.
Jean-Marc Valin's avatar
Jean-Marc Valin committed
348 349 350 351 352 353
  *
  * @param error Error number
  * @returns Error string
  */
OPE_EXPORT const char *ope_strerror(int error);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
354 355
/** Returns a string representing the version of libopusenc being used at run time.
    \return A string describing the version of this library */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
356 357
OPE_EXPORT const char *ope_get_version_string(void);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
358 359
/** ABI version for this header. Can be used to check for features at run time.
    \return An integer representing the ABI version */
Jean-Marc Valin's avatar
Jean-Marc Valin committed
360 361
OPE_EXPORT int ope_get_abi_version(void);

Jean-Marc Valin's avatar
Jean-Marc Valin committed
362 363 364
/*@}*/
/*@}*/

Jean-Marc Valin's avatar
Jean-Marc Valin committed
365 366 367 368 369
# if defined(__cplusplus)
}
# endif

#endif