Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.xiph.org/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Marc Valin <jean-marc.valin@octasic.com>2010-07-06 22:41:20 +0400
committerJean-Marc Valin <jean-marc.valin@octasic.com>2010-07-06 22:41:20 +0400
commit24f36e0a95abe099545e0a660169f7c7fe083b63 (patch)
tree233b98b00222a3f8baff5b70dc42ba86cdc6a0b1 /src
parentf1babf8e9c025bc55fef06812a6ba0585c8f6332 (diff)
Adds a _ctl() control API to the encoder and decoder
Diffstat (limited to 'src')
-rw-r--r--src/hybrid.h53
-rw-r--r--src/hybrid_decoder.c84
-rw-r--r--src/hybrid_decoder.h3
-rw-r--r--src/hybrid_encoder.c102
-rw-r--r--src/hybrid_encoder.h4
-rw-r--r--src/test_hybrid.c8
6 files changed, 221 insertions, 33 deletions
diff --git a/src/hybrid.h b/src/hybrid.h
index ae03293b..94d9f063 100644
--- a/src/hybrid.h
+++ b/src/hybrid.h
@@ -29,6 +29,50 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifndef HYBRID_H
+#define HYBRID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__GNUC__) && defined(CELT_BUILD)
+#define EXPORT __attribute__ ((visibility ("default")))
+#elif defined(WIN32)
+#define EXPORT __declspec(dllexport)
+#else
+#define EXPORT
+#endif
+
+#define __check_int(x) (((void)((x) == (int)0)), (int)(x))
+#define __check_int_ptr(ptr) ((ptr) + ((ptr) - (int*)(ptr)))
+
+#define MODE_SILK_ONLY 1000
+#define MODE_HYBRID 1001
+#define MODE_CELT_ONLY 1002
+
+#define BANDWIDTH_NARROWBAND 1100
+#define BANDWIDTH_WIDEBAND 1101
+#define BANDWIDTH_SUPERWIDEBAND 1102
+#define BANDWIDTH_FULLBAND 1103
+
+
+
+#define HYBRID_SET_MODE_REQUEST 0
+#define HYBRID_SET_MODE(x) HYBRID_SET_MODE_REQUEST, __check_int(x)
+#define HYBRID_GET_MODE_REQUEST 1
+#define HYBRID_GET_MODE(x) HYBRID_GET_MODE_REQUEST, __check_int_ptr(x)
+
+#define HYBRID_SET_BANDWIDTH_REQUEST 2
+#define HYBRID_SET_BANDWIDTH(x) HYBRID_SET_BANDWIDTH_REQUEST, __check_int(x)
+#define HYBRID_GET_BANDWIDTH_REQUEST 3
+#define HYBRID_GET_BANDWIDTH(x) HYBRID_GET_BANDWIDTH_REQUEST, __check_int_ptr(x)
+
+#define HYBRID_SET_VBR_RATE_REQUEST 4
+#define HYBRID_SET_VBR_RATE(x) HYBRID_SET_VBR_RATE_REQUEST, __check_int(x)
+#define HYBRID_GET_VBR_RATE_REQUEST 5
+#define HYBRID_GET_VBR_RATE(x) HYBRID_GET_VBR_RATE_REQUEST, __check_int_ptr(x)
+
typedef struct HybridEncoder HybridEncoder;
typedef struct HybridDecoder HybridDecoder;
@@ -39,10 +83,19 @@ int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size,
void hybrid_encoder_destroy(HybridEncoder *st);
+void hybrid_encoder_ctl(HybridEncoder *st, int request, ...);
HybridDecoder *hybrid_decoder_create();
+
int hybrid_decode(HybridDecoder *st, const unsigned char *data, int len,
short *pcm, int frame_size);
+void hybrid_decoder_ctl(HybridDecoder *st, int request, ...);
+
void hybrid_decoder_destroy(HybridDecoder *st);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HYBRID_H */
diff --git a/src/hybrid_decoder.c b/src/hybrid_decoder.c
index fae32fb9..0bece75c 100644
--- a/src/hybrid_decoder.c
+++ b/src/hybrid_decoder.c
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <stdarg.h>
#include "hybrid_decoder.h"
#include "celt/libcelt/entdec.h"
#include "celt/libcelt/modes.h"
@@ -72,7 +73,7 @@ HybridDecoder *hybrid_decoder_create()
int hybrid_decode(HybridDecoder *st, const unsigned char *data,
int len, short *pcm, int frame_size)
{
- int i, silk_ret, celt_ret;
+ int i, silk_ret=0, celt_ret=0;
ec_dec dec;
ec_byte_buffer buf;
SKP_SILK_SDK_DecControlStruct DecControl;
@@ -82,27 +83,78 @@ int hybrid_decode(HybridDecoder *st, const unsigned char *data,
ec_byte_readinit(&buf,(unsigned char*)data,len);
ec_dec_init(&dec,&buf);
- DecControl.API_sampleRate = 48000;
- /* Call SILK encoder for the low band */
- silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, 0, &dec, len, pcm, &silk_frame_size );
- if (silk_ret)
- {
- fprintf (stderr, "SILK decode error\n");
- /* Handle error */
- }
-
- /* This should be adjusted based on the SILK bandwidth */
- celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(13));
+ if (st->mode != MODE_CELT_ONLY)
+ {
+ DecControl.API_sampleRate = 48000;
+ /* Call SILK encoder for the low band */
+ silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, 0, &dec, len, pcm, &silk_frame_size );
+ if (silk_ret)
+ {
+ fprintf (stderr, "SILK decode error\n");
+ /* Handle error */
+ }
+ } else {
+ for (i=0;i<960;i++)
+ pcm[i] = 0;
+ }
- /* Encode high band with CELT */
- celt_ret = celt_decode_with_ec(st->celt_dec, data, len, pcm_celt, frame_size, &dec);
- for (i=0;i<960;i++)
- pcm[i] += pcm_celt[i];
+ if (st->mode == MODE_HYBRID)
+ {
+ /* This should be adjusted based on the SILK bandwidth */
+ celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(13));
+ } else {
+ celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0));
+ }
+ if (st->mode != MODE_SILK_ONLY)
+ {
+ /* Encode high band with CELT */
+ celt_ret = celt_decode_with_ec(st->celt_dec, data, len, pcm_celt, frame_size, &dec);
+ for (i=0;i<960;i++)
+ pcm[i] += pcm_celt[i];
+ }
return celt_ret;
}
+void hybrid_decoder_ctl(HybridDecoder *st, int request, ...)
+{
+ va_list ap;
+
+ va_start(ap, request);
+
+ switch (request)
+ {
+ case HYBRID_SET_MODE_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->mode = value;
+ }
+ break;
+ case HYBRID_GET_MODE_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->mode;
+ }
+ break;
+ case HYBRID_SET_BANDWIDTH_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->bandwidth = value;
+ }
+ break;
+ case HYBRID_GET_BANDWIDTH_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->bandwidth;
+ }
+ break;
+ default:
+ fprintf(stderr, "unknown hybrid_decoder_ctl() request: %d", request);
+ break;
+ }
+}
+
void hybrid_decoder_destroy(HybridDecoder *st)
{
free(st->silk_dec);
diff --git a/src/hybrid_decoder.h b/src/hybrid_decoder.h
index 85a7b21e..180c32a3 100644
--- a/src/hybrid_decoder.h
+++ b/src/hybrid_decoder.h
@@ -39,6 +39,9 @@ struct HybridDecoder {
CELTMode *celt_mode;
CELTDecoder *celt_dec;
void *silk_dec;
+
+ int mode;
+ int bandwidth;
};
diff --git a/src/hybrid_encoder.c b/src/hybrid_encoder.c
index 900204ad..881ef09c 100644
--- a/src/hybrid_encoder.c
+++ b/src/hybrid_encoder.c
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include <stdarg.h>
#include "hybrid_encoder.h"
#include "celt/libcelt/entenc.h"
#include "celt/libcelt/modes.h"
@@ -74,13 +75,16 @@ HybridEncoder *hybrid_encoder_create()
/* Initialize CELT encoder */
st->celt_enc = celt_encoder_create(st->celt_mode, 1, NULL);
+ st->mode = MODE_HYBRID;
+ st->bandwidth = BANDWIDTH_FULLBAND;
+
return st;
}
int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size,
unsigned char *data, int bytes_per_packet)
{
- int silk_ret, celt_ret;
+ int ret=0;
SKP_int16 nBytes;
ec_enc enc;
ec_byte_buffer buf;
@@ -88,24 +92,87 @@ int hybrid_encode(HybridEncoder *st, const short *pcm, int frame_size,
ec_byte_writeinit_buffer(&buf, data, bytes_per_packet);
ec_enc_init(&enc,&buf);
- st->encControl.bitRate = (bytes_per_packet*50*8+4000)/2;
+ if (st->mode != MODE_CELT_ONLY)
+ {
+ st->encControl.bitRate = (bytes_per_packet*50*8+4000)/2;
+ /* Call SILK encoder for the low band */
+ nBytes = bytes_per_packet;
+ ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->encControl, pcm, 960, &enc, &nBytes );
+ if( ret ) {
+ fprintf (stderr, "SILK encode error\n");
+ /* Handle error */
+ }
+ ret = (ec_enc_tell(&enc, 0)+7)>>3;
+ }
+
+ if (st->mode == MODE_HYBRID)
+ {
+ /* This should be adjusted based on the SILK bandwidth */
+ celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(13));
+ } else {
+ celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
+ }
+
+ if (st->mode != MODE_SILK_ONLY)
+ {
+ /* Encode high band with CELT */
+ /* FIXME: Do some delay compensation here */
+ ret = celt_encode_with_ec(st->celt_enc, pcm, NULL, frame_size, data, bytes_per_packet, &enc);
+ } else {
+ ec_enc_done(&enc);
+ }
+
+ return ret;
+}
- /* Call SILK encoder for the low band */
- nBytes = bytes_per_packet;
- silk_ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->encControl, pcm, 960, &enc, &nBytes );
- if( silk_ret ) {
- fprintf (stderr, "SILK encode error\n");
- /* Handle error */
+void hybrid_encoder_ctl(HybridEncoder *st, int request, ...)
+{
+ va_list ap;
+
+ va_start(ap, request);
+
+ switch (request)
+ {
+ case HYBRID_SET_MODE_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->mode = value;
+ }
+ break;
+ case HYBRID_GET_MODE_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->mode;
+ }
+ break;
+ case HYBRID_SET_BANDWIDTH_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->bandwidth = value;
+ }
+ break;
+ case HYBRID_GET_BANDWIDTH_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->bandwidth;
+ }
+ break;
+ case HYBRID_SET_VBR_RATE_REQUEST:
+ {
+ int value = va_arg(ap, int);
+ st->vbr_rate = value;
+ }
+ break;
+ case HYBRID_GET_VBR_RATE_REQUEST:
+ {
+ int *value = va_arg(ap, int*);
+ *value = st->vbr_rate;
+ }
+ break;
+ default:
+ fprintf(stderr, "unknown hybrid_encoder_ctl() request: %d", request);
+ break;
}
-
- /* This should be adjusted based on the SILK bandwidth */
- celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(13));
-
- /* Encode high band with CELT */
- /* FIXME: Do some delay compensation here */
- celt_ret = celt_encode_with_ec(st->celt_enc, pcm, NULL, frame_size, data, bytes_per_packet, &enc);
-
- return celt_ret;
}
void hybrid_encoder_destroy(HybridEncoder *st)
@@ -117,3 +184,4 @@ void hybrid_encoder_destroy(HybridEncoder *st)
free(st);
}
+
diff --git a/src/hybrid_encoder.h b/src/hybrid_encoder.h
index 8d8269c3..66ef4dbe 100644
--- a/src/hybrid_encoder.h
+++ b/src/hybrid_encoder.h
@@ -41,6 +41,10 @@ struct HybridEncoder {
CELTEncoder *celt_enc;
void *silk_enc;
SKP_SILK_SDK_EncControlStruct encControl;
+
+ int mode;
+ int bandwidth;
+ int vbr_rate;
};
diff --git a/src/test_hybrid.c b/src/test_hybrid.c
index ed6a6b69..06ae8438 100644
--- a/src/test_hybrid.c
+++ b/src/test_hybrid.c
@@ -58,6 +58,7 @@ int main(int argc, char *argv[])
int count = 0;
int skip;
short *in, *out;
+ int mode=MODE_HYBRID;
if (argc != 9 && argc != 8 && argc != 7)
{
fprintf (stderr, "Usage: test_hybrid <rate> <channels> <frame size> "
@@ -96,6 +97,13 @@ int main(int argc, char *argv[])
enc = hybrid_encoder_create();
dec = hybrid_decoder_create();
+ mode = MODE_HYBRID;
+ hybrid_encoder_ctl(enc, HYBRID_SET_BANDWIDTH(BANDWIDTH_FULLBAND));
+ hybrid_encoder_ctl(enc, HYBRID_SET_MODE(mode));
+
+ hybrid_decoder_ctl(dec, HYBRID_SET_BANDWIDTH(BANDWIDTH_FULLBAND));
+ hybrid_decoder_ctl(dec, HYBRID_SET_MODE(mode));
+
in = (short*)malloc(frame_size*channels*sizeof(short));
out = (short*)malloc(frame_size*channels*sizeof(short));
while (!feof(fin))