ref: 280c060bb11919aad4b96a60a2542a49ee3d5a0b
parent: 5095c47053bdacfafd0ee0d1c11058d54c235e9a
author: Jean-Marc Valin <[email protected]>
date: Thu May 5 16:47:42 EDT 2011
Adds opus_{en|de}coder_init() and opus_{en|de|coder_get_size()
--- a/src/opus.h
+++ b/src/opus.h
@@ -33,11 +33,11 @@
#endif
#if defined(__GNUC__) && defined(OPUS_BUILD)
-#define EXPORT __attribute__ ((visibility ("default")))
+#define OPUS_EXPORT __attribute__ ((visibility ("default")))
#elif defined(WIN32)
-#define EXPORT __declspec(dllexport)
+#define OPUS_EXPORT __declspec(dllexport)
#else
-#define EXPORT
+#define OPUS_EXPORT
#endif
#define __check_int(x) (((void)((x) == (int)0)), (int)(x))
@@ -133,36 +133,40 @@
typedef struct OpusEncoder OpusEncoder;
typedef struct OpusDecoder OpusDecoder;
-EXPORT OpusEncoder *opus_encoder_create(int Fs, int channels);
+OPUS_EXPORT OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels);
+OPUS_EXPORT OpusEncoder *opus_encoder_create(int Fs, int channels);
+
/* returns length of data payload (in bytes) */
-EXPORT int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
+OPUS_EXPORT int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
unsigned char *data, int max_data_bytes);
-EXPORT void opus_encoder_destroy(OpusEncoder *st);
+OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st);
-EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...);
+OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...);
-EXPORT OpusDecoder *opus_decoder_create(int Fs, int channels);
+OPUS_EXPORT OpusDecoder *opus_decoder_init(OpusDecoder *st, int Fs, int channels);
+OPUS_EXPORT OpusDecoder *opus_decoder_create(int Fs, int channels);
+
/* returns (CELT) error code */
-EXPORT int opus_decode(OpusDecoder *st, const unsigned char *data, int len,
+OPUS_EXPORT int opus_decode(OpusDecoder *st, const unsigned char *data, int len,
short *pcm, int frame_size, int decode_fec);
-EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...);
+OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...);
-EXPORT void opus_decoder_destroy(OpusDecoder *st);
+OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
-EXPORT int opus_packet_get_bandwidth(const unsigned char *data);
-EXPORT int opus_packet_get_samples_per_frame(const unsigned char *data, int Fs);
-EXPORT int opus_packet_get_nb_channels(const unsigned char *data);
-EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], int len);
-EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len);
+OPUS_EXPORT int opus_packet_get_bandwidth(const unsigned char *data);
+OPUS_EXPORT int opus_packet_get_samples_per_frame(const unsigned char *data, int Fs);
+OPUS_EXPORT int opus_packet_get_nb_channels(const unsigned char *data);
+OPUS_EXPORT int opus_packet_get_nb_frames(const unsigned char packet[], int len);
+OPUS_EXPORT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], int len);
#if OPUS_TEST_RANGE_CODER_STATE
-EXPORT int opus_encoder_get_final_range(OpusEncoder *st);
-EXPORT int opus_decoder_get_final_range(OpusDecoder *st);
+OPUS_EXPORT int opus_encoder_get_final_range(OpusEncoder *st);
+OPUS_EXPORT int opus_decoder_get_final_range(OpusDecoder *st);
#endif
--- a/src/opus_decoder.c
+++ b/src/opus_decoder.c
@@ -29,6 +29,7 @@
#include "config.h"
#endif
+#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
@@ -38,27 +39,44 @@
#include "modes.h"
#include "SKP_Silk_SDK_API.h"
+/* Make sure everything's aligned to 4 bytes (this may need to be increased
+ on really weird architectures) */
+static inline int align(int i)
+{
+ return (i+3)&-4;
+}
-OpusDecoder *opus_decoder_create(int Fs, int channels)
+int opus_decoder_get_size(int channels)
{
+ int silkDecSizeBytes, celtDecSizeBytes;
+ int ret;
+ ret = SKP_Silk_SDK_Get_Decoder_Size( &silkDecSizeBytes );
+ if(ret)
+ return 0;
+ silkDecSizeBytes = align(silkDecSizeBytes);
+ celtDecSizeBytes = celt_decoder_get_size(channels);
+ return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes;
+
+}
+
+OpusDecoder *opus_decoder_init(OpusDecoder *st, int Fs, int channels)
+{
void *silk_dec;
CELTDecoder *celt_dec;
- char *raw_state;
int ret, silkDecSizeBytes, celtDecSizeBytes;
- OpusDecoder *st;
+ memset(st, 0, sizeof(OpusDecoder));
/* Initialize SILK encoder */
ret = SKP_Silk_SDK_Get_Decoder_Size( &silkDecSizeBytes );
if( ret ) {
- /* Handle error */
+ return NULL;
}
+ silkDecSizeBytes = align(silkDecSizeBytes);
celtDecSizeBytes = celt_decoder_get_size(channels);
- raw_state = calloc(sizeof(OpusDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1);
- st = (OpusDecoder*)raw_state;
- st->silk_dec_offset = sizeof(OpusDecoder);
- st->celt_dec_offset = sizeof(OpusDecoder)+silkDecSizeBytes;
- silk_dec = raw_state+st->silk_dec_offset;
- celt_dec = (CELTDecoder*)(raw_state+st->celt_dec_offset);
+ st->silk_dec_offset = align(sizeof(OpusDecoder));
+ st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes;
+ silk_dec = (char*)st+st->silk_dec_offset;
+ celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset);
st->stream_channels = st->channels = channels;
st->Fs = Fs;
@@ -66,15 +84,28 @@
/* Reset decoder */
ret = SKP_Silk_SDK_InitDecoder( silk_dec );
if( ret ) {
- /* Handle error */
+ goto failure;
}
/* Initialize CELT decoder */
- celt_decoder_init(celt_dec, Fs, channels, NULL);
+ celt_decoder_init(celt_dec, Fs, channels, &ret);
+ if (ret != CELT_OK)
+ goto failure;
celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0));
st->prev_mode = 0;
return st;
+failure:
+ free(st);
+ return NULL;
+}
+
+OpusDecoder *opus_decoder_create(int Fs, int channels)
+{
+ char *raw_state = malloc(opus_decoder_get_size(channels));
+ if (raw_state == NULL)
+ return NULL;
+ return opus_decoder_init((OpusDecoder*)raw_state, Fs, channels);
}
static void smooth_fade(const short *in1, const short *in2, short *out,
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -29,6 +29,7 @@
#include "config.h"
#endif
+#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
@@ -54,27 +55,42 @@
33000, 2000, /* SWB<->FB */
};
+/* Make sure everything's aligned to 4 bytes (this may need to be increased
+ on really weird architectures) */
+static inline int align(int i)
+{
+ return (i+3)&-4;
+}
-OpusEncoder *opus_encoder_create(int Fs, int channels)
+int opus_encoder_get_size(int channels)
{
+ int silkEncSizeBytes, celtEncSizeBytes;
+ int ret;
+ ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes );
+ if(ret)
+ return 0;
+ silkEncSizeBytes = align(silkEncSizeBytes);
+ celtEncSizeBytes = celt_encoder_get_size(channels);
+ return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
+
+}
+
+OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels)
+{
void *silk_enc;
CELTEncoder *celt_enc;
int err;
- char *raw_state;
- OpusEncoder *st;
int ret, silkEncSizeBytes, celtEncSizeBytes;
+ memset(st, 0, sizeof(OpusEncoder));
/* Create SILK encoder */
ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes );
if( ret )
return NULL;
+ silkEncSizeBytes = align(silkEncSizeBytes);
celtEncSizeBytes = celt_encoder_get_size(channels);
- raw_state = calloc(sizeof(OpusEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1);
- if (raw_state == NULL)
- return NULL;
- st = (OpusEncoder*)raw_state;
- st->silk_enc_offset = sizeof(OpusEncoder);
- st->celt_enc_offset = sizeof(OpusEncoder)+silkEncSizeBytes;
+ st->silk_enc_offset = align(sizeof(OpusEncoder));
+ st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
silk_enc = (char*)st+st->silk_enc_offset;
celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
@@ -121,6 +137,14 @@
failure:
free(st);
return NULL;
+}
+
+OpusEncoder *opus_encoder_create(int Fs, int channels)
+{
+ char *raw_state = malloc(opus_encoder_get_size(channels));
+ if (raw_state == NULL)
+ return NULL;
+ return opus_encoder_init((OpusEncoder*)raw_state, Fs, channels);
}
int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,