diff options
-rw-r--r-- | COPYING | 6 | ||||
-rw-r--r-- | opus_sources.mk | 3 | ||||
-rw-r--r-- | src/opus.c | 45 | ||||
-rw-r--r-- | src/opus.h | 2 | ||||
-rw-r--r-- | src/opus_custom.h | 82 | ||||
-rw-r--r-- | src/test_opus_custom.c | 206 |
6 files changed, 340 insertions, 4 deletions
@@ -1,6 +1,6 @@ -Copyright 2001-2010 Xiph.Org, Jean-Marc Valin, - Timothy B. Terriberry, CSIRO, - and other contributors +Copyright 2001-2010 Xiph.Org, Skype, Octasic, + Jean-Marc Valin, Timothy B. Terriberry, + CSIRO, and other contributors Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/opus_sources.mk b/opus_sources.mk index 077d2117..06df75ab 100644 --- a/opus_sources.mk +++ b/opus_sources.mk @@ -1,2 +1,3 @@ -OPUS_SOURCES = src/opus_decoder.c \ +OPUS_SOURCES = src/opus.c \ +src/opus_decoder.c \ src/opus_encoder.c diff --git a/src/opus.c b/src/opus.c new file mode 100644 index 00000000..14dc3d87 --- /dev/null +++ b/src/opus.c @@ -0,0 +1,45 @@ +/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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 FOUNDATION 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. +*/ + + +const char *opus_strerror(int error) +{ + static const char *error_strings[8] = { + "success", + "invalid argument", + "buffer too small", + "internal error", + "corrupted stream", + "request not implemented", + "invalid state", + "memory allocation failed" + }; + if (error > 0 || error < -7) + return "unknown error"; + else + return error_strings[-error]; +} @@ -218,6 +218,8 @@ 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); +OPUS_EXPORT const char *opus_strerror(int error); + /* For testing purposes: the encoder and decoder state should always be identical after coding a payload */ #if OPUS_TEST_RANGE_CODER_STATE OPUS_EXPORT int opus_encoder_get_final_range(OpusEncoder *st); diff --git a/src/opus_custom.h b/src/opus_custom.h new file mode 100644 index 00000000..19719f09 --- /dev/null +++ b/src/opus_custom.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/** + @file celt.h + @brief Contains all the functions for encoding and decoding audio + */ + +/* + 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 FOUNDATION 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. +*/ + +#ifndef OPUS_CUSTOM_H +#define OPUS_CUSTOM_H + +#ifdef ENABLE_OPUS_CUSTOM + +#include "celt.h" +#include "opus.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define OpusCustomEncoder CELTEncoder +#define OpusCustomDecoder CELTDecoder +#define OpusCustomMode CELTMode + + + +#define opus_custom_mode_create celt_mode_create +#define opus_custom_mode_destroy celt_mode_destroy + +#define opus_custom_encoder_get_size celt_encoder_get_size_custom +#define opus_custom_encoder_create celt_encoder_create_custom +#define opus_custom_encoder_init celt_encoder_init_custom + + +#define opus_custom_encoder_destroy celt_encoder_destroy + +#define opus_custom_encode_float celt_encode_float +#define opus_custom_encode celt_encode +#define opus_custom_encoder_ctl celt_encoder_ctl +#define opus_custom_decoder_get_size celt_decoder_get_size_custom +#define opus_custom_decoder_create celt_decoder_create_custom +#define opus_custom_decoder_init celt_decoder_init_custom +#define opus_custom_decoder_destroy celt_decoder_destroy +#define opus_custom_decode_float celt_decode_float +#define opus_custom_decode celt_decode +#define opus_custom_decoder_ctl celt_decoder_ctl + + +#ifdef __cplusplus +} +#endif + +#endif /* ENABLE_OPUS_CUSTOM */ + +#endif /* OPUS_CUSTOM_H */ diff --git a/src/test_opus_custom.c b/src/test_opus_custom.c new file mode 100644 index 00000000..6e26f10a --- /dev/null +++ b/src/test_opus_custom.c @@ -0,0 +1,206 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by 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 FOUNDATION 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. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_custom.h" +#include "arch.h" +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <string.h> + +#define MAX_PACKET 1275 + +int main(int argc, char *argv[]) +{ + int err; + char *inFile, *outFile; + FILE *fin, *fout; + CELTMode *mode=NULL; + CELTEncoder *enc; + CELTDecoder *dec; + int len; + celt_int32 frame_size, channels; + int bytes_per_packet; + unsigned char data[MAX_PACKET]; + int rate; + int complexity; +#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) + int i; + double rmsd = 0; +#endif + int count = 0; + celt_int32 skip; + celt_int16 *in, *out; + if (argc != 9 && argc != 8 && argc != 7) + { + fprintf (stderr, "Usage: testcelt <rate> <channels> <frame size> " + " <bytes per packet> [<complexity> [packet loss rate]] " + "<input> <output>\n"); + return 1; + } + + rate = atoi(argv[1]); + channels = atoi(argv[2]); + frame_size = atoi(argv[3]); + mode = opus_custom_mode_create(rate, frame_size, NULL); + if (mode == NULL) + { + fprintf(stderr, "failed to create a mode\n"); + return 1; + } + + bytes_per_packet = atoi(argv[4]); + if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) + { + fprintf (stderr, "bytes per packet must be between 0 and %d\n", + MAX_PACKET); + return 1; + } + + inFile = argv[argc-2]; + fin = fopen(inFile, "rb"); + if (!fin) + { + fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); + return 1; + } + outFile = argv[argc-1]; + fout = fopen(outFile, "wb+"); + if (!fout) + { + fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); + return 1; + } + + enc = opus_custom_encoder_create(mode, channels, &err); + if (err != 0) + { + fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err)); + return 1; + } + dec = opus_custom_decoder_create(mode, channels, &err); + if (err != 0) + { + fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err)); + return 1; + } + opus_custom_decoder_ctl(dec, CELT_GET_LOOKAHEAD(&skip)); + + if (argc>7) + { + complexity=atoi(argv[5]); + opus_custom_encoder_ctl(enc,CELT_SET_COMPLEXITY(complexity)); + } + + in = (celt_int16*)malloc(frame_size*channels*sizeof(celt_int16)); + out = (celt_int16*)malloc(frame_size*channels*sizeof(celt_int16)); + + while (!feof(fin)) + { + int ret; + err = fread(in, sizeof(short), frame_size*channels, fin); + if (feof(fin)) + break; + len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet); + if (len <= 0) + fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len)); + + /* This is for simulating bit errors */ +#if 0 + int errors = 0; + int eid = 0; + /* This simulates random bit error */ + for (i=0;i<len*8;i++) + { + if (rand()%atoi(argv[8])==0) + { + if (i<64) + { + errors++; + eid = i; + } + data[i/8] ^= 1<<(7-(i%8)); + } + } + if (errors == 1) + data[eid/8] ^= 1<<(7-(eid%8)); + else if (errors%2 == 1) + data[rand()%8] ^= 1<<rand()%8; +#endif + +#if 1 /* Set to zero to use the encoder's output instead */ + /* This is to simulate packet loss */ + if (argc==9 && rand()%1000<atoi(argv[argc-3])) + /*if (errors && (errors%2==0))*/ + ret = opus_custom_decode(dec, NULL, len, out, frame_size); + else + ret = opus_custom_decode(dec, data, len, out, frame_size); + if (ret < 0) + fprintf(stderr, "opus_custom_decode() failed: %s\n", opus_strerror(ret)); +#else + for (i=0;i<ret*channels;i++) + out[i] = in[i]; +#endif +#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) + for (i=0;i<ret*channels;i++) + { + rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]); + /*out[i] -= in[i];*/ + } +#endif + count++; + fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout); + skip = 0; + } + PRINT_MIPS(stderr); + + opus_custom_encoder_destroy(enc); + opus_custom_decoder_destroy(dec); + fclose(fin); + fclose(fout); + opus_custom_mode_destroy(mode); + free(in); + free(out); +#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) + if (rmsd > 0) + { + rmsd = sqrt(rmsd/(1.0*frame_size*channels*count)); + fprintf (stderr, "Error: encoder doesn't match decoder\n"); + fprintf (stderr, "RMS mismatch is %f\n", rmsd); + return 1; + } else { + fprintf (stderr, "Encoder matches decoder!!\n"); + } +#endif + return 0; +} + |