early-access version 1255
This commit is contained in:
126
externals/opus/opus/tests/opus_decode_fuzzer.c
vendored
Executable file
126
externals/opus/opus/tests/opus_decode_fuzzer.c
vendored
Executable file
@@ -0,0 +1,126 @@
|
||||
/* Copyright (c) 2017 Google Inc. */
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "opus.h"
|
||||
#include "opus_types.h"
|
||||
|
||||
#define MAX_FRAME_SAMP 5760
|
||||
#define MAX_PACKET 1500
|
||||
|
||||
/* 4 bytes: packet length, 4 bytes: encoder final range */
|
||||
#define SETUP_BYTE_COUNT 8
|
||||
|
||||
typedef struct {
|
||||
int fs;
|
||||
int channels;
|
||||
} TocInfo;
|
||||
|
||||
static void ParseToc(const uint8_t *toc, TocInfo *const info) {
|
||||
const int samp_freqs[5] = {8000, 12000, 16000, 24000, 48000};
|
||||
const int bandwidth = opus_packet_get_bandwidth(toc);
|
||||
|
||||
info->fs = samp_freqs[bandwidth - OPUS_BANDWIDTH_NARROWBAND];
|
||||
info->channels = opus_packet_get_nb_channels(toc);
|
||||
}
|
||||
|
||||
/* Treats the input data as concatenated packets encoded by opus_demo,
|
||||
* structured as
|
||||
* bytes 0..3: packet length
|
||||
* bytes 4..7: encoder final range
|
||||
* bytes 8+ : Opus packet, including ToC
|
||||
*/
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
OpusDecoder *dec;
|
||||
opus_int16 *pcm;
|
||||
uint8_t *packet;
|
||||
TocInfo toc;
|
||||
int i, err;
|
||||
|
||||
/* Not enough data to setup the decoder (+1 for the ToC) */
|
||||
if (size < SETUP_BYTE_COUNT + 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create decoder based on info from the first ToC available */
|
||||
ParseToc(&data[SETUP_BYTE_COUNT], &toc);
|
||||
|
||||
dec = opus_decoder_create(toc.fs, toc.channels, &err);
|
||||
if (err != OPUS_OK | dec == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcm = (opus_int16*) malloc(sizeof(*pcm) * MAX_FRAME_SAMP * toc.channels);
|
||||
packet = (uint8_t*) calloc(MAX_PACKET, sizeof(*packet));
|
||||
|
||||
i = 0;
|
||||
while (1) {
|
||||
int len, fec;
|
||||
|
||||
if (i + SETUP_BYTE_COUNT >= size) {
|
||||
break;
|
||||
}
|
||||
|
||||
len = (opus_uint32) data[i ] << 24 |
|
||||
(opus_uint32) data[i + 1] << 16 |
|
||||
(opus_uint32) data[i + 2] << 8 |
|
||||
(opus_uint32) data[i + 3];
|
||||
if (len > MAX_PACKET || len < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Bytes 4..7 represent encoder final range, but are unused here.
|
||||
* Instead, byte 4 is repurposed to determine if FEC is used. */
|
||||
fec = data[i + 4] & 1;
|
||||
|
||||
/* Lost packet */
|
||||
if (len == 0) {
|
||||
int frame_size;
|
||||
opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&frame_size));
|
||||
(void) opus_decode(dec, NULL, size, pcm, frame_size, fec);
|
||||
} else {
|
||||
if (i + SETUP_BYTE_COUNT + len > size) {
|
||||
break;
|
||||
}
|
||||
memcpy(pcm, &data[i + SETUP_BYTE_COUNT], len);
|
||||
(void) opus_decode(dec, data, size, pcm, MAX_FRAME_SAMP, fec);
|
||||
}
|
||||
|
||||
i += SETUP_BYTE_COUNT + len;
|
||||
}
|
||||
|
||||
opus_decoder_destroy(dec);
|
||||
free(pcm);
|
||||
free(packet);
|
||||
|
||||
return 0;
|
||||
}
|
2
externals/opus/opus/tests/opus_decode_fuzzer.options
vendored
Executable file
2
externals/opus/opus/tests/opus_decode_fuzzer.options
vendored
Executable file
@@ -0,0 +1,2 @@
|
||||
[libfuzzer]
|
||||
max_len = 1000000
|
1035
externals/opus/opus/tests/opus_encode_regressions.c
vendored
Executable file
1035
externals/opus/opus/tests/opus_encode_regressions.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
143
externals/opus/opus/tests/run_vectors.sh
vendored
Executable file
143
externals/opus/opus/tests/run_vectors.sh
vendored
Executable file
@@ -0,0 +1,143 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2011-2012 Jean-Marc Valin
|
||||
#
|
||||
# This file is extracted from RFC6716. Please see that RFC for additional
|
||||
# information.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# - Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||
# names of specific contributors, may be used to endorse or promote
|
||||
# products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# 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.
|
||||
|
||||
rm -f logs_mono.txt logs_mono2.txt
|
||||
rm -f logs_stereo.txt logs_stereo2.txt
|
||||
|
||||
if [ "$#" -ne "3" ]; then
|
||||
echo "usage: run_vectors.sh <exec path> <vector path> <rate>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CMD_PATH=$1
|
||||
VECTOR_PATH=$2
|
||||
RATE=$3
|
||||
|
||||
: ${OPUS_DEMO:=$CMD_PATH/opus_demo}
|
||||
: ${OPUS_COMPARE:=$CMD_PATH/opus_compare}
|
||||
|
||||
if [ -d "$VECTOR_PATH" ]; then
|
||||
echo "Test vectors found in $VECTOR_PATH"
|
||||
else
|
||||
echo "No test vectors found"
|
||||
#Don't make the test fail here because the test vectors
|
||||
#will be distributed separately
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -x "$OPUS_COMPARE" ]; then
|
||||
echo "ERROR: Compare program not found: $OPUS_COMPARE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -x "$OPUS_DEMO" ]; then
|
||||
echo "Decoding with $OPUS_DEMO"
|
||||
else
|
||||
echo "ERROR: Decoder not found: $OPUS_DEMO"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=============="
|
||||
echo "Testing mono"
|
||||
echo "=============="
|
||||
echo
|
||||
|
||||
for file in 01 02 03 04 05 06 07 08 09 10 11 12
|
||||
do
|
||||
if [ -e "$VECTOR_PATH/testvector$file.bit" ]; then
|
||||
echo "Testing testvector$file"
|
||||
else
|
||||
echo "Bitstream file not found: testvector$file.bit"
|
||||
fi
|
||||
if "$OPUS_DEMO" -d "$RATE" 1 "$VECTOR_PATH/testvector$file.bit" tmp.out >> logs_mono.txt 2>&1; then
|
||||
echo "successfully decoded"
|
||||
else
|
||||
echo "ERROR: decoding failed"
|
||||
exit 1
|
||||
fi
|
||||
"$OPUS_COMPARE" -r "$RATE" "$VECTOR_PATH/testvector${file}.dec" tmp.out >> logs_mono.txt 2>&1
|
||||
float_ret=$?
|
||||
"$OPUS_COMPARE" -r "$RATE" "$VECTOR_PATH/testvector${file}m.dec" tmp.out >> logs_mono2.txt 2>&1
|
||||
float_ret2=$?
|
||||
if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
|
||||
echo "output matches reference"
|
||||
else
|
||||
echo "ERROR: output does not match reference"
|
||||
exit 1
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
echo "=============="
|
||||
echo Testing stereo
|
||||
echo "=============="
|
||||
echo
|
||||
|
||||
for file in 01 02 03 04 05 06 07 08 09 10 11 12
|
||||
do
|
||||
if [ -e "$VECTOR_PATH/testvector$file.bit" ]; then
|
||||
echo "Testing testvector$file"
|
||||
else
|
||||
echo "Bitstream file not found: testvector$file"
|
||||
fi
|
||||
if "$OPUS_DEMO" -d "$RATE" 2 "$VECTOR_PATH/testvector$file.bit" tmp.out >> logs_stereo.txt 2>&1; then
|
||||
echo "successfully decoded"
|
||||
else
|
||||
echo "ERROR: decoding failed"
|
||||
exit 1
|
||||
fi
|
||||
"$OPUS_COMPARE" -s -r "$RATE" "$VECTOR_PATH/testvector${file}.dec" tmp.out >> logs_stereo.txt 2>&1
|
||||
float_ret=$?
|
||||
"$OPUS_COMPARE" -s -r "$RATE" "$VECTOR_PATH/testvector${file}m.dec" tmp.out >> logs_stereo2.txt 2>&1
|
||||
float_ret2=$?
|
||||
if [ "$float_ret" -eq "0" ] || [ "$float_ret2" -eq "0" ]; then
|
||||
echo "output matches reference"
|
||||
else
|
||||
echo "ERROR: output does not match reference"
|
||||
exit 1
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
|
||||
|
||||
echo "All tests have passed successfully"
|
||||
mono1=`grep quality logs_mono.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
mono2=`grep quality logs_mono2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
echo $mono1 $mono2 | awk '{if ($2 > $1) $1 = $2; print "Average mono quality is", $1, "%"}'
|
||||
|
||||
stereo1=`grep quality logs_stereo.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
stereo2=`grep quality logs_stereo2.txt | awk '{sum+=$4}END{if (NR == 12) sum /= 12; else sum = 0; print sum}'`
|
||||
echo $stereo1 $stereo2 | awk '{if ($2 > $1) $1 = $2; print "Average stereo quality is", $1, "%"}'
|
1904
externals/opus/opus/tests/test_opus_api.c
vendored
Executable file
1904
externals/opus/opus/tests/test_opus_api.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
82
externals/opus/opus/tests/test_opus_common.h
vendored
Executable file
82
externals/opus/opus/tests/test_opus_common.h
vendored
Executable file
@@ -0,0 +1,82 @@
|
||||
/* Copyright (c) 2011 Xiph.Org Foundation
|
||||
Written by Gregory Maxwell */
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
static OPUS_INLINE void deb2_impl(unsigned char *_t,unsigned char **_p,int _k,int _x,int _y)
|
||||
{
|
||||
int i;
|
||||
if(_x>2){
|
||||
if(_y<3)for(i=0;i<_y;i++)*(--*_p)=_t[i+1];
|
||||
}else{
|
||||
_t[_x]=_t[_x-_y];
|
||||
deb2_impl(_t,_p,_k,_x+1,_y);
|
||||
for(i=_t[_x-_y]+1;i<_k;i++){
|
||||
_t[_x]=i;
|
||||
deb2_impl(_t,_p,_k,_x+1,_x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*Generates a De Bruijn sequence (k,2) with length k^2*/
|
||||
static OPUS_INLINE void debruijn2(int _k, unsigned char *_res)
|
||||
{
|
||||
unsigned char *p;
|
||||
unsigned char *t;
|
||||
t=malloc(sizeof(unsigned char)*_k*2);
|
||||
memset(t,0,sizeof(unsigned char)*_k*2);
|
||||
p=&_res[_k*_k];
|
||||
deb2_impl(t,&p,_k,1,1);
|
||||
free(t);
|
||||
}
|
||||
|
||||
/*MWC RNG of George Marsaglia*/
|
||||
static opus_uint32 Rz, Rw;
|
||||
static OPUS_INLINE opus_uint32 fast_rand(void)
|
||||
{
|
||||
Rz=36969*(Rz&65535)+(Rz>>16);
|
||||
Rw=18000*(Rw&65535)+(Rw>>16);
|
||||
return (Rz<<16)+Rw;
|
||||
}
|
||||
static opus_uint32 iseed;
|
||||
|
||||
#ifdef __GNUC__
|
||||
__attribute__((noreturn))
|
||||
#elif defined(_MSC_VER)
|
||||
__declspec(noreturn)
|
||||
#endif
|
||||
static OPUS_INLINE void _test_failed(const char *file, int line)
|
||||
{
|
||||
fprintf(stderr,"\n ***************************************************\n");
|
||||
fprintf(stderr," *** A fatal error was detected. ***\n");
|
||||
fprintf(stderr," ***************************************************\n");
|
||||
fprintf(stderr,"Please report this failure and include\n");
|
||||
fprintf(stderr,"'make check SEED=%u fails %s at line %d for %s'\n",iseed,file,line,opus_get_version_string());
|
||||
fprintf(stderr,"and any relevant details about your system.\n\n");
|
||||
abort();
|
||||
}
|
||||
#define test_failed() _test_failed(__FILE__, __LINE__);
|
||||
|
||||
void regression_test(void);
|
463
externals/opus/opus/tests/test_opus_decode.c
vendored
Executable file
463
externals/opus/opus/tests/test_opus_decode.c
vendored
Executable file
@@ -0,0 +1,463 @@
|
||||
/* Copyright (c) 2011-2013 Xiph.Org Foundation
|
||||
Written by Gregory Maxwell */
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
#include "opus.h"
|
||||
#include "test_opus_common.h"
|
||||
|
||||
#define MAX_PACKET (1500)
|
||||
#define MAX_FRAME_SAMP (5760)
|
||||
|
||||
int test_decoder_code0(int no_fuzz)
|
||||
{
|
||||
static const opus_int32 fsv[5]={48000,24000,16000,12000,8000};
|
||||
int err,skip,plen;
|
||||
int out_samples,fec;
|
||||
int t;
|
||||
opus_int32 i;
|
||||
OpusDecoder *dec[5*2];
|
||||
opus_int32 decsize;
|
||||
OpusDecoder *decbak;
|
||||
opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc;
|
||||
unsigned char *packet;
|
||||
unsigned char modes[4096];
|
||||
short *outbuf_int;
|
||||
short *outbuf;
|
||||
|
||||
dec_final_range1=dec_final_range2=2;
|
||||
|
||||
packet=malloc(sizeof(unsigned char)*MAX_PACKET);
|
||||
if(packet==NULL)test_failed();
|
||||
|
||||
outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2);
|
||||
for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749;
|
||||
outbuf=&outbuf_int[8*2];
|
||||
|
||||
fprintf(stdout," Starting %d decoders...\n",5*2);
|
||||
for(t=0;t<5*2;t++)
|
||||
{
|
||||
int fs=fsv[t>>1];
|
||||
int c=(t&1)+1;
|
||||
err=OPUS_INTERNAL_ERROR;
|
||||
dec[t] = opus_decoder_create(fs, c, &err);
|
||||
if(err!=OPUS_OK || dec[t]==NULL)test_failed();
|
||||
fprintf(stdout," opus_decoder_create(%5d,%d) OK. Copy ",fs,c);
|
||||
{
|
||||
OpusDecoder *dec2;
|
||||
/*The opus state structures contain no pointers and can be freely copied*/
|
||||
dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c));
|
||||
if(dec2==NULL)test_failed();
|
||||
memcpy(dec2,dec[t],opus_decoder_get_size(c));
|
||||
memset(dec[t],255,opus_decoder_get_size(c));
|
||||
opus_decoder_destroy(dec[t]);
|
||||
printf("OK.\n");
|
||||
dec[t]=dec2;
|
||||
}
|
||||
}
|
||||
|
||||
decsize=opus_decoder_get_size(1);
|
||||
decbak=(OpusDecoder *)malloc(decsize);
|
||||
if(decbak==NULL)test_failed();
|
||||
|
||||
for(t=0;t<5*2;t++)
|
||||
{
|
||||
int factor=48000/fsv[t>>1];
|
||||
for(fec=0;fec<2;fec++)
|
||||
{
|
||||
opus_int32 dur;
|
||||
/*Test PLC on a fresh decoder*/
|
||||
out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
|
||||
if(dur!=120/factor)test_failed();
|
||||
|
||||
/*Test on a size which isn't a multiple of 2.5ms*/
|
||||
out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec);
|
||||
if(out_samples!=OPUS_BAD_ARG)test_failed();
|
||||
|
||||
/*Test null pointer input*/
|
||||
out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
|
||||
if(dur!=120/factor)test_failed();
|
||||
|
||||
/*Zero lengths*/
|
||||
out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
|
||||
/*Zero buffer*/
|
||||
outbuf[0]=32749;
|
||||
out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);
|
||||
if(out_samples>0)test_failed();
|
||||
#if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnonnull"
|
||||
#endif
|
||||
out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
|
||||
#if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
if(out_samples>0)test_failed();
|
||||
if(outbuf[0]!=32749)test_failed();
|
||||
|
||||
/*Invalid lengths*/
|
||||
out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);
|
||||
if(out_samples>=0)test_failed();
|
||||
out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);
|
||||
if(out_samples>=0)test_failed();
|
||||
out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);
|
||||
if(out_samples>=0)test_failed();
|
||||
|
||||
/*Crazy FEC values*/
|
||||
out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);
|
||||
if(out_samples>=0)test_failed();
|
||||
|
||||
/*Reset the decoder*/
|
||||
if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
}
|
||||
}
|
||||
fprintf(stdout," dec[all] initial frame PLC OK.\n");
|
||||
|
||||
/*Count code 0 tests*/
|
||||
for(i=0;i<64;i++)
|
||||
{
|
||||
opus_int32 dur;
|
||||
int j,expected[5*2];
|
||||
packet[0]=i<<2;
|
||||
packet[1]=255;
|
||||
packet[2]=255;
|
||||
err=opus_packet_get_nb_channels(packet);
|
||||
if(err!=(i&1)+1)test_failed();
|
||||
|
||||
for(t=0;t<5*2;t++){
|
||||
expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
|
||||
if(expected[t]>2880)test_failed();
|
||||
}
|
||||
|
||||
for(j=0;j<256;j++)
|
||||
{
|
||||
packet[1]=j;
|
||||
for(t=0;t<5*2;t++)
|
||||
{
|
||||
out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=expected[t])test_failed();
|
||||
if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
|
||||
if(dur!=out_samples)test_failed();
|
||||
opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
|
||||
if(t==0)dec_final_range2=dec_final_range1;
|
||||
else if(dec_final_range1!=dec_final_range2)test_failed();
|
||||
}
|
||||
}
|
||||
|
||||
for(t=0;t<5*2;t++){
|
||||
int factor=48000/fsv[t>>1];
|
||||
/* The PLC is run for 6 frames in order to get better PLC coverage. */
|
||||
for(j=0;j<6;j++)
|
||||
{
|
||||
out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
|
||||
if(out_samples!=expected[t])test_failed();
|
||||
if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
|
||||
if(dur!=out_samples)test_failed();
|
||||
}
|
||||
/* Run the PLC once at 2.5ms, as a simulation of someone trying to
|
||||
do small drift corrections. */
|
||||
if(expected[t]!=120/factor)
|
||||
{
|
||||
out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
|
||||
if(dur!=out_samples)test_failed();
|
||||
}
|
||||
out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
|
||||
if(out_samples>0)test_failed();
|
||||
}
|
||||
}
|
||||
fprintf(stdout," dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n");
|
||||
|
||||
if(no_fuzz)
|
||||
{
|
||||
fprintf(stdout," Skipping many tests which fuzz the decoder as requested.\n");
|
||||
free(decbak);
|
||||
for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
|
||||
printf(" Decoders stopped.\n");
|
||||
|
||||
err=0;
|
||||
for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
|
||||
for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
|
||||
if(err)test_failed();
|
||||
|
||||
free(outbuf_int);
|
||||
free(packet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
{
|
||||
/*We only test a subset of the modes here simply because the longer
|
||||
durations end up taking a long time.*/
|
||||
static const int cmodes[4]={16,20,24,28};
|
||||
static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u};
|
||||
static const opus_uint32 lres[3]={3285687739u,1481572662,694350475};
|
||||
static const int lmodes[3]={0,4,8};
|
||||
int mode=fast_rand()%4;
|
||||
|
||||
packet[0]=cmodes[mode]<<3;
|
||||
dec_final_acc=0;
|
||||
t=fast_rand()%10;
|
||||
|
||||
for(i=0;i<65536;i++)
|
||||
{
|
||||
int factor=48000/fsv[t>>1];
|
||||
packet[1]=i>>8;
|
||||
packet[2]=i&255;
|
||||
packet[3]=255;
|
||||
out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=120/factor)test_failed();
|
||||
opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
|
||||
dec_final_acc+=dec_final_range1;
|
||||
}
|
||||
if(dec_final_acc!=cres[mode])test_failed();
|
||||
fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]);
|
||||
|
||||
mode=fast_rand()%3;
|
||||
packet[0]=lmodes[mode]<<3;
|
||||
dec_final_acc=0;
|
||||
t=fast_rand()%10;
|
||||
for(i=0;i<65536;i++)
|
||||
{
|
||||
int factor=48000/fsv[t>>1];
|
||||
packet[1]=i>>8;
|
||||
packet[2]=i&255;
|
||||
packet[3]=255;
|
||||
out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=480/factor)test_failed();
|
||||
opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
|
||||
dec_final_acc+=dec_final_range1;
|
||||
}
|
||||
if(dec_final_acc!=lres[mode])test_failed();
|
||||
fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]);
|
||||
}
|
||||
|
||||
skip=fast_rand()%7;
|
||||
for(i=0;i<64;i++)
|
||||
{
|
||||
int j,expected[5*2];
|
||||
packet[0]=i<<2;
|
||||
for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
|
||||
for(j=2+skip;j<1275;j+=4)
|
||||
{
|
||||
int jj;
|
||||
for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;
|
||||
for(t=0;t<5*2;t++)
|
||||
{
|
||||
out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=expected[t])test_failed();
|
||||
opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
|
||||
if(t==0)dec_final_range2=dec_final_range1;
|
||||
else if(dec_final_range1!=dec_final_range2)test_failed();
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(stdout," dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip);
|
||||
|
||||
debruijn2(64,modes);
|
||||
plen=(fast_rand()%18+3)*8+skip+3;
|
||||
for(i=0;i<4096;i++)
|
||||
{
|
||||
int j,expected[5*2];
|
||||
packet[0]=modes[i]<<2;
|
||||
for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
|
||||
for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
|
||||
memcpy(decbak,dec[0],decsize);
|
||||
if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
|
||||
memcpy(decbak,dec[0],decsize);
|
||||
if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
|
||||
memcpy(decbak,dec[0],decsize);
|
||||
if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
|
||||
for(t=0;t<5*2;t++)
|
||||
{
|
||||
opus_int32 dur;
|
||||
out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=expected[t])test_failed();
|
||||
if(t==0)dec_final_range2=dec_final_range1;
|
||||
else if(dec_final_range1!=dec_final_range2)test_failed();
|
||||
if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
|
||||
if(dur!=out_samples)test_failed();
|
||||
}
|
||||
}
|
||||
fprintf(stdout," dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
|
||||
|
||||
plen=(fast_rand()%18+3)*8+skip+3;
|
||||
t=rand()&3;
|
||||
for(i=0;i<4096;i++)
|
||||
{
|
||||
int count,j,expected;
|
||||
packet[0]=modes[i]<<2;
|
||||
expected=opus_decoder_get_nb_samples(dec[t],packet,plen);
|
||||
for(count=0;count<10;count++)
|
||||
{
|
||||
for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
|
||||
out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=expected)test_failed();
|
||||
}
|
||||
}
|
||||
fprintf(stdout," dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1);
|
||||
|
||||
{
|
||||
int tmodes[1]={25<<2};
|
||||
opus_uint32 tseeds[1]={140441};
|
||||
int tlen[1]={157};
|
||||
opus_int32 tret[1]={480};
|
||||
t=fast_rand()&1;
|
||||
for(i=0;i<1;i++)
|
||||
{
|
||||
int j;
|
||||
packet[0]=tmodes[i];
|
||||
Rw=Rz=tseeds[i];
|
||||
for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;
|
||||
out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=tret[i])test_failed();
|
||||
}
|
||||
fprintf(stdout," dec[%3d] pre-selected random packets OK.\n",t);
|
||||
}
|
||||
|
||||
free(decbak);
|
||||
for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
|
||||
printf(" Decoders stopped.\n");
|
||||
|
||||
err=0;
|
||||
for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
|
||||
for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
|
||||
if(err)test_failed();
|
||||
|
||||
free(outbuf_int);
|
||||
free(packet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
void test_soft_clip(void)
|
||||
{
|
||||
int i,j;
|
||||
float x[1024];
|
||||
float s[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
fprintf(stdout," Testing opus_pcm_soft_clip... ");
|
||||
for(i=0;i<1024;i++)
|
||||
{
|
||||
for (j=0;j<1024;j++)
|
||||
{
|
||||
x[j]=(j&255)*(1/32.f)-4.f;
|
||||
}
|
||||
opus_pcm_soft_clip(&x[i],1024-i,1,s);
|
||||
for (j=i;j<1024;j++)
|
||||
{
|
||||
if(x[j]>1.f)test_failed();
|
||||
if(x[j]<-1.f)test_failed();
|
||||
}
|
||||
}
|
||||
for(i=1;i<9;i++)
|
||||
{
|
||||
for (j=0;j<1024;j++)
|
||||
{
|
||||
x[j]=(j&255)*(1/32.f)-4.f;
|
||||
}
|
||||
opus_pcm_soft_clip(x,1024/i,i,s);
|
||||
for (j=0;j<(1024/i)*i;j++)
|
||||
{
|
||||
if(x[j]>1.f)test_failed();
|
||||
if(x[j]<-1.f)test_failed();
|
||||
}
|
||||
}
|
||||
opus_pcm_soft_clip(x,0,1,s);
|
||||
opus_pcm_soft_clip(x,1,0,s);
|
||||
opus_pcm_soft_clip(x,1,1,0);
|
||||
opus_pcm_soft_clip(x,1,-1,s);
|
||||
opus_pcm_soft_clip(x,-1,1,s);
|
||||
opus_pcm_soft_clip(0,1,1,s);
|
||||
printf("OK.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int _argc, char **_argv)
|
||||
{
|
||||
const char * oversion;
|
||||
const char * env_seed;
|
||||
int env_used;
|
||||
|
||||
if(_argc>2)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
env_used=0;
|
||||
env_seed=getenv("SEED");
|
||||
if(_argc>1)iseed=atoi(_argv[1]);
|
||||
else if(env_seed)
|
||||
{
|
||||
iseed=atoi(env_seed);
|
||||
env_used=1;
|
||||
}
|
||||
else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
|
||||
Rw=Rz=iseed;
|
||||
|
||||
oversion=opus_get_version_string();
|
||||
if(!oversion)test_failed();
|
||||
fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
|
||||
if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed);
|
||||
|
||||
/*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
|
||||
into the decoders. This is helpful because garbage data
|
||||
may cause the decoders to clip, which angers CLANG IOC.*/
|
||||
test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL);
|
||||
#ifndef DISABLE_FLOAT_API
|
||||
test_soft_clip();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
703
externals/opus/opus/tests/test_opus_encode.c
vendored
Executable file
703
externals/opus/opus/tests/test_opus_encode.c
vendored
Executable file
@@ -0,0 +1,703 @@
|
||||
/* Copyright (c) 2011-2013 Xiph.Org Foundation
|
||||
Written by Gregory Maxwell */
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include <process.h>
|
||||
#define getpid _getpid
|
||||
#endif
|
||||
#include "opus_multistream.h"
|
||||
#include "opus.h"
|
||||
#include "../src/opus_private.h"
|
||||
#include "test_opus_common.h"
|
||||
|
||||
#define MAX_PACKET (1500)
|
||||
#define SAMPLES (48000*30)
|
||||
#define SSAMPLES (SAMPLES/3)
|
||||
#define MAX_FRAME_SAMP (5760)
|
||||
#define PI (3.141592653589793238462643f)
|
||||
#define RAND_SAMPLE(a) (a[fast_rand() % sizeof(a)/sizeof(a[0])])
|
||||
|
||||
void generate_music(short *buf, opus_int32 len)
|
||||
{
|
||||
opus_int32 a1,b1,a2,b2;
|
||||
opus_int32 c1,c2,d1,d2;
|
||||
opus_int32 i,j;
|
||||
a1=b1=a2=b2=0;
|
||||
c1=c2=d1=d2=0;
|
||||
j=0;
|
||||
/*60ms silence*/
|
||||
for(i=0;i<2880;i++)buf[i*2]=buf[i*2+1]=0;
|
||||
for(i=2880;i<len;i++)
|
||||
{
|
||||
opus_uint32 r;
|
||||
opus_int32 v1,v2;
|
||||
v1=v2=(((j*((j>>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15;
|
||||
r=fast_rand();v1+=r&65535;v1-=r>>16;
|
||||
r=fast_rand();v2+=r&65535;v2-=r>>16;
|
||||
b1=v1-a1+((b1*61+32)>>6);a1=v1;
|
||||
b2=v2-a2+((b2*61+32)>>6);a2=v2;
|
||||
c1=(30*(c1+b1+d1)+32)>>6;d1=b1;
|
||||
c2=(30*(c2+b2+d2)+32)>>6;d2=b2;
|
||||
v1=(c1+128)>>8;
|
||||
v2=(c2+128)>>8;
|
||||
buf[i*2]=v1>32767?32767:(v1<-32768?-32768:v1);
|
||||
buf[i*2+1]=v2>32767?32767:(v2<-32768?-32768:v2);
|
||||
if(i%6==0)j++;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int save_ctr = 0;
|
||||
static void int_to_char(opus_uint32 i, unsigned char ch[4])
|
||||
{
|
||||
ch[0] = i>>24;
|
||||
ch[1] = (i>>16)&0xFF;
|
||||
ch[2] = (i>>8)&0xFF;
|
||||
ch[3] = i&0xFF;
|
||||
}
|
||||
|
||||
static OPUS_INLINE void save_packet(unsigned char* p, int len, opus_uint32 rng)
|
||||
{
|
||||
FILE *fout;
|
||||
unsigned char int_field[4];
|
||||
char name[256];
|
||||
snprintf(name,255,"test_opus_encode.%llu.%d.bit",(unsigned long long)iseed,save_ctr);
|
||||
fprintf(stdout,"writing %d byte packet to %s\n",len,name);
|
||||
fout=fopen(name, "wb+");
|
||||
if(fout==NULL)test_failed();
|
||||
int_to_char(len, int_field);
|
||||
fwrite(int_field, 1, 4, fout);
|
||||
int_to_char(rng, int_field);
|
||||
fwrite(int_field, 1, 4, fout);
|
||||
fwrite(p, 1, len, fout);
|
||||
fclose(fout);
|
||||
save_ctr++;
|
||||
}
|
||||
#endif
|
||||
|
||||
int get_frame_size_enum(int frame_size, int sampling_rate)
|
||||
{
|
||||
int frame_size_enum;
|
||||
|
||||
if(frame_size==sampling_rate/400)
|
||||
frame_size_enum = OPUS_FRAMESIZE_2_5_MS;
|
||||
else if(frame_size==sampling_rate/200)
|
||||
frame_size_enum = OPUS_FRAMESIZE_5_MS;
|
||||
else if(frame_size==sampling_rate/100)
|
||||
frame_size_enum = OPUS_FRAMESIZE_10_MS;
|
||||
else if(frame_size==sampling_rate/50)
|
||||
frame_size_enum = OPUS_FRAMESIZE_20_MS;
|
||||
else if(frame_size==sampling_rate/25)
|
||||
frame_size_enum = OPUS_FRAMESIZE_40_MS;
|
||||
else if(frame_size==3*sampling_rate/50)
|
||||
frame_size_enum = OPUS_FRAMESIZE_60_MS;
|
||||
else if(frame_size==4*sampling_rate/50)
|
||||
frame_size_enum = OPUS_FRAMESIZE_80_MS;
|
||||
else if(frame_size==5*sampling_rate/50)
|
||||
frame_size_enum = OPUS_FRAMESIZE_100_MS;
|
||||
else if(frame_size==6*sampling_rate/50)
|
||||
frame_size_enum = OPUS_FRAMESIZE_120_MS;
|
||||
else
|
||||
test_failed();
|
||||
|
||||
return frame_size_enum;
|
||||
}
|
||||
|
||||
int test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *dec)
|
||||
{
|
||||
int samp_count = 0;
|
||||
opus_int16 *inbuf;
|
||||
unsigned char packet[MAX_PACKET+257];
|
||||
int len;
|
||||
opus_int16 *outbuf;
|
||||
int out_samples;
|
||||
int ret = 0;
|
||||
|
||||
/* Generate input data */
|
||||
inbuf = (opus_int16*)malloc(sizeof(*inbuf)*SSAMPLES);
|
||||
generate_music(inbuf, SSAMPLES/2);
|
||||
|
||||
/* Allocate memory for output data */
|
||||
outbuf = (opus_int16*)malloc(sizeof(*outbuf)*MAX_FRAME_SAMP*3);
|
||||
|
||||
/* Encode data, then decode for sanity check */
|
||||
do {
|
||||
len = opus_encode(enc, &inbuf[samp_count*channels], frame_size, packet, MAX_PACKET);
|
||||
if(len<0 || len>MAX_PACKET) {
|
||||
fprintf(stderr,"opus_encode() returned %d\n",len);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
out_samples = opus_decode(dec, packet, len, outbuf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=frame_size) {
|
||||
fprintf(stderr,"opus_decode() returned %d\n",out_samples);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
samp_count += frame_size;
|
||||
} while (samp_count < ((SSAMPLES/2)-MAX_FRAME_SAMP));
|
||||
|
||||
/* Clean up */
|
||||
free(inbuf);
|
||||
free(outbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes)
|
||||
{
|
||||
OpusEncoder *enc;
|
||||
OpusDecoder *dec;
|
||||
int i,j,err;
|
||||
|
||||
/* Parameters to fuzz. Some values are duplicated to increase their probability of being tested. */
|
||||
int sampling_rates[5] = {8000, 12000, 16000, 24000, 48000};
|
||||
int channels[2] = {1, 2};
|
||||
int applications[3] = {OPUS_APPLICATION_AUDIO, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY};
|
||||
int bitrates[11] = {6000, 12000, 16000, 24000, 32000, 48000, 64000, 96000, 510000, OPUS_AUTO, OPUS_BITRATE_MAX};
|
||||
int force_channels[4] = {OPUS_AUTO, OPUS_AUTO, 1, 2};
|
||||
int use_vbr[3] = {0, 1, 1};
|
||||
int vbr_constraints[3] = {0, 1, 1};
|
||||
int complexities[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
int max_bandwidths[6] = {OPUS_BANDWIDTH_NARROWBAND, OPUS_BANDWIDTH_MEDIUMBAND,
|
||||
OPUS_BANDWIDTH_WIDEBAND, OPUS_BANDWIDTH_SUPERWIDEBAND,
|
||||
OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_FULLBAND};
|
||||
int signals[4] = {OPUS_AUTO, OPUS_AUTO, OPUS_SIGNAL_VOICE, OPUS_SIGNAL_MUSIC};
|
||||
int inband_fecs[3] = {0, 0, 1};
|
||||
int packet_loss_perc[4] = {0, 1, 2, 5};
|
||||
int lsb_depths[2] = {8, 24};
|
||||
int prediction_disabled[3] = {0, 0, 1};
|
||||
int use_dtx[2] = {0, 1};
|
||||
int frame_sizes_ms_x2[9] = {5, 10, 20, 40, 80, 120, 160, 200, 240}; /* x2 to avoid 2.5 ms */
|
||||
|
||||
for (i=0; i<num_encoders; i++) {
|
||||
int sampling_rate = RAND_SAMPLE(sampling_rates);
|
||||
int num_channels = RAND_SAMPLE(channels);
|
||||
int application = RAND_SAMPLE(applications);
|
||||
|
||||
dec = opus_decoder_create(sampling_rate, num_channels, &err);
|
||||
if(err!=OPUS_OK || dec==NULL)test_failed();
|
||||
|
||||
enc = opus_encoder_create(sampling_rate, num_channels, application, &err);
|
||||
if(err!=OPUS_OK || enc==NULL)test_failed();
|
||||
|
||||
for (j=0; j<num_setting_changes; j++) {
|
||||
int bitrate = RAND_SAMPLE(bitrates);
|
||||
int force_channel = RAND_SAMPLE(force_channels);
|
||||
int vbr = RAND_SAMPLE(use_vbr);
|
||||
int vbr_constraint = RAND_SAMPLE(vbr_constraints);
|
||||
int complexity = RAND_SAMPLE(complexities);
|
||||
int max_bw = RAND_SAMPLE(max_bandwidths);
|
||||
int sig = RAND_SAMPLE(signals);
|
||||
int inband_fec = RAND_SAMPLE(inband_fecs);
|
||||
int pkt_loss = RAND_SAMPLE(packet_loss_perc);
|
||||
int lsb_depth = RAND_SAMPLE(lsb_depths);
|
||||
int pred_disabled = RAND_SAMPLE(prediction_disabled);
|
||||
int dtx = RAND_SAMPLE(use_dtx);
|
||||
int frame_size_ms_x2 = RAND_SAMPLE(frame_sizes_ms_x2);
|
||||
int frame_size = frame_size_ms_x2*sampling_rate/2000;
|
||||
int frame_size_enum = get_frame_size_enum(frame_size, sampling_rate);
|
||||
force_channel = IMIN(force_channel, num_channels);
|
||||
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(force_channel)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_VBR(vbr)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(vbr_constraint)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(max_bw)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_SIGNAL(sig)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(inband_fec)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(pkt_loss)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(lsb_depth)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(pred_disabled)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_DTX(dtx)) != OPUS_OK) test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(frame_size_enum)) != OPUS_OK) test_failed();
|
||||
|
||||
if(test_encode(enc, num_channels, frame_size, dec)) {
|
||||
fprintf(stderr,
|
||||
"fuzz_encoder_settings: %d kHz, %d ch, application: %d, "
|
||||
"%d bps, force ch: %d, vbr: %d, vbr constraint: %d, complexity: %d, "
|
||||
"max bw: %d, signal: %d, inband fec: %d, pkt loss: %d%%, lsb depth: %d, "
|
||||
"pred disabled: %d, dtx: %d, (%d/2) ms\n",
|
||||
sampling_rate/1000, num_channels, application, bitrate,
|
||||
force_channel, vbr, vbr_constraint, complexity, max_bw, sig, inband_fec,
|
||||
pkt_loss, lsb_depth, pred_disabled, dtx, frame_size_ms_x2);
|
||||
test_failed();
|
||||
}
|
||||
}
|
||||
|
||||
opus_encoder_destroy(enc);
|
||||
opus_decoder_destroy(dec);
|
||||
}
|
||||
}
|
||||
|
||||
int run_test1(int no_fuzz)
|
||||
{
|
||||
static const int fsizes[6]={960*3,960*2,120,240,480,960};
|
||||
static const char *mstrings[3] = {" LP","Hybrid"," MDCT"};
|
||||
unsigned char mapping[256] = {0,1,255};
|
||||
unsigned char db62[36];
|
||||
opus_int32 i,j;
|
||||
int rc,err;
|
||||
OpusEncoder *enc;
|
||||
OpusMSEncoder *MSenc;
|
||||
OpusDecoder *dec;
|
||||
OpusMSDecoder *MSdec;
|
||||
OpusMSDecoder *MSdec_err;
|
||||
OpusDecoder *dec_err[10];
|
||||
short *inbuf;
|
||||
short *outbuf;
|
||||
short *out2buf;
|
||||
opus_int32 bitrate_bps;
|
||||
unsigned char packet[MAX_PACKET+257];
|
||||
opus_uint32 enc_final_range;
|
||||
opus_uint32 dec_final_range;
|
||||
int fswitch;
|
||||
int fsize;
|
||||
int count;
|
||||
|
||||
/*FIXME: encoder api tests, fs!=48k, mono, VBR*/
|
||||
|
||||
fprintf(stdout," Encode+Decode tests.\n");
|
||||
|
||||
enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err);
|
||||
if(err != OPUS_OK || enc==NULL)test_failed();
|
||||
|
||||
for(i=0;i<2;i++)
|
||||
{
|
||||
int *ret_err;
|
||||
ret_err = i?0:&err;
|
||||
MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_UNIMPLEMENTED, ret_err);
|
||||
if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
|
||||
|
||||
MSenc = opus_multistream_encoder_create(8000, 0, 1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
|
||||
if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
|
||||
|
||||
MSenc = opus_multistream_encoder_create(44100, 2, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
|
||||
if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
|
||||
|
||||
MSenc = opus_multistream_encoder_create(8000, 2, 2, 3, mapping, OPUS_APPLICATION_VOIP, ret_err);
|
||||
if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
|
||||
|
||||
MSenc = opus_multistream_encoder_create(8000, 2, -1, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
|
||||
if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
|
||||
|
||||
MSenc = opus_multistream_encoder_create(8000, 256, 2, 0, mapping, OPUS_APPLICATION_VOIP, ret_err);
|
||||
if((ret_err && *ret_err != OPUS_BAD_ARG) || MSenc!=NULL)test_failed();
|
||||
}
|
||||
|
||||
MSenc = opus_multistream_encoder_create(8000, 2, 2, 0, mapping, OPUS_APPLICATION_AUDIO, &err);
|
||||
if(err != OPUS_OK || MSenc==NULL)test_failed();
|
||||
|
||||
/*Some multistream encoder API tests*/
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_LSB_DEPTH(&i))!=OPUS_OK)test_failed();
|
||||
if(i<16)test_failed();
|
||||
|
||||
{
|
||||
OpusEncoder *tmp_enc;
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_MULTISTREAM_GET_ENCODER_STATE(1,&tmp_enc))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(tmp_enc, OPUS_GET_LSB_DEPTH(&j))!=OPUS_OK)test_failed();
|
||||
if(i!=j)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_MULTISTREAM_GET_ENCODER_STATE(2,&tmp_enc))!=OPUS_BAD_ARG)test_failed();
|
||||
}
|
||||
|
||||
dec = opus_decoder_create(48000, 2, &err);
|
||||
if(err != OPUS_OK || dec==NULL)test_failed();
|
||||
|
||||
MSdec = opus_multistream_decoder_create(48000, 2, 2, 0, mapping, &err);
|
||||
if(err != OPUS_OK || MSdec==NULL)test_failed();
|
||||
|
||||
MSdec_err = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, &err);
|
||||
if(err != OPUS_OK || MSdec_err==NULL)test_failed();
|
||||
|
||||
dec_err[0]=(OpusDecoder *)malloc(opus_decoder_get_size(2));
|
||||
memcpy(dec_err[0],dec,opus_decoder_get_size(2));
|
||||
dec_err[1] = opus_decoder_create(48000, 1, &err);
|
||||
dec_err[2] = opus_decoder_create(24000, 2, &err);
|
||||
dec_err[3] = opus_decoder_create(24000, 1, &err);
|
||||
dec_err[4] = opus_decoder_create(16000, 2, &err);
|
||||
dec_err[5] = opus_decoder_create(16000, 1, &err);
|
||||
dec_err[6] = opus_decoder_create(12000, 2, &err);
|
||||
dec_err[7] = opus_decoder_create(12000, 1, &err);
|
||||
dec_err[8] = opus_decoder_create(8000, 2, &err);
|
||||
dec_err[9] = opus_decoder_create(8000, 1, &err);
|
||||
for(i=0;i<10;i++)if(dec_err[i]==NULL)test_failed();
|
||||
|
||||
{
|
||||
OpusEncoder *enccpy;
|
||||
/*The opus state structures contain no pointers and can be freely copied*/
|
||||
enccpy=(OpusEncoder *)malloc(opus_encoder_get_size(2));
|
||||
memcpy(enccpy,enc,opus_encoder_get_size(2));
|
||||
memset(enc,255,opus_encoder_get_size(2));
|
||||
opus_encoder_destroy(enc);
|
||||
enc=enccpy;
|
||||
}
|
||||
|
||||
inbuf=(short *)malloc(sizeof(short)*SAMPLES*2);
|
||||
outbuf=(short *)malloc(sizeof(short)*SAMPLES*2);
|
||||
out2buf=(short *)malloc(sizeof(short)*MAX_FRAME_SAMP*3);
|
||||
if(inbuf==NULL || outbuf==NULL || out2buf==NULL)test_failed();
|
||||
|
||||
generate_music(inbuf,SAMPLES);
|
||||
|
||||
/* FILE *foo;
|
||||
foo = fopen("foo.sw", "wb+");
|
||||
fwrite(inbuf, 1, SAMPLES*2*2, foo);
|
||||
fclose(foo);*/
|
||||
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(-2))!=OPUS_BAD_ARG)test_failed();
|
||||
if(opus_encode(enc, inbuf, 500, packet, MAX_PACKET)!=OPUS_BAD_ARG)test_failed();
|
||||
|
||||
for(rc=0;rc<3;rc++)
|
||||
{
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();
|
||||
for(j=0;j<13;j++)
|
||||
{
|
||||
int rate;
|
||||
int modes[13]={0,0,0,1,1,1,1,2,2,2,2,2,2};
|
||||
int rates[13]={6000,12000,48000,16000,32000,48000,64000,512000,13000,24000,48000,64000,96000};
|
||||
int frame[13]={960*2,960,480,960,960,960,480,960*3,960*3,960,480,240,120};
|
||||
rate=rates[j]+fast_rand()%rates[j];
|
||||
count=i=0;
|
||||
do {
|
||||
int bw,len,out_samples,frame_size;
|
||||
frame_size=frame[j];
|
||||
if((fast_rand()&255)==0)
|
||||
{
|
||||
if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
if((fast_rand()&1)!=0)
|
||||
{
|
||||
if(opus_decoder_ctl(dec_err[fast_rand()&1], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
}
|
||||
}
|
||||
if((fast_rand()&127)==0)
|
||||
{
|
||||
if(opus_decoder_ctl(dec_err[fast_rand()&1], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
}
|
||||
if(fast_rand()%10==0){
|
||||
int complex=fast_rand()%11;
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complex))!=OPUS_OK)test_failed();
|
||||
}
|
||||
if(fast_rand()%50==0)opus_decoder_ctl(dec, OPUS_RESET_STATE);
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS((rates[j]>=64000?2:1)))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed();
|
||||
bw=modes[j]==0?OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%3):
|
||||
modes[j]==1?OPUS_BANDWIDTH_SUPERWIDEBAND+(fast_rand()&1):
|
||||
OPUS_BANDWIDTH_NARROWBAND+(fast_rand()%5);
|
||||
if(modes[j]==2&&bw==OPUS_BANDWIDTH_MEDIUMBAND)bw+=3;
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bw))!=OPUS_OK)test_failed();
|
||||
len = opus_encode(enc, &inbuf[i<<1], frame_size, packet, MAX_PACKET);
|
||||
if(len<0 || len>MAX_PACKET)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();
|
||||
if((fast_rand()&3)==0)
|
||||
{
|
||||
if(opus_packet_pad(packet,len,len+1)!=OPUS_OK)test_failed();
|
||||
len++;
|
||||
}
|
||||
if((fast_rand()&7)==0)
|
||||
{
|
||||
if(opus_packet_pad(packet,len,len+256)!=OPUS_OK)test_failed();
|
||||
len+=256;
|
||||
}
|
||||
if((fast_rand()&3)==0)
|
||||
{
|
||||
len=opus_packet_unpad(packet,len);
|
||||
if(len<1)test_failed();
|
||||
}
|
||||
out_samples = opus_decode(dec, packet, len, &outbuf[i<<1], MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=frame_size)test_failed();
|
||||
if(opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();
|
||||
if(enc_final_range!=dec_final_range)test_failed();
|
||||
/*LBRR decode*/
|
||||
out_samples = opus_decode(dec_err[0], packet, len, out2buf, frame_size, (fast_rand()&3)!=0);
|
||||
if(out_samples!=frame_size)test_failed();
|
||||
out_samples = opus_decode(dec_err[1], packet, (fast_rand()&3)==0?0:len, out2buf, MAX_FRAME_SAMP, (fast_rand()&7)!=0);
|
||||
if(out_samples<120)test_failed();
|
||||
i+=frame_size;
|
||||
count++;
|
||||
}while(i<(SSAMPLES-MAX_FRAME_SAMP));
|
||||
fprintf(stdout," Mode %s FB encode %s, %6d bps OK.\n",mstrings[modes[j]],rc==0?" VBR":rc==1?"CVBR":" CBR",rate);
|
||||
}
|
||||
}
|
||||
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(OPUS_AUTO))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0))!=OPUS_OK)test_failed();
|
||||
if(opus_encoder_ctl(enc, OPUS_SET_DTX(0))!=OPUS_OK)test_failed();
|
||||
|
||||
for(rc=0;rc<3;rc++)
|
||||
{
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR(rc<2))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_VBR_CONSTRAINT(rc==1))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0))!=OPUS_OK)test_failed();
|
||||
for(j=0;j<16;j++)
|
||||
{
|
||||
int rate;
|
||||
int modes[16]={0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2};
|
||||
int rates[16]={4000,12000,32000,8000,16000,32000,48000,88000,4000,12000,32000,8000,16000,32000,48000,88000};
|
||||
int frame[16]={160*1,160,80,160,160,80,40,20,160*1,160,80,160,160,80,40,20};
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_INBAND_FEC(rc==0&&j==1))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_FORCE_MODE(MODE_SILK_ONLY+modes[j]))!=OPUS_OK)test_failed();
|
||||
rate=rates[j]+fast_rand()%rates[j];
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_DTX(fast_rand()&1))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_BITRATE(rate))!=OPUS_OK)test_failed();
|
||||
count=i=0;
|
||||
do {
|
||||
int len,out_samples,frame_size,loss;
|
||||
opus_int32 pred;
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_PREDICTION_DISABLED(&pred))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PREDICTION_DISABLED((int)(fast_rand()&15)<(pred?11:4)))!=OPUS_OK)test_failed();
|
||||
frame_size=frame[j];
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_COMPLEXITY((count>>2)%11))!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_SET_PACKET_LOSS_PERC((fast_rand()&15)&(fast_rand()%15)))!=OPUS_OK)test_failed();
|
||||
if((fast_rand()&255)==0)
|
||||
{
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
if(opus_multistream_decoder_ctl(MSdec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
if((fast_rand()&3)!=0)
|
||||
{
|
||||
if(opus_multistream_decoder_ctl(MSdec_err, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
}
|
||||
}
|
||||
if((fast_rand()&255)==0)
|
||||
{
|
||||
if(opus_multistream_decoder_ctl(MSdec_err, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
}
|
||||
len = opus_multistream_encode(MSenc, &inbuf[i<<1], frame_size, packet, MAX_PACKET);
|
||||
if(len<0 || len>MAX_PACKET)test_failed();
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed();
|
||||
if((fast_rand()&3)==0)
|
||||
{
|
||||
if(opus_multistream_packet_pad(packet,len,len+1,2)!=OPUS_OK)test_failed();
|
||||
len++;
|
||||
}
|
||||
if((fast_rand()&7)==0)
|
||||
{
|
||||
if(opus_multistream_packet_pad(packet,len,len+256,2)!=OPUS_OK)test_failed();
|
||||
len+=256;
|
||||
}
|
||||
if((fast_rand()&3)==0)
|
||||
{
|
||||
len=opus_multistream_packet_unpad(packet,len,2);
|
||||
if(len<1)test_failed();
|
||||
}
|
||||
out_samples = opus_multistream_decode(MSdec, packet, len, out2buf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=frame_size*6)test_failed();
|
||||
if(opus_multistream_decoder_ctl(MSdec, OPUS_GET_FINAL_RANGE(&dec_final_range))!=OPUS_OK)test_failed();
|
||||
if(enc_final_range!=dec_final_range)test_failed();
|
||||
/*LBRR decode*/
|
||||
loss=(fast_rand()&63)==0;
|
||||
out_samples = opus_multistream_decode(MSdec_err, packet, loss?0:len, out2buf, frame_size*6, (fast_rand()&3)!=0);
|
||||
if(out_samples!=(frame_size*6))test_failed();
|
||||
i+=frame_size;
|
||||
count++;
|
||||
}while(i<(SSAMPLES/12-MAX_FRAME_SAMP));
|
||||
fprintf(stdout," Mode %s NB dual-mono MS encode %s, %6d bps OK.\n",mstrings[modes[j]],rc==0?" VBR":rc==1?"CVBR":" CBR",rate);
|
||||
}
|
||||
}
|
||||
|
||||
bitrate_bps=512000;
|
||||
fsize=fast_rand()%31;
|
||||
fswitch=100;
|
||||
|
||||
debruijn2(6,db62);
|
||||
count=i=0;
|
||||
do {
|
||||
unsigned char toc;
|
||||
const unsigned char *frames[48];
|
||||
short size[48];
|
||||
int payload_offset;
|
||||
opus_uint32 dec_final_range2;
|
||||
int jj,dec2;
|
||||
int len,out_samples;
|
||||
int frame_size=fsizes[db62[fsize]];
|
||||
opus_int32 offset=i%(SAMPLES-MAX_FRAME_SAMP);
|
||||
|
||||
opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
|
||||
|
||||
len = opus_encode(enc, &inbuf[offset<<1], frame_size, packet, MAX_PACKET);
|
||||
if(len<0 || len>MAX_PACKET)test_failed();
|
||||
count++;
|
||||
|
||||
opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range));
|
||||
|
||||
out_samples = opus_decode(dec, packet, len, &outbuf[offset<<1], MAX_FRAME_SAMP, 0);
|
||||
if(out_samples!=frame_size)test_failed();
|
||||
|
||||
opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
|
||||
|
||||
/* compare final range encoder rng values of encoder and decoder */
|
||||
if(dec_final_range!=enc_final_range)test_failed();
|
||||
|
||||
/* We fuzz the packet, but take care not to only corrupt the payload
|
||||
Corrupted headers are tested elsewhere and we need to actually run
|
||||
the decoders in order to compare them. */
|
||||
if(opus_packet_parse(packet,len,&toc,frames,size,&payload_offset)<=0)test_failed();
|
||||
if((fast_rand()&1023)==0)len=0;
|
||||
for(j=(opus_int32)(frames[0]-packet);j<len;j++)for(jj=0;jj<8;jj++)packet[j]^=((!no_fuzz)&&((fast_rand()&1023)==0))<<jj;
|
||||
out_samples = opus_decode(dec_err[0], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed();
|
||||
if((len>0&&out_samples!=frame_size))test_failed(); /*FIXME use lastframe*/
|
||||
|
||||
opus_decoder_ctl(dec_err[0], OPUS_GET_FINAL_RANGE(&dec_final_range));
|
||||
|
||||
/*randomly select one of the decoders to compare with*/
|
||||
dec2=fast_rand()%9+1;
|
||||
out_samples = opus_decode(dec_err[dec2], len>0?packet:NULL, len, out2buf, MAX_FRAME_SAMP, 0);
|
||||
if(out_samples<0||out_samples>MAX_FRAME_SAMP)test_failed(); /*FIXME, use factor, lastframe for loss*/
|
||||
|
||||
opus_decoder_ctl(dec_err[dec2], OPUS_GET_FINAL_RANGE(&dec_final_range2));
|
||||
if(len>0&&dec_final_range!=dec_final_range2)test_failed();
|
||||
|
||||
fswitch--;
|
||||
if(fswitch<1)
|
||||
{
|
||||
int new_size;
|
||||
fsize=(fsize+1)%36;
|
||||
new_size=fsizes[db62[fsize]];
|
||||
if(new_size==960||new_size==480)fswitch=2880/new_size*(fast_rand()%19+1);
|
||||
else fswitch=(fast_rand()%(2880/new_size))+1;
|
||||
}
|
||||
bitrate_bps=((fast_rand()%508000+4000)+bitrate_bps)>>1;
|
||||
i+=frame_size;
|
||||
}while(i<SAMPLES*4);
|
||||
fprintf(stdout," All framesize pairs switching encode, %d frames OK.\n",count);
|
||||
|
||||
if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
opus_encoder_destroy(enc);
|
||||
if(opus_multistream_encoder_ctl(MSenc, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
opus_multistream_encoder_destroy(MSenc);
|
||||
if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
opus_decoder_destroy(dec);
|
||||
if(opus_multistream_decoder_ctl(MSdec, OPUS_RESET_STATE)!=OPUS_OK)test_failed();
|
||||
opus_multistream_decoder_destroy(MSdec);
|
||||
opus_multistream_decoder_destroy(MSdec_err);
|
||||
for(i=0;i<10;i++)opus_decoder_destroy(dec_err[i]);
|
||||
free(inbuf);
|
||||
free(outbuf);
|
||||
free(out2buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_usage(char* _argv[])
|
||||
{
|
||||
fprintf(stderr,"Usage: %s [<seed>] [-fuzz <num_encoders> <num_settings_per_encoder>]\n",_argv[0]);
|
||||
}
|
||||
|
||||
int main(int _argc, char **_argv)
|
||||
{
|
||||
int args=1;
|
||||
char * strtol_str=NULL;
|
||||
const char * oversion;
|
||||
const char * env_seed;
|
||||
int env_used;
|
||||
int num_encoders_to_fuzz=5;
|
||||
int num_setting_changes=40;
|
||||
|
||||
env_used=0;
|
||||
env_seed=getenv("SEED");
|
||||
if(_argc>1)
|
||||
iseed=strtol(_argv[1], &strtol_str, 10); /* the first input argument might be the seed */
|
||||
if(strtol_str!=NULL && strtol_str[0]=='\0') /* iseed is a valid number */
|
||||
args++;
|
||||
else if(env_seed) {
|
||||
iseed=atoi(env_seed);
|
||||
env_used=1;
|
||||
}
|
||||
else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
|
||||
Rw=Rz=iseed;
|
||||
|
||||
while(args<_argc)
|
||||
{
|
||||
if(strcmp(_argv[args], "-fuzz")==0 && _argc==(args+3)) {
|
||||
num_encoders_to_fuzz=strtol(_argv[args+1], &strtol_str, 10);
|
||||
if(strtol_str[0]!='\0' || num_encoders_to_fuzz<=0) {
|
||||
print_usage(_argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
num_setting_changes=strtol(_argv[args+2], &strtol_str, 10);
|
||||
if(strtol_str[0]!='\0' || num_setting_changes<=0) {
|
||||
print_usage(_argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
args+=3;
|
||||
}
|
||||
else {
|
||||
print_usage(_argv);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
oversion=opus_get_version_string();
|
||||
if(!oversion)test_failed();
|
||||
fprintf(stderr,"Testing %s encoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
|
||||
if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed);
|
||||
|
||||
regression_test();
|
||||
|
||||
/*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
|
||||
into the decoders. This is helpful because garbage data
|
||||
may cause the decoders to clip, which angers CLANG IOC.*/
|
||||
run_test1(getenv("TEST_OPUS_NOFUZZ")!=NULL);
|
||||
|
||||
/* Fuzz encoder settings online */
|
||||
if(getenv("TEST_OPUS_NOFUZZ")==NULL) {
|
||||
fprintf(stderr,"Running fuzz_encoder_settings with %d encoder(s) and %d setting change(s) each.\n",
|
||||
num_encoders_to_fuzz, num_setting_changes);
|
||||
fuzz_encoder_settings(num_encoders_to_fuzz, num_setting_changes);
|
||||
}
|
||||
|
||||
fprintf(stderr,"Tests completed successfully.\n");
|
||||
|
||||
return 0;
|
||||
}
|
93
externals/opus/opus/tests/test_opus_padding.c
vendored
Executable file
93
externals/opus/opus/tests/test_opus_padding.c
vendored
Executable file
@@ -0,0 +1,93 @@
|
||||
/* Copyright (c) 2012 Xiph.Org Foundation
|
||||
Written by Jüri Aedla and Ralph Giles */
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/* Check for overflow in reading the padding length.
|
||||
* http://lists.xiph.org/pipermail/opus/2012-November/001834.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "opus.h"
|
||||
#include "test_opus_common.h"
|
||||
|
||||
#define PACKETSIZE 16909318
|
||||
#define CHANNELS 2
|
||||
#define FRAMESIZE 5760
|
||||
|
||||
int test_overflow(void)
|
||||
{
|
||||
OpusDecoder *decoder;
|
||||
int result;
|
||||
int error;
|
||||
|
||||
unsigned char *in = malloc(PACKETSIZE);
|
||||
opus_int16 *out = malloc(FRAMESIZE*CHANNELS*sizeof(*out));
|
||||
|
||||
fprintf(stderr, " Checking for padding overflow... ");
|
||||
if (!in || !out) {
|
||||
fprintf(stderr, "FAIL (out of memory)\n");
|
||||
return -1;
|
||||
}
|
||||
in[0] = 0xff;
|
||||
in[1] = 0x41;
|
||||
memset(in + 2, 0xff, PACKETSIZE - 3);
|
||||
in[PACKETSIZE-1] = 0x0b;
|
||||
|
||||
decoder = opus_decoder_create(48000, CHANNELS, &error);
|
||||
result = opus_decode(decoder, in, PACKETSIZE, out, FRAMESIZE, 0);
|
||||
opus_decoder_destroy(decoder);
|
||||
|
||||
free(in);
|
||||
free(out);
|
||||
|
||||
if (result != OPUS_INVALID_PACKET) {
|
||||
fprintf(stderr, "FAIL!\n");
|
||||
test_failed();
|
||||
}
|
||||
|
||||
fprintf(stderr, "OK.\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
const char *oversion;
|
||||
int tests = 0;;
|
||||
|
||||
iseed = 0;
|
||||
oversion = opus_get_version_string();
|
||||
if (!oversion) test_failed();
|
||||
fprintf(stderr, "Testing %s padding.\n", oversion);
|
||||
|
||||
tests += test_overflow();
|
||||
|
||||
fprintf(stderr, "All padding tests passed.\n");
|
||||
|
||||
return 0;
|
||||
}
|
394
externals/opus/opus/tests/test_opus_projection.c
vendored
Executable file
394
externals/opus/opus/tests/test_opus_projection.c
vendored
Executable file
@@ -0,0 +1,394 @@
|
||||
/* Copyright (c) 2017 Google Inc.
|
||||
Written by Andrew Allen */
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "float_cast.h"
|
||||
#include "opus.h"
|
||||
#include "test_opus_common.h"
|
||||
#include "opus_projection.h"
|
||||
#include "mathops.h"
|
||||
#include "../src/mapping_matrix.h"
|
||||
#include "mathops.h"
|
||||
|
||||
#define BUFFER_SIZE 960
|
||||
#define MAX_DATA_BYTES 32768
|
||||
#define MAX_FRAME_SAMPLES 5760
|
||||
#define ERROR_TOLERANCE 1
|
||||
|
||||
#define SIMPLE_MATRIX_SIZE 12
|
||||
#define SIMPLE_MATRIX_FRAME_SIZE 10
|
||||
#define SIMPLE_MATRIX_INPUT_SIZE 30
|
||||
#define SIMPLE_MATRIX_OUTPUT_SIZE 40
|
||||
|
||||
int assert_is_equal(
|
||||
const opus_val16 *a, const opus_int16 *b, int size, opus_int16 tolerance)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
opus_int16 val = a[i];
|
||||
#else
|
||||
opus_int16 val = FLOAT2INT16(a[i]);
|
||||
#endif
|
||||
if (abs(val - b[i]) > tolerance)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int assert_is_equal_short(
|
||||
const opus_int16 *a, const opus_int16 *b, int size, opus_int16 tolerance)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
if (abs(a[i] - b[i]) > tolerance)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_simple_matrix(void)
|
||||
{
|
||||
const MappingMatrix simple_matrix_params = {4, 3, 0};
|
||||
const opus_int16 simple_matrix_data[SIMPLE_MATRIX_SIZE] = {0, 32767, 0, 0, 32767, 0, 0, 0, 0, 0, 0, 32767};
|
||||
const opus_int16 input_int16[SIMPLE_MATRIX_INPUT_SIZE] = {
|
||||
32767, 0, -32768, 29491, -3277, -29491, 26214, -6554, -26214, 22938, -9830,
|
||||
-22938, 19661, -13107, -19661, 16384, -16384, -16384, 13107, -19661, -13107,
|
||||
9830, -22938, -9830, 6554, -26214, -6554, 3277, -29491, -3277};
|
||||
const opus_int16 expected_output_int16[SIMPLE_MATRIX_OUTPUT_SIZE] = {
|
||||
0, 32767, 0, -32768, -3277, 29491, 0, -29491, -6554, 26214, 0, -26214,
|
||||
-9830, 22938, 0, -22938, -13107, 19661, 0, -19661, -16384, 16384, 0, -16384,
|
||||
-19661, 13107, 0, -13107, -22938, 9830, 0, -9830, -26214, 6554, 0, -6554,
|
||||
-29491, 3277, 0, -3277};
|
||||
|
||||
int i, ret;
|
||||
opus_int32 simple_matrix_size;
|
||||
opus_val16 *input_val16;
|
||||
opus_val16 *output_val16;
|
||||
opus_int16 *output_int16;
|
||||
MappingMatrix *simple_matrix;
|
||||
|
||||
/* Allocate input/output buffers. */
|
||||
input_val16 = (opus_val16 *)opus_alloc(sizeof(opus_val16) * SIMPLE_MATRIX_INPUT_SIZE);
|
||||
output_int16 = (opus_int16 *)opus_alloc(sizeof(opus_int16) * SIMPLE_MATRIX_OUTPUT_SIZE);
|
||||
output_val16 = (opus_val16 *)opus_alloc(sizeof(opus_val16) * SIMPLE_MATRIX_OUTPUT_SIZE);
|
||||
|
||||
/* Initialize matrix */
|
||||
simple_matrix_size = mapping_matrix_get_size(simple_matrix_params.rows,
|
||||
simple_matrix_params.cols);
|
||||
if (!simple_matrix_size)
|
||||
test_failed();
|
||||
|
||||
simple_matrix = (MappingMatrix *)opus_alloc(simple_matrix_size);
|
||||
mapping_matrix_init(simple_matrix, simple_matrix_params.rows,
|
||||
simple_matrix_params.cols, simple_matrix_params.gain, simple_matrix_data,
|
||||
sizeof(simple_matrix_data));
|
||||
|
||||
/* Copy inputs. */
|
||||
for (i = 0; i < SIMPLE_MATRIX_INPUT_SIZE; i++)
|
||||
{
|
||||
#ifdef FIXED_POINT
|
||||
input_val16[i] = input_int16[i];
|
||||
#else
|
||||
input_val16[i] = (1/32768.f)*input_int16[i];
|
||||
#endif
|
||||
}
|
||||
|
||||
/* _in_short */
|
||||
for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
|
||||
output_val16[i] = 0;
|
||||
for (i = 0; i < simple_matrix->rows; i++)
|
||||
{
|
||||
mapping_matrix_multiply_channel_in_short(simple_matrix,
|
||||
input_int16, simple_matrix->cols, &output_val16[i], i,
|
||||
simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
|
||||
}
|
||||
ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
|
||||
if (ret)
|
||||
test_failed();
|
||||
|
||||
/* _out_short */
|
||||
for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
|
||||
output_int16[i] = 0;
|
||||
for (i = 0; i < simple_matrix->cols; i++)
|
||||
{
|
||||
mapping_matrix_multiply_channel_out_short(simple_matrix,
|
||||
&input_val16[i], i, simple_matrix->cols, output_int16,
|
||||
simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
|
||||
}
|
||||
ret = assert_is_equal_short(output_int16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
|
||||
if (ret)
|
||||
test_failed();
|
||||
|
||||
#if !defined(DISABLE_FLOAT_API) && !defined(FIXED_POINT)
|
||||
/* _in_float */
|
||||
for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
|
||||
output_val16[i] = 0;
|
||||
for (i = 0; i < simple_matrix->rows; i++)
|
||||
{
|
||||
mapping_matrix_multiply_channel_in_float(simple_matrix,
|
||||
input_val16, simple_matrix->cols, &output_val16[i], i,
|
||||
simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
|
||||
}
|
||||
ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
|
||||
if (ret)
|
||||
test_failed();
|
||||
|
||||
/* _out_float */
|
||||
for (i = 0; i < SIMPLE_MATRIX_OUTPUT_SIZE; i++)
|
||||
output_val16[i] = 0;
|
||||
for (i = 0; i < simple_matrix->cols; i++)
|
||||
{
|
||||
mapping_matrix_multiply_channel_out_float(simple_matrix,
|
||||
&input_val16[i], i, simple_matrix->cols, output_val16,
|
||||
simple_matrix->rows, SIMPLE_MATRIX_FRAME_SIZE);
|
||||
}
|
||||
ret = assert_is_equal(output_val16, expected_output_int16, SIMPLE_MATRIX_OUTPUT_SIZE, ERROR_TOLERANCE);
|
||||
if (ret)
|
||||
test_failed();
|
||||
#endif
|
||||
|
||||
opus_free(input_val16);
|
||||
opus_free(output_int16);
|
||||
opus_free(output_val16);
|
||||
opus_free(simple_matrix);
|
||||
}
|
||||
|
||||
void test_creation_arguments(const int channels, const int mapping_family)
|
||||
{
|
||||
int streams;
|
||||
int coupled_streams;
|
||||
int enc_error;
|
||||
int dec_error;
|
||||
int ret;
|
||||
OpusProjectionEncoder *st_enc = NULL;
|
||||
OpusProjectionDecoder *st_dec = NULL;
|
||||
|
||||
const opus_int32 Fs = 48000;
|
||||
const int application = OPUS_APPLICATION_AUDIO;
|
||||
|
||||
int order_plus_one = (int)floor(sqrt((float)channels));
|
||||
int nondiegetic_channels = channels - order_plus_one * order_plus_one;
|
||||
|
||||
int is_channels_valid = 0;
|
||||
int is_projection_valid = 0;
|
||||
|
||||
st_enc = opus_projection_ambisonics_encoder_create(Fs, channels,
|
||||
mapping_family, &streams, &coupled_streams, application, &enc_error);
|
||||
if (st_enc != NULL)
|
||||
{
|
||||
opus_int32 matrix_size;
|
||||
unsigned char *matrix;
|
||||
|
||||
ret = opus_projection_encoder_ctl(st_enc,
|
||||
OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, &matrix_size);
|
||||
if (ret != OPUS_OK || !matrix_size)
|
||||
test_failed();
|
||||
|
||||
matrix = (unsigned char *)opus_alloc(matrix_size);
|
||||
ret = opus_projection_encoder_ctl(st_enc,
|
||||
OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, matrix, matrix_size);
|
||||
|
||||
opus_projection_encoder_destroy(st_enc);
|
||||
|
||||
st_dec = opus_projection_decoder_create(Fs, channels, streams,
|
||||
coupled_streams, matrix, matrix_size, &dec_error);
|
||||
if (st_dec != NULL)
|
||||
{
|
||||
opus_projection_decoder_destroy(st_dec);
|
||||
}
|
||||
opus_free(matrix);
|
||||
}
|
||||
|
||||
is_channels_valid = (order_plus_one >= 2 && order_plus_one <= 4) &&
|
||||
(nondiegetic_channels == 0 || nondiegetic_channels == 2);
|
||||
is_projection_valid = (enc_error == OPUS_OK && dec_error == OPUS_OK);
|
||||
if (is_channels_valid ^ is_projection_valid)
|
||||
{
|
||||
fprintf(stderr, "Channels: %d, Family: %d\n", channels, mapping_family);
|
||||
fprintf(stderr, "Order+1: %d, Non-diegetic Channels: %d\n",
|
||||
order_plus_one, nondiegetic_channels);
|
||||
fprintf(stderr, "Streams: %d, Coupled Streams: %d\n",
|
||||
streams, coupled_streams);
|
||||
test_failed();
|
||||
}
|
||||
}
|
||||
|
||||
void generate_music(short *buf, opus_int32 len, opus_int32 channels)
|
||||
{
|
||||
opus_int32 i,j,k;
|
||||
opus_int32 *a,*b,*c,*d;
|
||||
a = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
|
||||
b = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
|
||||
c = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
|
||||
d = (opus_int32 *)malloc(sizeof(opus_int32) * channels);
|
||||
memset(a, 0, sizeof(opus_int32) * channels);
|
||||
memset(b, 0, sizeof(opus_int32) * channels);
|
||||
memset(c, 0, sizeof(opus_int32) * channels);
|
||||
memset(d, 0, sizeof(opus_int32) * channels);
|
||||
j=0;
|
||||
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
for(k=0;k<channels;k++)
|
||||
{
|
||||
opus_uint32 r;
|
||||
opus_int32 v;
|
||||
v=(((j*((j>>12)^((j>>10|j>>12)&26&j>>7)))&128)+128)<<15;
|
||||
r=fast_rand();v+=r&65535;v-=r>>16;
|
||||
b[k]=v-a[k]+((b[k]*61+32)>>6);a[k]=v;
|
||||
c[k]=(30*(c[k]+b[k]+d[k])+32)>>6;d[k]=b[k];
|
||||
v=(c[k]+128)>>8;
|
||||
buf[i*channels+k]=v>32767?32767:(v<-32768?-32768:v);
|
||||
if(i%6==0)j++;
|
||||
}
|
||||
}
|
||||
|
||||
free(a);
|
||||
free(b);
|
||||
free(c);
|
||||
free(d);
|
||||
}
|
||||
|
||||
void test_encode_decode(opus_int32 bitrate, opus_int32 channels,
|
||||
const int mapping_family)
|
||||
{
|
||||
const opus_int32 Fs = 48000;
|
||||
const int application = OPUS_APPLICATION_AUDIO;
|
||||
|
||||
OpusProjectionEncoder *st_enc;
|
||||
OpusProjectionDecoder *st_dec;
|
||||
int streams;
|
||||
int coupled;
|
||||
int error;
|
||||
short *buffer_in;
|
||||
short *buffer_out;
|
||||
unsigned char data[MAX_DATA_BYTES] = { 0 };
|
||||
int len;
|
||||
int out_samples;
|
||||
opus_int32 matrix_size = 0;
|
||||
unsigned char *matrix = NULL;
|
||||
|
||||
buffer_in = (short *)malloc(sizeof(short) * BUFFER_SIZE * channels);
|
||||
buffer_out = (short *)malloc(sizeof(short) * BUFFER_SIZE * channels);
|
||||
|
||||
st_enc = opus_projection_ambisonics_encoder_create(Fs, channels,
|
||||
mapping_family, &streams, &coupled, application, &error);
|
||||
if (error != OPUS_OK) {
|
||||
fprintf(stderr,
|
||||
"Couldn\'t create encoder with %d channels and mapping family %d.\n",
|
||||
channels, mapping_family);
|
||||
free(buffer_in);
|
||||
free(buffer_out);
|
||||
test_failed();
|
||||
}
|
||||
|
||||
error = opus_projection_encoder_ctl(st_enc,
|
||||
OPUS_SET_BITRATE(bitrate * 1000 * (streams + coupled)));
|
||||
if (error != OPUS_OK)
|
||||
{
|
||||
goto bad_cleanup;
|
||||
}
|
||||
|
||||
error = opus_projection_encoder_ctl(st_enc,
|
||||
OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, &matrix_size);
|
||||
if (error != OPUS_OK || !matrix_size)
|
||||
{
|
||||
goto bad_cleanup;
|
||||
}
|
||||
|
||||
matrix = (unsigned char *)opus_alloc(matrix_size);
|
||||
error = opus_projection_encoder_ctl(st_enc,
|
||||
OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, matrix, matrix_size);
|
||||
|
||||
st_dec = opus_projection_decoder_create(Fs, channels, streams, coupled,
|
||||
matrix, matrix_size, &error);
|
||||
opus_free(matrix);
|
||||
|
||||
if (error != OPUS_OK) {
|
||||
fprintf(stderr,
|
||||
"Couldn\'t create decoder with %d channels, %d streams "
|
||||
"and %d coupled streams.\n", channels, streams, coupled);
|
||||
goto bad_cleanup;
|
||||
}
|
||||
|
||||
generate_music(buffer_in, BUFFER_SIZE, channels);
|
||||
|
||||
len = opus_projection_encode(
|
||||
st_enc, buffer_in, BUFFER_SIZE, data, MAX_DATA_BYTES);
|
||||
if(len<0 || len>MAX_DATA_BYTES) {
|
||||
fprintf(stderr,"opus_encode() returned %d\n", len);
|
||||
goto bad_cleanup;
|
||||
}
|
||||
|
||||
out_samples = opus_projection_decode(
|
||||
st_dec, data, len, buffer_out, MAX_FRAME_SAMPLES, 0);
|
||||
if(out_samples!=BUFFER_SIZE) {
|
||||
fprintf(stderr,"opus_decode() returned %d\n", out_samples);
|
||||
goto bad_cleanup;
|
||||
}
|
||||
|
||||
opus_projection_decoder_destroy(st_dec);
|
||||
opus_projection_encoder_destroy(st_enc);
|
||||
free(buffer_in);
|
||||
free(buffer_out);
|
||||
return;
|
||||
bad_cleanup:
|
||||
free(buffer_in);
|
||||
free(buffer_out);
|
||||
test_failed();
|
||||
}
|
||||
|
||||
int main(int _argc, char **_argv)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
(void)_argc;
|
||||
(void)_argv;
|
||||
|
||||
/* Test simple matrix multiplication routines. */
|
||||
test_simple_matrix();
|
||||
|
||||
/* Test full range of channels in creation arguments. */
|
||||
for (i = 0; i < 255; i++)
|
||||
test_creation_arguments(i, 3);
|
||||
|
||||
/* Test encode/decode pipeline. */
|
||||
test_encode_decode(64 * 18, 18, 3);
|
||||
|
||||
fprintf(stderr, "All projection tests passed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user