diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-08-01 10:14:23 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-08-01 10:14:23 +1000 |
| commit | 23393312b7183fa61d4a6ba9e97af21f2337a8af (patch) | |
| tree | 16e8c632a30fffb470156cd33519aa0607e72d8a /lib/opus/tests | |
| parent | d41de537a0e31e1c5ad18b5024c781f6e4a07bbb (diff) | |
| download | tangara-fw-23393312b7183fa61d4a6ba9e97af21f2337a8af.tar.gz | |
checkin in opus reference decoder
Diffstat (limited to 'lib/opus/tests')
| -rw-r--r-- | lib/opus/tests/meson.build | 34 | ||||
| -rwxr-xr-x | lib/opus/tests/opus_build_test.sh | 29 | ||||
| -rw-r--r-- | lib/opus/tests/opus_decode_fuzzer.c | 124 | ||||
| -rw-r--r-- | lib/opus/tests/opus_decode_fuzzer.options | 2 | ||||
| -rw-r--r-- | lib/opus/tests/opus_encode_regressions.c | 1034 | ||||
| -rwxr-xr-x | lib/opus/tests/random_config.sh | 126 | ||||
| -rwxr-xr-x | lib/opus/tests/run_vectors.sh | 143 | ||||
| -rw-r--r-- | lib/opus/tests/test_opus_api.c | 1904 | ||||
| -rw-r--r-- | lib/opus/tests/test_opus_common.h | 85 | ||||
| -rw-r--r-- | lib/opus/tests/test_opus_decode.c | 463 | ||||
| -rw-r--r-- | lib/opus/tests/test_opus_encode.c | 707 | ||||
| -rw-r--r-- | lib/opus/tests/test_opus_padding.c | 90 | ||||
| -rw-r--r-- | lib/opus/tests/test_opus_projection.c | 393 |
13 files changed, 5134 insertions, 0 deletions
diff --git a/lib/opus/tests/meson.build b/lib/opus/tests/meson.build new file mode 100644 index 00000000..5f3ac9df --- /dev/null +++ b/lib/opus/tests/meson.build @@ -0,0 +1,34 @@ +# Tests that link to libopus +opus_tests = [ + ['test_opus_api'], + ['test_opus_decode', [], 60], + ['test_opus_encode', 'opus_encode_regressions.c', 120], + ['test_opus_padding'], + ['test_opus_projection'], +] + +foreach t : opus_tests + test_name = t.get(0) + extra_srcs = t.get(1, []) + + test_kwargs = {} + if t.length() > 2 + test_kwargs += {'timeout': t[2]} + endif + + exe_kwargs = {} + # This test uses private symbols + if test_name == 'test_opus_projection' + exe_kwargs = { + 'link_with': [celt_lib, silk_lib], + 'objects': opus_lib.extract_all_objects(), + } + endif + + exe = executable(test_name, '@0@.c'.format(test_name), extra_srcs, + include_directories: opus_includes, + dependencies: [libm, opus_dep], + install: false, + kwargs: exe_kwargs) + test(test_name, exe, kwargs: test_kwargs) +endforeach diff --git a/lib/opus/tests/opus_build_test.sh b/lib/opus/tests/opus_build_test.sh new file mode 100755 index 00000000..573f4473 --- /dev/null +++ b/lib/opus/tests/opus_build_test.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +tarball=`realpath "$1"` +nb_tests="$2" +oldvectors=`realpath "$3"` +newvectors=`realpath "$4"` +base=`basename "$tarball" .tar.gz` + +tar xvf "$tarball" > /dev/null 2>&1 +cd "$base" + +if [ $? -ne 0 ] +then + echo cannot go to "$base" + exit 1 +fi + +mkdir build_tests + +configure_dir=`pwd` +seq -w "$nb_tests" | parallel --halt now,fail=10 -j +2 -q ../random_config.sh "build_tests/run_{}" "$configure_dir" "$oldvectors" "$newvectors" + +if [ $? -ne 0 ] +then + echo Check found errors + exit 1 +else + echo No error found +fi diff --git a/lib/opus/tests/opus_decode_fuzzer.c b/lib/opus/tests/opus_decode_fuzzer.c new file mode 100644 index 00000000..ea6ec4fd --- /dev/null +++ b/lib/opus/tests/opus_decode_fuzzer.c @@ -0,0 +1,124 @@ +/* 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 + +#define MAX_DECODES 12 + +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 *temp_data; + TocInfo toc; + int i = 0; + int err = OPUS_OK; + int num_decodes = 0; + + /* 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); + + while (i + SETUP_BYTE_COUNT < size && num_decodes++ < MAX_DECODES) { + int len, fec; + + 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 || i + SETUP_BYTE_COUNT + len > size) { + 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; + + if (len == 0) { + /* Lost packet */ + int frame_size; + opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&frame_size)); + (void) opus_decode(dec, NULL, len, pcm, frame_size, fec); + } else { + temp_data = (uint8_t*) malloc(len); + memcpy(temp_data, &data[i + SETUP_BYTE_COUNT], len); + + (void) opus_decode(dec, temp_data, len, pcm, MAX_FRAME_SAMP, fec); + + free(temp_data); + } + + i += SETUP_BYTE_COUNT + len; + } + + opus_decoder_destroy(dec); + free(pcm); + + return 0; +} diff --git a/lib/opus/tests/opus_decode_fuzzer.options b/lib/opus/tests/opus_decode_fuzzer.options new file mode 100644 index 00000000..e5ae71b9 --- /dev/null +++ b/lib/opus/tests/opus_decode_fuzzer.options @@ -0,0 +1,2 @@ +[libfuzzer] +max_len = 1000000 diff --git a/lib/opus/tests/opus_encode_regressions.c b/lib/opus/tests/opus_encode_regressions.c new file mode 100644 index 00000000..4d506eb6 --- /dev/null +++ b/lib/opus/tests/opus_encode_regressions.c @@ -0,0 +1,1034 @@ +/* Copyright (c) 2016 Mark Harris, Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#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 "opus_multistream.h" +#include "opus.h" +#include "test_opus_common.h" + + +static int celt_ec_internal_error(void) +{ + OpusMSEncoder *enc; + int err; + unsigned char data[2460]; + int streams; + int coupled_streams; + unsigned char mapping[1]; + + enc = opus_multistream_surround_encoder_create(16000, 1, 1, &streams, + &coupled_streams, mapping, OPUS_APPLICATION_VOIP, &err); + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(OPUS_AUTO)); + { + static const short pcm[320] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1792, 1799, 1799, + 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 1799, 1799, 1799, 1799, 1799, 0, 25600, 1799, 1799, + 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 1799, 1799, 1799, 1799, 7, 0, 255, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32767, -1, + 0, 0, 0, 100, 0, 16384, 0, 0, 0, + 0, 0, 0, 4, 0, 0, -256, 255, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,-32768, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 0, 0, 0, 0, + 0, 0, 0, 0, -256, 0, 0, 32, 0, + 0, 0, 0, 0, 0, 0, 4352, 4, 228, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 5632, 0, 0, + 0, 0,-32768, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 256, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + -3944, 10500, 4285, 10459, -6474, 10204, -6539, 11601, -6824, + 13385, -7142, 13872,-11553, 13670, -7725, 13463, -6887, 7874, + -5580, 12600, -4964, 12480, 3254, 11741, -4210, 9741, -3155, + 7558, -5468, 5431, -1073, 3641, -1304, 0, -1, 343, + 26, 0, 0, 150, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1799, 1799, 1799, 1799, 1799, -2553, + 7, 1792, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 1799, 1799, 1799, 1799, -9721 + }; + err = opus_multistream_encode(enc, pcm, 320, data, 2460); + opus_test_assert(err > 0); + } + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); + { + static const short pcm[160] = + { + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9526, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, 25600, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510 + }; + err = opus_multistream_encode(enc, pcm, 160, data, 2460); + opus_test_assert(err > 0); + } + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); + { + static const short pcm[160] = + { + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9494, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510 + }; + err = opus_multistream_encode(enc, pcm, 160, data, 2460); + opus_test_assert(err > 0); + } + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); + { + static const short pcm[160] = + { + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9479, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, -9510, + -9510, -9510, -9510, -9510, -9510, -9510, -9510 + }; + err = opus_multistream_encode(enc, pcm, 160, data, 2460); + opus_test_assert(err > 0); + } + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(18)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(90)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(280130)); + { + static const short pcm[160] = + { + -9510, -9510, 1799, 1799, 1799, 1799, 1799, 1799, 1799, + 1799, 1799, 1799, 1799, 1799, 1799, 1799, 1799, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + -256, 255, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 128, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 32, 0, 0, 0, 0, 0, 0, 0, + 4352, 4, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 148, 0, 0, 0, 0, + 5632 + }; + err = opus_multistream_encode(enc, pcm, 160, data, 2460); + opus_test_assert(err > 0); + } + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(12)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(41)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(21425)); + { + static const short pcm[40] = + { + 10459, -6474, 10204, -6539, 11601, -6824, 13385, -7142, 13872, + -11553, 13670, -7725, 13463, -6887, 12482, -5580, 12600, -4964, + 12480, 3254, 11741, -4210, 9741, -3155, 7558, -5468, 5431, + -1073, 3641, -1304, 0, -1, 343, 26, 0, 0, + 0, 0, -256, 226 + }; + err = opus_multistream_encode(enc, pcm, 40, data, 2460); + opus_test_assert(err > 0); + /* returns -3 */ + } + opus_multistream_encoder_destroy(enc); + return 0; +} + +static int mscbr_encode_fail10(void) +{ + OpusMSEncoder *enc; + int err; + unsigned char data[627300]; + static const unsigned char mapping[255] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, + 102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, + 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152, + 153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, + 170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186, + 187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203, + 204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, + 221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237, + 238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254 + }; + + enc = opus_multistream_encoder_create(8000, 255, 254, 1, mapping, + OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err); + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(2)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(14)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(57)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(3642675)); + { + static const short pcm[20*255] = + { + 0 + }; + err = opus_multistream_encode(enc, pcm, 20, data, 627300); + opus_test_assert(err > 0); + /* returns -1 */ + } + opus_multistream_encoder_destroy(enc); + return 0; +} + +static int mscbr_encode_fail(void) +{ + OpusMSEncoder *enc; + int err; + unsigned char data[472320]; + static const unsigned char mapping[192] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101, + 102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118, + 119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135, + 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152, + 153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169, + 170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186, + 187,188,189,190,191 + }; + + enc = opus_multistream_encoder_create(8000, 192, 189, 3, mapping, + OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err); + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(15360)); + { + static const short pcm[20*192] = + { + 0 + }; + err = opus_multistream_encode(enc, pcm, 20, data, 472320); + opus_test_assert(err > 0); + /* returns -1 */ + } + opus_multistream_encoder_destroy(enc); + return 0; +} + +static int surround_analysis_uninit(void) +{ + OpusMSEncoder *enc; + int err; + unsigned char data[7380]; + int streams; + int coupled_streams; + unsigned char mapping[3]; + + enc = opus_multistream_surround_encoder_create(24000, 3, 1, &streams, + &coupled_streams, mapping, OPUS_APPLICATION_AUDIO, &err); + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(8)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(84315)); + { + static const short pcm[960*3] = + { + -6896, 4901, -6158, 4120, -5164, 3631, -4442, 3153, -4070, + 3349, -4577, 4474, -5541, 5058, -6701, 3881, -7933, 1863, + -8041, 697, -6738,-31464, 14330,-12523, 4096, -6130, 29178, + -250,-21252, 10467, 16907, -3359, -6644, 31965, 14607,-21544, + -32497, 24020, 12557,-26926,-18421, -1842, 24587, 19659, 4878, + 10954, 23060, 8907,-10215,-16179, 31772,-11825,-15590,-23089, + 17173,-25903,-17387, 11733, 4884, 10204,-16476,-14367, 516, + 20453,-16898, 20967,-23813, -20, 22011,-17167, 9459, 32499, + -25855, -523, -3883, -390, -4206, 634, -3767, 2325, -2751, + 3115, -2392, 2746, -2173, 2317, -1147, 2326, 23142, 11314, + -15350,-24529, 3026, 6146, 2150, 2476, 1105, -830, 1775, + -3425, 3674,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + 4293,-14023, 3879,-15553, 3158,-16161, 2629, 18433,-12535, + -6645,-20735,-32763,-13824,-20992, 25859, 13052, -8731, 2292, + -3860, 24049, 10225,-19220, 10478,-22294, 22773, 28137, 13816, + 30953,-25863,-24598, 16888,-14612,-28942, 20974,-27397,-18944, + -18690, 20991,-16638, 5632,-14330, 28911,-25594, 17408, 29958, + -517,-20984, -1800, 11281, 9977,-21221,-14854, 23840, -9477, + 3362,-12805,-22493, 32507, 156, 16384, -1163, 2301, -1874, + 4600, -1748, 6950, 16557, 8192, -7372, -1033, -3278, 2806, + 20275, 3317, -717, 9792, -767, 9099, -613, 8362, 5027, + 7774, 2597, 8549, 5278, 8743, 9343, 6940, 13038, 4826, + 14086, 2964, 13215, 1355, 11596, 455, 9850, -519, 10680, + -2287, 12551, -3736, 13639, -4291, 13790, -2722, 14544, -866, + 15050, -304, 22833, -1196, 13520, -2063, 13051, -2317, 13066, + -2737, 13773, -2664, 14105, -3447, 13854, 24589, 24672, -5280, + 10388, -4933, 7543, -4149, 3654, -1552, 1726, 661, 57, + 2922, -751, 3917, 8419, 3840, -5218, 3435, 5540, -1073, + 4153, -6656, 1649, -769, -7276,-13072, 6380, -7948, 20717, + 18425, 17392, 14335,-18190, -1842, 24587, 19659, 11790, 10954, + 23060, 8907,-10215,-16179, 31772,-11825,-15590,-23101, 17173, + -25903,-17387, 11733, 4884, 10192,-16627,-14367, 516, 20453, + -16898, 20967,-23813, -20, 22011,-17167, 9468, 32499,-25607, + -523, -3883, -390, -4206, 634, -3767, 2325, -2751, 3115, + -2392, 2746, -2161, 2317, -1147, 2326, 23142, 11314,-15350, + -29137, 3026,-15056, -491,-15170, -386,-16015, -641,-16505, + -930,-16206, -717,-16175, -2839,-16374, -4558,-16237, -5207, + -15903, -6421, 6373, -1403, 5431, -1073, 3641, -1304, -4495, + -769, -7276, 2856, -7870, 3314, -8730, 3964,-10183, 4011, + -11135, 3421,-11727, 2966,-12360, 2818,-13472, 3660,-13805, + 5162,-13478, 6434,-12840, 7335,-12420, 6865,-12349, 5541, + -11965, 5530,-10820, 5132, -9197, 3367, -7745, 1223, -6910, + -433, -6211, -1711, -4958, -1025, -3755, -836, -3292, -1666, + -2661,-10755, 31472,-27906, 31471, 18690, 5617, 16649, 11253, + -22516,-17674,-31990, 3575,-31479, 5883, 26121, 12890, -6612, + 12228,-11634, 523, 26136,-21496, 20745,-15868, -4100,-24826, + 23282, 22798, 491, -1774, 15075,-27373,-13094, 6417,-29487, + 14608, 10185, 16143, 22211, -8436, 4288, -8694, 2375, 3023, + 486, 1455, 128, 202, 942, -923, 2068, -1233, -717, + -1042, -2167, 32255, -4632, 310, -4458, -3639, -5258, 2106, + -6857, 2681, -7497, 2765, -6601, 1945, -5219, 19154, -4877, + 619, -5719, -1928, -6208, -121, 593, 188, 1558, -4152, + 1648, 156, 1604, -3664, -6862, -2851, -5112, -3600, -3747, + -5081, -4428, -5592, 20974,-27397,-18944,-18690, 20991,-17406, + 5632,-14330, 28911, 15934, 15934, 15934, 15934, 15934, 15934, + 15934, 15934, 15934, 15934, 15934, 15934,-25594, 17408, 29958, + -7173,-16888, 9098, -613, 8362, 675, 7774, 2597, 8549, + 5278, 8743, 9375, 6940, 13038, 4826, 14598, 7721,-24308, + -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24353, + 28648, 6946, -1363, 12485, -1187, 26074,-25055, 10004,-24798, + 7204, -4581, -9678, 1554, 10553, 3102, 12193, 2443, 11955, + 1213, 10689, -1293, 921, -4173, 10709, -6049, 8815, -7128, + 8147, -8308, 6847, -2977, 4920,-11447,-22426,-11794, 3514, + -10220, 3430, -7993, 1926, -7072, 327, -7569, -608, -7605, + 3695, -6271, -1579, -4877, -1419, -3103, -2197, 128, -3904, + 3760, -5401, 4906, -6051, 4250, -6272, 3492, -6343, 3197, + -6397, 4041, -6341, 6255, -6381, 7905, 16504, 0, -6144, + 8062, -5606, 8622, -5555, -9, -1, 7423, 0, 1, + 238, 5148, 1309, 4700, 2218, 4403, 2573, 3568, 28303, + 1758, 3454, -1247, 3434, -4912, 2862, -7844, 1718,-10095, + 369,-12631, 128, -3904, 3632, -5401, 4906, -6051, 4250, + -6272, 3492, -6343, 3197, -6397, 4041, -6341, 6255, -6381, + 7905, 16504, 0, -6144, 8062, -5606, 8622, -5555, 8439, + -3382, 7398, -1170, 6132, 238, 5148, 1309, 4700, 2218, + 4403, 2573, 3568, 2703, 1758, 3454, -1247, 3434, -4912, + 2862, -7844, 1718,-10095, 369,-12631, -259,-14632, 234, + -15056, -521,-15170, -386,-16015, -641,-16505, -930,-16206, + -1209,-16146, -2839,-16374, -4558,-16218, -5207,-15903, -6421, + -15615, -6925,-14871, -6149,-13759, -5233,-12844, 18313, -4357, + -5696, 2804, 12992,-22802, -6720, -9770, -7088, -8998, 14330, + -12523, 14843, -6130, 29178, -250,-27396, 10467, 16907, -3359, + -6644, 31965, 14607,-21544,-32497, 24020, 12557,-26926, -173, + -129, -6401, -130,-25089, -3841, -4916, -3048, 224, -237, + -3969, -189, -3529, -535, -3464,-14863,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14395,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907, 0, 32512,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907, 9925, -718, 9753, -767, + 9099, -613, 8362, 675, 7774, 2597, 8549, 5278, 8743, + 9375, 6940, 13038, 4826, 14598, 7721,-24308,-29905,-19703, + -17106,-16124, -3287,-26118,-19709, 0, 24353, 28648, 10274, + -11292,-29665,-16417, 24346, 14553, 18707, 26323, -4596,-17711, + 5133, 26328, 13,-31168, 24583, 18404,-28927,-24350, 19453, + 28642, 1019,-10777, -3079, 30188, -7686, 27635,-32521,-16384, + 12528, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, + 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, + 32488, 6687,-20758, 19745, -2070,-13792, -6414, 28188, -2821, + -4585, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, + -8694, 32262, 8461, 27387,-12275, 12012, 23563,-18719,-28410, + 29144,-22271, -562, -9986, -5434, 12288, 5573,-16642, 32448, + 29182, 32705,-30723, 24255,-19716, 18368, -4357, -5696, 2804, + 12992,-22802,-22080, -7701, -5183, 486, -3133, -5660, -1083, + 16871,-28726,-11029,-30259, -1209,-16146, -2839,-16374, -4558, + -16218,-10523, 20697, -9500, -1316, 5431, -1073, 3641, -1304, + 1649, -769, -7276, 2856, -7870, 3314, -8730, 3964,-10183, + 4011,-11135, 3421,-11727, 21398, 32767, -1, 32486, -1, + 6301,-13071, 6380, -7948, -1, 32767, 240, 14081, -5646, + 30973, -3598,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907, 8901, 9375, 6940, 13038, 4826, 14598, 7721,-24308, + -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361, + 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323, + -4440,-17711, 5133, 26328,-14579,-31008, 24583, 18404, 28417, + -24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635, + -32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321, + 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705,-15074, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907, 8192,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14897,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -15931,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907, 26121, 12890, 2604, + 12228,-11634, 12299, 5573,-16642, 32452, 29182, 32705,-30723, + 24255,-19716, 13248,-11779, -5696, 2804, 12992,-27666,-22080, + -7701, -5183, -6682,-31464, 14330,-12523, 14843, -6130, 29178, + -18,-27396, 10467, 16907, -3359, -6644, 31965, 14607,-21544, + -32497, 24020, 12557,-26926,-18421, 706, 24587, 19659, 4878, + 10954, 23060, 8907,-10215,-22579, 31772,-11825,-15590,-23089, + 17173,-25903,-17387, 3285, 4884, 10204,-16627,-14367, 516, + 20453,-16898, 20967,-23815, -20, 22011,-17167, 9468, 32499, + -25607, -523, -3883, -390, -4206, 634, -3767, 2325, -2751, + 3115, -2392, 2746, -2173, 2317, -1147, 2326, 23142, 11314, + -15130,-29137, 3026, 6146, 2150, 2476, 1105, -830, 1775, + -3425, 3674, -5287, 4609, -7175, 4922, -9579, 4556,-12007, + 4236,-14023, 3879,-15553, 3158,-16161, 2576, 18398,-12535, + -6645,-20735,-32763,-13824,-20992, 25859, 5372, 12040, 13307, + -4355,-30213, -9, -6019, 14061,-31487,-13842, 30449, 15083, + 14088, 31205,-18678,-12830, 14090,-26138,-25337,-11541, -3254, + 27628,-22270, 30953,-16136,-30745, 20991,-17406, 5632,-14330, + 28911,-25594, 17408,-20474, 13041, -8731, 2292, -3860, 24049, + 10225,-19220, 10478, -4374, -1199, 148, -330, -74, 593, + 188, 1558, -4152, 15984, 15934, 15934, 15934, 15934, 15934, + 15934, 15934, 15934, 15934, 15934, 15934, 1598, 156, 1604, + -1163, 2278,-30018,-25821,-21763,-23776, 24066, 9502, 25866, + -25055, 10004,-24798, 7204, -4581, -9678, 1554, 10553, 3102, + 12193, 2443, 11955, 1213, 10689, -1293, 921, -4173, 8661, + -6049, 8815,-21221,-14854, 23840, -9477, 8549, 5278, 8743, + 9375, 6940, 13038, 4826, 14598, 7721,-24308,-29905,-19703, + -17106,-16124, -3287,-26118,-19709,-10769, 24361, 28648, 10274, + -11292,-29665,-16417, 24346, 14580, 18707, 26323, -4410,-17711, + 5133, 26328,-14579,-31008, 24583, 18404, 28417,-24350, 19453, + 28642,-32513,-10777, -3079, 30188, -7686, 27635,-32521,-16384, + -20240, -6386, 10986, 23827,-25880,-32752,-23321, 14605, 32231, + 780,-13849, 15119, 28647, 4888, -7705, 30750, 64, 0, + 32488, 6687,-20758, 19745, -2070, -1, -1, 28, 256, + -4608, 7168, 7444, 23557,-21998, 13064, 3345, -4086,-28915, + -8594, 32262, 8461, 27387,-12275, 12012, 23563,-18719,-28410, + 29144,-22271,-32562,-16384, 12528, -6386, 10986, 23827,-25880, + -32752,-23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, + -7705, 30750, 64, 0, 32488, 6687,-20758, 19745, -2070, + -13792, -6414, 28188, -2821, -4585, 7168, 7444, 23557,-21998, + 13064, 3345, -4086,-28915, -8694, 32262, 8461, 27387,-12275, + 12012, 23563,-18719,-28410, 29144,-22271, -562, -9986, -5434, + 12288, -2107,-16643, 32452, 29182, 32705,-30723, 24255,-19716, + 18368, -4357, -5696, 2804, 12992,-22802,-22080, -7701, -5183, + 486, -3133, -5660, -1083, 16871,-28726,-11029,-30259, -1209, + -16146, -2839,-16374, -4558,-16218,-10523, 20697, -9500, -1316, + 5431, -1073, 3641, -1304, 1649, -769, -7276, 2856, -7870, + 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, 21398, + 32767, -1, 32486, -1, -99,-13072, 6380, -7948, 4864, + 32767, 17392, 14335, -5646, 30973, -3598,-10299,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14905,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-19771,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-16443,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-15931,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907, -1,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907, 7877, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, -994, -7276, 2856, -7870, + 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, 21398, + 32767, -1, 32486, -1, -99,-13072, 6380, -7948, 4864, + 32767, 17392, 14335, -5646, 30973, -3598,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14905,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907, 197, 0,-14977,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907, 12838, 6653, 294, + -29699,-25821,-21763,-23776, 24066, 9502, 25866,-25055, 10004, + -24798, 7204, -4581, -9678, 1554, 10553, 3102, 12193, 2443, + 11955, 1213, 10689, -1293, 921, 179, 8448, -6049, 8815, + -7128, 8147, -8308, 6847, -9889, 4920,-11447, 3174,-11794, + 3514,-10220, 3430, 16384, 1926, -7072, 327, -7537, -608, + -7605, -1169, -6397, -1579, -4877, -1419, -3103, -2197, 128, + -3904, 3632, -5401, 4906, -6051, 4250, -6272, 3492, -6343, + 3197, -6397, 4041, -6341, 6255, -6381, 7905, 16504, 0, + -6144, 8062, -5606, 8622, -5555, 8439, -3382, 7398, -1170, + 6132, 238, 5148, 1309, 4700, 2218, 4403, 2573, 3568, + 2703, 1758, 3454, -1247, 3434, -4912, 2862, -7844, 1718, + -10095, 369,-12631, -259,-14632, 234,-15056, -491,-16194, + -386,-16015, -641,-16505, -930,-16206, -1209,-16146, -2839, + -16374, -4558,-16218, -5207,-15903, -6421,-15615, -6925,-14871, + -6149,-13759, -5233,-12844, 18313, -4357, -5696, 2804, 12992, + -22802, -6720, -9770, -7088, -8998, 14330,-12523, 14843, -6130, + 29178, -250,-27396, 10467, 16907, -3359, -6644, 31965, 14607, + -21544,-32497, 24020, 12557,-26926, -173, -129, -6401, -130, + -25089, -3816, -4916, -3048, -32, -1, -3969, 256, -3529, + -535, -3464,-14863,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -1209,-16146, -2839,-16374, -4558,-16218,-10523, 20697, -9500, + -1316, 5431, -1073, 3641, -1304, 1649, -769, -7276, 2856, + -7870, 3314, -8730, 3964,-10183, 4011,-11135, 3421,-11727, + 21398, 32767, -1, 32486, -1, 6301,-13071, 6380, -7948, + -1, 32767, 240, 14081, -5646, 30973, -3598,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + 32767,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907, 8901, 9375, 6940, + 13038, 4826, 14598, 7721,-24308,-29905,-19703,-17106,-16124, + -3287,-26118,-19709,-10769, 24361, 28648, 10274,-11292,-29665, + -16417, 24346, 14580, 18707, 26323, -4440,-17711, 5133, 26328, + -14579,-31008, 24583, 18404, 28417,-24350, 19453, 28642,-32513, + -10777, -3079, 30188, -7686, 27635,-32521,-16384,-20240, -6386, + 10986, 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, + 15119, 28647, 4888, -7705,-15074,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, 8192, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14897, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-15931,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907, 26121, 12890, 2604, 12228,-11634, 12299, 5573, + -16642, 32452, 29182, 32705,-30723, 24255,-19716, 13248,-11779, + -5696, 2804, 12992,-27666,-22080, -7701, -5183, -6682,-31464, + 14330,-12523, 14843, -6130, 29178, -18,-27396, 10467, 16907, + -3359, -6644, 31965, 14607,-21544,-32497, 24020, 12557,-26926, + -18421, 706, 24587, 19659, 4878, 10954, 23060, 8907,-10215, + -22579, 31772,-11825,-15590,-23089, 17173,-25903,-17387, 3285, + 4884, 10204,-16627,-14367, 516, 20453,-16898, 20967,-23815, + -20, 22011,-17167, 9468, 32499,-25607, -523, -3883, -390, + -4206, 634, -3767, 2325, -2751, 3115, -2392, 2746, -2173, + 2317, -1147, 2326, 23142, 11314,-15130,-29137, 3026, 6146, + 2150, 2476, 1105, -830, 1775, -3425, 3674, -5287, 4609, + -7175, 4922, -9579, 4556,-12007, 4236,-14023, 3879,-15553, + 3158,-16161, 2576, 18398,-12535, -6645,-20735,-32763,-13824, + -20992, 25859, 5372, 12040, 13307, -4355,-30213, -9, -6019 + }; + err = opus_multistream_encode(enc, pcm, 960, data, 7380); + opus_test_assert(err > 0); + } + opus_multistream_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(0)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PHASE_INVERSION_DISABLED(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_DTX(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_COMPLEXITY(6)); + opus_multistream_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_AUTO)); + opus_multistream_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(9)); + opus_multistream_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_multistream_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(5)); + opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(775410)); + { + static const short pcm[1440*3] = + { + 30449, 15083, 14088, 31205,-18678,-12830, 14090,-26138,-25337, + -11541, -3254, 27628,-22270, 30953,-16136,-30745, 20991,-17406, + 5632,-14330, 28911,-25594, 17408,-20474, 13041, -8731, 2292, + -3860, 24049, 10225,-19220, 10478, -4374, -1199, 148, -330, + -74, 593, 188, 1558, -4152, 15984, 15934, 15934, 15934, + 15934, 15934, 15934, 15934, 15934, 15934, 15934, 15934, 1598, + 156, 1604, -1163, 2278,-30018,-25821,-21763,-23776, 24066, + 9502, 25866,-25055, 10004,-24798, 7204, -4581, -9678, 1554, + 10553, 3102, 12193, 2443, 11955, 1213, 10689, -1293, 921, + -4173, 8661, -6049, 8815,-21221,-14854, 23840, -9477, 8549, + 5278, 8743, 9375, 6940, 13038, 4826, 14598, 7721,-24308, + -29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, 24361, + 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, 26323, + -4410,-17711, 5133, 26328,-14579,-31008, 24583, 18404, 28417, + -24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, 27635, + -32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752,-23321, + 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, 30750, + 64, 0, 32488, 6687,-20758, 19745, -2070, -1, -1, + 28, 256, -4608, 7168, 7444, 23557,-21998, 13064, 3345, + -4086,-28915, -8594, 32262, 8461, 27387,-12275, 12012, 23563, + -18719,-28410, 29144,-22271,-32562,-16384, 12528, -6386, 10986, + 23827,-25880,-32752,-23321, 14605, 32231, 780,-13849, 15119, + 28647, 4888, -7705, 30750, 64, 0, 32488, 6687,-20758, + 19745, -2070,-13792, -6414, 28188, -2821, -4585, 7168, 7444, + 23557,-21998, 13064, 3345, -4086,-28915, -8694, 32262, 8461, + -14853,-14907,-14907,-14907,-14907, 32767,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14891,-14907,-14907,-14907, + -14907,-14907, 8901, 9375, 6940, 13038, 4826, 14598, 7721, + -24308,-29905,-19703,-17106,-16124, -3287,-26118,-19709,-10769, + 24361, 28648, 10274,-11292,-29665,-16417, 24346, 14580, 18707, + 26323, -4440,-17711, 5133, 26328,-14579,-31008, 24583, 18404, + 28417,-24350, 19453, 28642,-32513,-10777, -3079, 30188, -7686, + 27635,-32521,-16384,-20240, -6386, 10986, 23827,-25880,-32752, + -23321, 14605, 32231, 780,-13849, 15119, 28647, 4888, -7705, + -15074,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907, 8192,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14897,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-15931,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907, 26121, 12890, + 2604, 12228,-11634, 12299, 5573,-16642, 32452, 29182, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, 7710, + 7710,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-10811,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14917,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14938,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907,-14907, + -14907,-14907,-14907,-14907, -571, -9986, -58, 12542,-18491, + 32507, 12838, 6653, 294, -1, 0,-19968, 18368, -4357, + -5696, 2804, 12998,-22802,-22080, -7701, -5183, 486, -3133, + -5660, -1083, 13799,-28726,-11029, 205,-14848, 32464, -1, + -129,-13072, 6380, -7948, 20717, 18425, 17392, 14335, -5646, + 30973, -3598, 7188, -3867, 3055, -4247, 5597, -4011,-26427, + -11,-30418, 7922, 2614, 237, -5839,-27413,-17624,-29716, + -13539, 239, 20991, 18164, -4082,-16647,-27386, 19458, 20224, + 4619, 19728, -7409,-18186,-25073, 27627,-23539, -7945,-31464, + 14330,-12523,-22021, -7701, -5183, 486, -3133, -5660, -1083, + 13799,-28726,-11029, 205,-14848, 32464, -1, -129,-13072, + 6380, -7948, 20717, 18425, 17392, 14093, -5646, 30973, -3598, + 7188, -3867, 3055, 3689, -5401, 4906, -6051, 4250, -6272, + 3492, -6343, 3197, -6397, 4041, -6341, 6255, -6381, 239, + 20991, 18164, -4082,-16647,-27386, 19458, 20224, 4619, 19728, + -7409,-18186,-25073, 27627,-23539, -7945,-31464, 14330,-12523, + 14843, -6130, 30202, -250,-28420, 10467, 16907, -3359, -6644, + 31965, 3343,-11727, 2966,-12616, 3064,-13472, 6732,-12349, + 5541,-11965, 5530,-10820, -1912, -3637, 32285, -4607, 310, + -32768, 0, -5258, 2106, -6857, 2681, -5449, -3606, -6717, + -5482, -3606, -1853, 4082, -7631, -9808, -1742, -2851, -5112, + 64, -868,-13546,-13365,-13365,-13365,-13365,-13365,-13365, + -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365, + -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365, + -13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365,-13365, + -13365,-13365,-13365,-13365,-13365,-13365,-13365, 7883, -2316, + 9086, -3944, 10500, 4285, 10459, -6474, 10204, -6539, 11601, + -6824, 13385, -7142, 13872, -7457, 13670, -7725, 13463, -6887, + 12482, -5580, 12600, -4964, 12480, 3254, 11741, -4210,-24819, + 23282, 22798, 491, -1774, -1073, 3641, -1304, 28928, -250, + -27396, 6657, -8961, 22524, 19987, 10231, 1791, 8947,-32763, + -26385,-31227, -792,-30461, 8926, 4866, 27863, 27756, 27756, + 27756, 27756, 27756, 27756, 27756, 27756, 5630,-11070,-16136, + 20671,-11530, 27328, 8179, 5059,-31503,-24379,-19472, 17863, + -29202, 22986, -23, 8909, 8422, 10450 + }; + err = opus_multistream_encode(enc, pcm, 1440, data, 7380); + /* reads uninitialized data at src/opus_multistream_encoder.c:293 */ + opus_test_assert(err > 0); + } + opus_multistream_encoder_destroy(enc); + return 0; +} + +static int ec_enc_shrink_assert(void) +{ + OpusEncoder *enc; + int err; + int data_len; + unsigned char data[2000]; + static const short pcm1[960] = { 5140 }; + static const short pcm2[2880] = + { + -256,-12033, 0, -2817, 6912, 0, -5359, 5200, 3061, + 0, -2903, 5652, -1281,-24656,-14433,-24678, 32,-29793, + 2870, 0, 4096, 5120, 5140, -234,-20230,-24673,-24633, + -24673,-24705, 0,-32768,-25444,-25444, 0,-25444,-25444, + 156,-20480, -7948, -5920, -7968, -7968, 224, 0, 20480, + 11, 20496, 13, 20496, 11,-20480, 2292,-20240, 244, + 20480, 11, 20496, 11,-20480, 244,-20240, 7156, 20456, + -246,-20243, 244, 128, 244, 20480, 11, 20496, 11, + -20480, 244,-20256, 244, 20480, 256, 0, -246, 16609, + -176, 0, 29872, -4096, -2888, 516, 2896, 4096, 2896, + -20480, -3852, -2896, -1025,-31056,-14433, 244, 1792, -256, + -12033, 0, -2817, 0, 0, -5359, 5200, 3061, 16, + -2903, 5652, -1281,-24656,-14433,-24678, 32,-29793, 2870, + 0, 4096, 5120, 5140, -234,-20230,-24673,-24633,-24673, + -24705, 0,-32768,-25444,-25444, 0,-25444,-25444, 156, + -20480, -7973, -5920, -7968, -7968, 224, 0, 20480, 11, + 20496, 11, 20496, 11,-20480, 2292,-20213, 244, 20480, + 11, 20496, 11,-24698, -2873, 0, 7, -1, 208, + -256, 244, 0, 4352, 20715, -2796, 11,-22272, 5364, + -234,-20230,-24673,-25913, 8351,-24832, 13963, 11, 0, + 16, 5140, 5652, -1281,-24656,-14433,-24673, 32671, 159, + 0,-25472,-25444, 156,-25600,-25444,-25444, 0, -2896, + -7968, -7960, -7968, -7968, 0, 0, 2896, 4096, 2896, + 4096, 2896, 0, -2896, -4088, -2896, 0, 2896, 0, + -2896, -4096, -2896, 11, 2640, -4609, -2896,-32768, -3072, + 0, 2896, 4096, 2896, 0, -2896, -4096, -2896, 0, + 80, 1, 2816, 0, 20656, 255,-20480, 116,-18192 + }; + static const short pcm3[2880] = { 0 }; + + enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err); + opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10)); + opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(6)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000)); + data_len = opus_encode(enc, pcm1, 960, data, 2000); + opus_test_assert(data_len > 0); + + opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); + opus_encoder_ctl(enc, OPUS_SET_PREDICTION_DISABLED(1)); + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); + opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(1)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(15600)); + data_len = opus_encode(enc, pcm2, 2880, data, 122); + opus_test_assert(data_len > 0); + + opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(27000)); + data_len = opus_encode(enc, pcm3, 2880, data, 122); /* assertion failure */ + opus_test_assert(data_len > 0); + + opus_encoder_destroy(enc); + return 0; +} + +static int ec_enc_shrink_assert2(void) +{ + OpusEncoder *enc; + int err; + int data_len; + unsigned char data[2000]; + + enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_AUDIO, &err); + opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(6)); + opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE)); + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(26)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(27000)); + { + static const short pcm[960] = { 0 }; + data_len = opus_encode(enc, pcm, 960, data, 2000); + opus_test_assert(data_len > 0); + } + opus_encoder_ctl(enc, OPUS_SET_SIGNAL(OPUS_SIGNAL_MUSIC)); + { + static const short pcm[480] = + { + 32767, 32767, 0, 0, 32767, 32767, 0, 0, 32767, 32767, + -32768, -32768, 0, 0, -32768, -32768, 0, 0, -32768, -32768 + }; + data_len = opus_encode(enc, pcm, 480, data, 19); + opus_test_assert(data_len > 0); + } + opus_encoder_destroy(enc); + return 0; +} + +static int silk_gain_assert(void) +{ + OpusEncoder *enc; + int err; + int data_len; + unsigned char data[1000]; + static const short pcm1[160] = { 0 }; + static const short pcm2[960] = + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 32767 + }; + + enc = opus_encoder_create(8000, 1, OPUS_APPLICATION_AUDIO, &err); + opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(3)); + opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(6000)); + data_len = opus_encode(enc, pcm1, 160, data, 1000); + opus_test_assert(data_len > 0); + + opus_encoder_ctl(enc, OPUS_SET_VBR(0)); + opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(0)); + opus_encoder_ctl(enc, OPUS_SET_MAX_BANDWIDTH(OPUS_BANDWIDTH_MEDIUMBAND)); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(2867)); + data_len = opus_encode(enc, pcm2, 960, data, 1000); + opus_test_assert(data_len > 0); + + opus_encoder_destroy(enc); + return 0; +} + +void regression_test(void) +{ + fprintf(stderr, "Running simple tests for bugs that have been fixed previously\n"); + celt_ec_internal_error(); + mscbr_encode_fail10(); + mscbr_encode_fail(); + surround_analysis_uninit(); + ec_enc_shrink_assert(); + ec_enc_shrink_assert2(); + silk_gain_assert(); +} diff --git a/lib/opus/tests/random_config.sh b/lib/opus/tests/random_config.sh new file mode 100755 index 00000000..0cdd855f --- /dev/null +++ b/lib/opus/tests/random_config.sh @@ -0,0 +1,126 @@ +#!/bin/bash + +dir="$1" +mkdir "$dir" +if [ $? -ne 0 ] +then + exit 1 +fi + +cd "$dir" +if [ $? -ne 0 ] +then + exit 1 +fi + + +configure_path="$2" +config="random_config.txt" + +case `seq 3 | shuf -n1` in +1) +approx=--enable-float-approx +math=-ffast-math +;; +2) +approx=--enable-float-approx +;; +*) +approx= +math= +;; +esac + +CFLAGS='-g' + +opt=`echo -e "-O1\n-O2\n-O3" | shuf -n1` + +#arch=-march=`echo -e "core2\nsandybridge\nbroadwell\nskylake" | shuf -n1` +arch=`echo -e "\n-march=core2\n-march=sandybridge\n-march=broadwell\n-march=skylake\n-march=native" | shuf -n1` + +footprint=`echo -e "\n-DSMALL_FOOTPRINT" | shuf -n1` +std=`echo -e "\n-std=c90\n-std=c99\n-std=c11\n-std=c17" | shuf -n1` +sanitize=`echo -e "\n-fsanitize=address -fno-sanitize-recover=all\n-fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=signed-integer-overflow" | shuf -n1` + + +CFLAGS="$CFLAGS $std $opt $arch $footprint $math $sanitize" + +echo "CFLAGS=$CFLAGS" > "$config" + +lib=`echo -e "\n--disable-static\n--disable-shared" | shuf -n1` + +arithmetic=`echo -e "\n--enable-fixed-point\n--enable-fixed-point --enable-fixed-point-debug\n--enable-fixed-point --disable-float-api\n--enable-fixed-point --enable-fixed-point-debug --disable-float-api" | shuf -n1` + +custom=`echo -e "\n--enable-custom-modes" | shuf -n1` + +asm=`echo -e "\n--disable-asm\n--disable-rtcd\n--disable-intrinsics" | shuf -n1` +#asm=`echo -e "\n--disable-asm\n--disable-intrinsics" | shuf -n1` + +assert=`echo -e "\n--enable-assertions" | shuf -n1` +harden=`echo -e "\n--enable-hardening" | shuf -n1` +fuzz=`echo -e "\n--enable-fuzzing" | shuf -n1` +checkasm=`echo -e "\n--enable-check-asm" | shuf -n1` +rfc8251=`echo -e "\n--disable-rfc8251" | shuf -n1` + +if [ "$rfc8251" = --disable-rfc8251 ] +then + vectors="$3" +else + vectors="$4" +fi +echo using testvectors at "$vectors" >> "$config" + + +config_opt="$lib $arithmetic $custom $asm $assert $harden $fuzz $checkasm $rfc8251 $approx" + +echo configure $config_opt >> "$config" + +export CFLAGS +"$configure_path/configure" $config_opt > configure_output.txt 2>&1 + +if [ $? -ne 0 ] +then + echo configure FAIL >> "$config" + exit 1 +fi + +make > make_output.txt 2>&1 + +if [ $? -ne 0 ] +then + echo make FAIL >> "$config" + exit 1 +fi + +#Run valgrind 5% of the time (minus the asan cases) +if [ "`seq 20 | shuf -n1`" -ne 1 -o "$sanitize" = "-fsanitize=address -fno-sanitize-recover=all" ] +then + make check > makecheck_output.txt 2>&1 +else + echo valgrind enabled >> "$config" + valgrind --trace-children=yes --error-exitcode=128 make check > makecheck_output.txt 2>&1 +fi + +if [ $? -ne 0 ] +then + echo check FAIL >> "$config" + exit 1 +fi + + +rate=`echo -e "8000\n12000\n16000\n24000\n48000" | shuf -n1` +echo testvectors for "$rate" Hz > testvectors_output.txt +../../../run_vectors.sh . "$vectors" "$rate" >> testvectors_output.txt 2>&1 + +if [ $? -ne 0 ] +then + echo testvectors FAIL >> "$config" + exit 1 +fi + +echo all tests PASS >> "$config" + +#When everything's good, do some cleaning up to save space +make distclean > /dev/null 2>&1 +rm -f tmp.out +gzip make_output.txt diff --git a/lib/opus/tests/run_vectors.sh b/lib/opus/tests/run_vectors.sh new file mode 100755 index 00000000..dcb76cf1 --- /dev/null +++ b/lib/opus/tests/run_vectors.sh @@ -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, "%"}' diff --git a/lib/opus/tests/test_opus_api.c b/lib/opus/tests/test_opus_api.c new file mode 100644 index 00000000..0e7ed2cc --- /dev/null +++ b/lib/opus/tests/test_opus_api.c @@ -0,0 +1,1904 @@ +/* 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. +*/ + +/* This tests the API presented by the libopus system. + It does not attempt to extensively exercise the codec internals. + The strategy here is to simply the API interface invariants: + That sane options are accepted, insane options are rejected, + and that nothing blows up. In particular we don't actually test + that settings are heeded by the codec (though we do check that + get after set returns a sane value when it should). Other + tests check the actual codec behavior. + In cases where its reasonable to do so we test exhaustively, + but its not reasonable to do so in all cases. + Although these tests are simple they found several library bugs + when they were initially developed. */ + +/* These tests are more sensitive if compiled with -DVALGRIND and + run inside valgrind. Malloc failure testing requires glibc. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include "arch.h" +#include "opus_multistream.h" +#include "opus.h" +#include "test_opus_common.h" + +#ifdef VALGRIND +#include <valgrind/memcheck.h> +#define VG_UNDEF(x,y) VALGRIND_MAKE_MEM_UNDEFINED((x),(y)) +#define VG_CHECK(x,y) VALGRIND_CHECK_MEM_IS_DEFINED((x),(y)) +#else +#define VG_UNDEF(x,y) +#define VG_CHECK(x,y) +#endif + +#if defined(HAVE___MALLOC_HOOK) +#define MALLOC_FAIL +#include "os_support.h" +#include <malloc.h> + +static const opus_int32 opus_apps[3] = {OPUS_APPLICATION_VOIP, + OPUS_APPLICATION_AUDIO,OPUS_APPLICATION_RESTRICTED_LOWDELAY}; + +void *malloc_hook(__attribute__((unused)) size_t size, + __attribute__((unused)) const void *caller) +{ + return 0; +} +#endif + +opus_int32 *null_int_ptr = (opus_int32 *)NULL; +opus_uint32 *null_uint_ptr = (opus_uint32 *)NULL; + +static const opus_int32 opus_rates[5] = {48000,24000,16000,12000,8000}; + +opus_int32 test_dec_api(void) +{ + opus_uint32 dec_final_range; + OpusDecoder *dec; + OpusDecoder *dec2; + opus_int32 i,j,cfgs; + unsigned char packet[1276]; +#ifndef DISABLE_FLOAT_API + float fbuf[960*2]; +#endif + short sbuf[960*2]; + int c,err; + + cfgs=0; + /*First test invalid configurations which should fail*/ + fprintf(stdout,"\n Decoder basic API tests\n"); + fprintf(stdout," ---------------------------------------------------\n"); + for(c=0;c<4;c++) + { + i=opus_decoder_get_size(c); + if(((c==1||c==2)&&(i<=2048||i>1<<16))||((c!=1&&c!=2)&&i!=0))test_failed(); + fprintf(stdout," opus_decoder_get_size(%d)=%d ...............%s OK.\n",c,i,i>0?"":"...."); + cfgs++; + } + + /*Test with unsupported sample rates*/ + for(c=0;c<4;c++) + { + for(i=-7;i<=96000;i++) + { + int fs; + if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue; + switch(i) + { + case(-5):fs=-8000;break; + case(-6):fs=INT32_MAX;break; + case(-7):fs=INT32_MIN;break; + default:fs=i; + } + err = OPUS_OK; + VG_UNDEF(&err,sizeof(err)); + dec = opus_decoder_create(fs, c, &err); + if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed(); + cfgs++; + dec = opus_decoder_create(fs, c, 0); + if(dec!=NULL)test_failed(); + cfgs++; + dec=malloc(opus_decoder_get_size(2)); + if(dec==NULL)test_failed(); + err = opus_decoder_init(dec,fs,c); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + free(dec); + } + } + + VG_UNDEF(&err,sizeof(err)); + dec = opus_decoder_create(48000, 2, &err); + if(err!=OPUS_OK || dec==NULL)test_failed(); + VG_CHECK(dec,opus_decoder_get_size(2)); + cfgs++; + + fprintf(stdout," opus_decoder_create() ........................ OK.\n"); + fprintf(stdout," opus_decoder_init() .......................... OK.\n"); + + err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(null_uint_ptr)); + if(err != OPUS_BAD_ARG)test_failed(); + VG_UNDEF(&dec_final_range,sizeof(dec_final_range)); + err=opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); + if(err!=OPUS_OK)test_failed(); + VG_CHECK(&dec_final_range,sizeof(dec_final_range)); + fprintf(stdout," OPUS_GET_FINAL_RANGE ......................... OK.\n"); + cfgs++; + + err=opus_decoder_ctl(dec,OPUS_UNIMPLEMENTED); + if(err!=OPUS_UNIMPLEMENTED)test_failed(); + fprintf(stdout," OPUS_UNIMPLEMENTED ........................... OK.\n"); + cfgs++; + + err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(null_int_ptr)); + if(err != OPUS_BAD_ARG)test_failed(); + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i)); + if(err != OPUS_OK || i!=0)test_failed(); + fprintf(stdout," OPUS_GET_BANDWIDTH ........................... OK.\n"); + cfgs++; + + err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(null_int_ptr)); + if(err != OPUS_BAD_ARG)test_failed(); + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_SAMPLE_RATE(&i)); + if(err != OPUS_OK || i!=48000)test_failed(); + fprintf(stdout," OPUS_GET_SAMPLE_RATE ......................... OK.\n"); + cfgs++; + + /*GET_PITCH has different execution paths depending on the previously decoded frame.*/ + err=opus_decoder_ctl(dec, OPUS_GET_PITCH(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i)); + if(err != OPUS_OK || i>0 || i<-1)test_failed(); + cfgs++; + VG_UNDEF(packet,sizeof(packet)); + packet[0]=63<<2;packet[1]=packet[2]=0; + if(opus_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i)); + if(err != OPUS_OK || i>0 || i<-1)test_failed(); + cfgs++; + packet[0]=1; + if(opus_decode(dec, packet, 1, sbuf, 960, 0)!=960)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_PITCH(&i)); + if(err != OPUS_OK || i>0 || i<-1)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_PITCH ............................... OK.\n"); + + err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(null_int_ptr)); + if(err != OPUS_BAD_ARG)test_failed(); + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&i)); + if(err != OPUS_OK || i!=960)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_LAST_PACKET_DURATION ................ OK.\n"); + + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_GAIN(&i)); + VG_CHECK(&i,sizeof(i)); + if(err != OPUS_OK || i!=0)test_failed(); + cfgs++; + err=opus_decoder_ctl(dec, OPUS_GET_GAIN(null_int_ptr)); + if(err != OPUS_BAD_ARG)test_failed(); + cfgs++; + err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-32769)); + if(err != OPUS_BAD_ARG)test_failed(); + cfgs++; + err=opus_decoder_ctl(dec, OPUS_SET_GAIN(32768)); + if(err != OPUS_BAD_ARG)test_failed(); + cfgs++; + err=opus_decoder_ctl(dec, OPUS_SET_GAIN(-15)); + if(err != OPUS_OK)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(dec, OPUS_GET_GAIN(&i)); + VG_CHECK(&i,sizeof(i)); + if(err != OPUS_OK || i!=-15)test_failed(); + cfgs++; + fprintf(stdout," OPUS_SET_GAIN ................................ OK.\n"); + fprintf(stdout," OPUS_GET_GAIN ................................ OK.\n"); + + /*Reset the decoder*/ + dec2=malloc(opus_decoder_get_size(2)); + memcpy(dec2,dec,opus_decoder_get_size(2)); + if(opus_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); + if(memcmp(dec2,dec,opus_decoder_get_size(2))==0)test_failed(); + free(dec2); + fprintf(stdout," OPUS_RESET_STATE ............................. OK.\n"); + cfgs++; + + VG_UNDEF(packet,sizeof(packet)); + packet[0]=0; + if(opus_decoder_get_nb_samples(dec,packet,1)!=480)test_failed(); + if(opus_packet_get_nb_samples(packet,1,48000)!=480)test_failed(); + if(opus_packet_get_nb_samples(packet,1,96000)!=960)test_failed(); + if(opus_packet_get_nb_samples(packet,1,32000)!=320)test_failed(); + if(opus_packet_get_nb_samples(packet,1,8000)!=80)test_failed(); + packet[0]=3; + if(opus_packet_get_nb_samples(packet,1,24000)!=OPUS_INVALID_PACKET)test_failed(); + packet[0]=(63<<2)|3; + packet[1]=63; + if(opus_packet_get_nb_samples(packet,0,24000)!=OPUS_BAD_ARG)test_failed(); + if(opus_packet_get_nb_samples(packet,2,48000)!=OPUS_INVALID_PACKET)test_failed(); + if(opus_decoder_get_nb_samples(dec,packet,2)!=OPUS_INVALID_PACKET)test_failed(); + fprintf(stdout," opus_{packet,decoder}_get_nb_samples() ....... OK.\n"); + cfgs+=9; + + if(OPUS_BAD_ARG!=opus_packet_get_nb_frames(packet,0))test_failed(); + for(i=0;i<256;i++) { + int l1res[4]={1,2,2,OPUS_INVALID_PACKET}; + packet[0]=i; + if(l1res[packet[0]&3]!=opus_packet_get_nb_frames(packet,1))test_failed(); + cfgs++; + for(j=0;j<256;j++) { + packet[1]=j; + if(((packet[0]&3)!=3?l1res[packet[0]&3]:packet[1]&63)!=opus_packet_get_nb_frames(packet,2))test_failed(); + cfgs++; + } + } + fprintf(stdout," opus_packet_get_nb_frames() .................. OK.\n"); + + for(i=0;i<256;i++) { + int bw; + packet[0]=i; + bw=packet[0]>>4; + bw=OPUS_BANDWIDTH_NARROWBAND+(((((bw&7)*9)&(63-(bw&8)))+2+12*((bw&8)!=0))>>4); + if(bw!=opus_packet_get_bandwidth(packet))test_failed(); + cfgs++; + } + fprintf(stdout," opus_packet_get_bandwidth() .................. OK.\n"); + + for(i=0;i<256;i++) { + int fp3s,rate; + packet[0]=i; + fp3s=packet[0]>>3; + fp3s=((((3-(fp3s&3))*13&119)+9)>>2)*((fp3s>13)*(3-((fp3s&3)==3))+1)*25; + for(rate=0;rate<5;rate++) { + if((opus_rates[rate]*3/fp3s)!=opus_packet_get_samples_per_frame(packet,opus_rates[rate]))test_failed(); + cfgs++; + } + } + fprintf(stdout," opus_packet_get_samples_per_frame() .......... OK.\n"); + + packet[0]=(63<<2)+3; + packet[1]=49; + for(j=2;j<51;j++)packet[j]=0; + VG_UNDEF(sbuf,sizeof(sbuf)); + if(opus_decode(dec, packet, 51, sbuf, 960, 0)!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + packet[0]=(63<<2); + packet[1]=packet[2]=0; + if(opus_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + if(opus_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + if(opus_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); + cfgs++; + fprintf(stdout," opus_decode() ................................ OK.\n"); +#ifndef DISABLE_FLOAT_API + VG_UNDEF(fbuf,sizeof(fbuf)); + if(opus_decode_float(dec, packet, 3, fbuf, 960, 0)!=960)test_failed(); + cfgs++; + fprintf(stdout," opus_decode_float() .......................... OK.\n"); +#endif + +#if 0 + /*These tests are disabled because the library crashes with null states*/ + if(opus_decoder_ctl(0,OPUS_RESET_STATE) !=OPUS_INVALID_STATE)test_failed(); + if(opus_decoder_init(0,48000,1) !=OPUS_INVALID_STATE)test_failed(); + if(opus_decode(0,packet,1,outbuf,2880,0) !=OPUS_INVALID_STATE)test_failed(); + if(opus_decode_float(0,packet,1,0,2880,0) !=OPUS_INVALID_STATE)test_failed(); + if(opus_decoder_get_nb_samples(0,packet,1) !=OPUS_INVALID_STATE)test_failed(); + if(opus_packet_get_nb_frames(NULL,1) !=OPUS_BAD_ARG)test_failed(); + if(opus_packet_get_bandwidth(NULL) !=OPUS_BAD_ARG)test_failed(); + if(opus_packet_get_samples_per_frame(NULL,48000)!=OPUS_BAD_ARG)test_failed(); +#endif + opus_decoder_destroy(dec); + cfgs++; + fprintf(stdout," All decoder interface tests passed\n"); + fprintf(stdout," (%6d API invocations)\n",cfgs); + return cfgs; +} + +opus_int32 test_msdec_api(void) +{ + opus_uint32 dec_final_range; + OpusMSDecoder *dec; + OpusDecoder *streamdec; + opus_int32 i,j,cfgs; + unsigned char packet[1276]; + unsigned char mapping[256]; +#ifndef DISABLE_FLOAT_API + float fbuf[960*2]; +#endif + short sbuf[960*2]; + int a,b,c,err; + + mapping[0]=0; + mapping[1]=1; + for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char)); + + cfgs=0; + /*First test invalid configurations which should fail*/ + fprintf(stdout,"\n Multistream decoder basic API tests\n"); + fprintf(stdout," ---------------------------------------------------\n"); + for(a=-1;a<4;a++) + { + for(b=-1;b<4;b++) + { + i=opus_multistream_decoder_get_size(a,b); + if(((a>0&&b<=a&&b>=0)&&(i<=2048||i>((1<<16)*a)))||((a<1||b>a||b<0)&&i!=0))test_failed(); + fprintf(stdout," opus_multistream_decoder_get_size(%2d,%2d)=%d %sOK.\n",a,b,i,i>0?"":"... "); + cfgs++; + } + } + + /*Test with unsupported sample rates*/ + for(c=1;c<3;c++) + { + for(i=-7;i<=96000;i++) + { + int fs; + if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue; + switch(i) + { + case(-5):fs=-8000;break; + case(-6):fs=INT32_MAX;break; + case(-7):fs=INT32_MIN;break; + default:fs=i; + } + err = OPUS_OK; + VG_UNDEF(&err,sizeof(err)); + dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, &err); + if(err!=OPUS_BAD_ARG || dec!=NULL)test_failed(); + cfgs++; + dec = opus_multistream_decoder_create(fs, c, 1, c-1, mapping, 0); + if(dec!=NULL)test_failed(); + cfgs++; + dec=malloc(opus_multistream_decoder_get_size(1,1)); + if(dec==NULL)test_failed(); + err = opus_multistream_decoder_init(dec,fs,c,1,c-1, mapping); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + free(dec); + } + } + + for(c=0;c<2;c++) + { + int *ret_err; + ret_err = c?0:&err; + + mapping[0]=0; + mapping[1]=1; + for(i=2;i<256;i++)VG_UNDEF(&mapping[i],sizeof(unsigned char)); + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + mapping[0]=mapping[1]=0; + dec = opus_multistream_decoder_create(48000, 2, 1, 0, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); + cfgs++; + opus_multistream_decoder_destroy(dec); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 1, 4, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); + cfgs++; + + err = opus_multistream_decoder_init(dec,48000, 1, 0, 0, mapping); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + + err = opus_multistream_decoder_init(dec,48000, 1, 1, -1, mapping); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + + opus_multistream_decoder_destroy(dec); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); + cfgs++; + opus_multistream_decoder_destroy(dec); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 255, 255, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, -1, 1, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 0, 1, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 1, -1, 2, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 1, -1, -1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 256, 255, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + dec = opus_multistream_decoder_create(48000, 256, 255, 0, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + mapping[0]=255; + mapping[1]=1; + mapping[2]=2; + dec = opus_multistream_decoder_create(48000, 3, 2, 0, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + mapping[0]=0; + mapping[1]=0; + mapping[2]=0; + dec = opus_multistream_decoder_create(48000, 3, 2, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_OK) || dec==NULL)test_failed(); + cfgs++; + opus_multistream_decoder_destroy(dec); + cfgs++; + + VG_UNDEF(ret_err,sizeof(*ret_err)); + mapping[0]=0; + mapping[1]=255; + mapping[2]=1; + mapping[3]=2; + mapping[4]=3; + dec = opus_multistream_decoder_create(48001, 5, 4, 1, mapping, ret_err); + if(ret_err){VG_CHECK(ret_err,sizeof(*ret_err));} + if((ret_err && *ret_err!=OPUS_BAD_ARG) || dec!=NULL)test_failed(); + cfgs++; + } + + VG_UNDEF(&err,sizeof(err)); + mapping[0]=0; + mapping[1]=255; + mapping[2]=1; + mapping[3]=2; + dec = opus_multistream_decoder_create(48000, 4, 2, 1, mapping, &err); + VG_CHECK(&err,sizeof(err)); + if(err!=OPUS_OK || dec==NULL)test_failed(); + cfgs++; + + fprintf(stdout," opus_multistream_decoder_create() ............ OK.\n"); + fprintf(stdout," opus_multistream_decoder_init() .............. OK.\n"); + + VG_UNDEF(&dec_final_range,sizeof(dec_final_range)); + err=opus_multistream_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range)); + if(err!=OPUS_OK)test_failed(); + VG_CHECK(&dec_final_range,sizeof(dec_final_range)); + fprintf(stdout," OPUS_GET_FINAL_RANGE ......................... OK.\n"); + cfgs++; + + streamdec=0; + VG_UNDEF(&streamdec,sizeof(streamdec)); + err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(-1,&streamdec)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(1,&streamdec)); + if(err!=OPUS_OK||streamdec==NULL)test_failed(); + VG_CHECK(streamdec,opus_decoder_get_size(1)); + cfgs++; + err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(2,&streamdec)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + err=opus_multistream_decoder_ctl(dec, OPUS_MULTISTREAM_GET_DECODER_STATE(0,&streamdec)); + if(err!=OPUS_OK||streamdec==NULL)test_failed(); + VG_CHECK(streamdec,opus_decoder_get_size(1)); + fprintf(stdout," OPUS_MULTISTREAM_GET_DECODER_STATE ........... OK.\n"); + cfgs++; + + for(j=0;j<2;j++) + { + OpusDecoder *od; + err=opus_multistream_decoder_ctl(dec,OPUS_MULTISTREAM_GET_DECODER_STATE(j,&od)); + if(err != OPUS_OK)test_failed(); + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(od, OPUS_GET_GAIN(&i)); + VG_CHECK(&i,sizeof(i)); + if(err != OPUS_OK || i!=0)test_failed(); + cfgs++; + } + err=opus_multistream_decoder_ctl(dec,OPUS_SET_GAIN(15)); + if(err!=OPUS_OK)test_failed(); + fprintf(stdout," OPUS_SET_GAIN ................................ OK.\n"); + for(j=0;j<2;j++) + { + OpusDecoder *od; + err=opus_multistream_decoder_ctl(dec,OPUS_MULTISTREAM_GET_DECODER_STATE(j,&od)); + if(err != OPUS_OK)test_failed(); + VG_UNDEF(&i,sizeof(i)); + err=opus_decoder_ctl(od, OPUS_GET_GAIN(&i)); + VG_CHECK(&i,sizeof(i)); + if(err != OPUS_OK || i!=15)test_failed(); + cfgs++; + } + fprintf(stdout," OPUS_GET_GAIN ................................ OK.\n"); + + VG_UNDEF(&i,sizeof(i)); + err=opus_multistream_decoder_ctl(dec, OPUS_GET_BANDWIDTH(&i)); + if(err != OPUS_OK || i!=0)test_failed(); + fprintf(stdout," OPUS_GET_BANDWIDTH ........................... OK.\n"); + cfgs++; + + err=opus_multistream_decoder_ctl(dec,OPUS_UNIMPLEMENTED); + if(err!=OPUS_UNIMPLEMENTED)test_failed(); + fprintf(stdout," OPUS_UNIMPLEMENTED ........................... OK.\n"); + cfgs++; + +#if 0 + /*Currently unimplemented for multistream*/ + /*GET_PITCH has different execution paths depending on the previously decoded frame.*/ + err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i)); + if(err != OPUS_OK || i>0 || i<-1)test_failed(); + cfgs++; + VG_UNDEF(packet,sizeof(packet)); + packet[0]=63<<2;packet[1]=packet[2]=0; + if(opus_multistream_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i)); + if(err != OPUS_OK || i>0 || i<-1)test_failed(); + cfgs++; + packet[0]=1; + if(opus_multistream_decode(dec, packet, 1, sbuf, 960, 0)!=960)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + err=opus_multistream_decoder_ctl(dec, OPUS_GET_PITCH(&i)); + if(err != OPUS_OK || i>0 || i<-1)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_PITCH ............................... OK.\n"); +#endif + + /*Reset the decoder*/ + if(opus_multistream_decoder_ctl(dec, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); + fprintf(stdout," OPUS_RESET_STATE ............................. OK.\n"); + cfgs++; + + opus_multistream_decoder_destroy(dec); + cfgs++; + VG_UNDEF(&err,sizeof(err)); + dec = opus_multistream_decoder_create(48000, 2, 1, 1, mapping, &err); + if(err!=OPUS_OK || dec==NULL)test_failed(); + cfgs++; + + packet[0]=(63<<2)+3; + packet[1]=49; + for(j=2;j<51;j++)packet[j]=0; + VG_UNDEF(sbuf,sizeof(sbuf)); + if(opus_multistream_decode(dec, packet, 51, sbuf, 960, 0)!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + packet[0]=(63<<2); + packet[1]=packet[2]=0; + if(opus_multistream_decode(dec, packet, -1, sbuf, 960, 0)!=OPUS_BAD_ARG){printf("%d\n",opus_multistream_decode(dec, packet, -1, sbuf, 960, 0));test_failed();} + cfgs++; + if(opus_multistream_decode(dec, packet, 3, sbuf, -960, 0)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_multistream_decode(dec, packet, 3, sbuf, 60, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + if(opus_multistream_decode(dec, packet, 3, sbuf, 480, 0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + if(opus_multistream_decode(dec, packet, 3, sbuf, 960, 0)!=960)test_failed(); + cfgs++; + fprintf(stdout," opus_multistream_decode() .................... OK.\n"); +#ifndef DISABLE_FLOAT_API + VG_UNDEF(fbuf,sizeof(fbuf)); + if(opus_multistream_decode_float(dec, packet, 3, fbuf, 960, 0)!=960)test_failed(); + cfgs++; + fprintf(stdout," opus_multistream_decode_float() .............. OK.\n"); +#endif + +#if 0 + /*These tests are disabled because the library crashes with null states*/ + if(opus_multistream_decoder_ctl(0,OPUS_RESET_STATE) !=OPUS_INVALID_STATE)test_failed(); + if(opus_multistream_decoder_init(0,48000,1) !=OPUS_INVALID_STATE)test_failed(); + if(opus_multistream_decode(0,packet,1,outbuf,2880,0) !=OPUS_INVALID_STATE)test_failed(); + if(opus_multistream_decode_float(0,packet,1,0,2880,0) !=OPUS_INVALID_STATE)test_failed(); + if(opus_multistream_decoder_get_nb_samples(0,packet,1) !=OPUS_INVALID_STATE)test_failed(); +#endif + opus_multistream_decoder_destroy(dec); + cfgs++; + fprintf(stdout," All multistream decoder interface tests passed\n"); + fprintf(stdout," (%6d API invocations)\n",cfgs); + return cfgs; +} + +#ifdef VALGRIND +#define UNDEFINE_FOR_PARSE toc=-1; \ + frames[0]=(unsigned char *)0; \ + frames[1]=(unsigned char *)0; \ + payload_offset=-1; \ + VG_UNDEF(&toc,sizeof(toc)); \ + VG_UNDEF(frames,sizeof(frames));\ + VG_UNDEF(&payload_offset,sizeof(payload_offset)); +#else +#define UNDEFINE_FOR_PARSE toc=-1; \ + frames[0]=(unsigned char *)0; \ + frames[1]=(unsigned char *)0; \ + payload_offset=-1; +#endif + +/* This test exercises the heck out of the libopus parser. + It is much larger than the parser itself in part because + it tries to hit a lot of corner cases that could never + fail with the libopus code, but might be problematic for + other implementations. */ +opus_int32 test_parse(void) +{ + opus_int32 i,j,jj,sz; + unsigned char packet[1276]; + opus_int32 cfgs,cfgs_total; + unsigned char toc; + const unsigned char *frames[48]; + short size[48]; + int payload_offset, ret; + fprintf(stdout,"\n Packet header parsing tests\n"); + fprintf(stdout," ---------------------------------------------------\n"); + memset(packet,0,sizeof(char)*1276); + packet[0]=63<<2; + if(opus_packet_parse(packet,1,&toc,frames,0,&payload_offset)!=OPUS_BAD_ARG)test_failed(); + cfgs_total=cfgs=1; + /*code 0*/ + for(i=0;i<64;i++) + { + packet[0]=i<<2; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,4,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=1)test_failed(); + if(size[0]!=3)test_failed(); + if(frames[0]!=packet+1)test_failed(); + } + fprintf(stdout," code 0 (%2d cases) ............................ OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + /*code 1, two frames of the same size*/ + for(i=0;i<64;i++) + { + packet[0]=(i<<2)+1; + for(jj=0;jj<=1275*2+3;jj++) + { + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,jj,&toc,frames,size,&payload_offset); + cfgs++; + if((jj&1)==1 && jj<=2551) + { + /* Must pass if payload length even (packet length odd) and + size<=2551, must fail otherwise. */ + if(ret!=2)test_failed(); + if(size[0]!=size[1] || size[0]!=((jj-1)>>1))test_failed(); + if(frames[0]!=packet+1)test_failed(); + if(frames[1]!=frames[0]+size[0])test_failed(); + if((toc>>2)!=i)test_failed(); + } else if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + } + fprintf(stdout," code 1 (%6d cases) ........................ OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + /*code 2, length code overflow*/ + packet[0]=(i<<2)+2; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + packet[1]=252; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + for(j=0;j<1275;j++) + { + if(j<252)packet[1]=j; + else{packet[1]=252+(j&3);packet[2]=(j-252)>>2;} + /*Code 2, one too short*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,j+(j<252?2:3)-1,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + /*Code 2, one too long*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,j+(j<252?2:3)+1276,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + /*Code 2, second zero*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,j+(j<252?2:3),&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=2)test_failed(); + if(size[0]!=j||size[1]!=0)test_failed(); + if(frames[1]!=frames[0]+size[0])test_failed(); + if((toc>>2)!=i)test_failed(); + /*Code 2, normal*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,(j<<1)+4,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=2)test_failed(); + if(size[0]!=j||size[1]!=(j<<1)+3-j-(j<252?1:2))test_failed(); + if(frames[1]!=frames[0]+size[0])test_failed(); + if((toc>>2)!=i)test_failed(); + } + } + fprintf(stdout," code 2 (%6d cases) ........................ OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + packet[0]=(i<<2)+3; + /*code 3, length code overflow*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + fprintf(stdout," code 3 m-truncation (%2d cases) ............... OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + /*code 3, m is zero or 49-63*/ + packet[0]=(i<<2)+3; + for(jj=49;jj<=64;jj++) + { + packet[1]=0+(jj&63); /*CBR, no padding*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + packet[1]=128+(jj&63); /*VBR, no padding*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + packet[1]=64+(jj&63); /*CBR, padding*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + packet[1]=128+64+(jj&63); /*VBR, padding*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1275,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + } + fprintf(stdout," code 3 m=0,49-64 (%2d cases) ................ OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + packet[0]=(i<<2)+3; + /*code 3, m is one, cbr*/ + packet[1]=1; + for(j=0;j<1276;j++) + { + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,j+2,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=1)test_failed(); + if(size[0]!=j)test_failed(); + if((toc>>2)!=i)test_failed(); + } + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1276+2,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + fprintf(stdout," code 3 m=1 CBR (%2d cases) ................. OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + int frame_samp; + /*code 3, m>1 CBR*/ + packet[0]=(i<<2)+3; + frame_samp=opus_packet_get_samples_per_frame(packet,48000); + for(j=2;j<49;j++) + { + packet[1]=j; + for(sz=2;sz<((j+2)*1275);sz++) + { + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,sz,&toc,frames,size,&payload_offset); + cfgs++; + /*Must be <=120ms, must be evenly divisible, can't have frames>1275 bytes*/ + if(frame_samp*j<=5760 && (sz-2)%j==0 && (sz-2)/j<1276) + { + if(ret!=j)test_failed(); + for(jj=1;jj<ret;jj++)if(frames[jj]!=frames[jj-1]+size[jj-1])test_failed(); + if((toc>>2)!=i)test_failed(); + } else if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + } + /*Super jumbo packets*/ + packet[1]=5760/frame_samp; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,1275*packet[1]+2,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=packet[1])test_failed(); + for(jj=0;jj<ret;jj++)if(size[jj]!=1275)test_failed(); + } + fprintf(stdout," code 3 m=1-48 CBR (%2d cases) .......... OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + int frame_samp; + /*Code 3 VBR, m one*/ + packet[0]=(i<<2)+3; + packet[1]=128+1; + frame_samp=opus_packet_get_samples_per_frame(packet,48000); + for(jj=0;jj<1276;jj++) + { + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+jj,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=1)test_failed(); + if(size[0]!=jj)test_failed(); + if((toc>>2)!=i)test_failed(); + } + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+1276,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + for(j=2;j<49;j++) + { + packet[1]=128+j; + /*Length code overflow*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+j-2,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + packet[2]=252; + packet[3]=0; + for(jj=4;jj<2+j;jj++)packet[jj]=0; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+j,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + /*One byte too short*/ + for(jj=2;jj<2+j;jj++)packet[jj]=0; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+j-2,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + /*One byte too short thanks to length coding*/ + packet[2]=252; + packet[3]=0; + for(jj=4;jj<2+j;jj++)packet[jj]=0; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+j+252-1,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + /*Most expensive way of coding zeros*/ + for(jj=2;jj<2+j;jj++)packet[jj]=0; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+j-1,&toc,frames,size,&payload_offset); + cfgs++; + if(frame_samp*j<=5760){ + if(ret!=j)test_failed(); + for(jj=0;jj<j;jj++)if(size[jj]!=0)test_failed(); + if((toc>>2)!=i)test_failed(); + } else if(ret!=OPUS_INVALID_PACKET)test_failed(); + /*Quasi-CBR use of mode 3*/ + for(sz=0;sz<8;sz++) + { + const int tsz[8]={50,201,403,700,1472,5110,20400,61298}; + int pos=0; + int as=(tsz[sz]+i-j-2)/j; + for(jj=0;jj<j-1;jj++) + { + if(as<252){packet[2+pos]=as;pos++;} + else{packet[2+pos]=252+(as&3);packet[3+pos]=(as-252)>>2;pos+=2;} + } + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,tsz[sz]+i,&toc,frames,size,&payload_offset); + cfgs++; + if(frame_samp*j<=5760 && as<1276 && (tsz[sz]+i-2-pos-as*(j-1))<1276){ + if(ret!=j)test_failed(); + for(jj=0;jj<j-1;jj++)if(size[jj]!=as)test_failed(); + if(size[j-1]!=(tsz[sz]+i-2-pos-as*(j-1)))test_failed(); + if((toc>>2)!=i)test_failed(); + } else if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + } + } + fprintf(stdout," code 3 m=1-48 VBR (%2d cases) ............. OK.\n",cfgs); + cfgs_total+=cfgs;cfgs=0; + + for(i=0;i<64;i++) + { + packet[0]=(i<<2)+3; + /*Padding*/ + packet[1]=128+1+64; + /*Overflow the length coding*/ + for(jj=2;jj<127;jj++)packet[jj]=255; + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,127,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + + for(sz=0;sz<4;sz++) + { + const int tsz[4]={0,72,512,1275}; + for(jj=sz;jj<65025;jj+=11) + { + int pos; + for(pos=0;pos<jj/254;pos++)packet[2+pos]=255; + packet[2+pos]=jj%254; + pos++; + if(sz==0&&i==63) + { + /*Code more padding than there is room in the packet*/ + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+jj+pos-1,&toc,frames,size,&payload_offset); + cfgs++; + if(ret!=OPUS_INVALID_PACKET)test_failed(); + } + UNDEFINE_FOR_PARSE + ret=opus_packet_parse(packet,2+jj+tsz[sz]+i+pos,&toc,frames,size,&payload_offset); + cfgs++; + if(tsz[sz]+i<1276) + { + if(ret!=1)test_failed(); + if(size[0]!=tsz[sz]+i)test_failed(); + if((toc>>2)!=i)test_failed(); + } else if (ret!=OPUS_INVALID_PACKET)test_failed(); + } + } + } + fprintf(stdout," code 3 padding (%2d cases) ............... OK.\n",cfgs); + cfgs_total+=cfgs; + fprintf(stdout," opus_packet_parse ............................ OK.\n"); + fprintf(stdout," All packet parsing tests passed\n"); + fprintf(stdout," (%d API invocations)\n",cfgs_total); + return cfgs_total; +} + +/* This is a helper macro for the encoder tests. + The encoder api tests all have a pattern of set-must-fail, set-must-fail, + set-must-pass, get-and-compare, set-must-pass, get-and-compare. */ +#define CHECK_SETGET(setcall,getcall,badv,badv2,goodv,goodv2,sok,gok) \ + i=(badv);\ + if(opus_encoder_ctl(enc,setcall)==OPUS_OK)test_failed();\ + i=(badv2);\ + if(opus_encoder_ctl(enc,setcall)==OPUS_OK)test_failed();\ + j=i=(goodv);\ + if(opus_encoder_ctl(enc,setcall)!=OPUS_OK)test_failed();\ + i=-12345;\ + VG_UNDEF(&i,sizeof(i)); \ + err=opus_encoder_ctl(enc,getcall);\ + if(err!=OPUS_OK || i!=j)test_failed();\ + j=i=(goodv2);\ + if(opus_encoder_ctl(enc,setcall)!=OPUS_OK)test_failed();\ + fprintf(stdout,sok);\ + i=-12345;\ + VG_UNDEF(&i,sizeof(i)); \ + err=opus_encoder_ctl(enc,getcall);\ + if(err!=OPUS_OK || i!=j)test_failed();\ + fprintf(stdout,gok);\ + cfgs+=6; + +opus_int32 test_enc_api(void) +{ + opus_uint32 enc_final_range; + OpusEncoder *enc; + opus_int32 i,j; + unsigned char packet[1276]; +#ifndef DISABLE_FLOAT_API + float fbuf[960*2]; +#endif + short sbuf[960*2]; + int c,err,cfgs; + + cfgs=0; + /*First test invalid configurations which should fail*/ + fprintf(stdout,"\n Encoder basic API tests\n"); + fprintf(stdout," ---------------------------------------------------\n"); + for(c=0;c<4;c++) + { + i=opus_encoder_get_size(c); + if(((c==1||c==2)&&(i<=2048||i>1<<17))||((c!=1&&c!=2)&&i!=0))test_failed(); + fprintf(stdout," opus_encoder_get_size(%d)=%d ...............%s OK.\n",c,i,i>0?"":"...."); + cfgs++; + } + + /*Test with unsupported sample rates, channel counts*/ + for(c=0;c<4;c++) + { + for(i=-7;i<=96000;i++) + { + int fs; + if((i==8000||i==12000||i==16000||i==24000||i==48000)&&(c==1||c==2))continue; + switch(i) + { + case(-5):fs=-8000;break; + case(-6):fs=INT32_MAX;break; + case(-7):fs=INT32_MIN;break; + default:fs=i; + } + err = OPUS_OK; + VG_UNDEF(&err,sizeof(err)); + enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, &err); + if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed(); + cfgs++; + enc = opus_encoder_create(fs, c, OPUS_APPLICATION_VOIP, 0); + if(enc!=NULL)test_failed(); + cfgs++; + opus_encoder_destroy(enc); + enc=malloc(opus_encoder_get_size(2)); + if(enc==NULL)test_failed(); + err = opus_encoder_init(enc, fs, c, OPUS_APPLICATION_VOIP); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + free(enc); + } + } + + enc = opus_encoder_create(48000, 2, OPUS_AUTO, NULL); + if(enc!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(&err,sizeof(err)); + enc = opus_encoder_create(48000, 2, OPUS_AUTO, &err); + if(err!=OPUS_BAD_ARG || enc!=NULL)test_failed(); + cfgs++; + + VG_UNDEF(&err,sizeof(err)); + enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, NULL); + if(enc==NULL)test_failed(); + opus_encoder_destroy(enc); + cfgs++; + + VG_UNDEF(&err,sizeof(err)); + enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_RESTRICTED_LOWDELAY, &err); + if(err!=OPUS_OK || enc==NULL)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i)); + if(err!=OPUS_OK || i<0 || i>32766)test_failed(); + cfgs++; + opus_encoder_destroy(enc); + + VG_UNDEF(&err,sizeof(err)); + enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_AUDIO, &err); + if(err!=OPUS_OK || enc==NULL)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i)); + if(err!=OPUS_OK || i<0 || i>32766)test_failed(); + opus_encoder_destroy(enc); + cfgs++; + + VG_UNDEF(&err,sizeof(err)); + enc = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err); + if(err!=OPUS_OK || enc==NULL)test_failed(); + cfgs++; + + fprintf(stdout," opus_encoder_create() ........................ OK.\n"); + fprintf(stdout," opus_encoder_init() .......................... OK.\n"); + + i=-12345; + VG_UNDEF(&i,sizeof(i)); + err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(&i)); + if(err!=OPUS_OK || i<0 || i>32766)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_LOOKAHEAD(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_LOOKAHEAD ........................... OK.\n"); + + err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(&i)); + if(err!=OPUS_OK || i!=48000)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_SAMPLE_RATE(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_SAMPLE_RATE ......................... OK.\n"); + + if(opus_encoder_ctl(enc,OPUS_UNIMPLEMENTED)!=OPUS_UNIMPLEMENTED)test_failed(); + fprintf(stdout," OPUS_UNIMPLEMENTED ........................... OK.\n"); + cfgs++; + + err=opus_encoder_ctl(enc,OPUS_GET_APPLICATION(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_APPLICATION(i),OPUS_GET_APPLICATION(&i),-1,OPUS_AUTO, + OPUS_APPLICATION_AUDIO,OPUS_APPLICATION_RESTRICTED_LOWDELAY, + " OPUS_SET_APPLICATION ......................... OK.\n", + " OPUS_GET_APPLICATION ......................... OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_BITRATE(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_encoder_ctl(enc,OPUS_SET_BITRATE(1073741832))!=OPUS_OK)test_failed(); + cfgs++; + VG_UNDEF(&i,sizeof(i)); + if(opus_encoder_ctl(enc,OPUS_GET_BITRATE(&i))!=OPUS_OK)test_failed(); + if(i>700000||i<256000)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_BITRATE(i),OPUS_GET_BITRATE(&i),-12345,0, + 500,256000, + " OPUS_SET_BITRATE ............................. OK.\n", + " OPUS_GET_BITRATE ............................. OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_FORCE_CHANNELS(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_FORCE_CHANNELS(i),OPUS_GET_FORCE_CHANNELS(&i),-1,3, + 1,OPUS_AUTO, + " OPUS_SET_FORCE_CHANNELS ...................... OK.\n", + " OPUS_GET_FORCE_CHANNELS ...................... OK.\n") + + i=-2; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))==OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_FULLBAND+1; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))==OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_NARROWBAND; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_FULLBAND; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_WIDEBAND; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_MEDIUMBAND; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + fprintf(stdout," OPUS_SET_BANDWIDTH ........................... OK.\n"); + /*We don't test if the bandwidth has actually changed. + because the change may be delayed until the encoder is advanced.*/ + i=-12345; + VG_UNDEF(&i,sizeof(i)); + err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH(&i)); + if(err!=OPUS_OK || (i!=OPUS_BANDWIDTH_NARROWBAND&& + i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&& + i!=OPUS_BANDWIDTH_FULLBAND&&i!=OPUS_AUTO))test_failed(); + cfgs++; + if(opus_encoder_ctl(enc,OPUS_SET_BANDWIDTH(OPUS_AUTO))!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_BANDWIDTH(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_BANDWIDTH ........................... OK.\n"); + + i=-2; + if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))==OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_FULLBAND+1; + if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))==OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_NARROWBAND; + if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_FULLBAND; + if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_WIDEBAND; + if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + i=OPUS_BANDWIDTH_MEDIUMBAND; + if(opus_encoder_ctl(enc,OPUS_SET_MAX_BANDWIDTH(i))!=OPUS_OK)test_failed(); + cfgs++; + fprintf(stdout," OPUS_SET_MAX_BANDWIDTH ....................... OK.\n"); + /*We don't test if the bandwidth has actually changed. + because the change may be delayed until the encoder is advanced.*/ + i=-12345; + VG_UNDEF(&i,sizeof(i)); + err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH(&i)); + if(err!=OPUS_OK || (i!=OPUS_BANDWIDTH_NARROWBAND&& + i!=OPUS_BANDWIDTH_MEDIUMBAND&&i!=OPUS_BANDWIDTH_WIDEBAND&& + i!=OPUS_BANDWIDTH_FULLBAND))test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_MAX_BANDWIDTH(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_MAX_BANDWIDTH ....................... OK.\n"); + + err=opus_encoder_ctl(enc,OPUS_GET_DTX(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_DTX(i),OPUS_GET_DTX(&i),-1,2, + 1,0, + " OPUS_SET_DTX ................................. OK.\n", + " OPUS_GET_DTX ................................. OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_COMPLEXITY(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_COMPLEXITY(i),OPUS_GET_COMPLEXITY(&i),-1,11, + 0,10, + " OPUS_SET_COMPLEXITY .......................... OK.\n", + " OPUS_GET_COMPLEXITY .......................... OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_INBAND_FEC(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_INBAND_FEC(i),OPUS_GET_INBAND_FEC(&i),-1,3, + 1,0, + " OPUS_SET_INBAND_FEC .......................... OK.\n", + " OPUS_GET_INBAND_FEC .......................... OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_PACKET_LOSS_PERC(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_PACKET_LOSS_PERC(i),OPUS_GET_PACKET_LOSS_PERC(&i),-1,101, + 100,0, + " OPUS_SET_PACKET_LOSS_PERC .................... OK.\n", + " OPUS_GET_PACKET_LOSS_PERC .................... OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_VBR(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_VBR(i),OPUS_GET_VBR(&i),-1,2, + 1,0, + " OPUS_SET_VBR ................................. OK.\n", + " OPUS_GET_VBR ................................. OK.\n") + +/* err=opus_encoder_ctl(enc,OPUS_GET_VOICE_RATIO(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_VOICE_RATIO(i),OPUS_GET_VOICE_RATIO(&i),-2,101, + 0,50, + " OPUS_SET_VOICE_RATIO ......................... OK.\n", + " OPUS_GET_VOICE_RATIO ......................... OK.\n")*/ + + err=opus_encoder_ctl(enc,OPUS_GET_VBR_CONSTRAINT(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_VBR_CONSTRAINT(i),OPUS_GET_VBR_CONSTRAINT(&i),-1,2, + 1,0, + " OPUS_SET_VBR_CONSTRAINT ...................... OK.\n", + " OPUS_GET_VBR_CONSTRAINT ...................... OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_SIGNAL(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_SIGNAL(i),OPUS_GET_SIGNAL(&i),-12345,0x7FFFFFFF, + OPUS_SIGNAL_MUSIC,OPUS_AUTO, + " OPUS_SET_SIGNAL .............................. OK.\n", + " OPUS_GET_SIGNAL .............................. OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_LSB_DEPTH(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_LSB_DEPTH(i),OPUS_GET_LSB_DEPTH(&i),7,25,16,24, + " OPUS_SET_LSB_DEPTH ........................... OK.\n", + " OPUS_GET_LSB_DEPTH ........................... OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(&i)); + if(i!=0)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_GET_PREDICTION_DISABLED(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_PREDICTION_DISABLED(i),OPUS_GET_PREDICTION_DISABLED(&i),-1,2,1,0, + " OPUS_SET_PREDICTION_DISABLED ................. OK.\n", + " OPUS_GET_PREDICTION_DISABLED ................. OK.\n") + + err=opus_encoder_ctl(enc,OPUS_GET_EXPERT_FRAME_DURATION(null_int_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_2_5_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_5_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_10_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_40_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_60_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_80_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_100_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + err=opus_encoder_ctl(enc,OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_120_MS)); + if(err!=OPUS_OK)test_failed(); + cfgs++; + CHECK_SETGET(OPUS_SET_EXPERT_FRAME_DURATION(i),OPUS_GET_EXPERT_FRAME_DURATION(&i),0,-1, + OPUS_FRAMESIZE_60_MS,OPUS_FRAMESIZE_ARG, + " OPUS_SET_EXPERT_FRAME_DURATION ............... OK.\n", + " OPUS_GET_EXPERT_FRAME_DURATION ............... OK.\n") + + /*OPUS_SET_FORCE_MODE is not tested here because it's not a public API, however the encoder tests use it*/ + + err=opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(null_uint_ptr)); + if(err!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_encoder_ctl(enc,OPUS_GET_FINAL_RANGE(&enc_final_range))!=OPUS_OK)test_failed(); + cfgs++; + fprintf(stdout," OPUS_GET_FINAL_RANGE ......................... OK.\n"); + + /*Reset the encoder*/ + if(opus_encoder_ctl(enc, OPUS_RESET_STATE)!=OPUS_OK)test_failed(); + cfgs++; + fprintf(stdout," OPUS_RESET_STATE ............................. OK.\n"); + + memset(sbuf,0,sizeof(short)*2*960); + VG_UNDEF(packet,sizeof(packet)); + i=opus_encode(enc, sbuf, 960, packet, sizeof(packet)); + if(i<1 || (i>(opus_int32)sizeof(packet)))test_failed(); + VG_CHECK(packet,i); + cfgs++; + fprintf(stdout," opus_encode() ................................ OK.\n"); +#ifndef DISABLE_FLOAT_API + memset(fbuf,0,sizeof(float)*2*960); + VG_UNDEF(packet,sizeof(packet)); + i=opus_encode_float(enc, fbuf, 960, packet, sizeof(packet)); + if(i<1 || (i>(opus_int32)sizeof(packet)))test_failed(); + VG_CHECK(packet,i); + cfgs++; + fprintf(stdout," opus_encode_float() .......................... OK.\n"); +#endif + +#if 0 + /*These tests are disabled because the library crashes with null states*/ + if(opus_encoder_ctl(0,OPUS_RESET_STATE) !=OPUS_INVALID_STATE)test_failed(); + if(opus_encoder_init(0,48000,1,OPUS_APPLICATION_VOIP) !=OPUS_INVALID_STATE)test_failed(); + if(opus_encode(0,sbuf,960,packet,sizeof(packet)) !=OPUS_INVALID_STATE)test_failed(); + if(opus_encode_float(0,fbuf,960,packet,sizeof(packet))!=OPUS_INVALID_STATE)test_failed(); +#endif + opus_encoder_destroy(enc); + cfgs++; + fprintf(stdout," All encoder interface tests passed\n"); + fprintf(stdout," (%d API invocations)\n",cfgs); + return cfgs; +} + +#define max_out (1276*48+48*2+2) +int test_repacketizer_api(void) +{ + int ret,cfgs,i,j,k; + OpusRepacketizer *rp; + unsigned char *packet; + unsigned char *po; + cfgs=0; + fprintf(stdout,"\n Repacketizer tests\n"); + fprintf(stdout," ---------------------------------------------------\n"); + + packet=malloc(max_out); + if(packet==NULL)test_failed(); + memset(packet,0,max_out); + po=malloc(max_out+256); + if(po==NULL)test_failed(); + + i=opus_repacketizer_get_size(); + if(i<=0)test_failed(); + cfgs++; + fprintf(stdout," opus_repacketizer_get_size()=%d ............. OK.\n",i); + + rp=malloc(i); + rp=opus_repacketizer_init(rp); + if(rp==NULL)test_failed(); + cfgs++; + free(rp); + fprintf(stdout," opus_repacketizer_init ....................... OK.\n"); + + rp=opus_repacketizer_create(); + if(rp==NULL)test_failed(); + cfgs++; + fprintf(stdout," opus_repacketizer_create ..................... OK.\n"); + + if(opus_repacketizer_get_nb_frames(rp)!=0)test_failed(); + cfgs++; + fprintf(stdout," opus_repacketizer_get_nb_frames .............. OK.\n"); + + /*Length overflows*/ + VG_UNDEF(packet,4); + if(opus_repacketizer_cat(rp,packet,0)!=OPUS_INVALID_PACKET)test_failed(); /* Zero len */ + cfgs++; + packet[0]=1; + if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Odd payload code 1 */ + cfgs++; + packet[0]=2; + if(opus_repacketizer_cat(rp,packet,1)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow one */ + cfgs++; + packet[0]=3; + if(opus_repacketizer_cat(rp,packet,1)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 no count */ + cfgs++; + packet[0]=2; + packet[1]=255; + if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow two */ + cfgs++; + packet[0]=2; + packet[1]=250; + if(opus_repacketizer_cat(rp,packet,251)!=OPUS_INVALID_PACKET)test_failed(); /* Code 2 overflow three */ + cfgs++; + packet[0]=3; + packet[1]=0; + if(opus_repacketizer_cat(rp,packet,2)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 m=0 */ + cfgs++; + packet[1]=49; + if(opus_repacketizer_cat(rp,packet,100)!=OPUS_INVALID_PACKET)test_failed(); /* Code 3 m=49 */ + cfgs++; + packet[0]=0; + if(opus_repacketizer_cat(rp,packet,3)!=OPUS_OK)test_failed(); + cfgs++; + packet[0]=1<<2; + if(opus_repacketizer_cat(rp,packet,3)!=OPUS_INVALID_PACKET)test_failed(); /* Change in TOC */ + cfgs++; + + /* Code 0,1,3 CBR -> Code 0,1,3 CBR */ + opus_repacketizer_init(rp); + for(j=0;j<32;j++) + { + /* TOC types, test half with stereo */ + int maxi; + packet[0]=((j<<1)+(j&1))<<2; + maxi=960/opus_packet_get_samples_per_frame(packet,8000); + for(i=1;i<=maxi;i++) + { + /* Number of CBR frames in the input packets */ + int maxp; + packet[0]=((j<<1)+(j&1))<<2; + if(i>1)packet[0]+=i==2?1:3; + packet[1]=i>2?i:0; + maxp=960/(i*opus_packet_get_samples_per_frame(packet,8000)); + for(k=0;k<=(1275+75);k+=3) + { + /*Payload size*/ + opus_int32 cnt,rcnt; + if(k%i!=0)continue; /* Only testing CBR here, payload must be a multiple of the count */ + for(cnt=0;cnt<maxp+2;cnt++) + { + if(cnt>0) + { + ret=opus_repacketizer_cat(rp,packet,k+(i>2?2:1)); + if((cnt<=maxp&&k<=(1275*i))?ret!=OPUS_OK:ret!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + } + rcnt=k<=(1275*i)?(cnt<maxp?cnt:maxp):0; + if(opus_repacketizer_get_nb_frames(rp)!=rcnt*i)test_failed(); + cfgs++; + ret=opus_repacketizer_out_range(rp,0,rcnt*i,po,max_out); + if(rcnt>0) + { + int len; + len=k*rcnt+((rcnt*i)>2?2:1); + if(ret!=len)test_failed(); + if((rcnt*i)<2&&(po[0]&3)!=0)test_failed(); /* Code 0 */ + if((rcnt*i)==2&&(po[0]&3)!=1)test_failed(); /* Code 1 */ + if((rcnt*i)>2&&(((po[0]&3)!=3)||(po[1]!=rcnt*i)))test_failed(); /* Code 3 CBR */ + cfgs++; + if(opus_repacketizer_out(rp,po,len)!=len)test_failed(); + cfgs++; + if(opus_packet_unpad(po,len)!=len)test_failed(); + cfgs++; + if(opus_packet_pad(po,len,len+1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_packet_pad(po,len+1,len+256)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_packet_unpad(po,len+256)!=len)test_failed(); + cfgs++; + if(opus_multistream_packet_unpad(po,len,1)!=len)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,len,len+1,1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,len+1,len+256,1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_multistream_packet_unpad(po,len+256,1)!=len)test_failed(); + cfgs++; + if(opus_repacketizer_out(rp,po,len-1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + if(len>1) + { + if(opus_repacketizer_out(rp,po,1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + } + if(opus_repacketizer_out(rp,po,0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + } else if (ret!=OPUS_BAD_ARG)test_failed(); /* M must not be 0 */ + } + opus_repacketizer_init(rp); + } + } + } + + /*Change in input count code, CBR out*/ + opus_repacketizer_init(rp); + packet[0]=0; + if(opus_repacketizer_cat(rp,packet,5)!=OPUS_OK)test_failed(); + cfgs++; + packet[0]+=1; + if(opus_repacketizer_cat(rp,packet,9)!=OPUS_OK)test_failed(); + cfgs++; + i=opus_repacketizer_out(rp,po,max_out); + if((i!=(4+8+2))||((po[0]&3)!=3)||((po[1]&63)!=3)||((po[1]>>7)!=0))test_failed(); + cfgs++; + i=opus_repacketizer_out_range(rp,0,1,po,max_out); + if(i!=5||(po[0]&3)!=0)test_failed(); + cfgs++; + i=opus_repacketizer_out_range(rp,1,2,po,max_out); + if(i!=5||(po[0]&3)!=0)test_failed(); + cfgs++; + + /*Change in input count code, VBR out*/ + opus_repacketizer_init(rp); + packet[0]=1; + if(opus_repacketizer_cat(rp,packet,9)!=OPUS_OK)test_failed(); + cfgs++; + packet[0]=0; + if(opus_repacketizer_cat(rp,packet,3)!=OPUS_OK)test_failed(); + cfgs++; + i=opus_repacketizer_out(rp,po,max_out); + if((i!=(2+8+2+2))||((po[0]&3)!=3)||((po[1]&63)!=3)||((po[1]>>7)!=1))test_failed(); + cfgs++; + + /*VBR in, VBR out*/ + opus_repacketizer_init(rp); + packet[0]=2; + packet[1]=4; + if(opus_repacketizer_cat(rp,packet,8)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_repacketizer_cat(rp,packet,8)!=OPUS_OK)test_failed(); + cfgs++; + i=opus_repacketizer_out(rp,po,max_out); + if((i!=(2+1+1+1+4+2+4+2))||((po[0]&3)!=3)||((po[1]&63)!=4)||((po[1]>>7)!=1))test_failed(); + cfgs++; + + /*VBR in, CBR out*/ + opus_repacketizer_init(rp); + packet[0]=2; + packet[1]=4; + if(opus_repacketizer_cat(rp,packet,10)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_repacketizer_cat(rp,packet,10)!=OPUS_OK)test_failed(); + cfgs++; + i=opus_repacketizer_out(rp,po,max_out); + if((i!=(2+4+4+4+4))||((po[0]&3)!=3)||((po[1]&63)!=4)||((po[1]>>7)!=0))test_failed(); + cfgs++; + + /*Count 0 in, VBR out*/ + for(j=0;j<32;j++) + { + /* TOC types, test half with stereo */ + int maxi,sum,rcnt; + packet[0]=((j<<1)+(j&1))<<2; + maxi=960/opus_packet_get_samples_per_frame(packet,8000); + sum=0; + rcnt=0; + opus_repacketizer_init(rp); + for(i=1;i<=maxi+2;i++) + { + int len; + ret=opus_repacketizer_cat(rp,packet,i); + if(rcnt<maxi) + { + if(ret!=OPUS_OK)test_failed(); + rcnt++; + sum+=i-1; + } else if (ret!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + len=sum+(rcnt<2?1:rcnt<3?2:2+rcnt-1); + if(opus_repacketizer_out(rp,po,max_out)!=len)test_failed(); + if(rcnt>2&&(po[1]&63)!=rcnt)test_failed(); + if(rcnt==2&&(po[0]&3)!=2)test_failed(); + if(rcnt==1&&(po[0]&3)!=0)test_failed(); + cfgs++; + if(opus_repacketizer_out(rp,po,len)!=len)test_failed(); + cfgs++; + if(opus_packet_unpad(po,len)!=len)test_failed(); + cfgs++; + if(opus_packet_pad(po,len,len+1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_packet_pad(po,len+1,len+256)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_packet_unpad(po,len+256)!=len)test_failed(); + cfgs++; + if(opus_multistream_packet_unpad(po,len,1)!=len)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,len,len+1,1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,len+1,len+256,1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_multistream_packet_unpad(po,len+256,1)!=len)test_failed(); + cfgs++; + if(opus_repacketizer_out(rp,po,len-1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + if(len>1) + { + if(opus_repacketizer_out(rp,po,1)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + } + if(opus_repacketizer_out(rp,po,0)!=OPUS_BUFFER_TOO_SMALL)test_failed(); + cfgs++; + } + } + + po[0]='O'; + po[1]='p'; + if(opus_packet_pad(po,4,4)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,4,4,1)!=OPUS_OK)test_failed(); + cfgs++; + if(opus_packet_pad(po,4,5)!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,4,5,1)!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + if(opus_packet_pad(po,0,5)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,0,5,1)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_packet_unpad(po,0)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_multistream_packet_unpad(po,0,1)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_packet_unpad(po,4)!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + if(opus_multistream_packet_unpad(po,4,1)!=OPUS_INVALID_PACKET)test_failed(); + cfgs++; + po[0]=0; + po[1]=0; + po[2]=0; + if(opus_packet_pad(po,5,4)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + if(opus_multistream_packet_pad(po,5,4,1)!=OPUS_BAD_ARG)test_failed(); + cfgs++; + + fprintf(stdout," opus_repacketizer_cat ........................ OK.\n"); + fprintf(stdout," opus_repacketizer_out ........................ OK.\n"); + fprintf(stdout," opus_repacketizer_out_range .................. OK.\n"); + fprintf(stdout," opus_packet_pad .............................. OK.\n"); + fprintf(stdout," opus_packet_unpad ............................ OK.\n"); + fprintf(stdout," opus_multistream_packet_pad .................. OK.\n"); + fprintf(stdout," opus_multistream_packet_unpad ................ OK.\n"); + + opus_repacketizer_destroy(rp); + cfgs++; + free(packet); + free(po); + fprintf(stdout," All repacketizer tests passed\n"); + fprintf(stdout," (%7d API invocations)\n",cfgs); + + return cfgs; +} + +#ifdef MALLOC_FAIL +/* GLIBC 2.14 declares __malloc_hook as deprecated, generating a warning + * under GCC. However, this is the cleanest way to test malloc failure + * handling in our codebase, and the lack of thread safety isn't an + * issue here. We therefore disable the warning for this function. + */ +#if OPUS_GNUC_PREREQ(4,6) +/* Save the current warning settings */ +#pragma GCC diagnostic push +#endif +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +typedef void *(*mhook)(size_t __size, __const void *); +#endif + +int test_malloc_fail(void) +{ +#ifdef MALLOC_FAIL + OpusDecoder *dec; + OpusEncoder *enc; + OpusRepacketizer *rp; + unsigned char mapping[256] = {0,1}; + OpusMSDecoder *msdec; + OpusMSEncoder *msenc; + int rate,c,app,cfgs,err,useerr; + int *ep; + mhook orig_malloc; + cfgs=0; +#endif + fprintf(stdout,"\n malloc() failure tests\n"); + fprintf(stdout," ---------------------------------------------------\n"); +#ifdef MALLOC_FAIL + orig_malloc=__malloc_hook; + __malloc_hook=malloc_hook; + ep=(int *)opus_alloc(sizeof(int)); + if(ep!=NULL) + { + if(ep)free(ep); + __malloc_hook=orig_malloc; +#endif + fprintf(stdout," opus_decoder_create() ................... SKIPPED.\n"); + fprintf(stdout," opus_encoder_create() ................... SKIPPED.\n"); + fprintf(stdout," opus_repacketizer_create() .............. SKIPPED.\n"); + fprintf(stdout," opus_multistream_decoder_create() ....... SKIPPED.\n"); + fprintf(stdout," opus_multistream_encoder_create() ....... SKIPPED.\n"); + fprintf(stdout,"(Test only supported with GLIBC and without valgrind)\n"); + return 0; +#ifdef MALLOC_FAIL + } + for(useerr=0;useerr<2;useerr++) + { + ep=useerr?&err:0; + for(rate=0;rate<5;rate++) + { + for(c=1;c<3;c++) + { + err=1; + if(useerr) + { + VG_UNDEF(&err,sizeof(err)); + } + dec=opus_decoder_create(opus_rates[rate], c, ep); + if(dec!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) + { + __malloc_hook=orig_malloc; + test_failed(); + } + cfgs++; + msdec=opus_multistream_decoder_create(opus_rates[rate], c, 1, c-1, mapping, ep); + if(msdec!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) + { + __malloc_hook=orig_malloc; + test_failed(); + } + cfgs++; + for(app=0;app<3;app++) + { + if(useerr) + { + VG_UNDEF(&err,sizeof(err)); + } + enc=opus_encoder_create(opus_rates[rate], c, opus_apps[app],ep); + if(enc!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) + { + __malloc_hook=orig_malloc; + test_failed(); + } + cfgs++; + msenc=opus_multistream_encoder_create(opus_rates[rate], c, 1, c-1, mapping, opus_apps[app],ep); + if(msenc!=NULL||(useerr&&err!=OPUS_ALLOC_FAIL)) + { + __malloc_hook=orig_malloc; + test_failed(); + } + cfgs++; + } + } + } + } + rp=opus_repacketizer_create(); + if(rp!=NULL) + { + __malloc_hook=orig_malloc; + test_failed(); + } + cfgs++; + __malloc_hook=orig_malloc; + fprintf(stdout," opus_decoder_create() ........................ OK.\n"); + fprintf(stdout," opus_encoder_create() ........................ OK.\n"); + fprintf(stdout," opus_repacketizer_create() ................... OK.\n"); + fprintf(stdout," opus_multistream_decoder_create() ............ OK.\n"); + fprintf(stdout," opus_multistream_encoder_create() ............ OK.\n"); + fprintf(stdout," All malloc failure tests passed\n"); + fprintf(stdout," (%2d API invocations)\n",cfgs); + return cfgs; +#endif +} + +#ifdef MALLOC_FAIL +#if __GNUC_PREREQ(4,6) +#pragma GCC diagnostic pop /* restore -Wdeprecated-declarations */ +#endif +#endif + +int main(int _argc, char **_argv) +{ + opus_int32 total; + const char * oversion; + if(_argc>1) + { + fprintf(stderr,"Usage: %s\n",_argv[0]); + return 1; + } + iseed=0; + + oversion=opus_get_version_string(); + if(!oversion)test_failed(); + fprintf(stderr,"Testing the %s API deterministically\n", oversion); + if(opus_strerror(-32768)==NULL)test_failed(); + if(opus_strerror(32767)==NULL)test_failed(); + if(strlen(opus_strerror(0))<1)test_failed(); + total=4; + + total+=test_dec_api(); + total+=test_msdec_api(); + total+=test_parse(); + total+=test_enc_api(); + total+=test_repacketizer_api(); + total+=test_malloc_fail(); + + fprintf(stderr,"\nAll API tests passed.\nThe libopus API was invoked %d times.\n",total); + + return 0; +} diff --git a/lib/opus/tests/test_opus_common.h b/lib/opus/tests/test_opus_common.h new file mode 100644 index 00000000..5fb924f4 --- /dev/null +++ b/lib/opus/tests/test_opus_common.h @@ -0,0 +1,85 @@ +/* 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"); +#if defined(_MSC_VER) + _set_abort_behavior( 0, _WRITE_ABORT_MSG); +#endif + abort(); +} +#define test_failed() _test_failed(__FILE__, __LINE__); +#define opus_test_assert(cond) {if (!(cond)) {test_failed();}} +void regression_test(void); diff --git a/lib/opus/tests/test_opus_decode.c b/lib/opus/tests/test_opus_decode.c new file mode 100644 index 00000000..2d1e2d41 --- /dev/null +++ b/lib/opus/tests/test_opus_decode.c @@ -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> +#ifndef _WIN32 +#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; +} diff --git a/lib/opus/tests/test_opus_encode.c b/lib/opus/tests/test_opus_encode.c new file mode 100644 index 00000000..d6e8e2d3 --- /dev/null +++ b/lib/opus/tests/test_opus_encode.c @@ -0,0 +1,707 @@ +/* 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"); + fflush(stdout); + + 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); + fflush(stdout); + } + } + + 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); + fflush(stdout); + } + } + + 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); + fflush(stdout); + + 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; +} diff --git a/lib/opus/tests/test_opus_padding.c b/lib/opus/tests/test_opus_padding.c new file mode 100644 index 00000000..c9ef7375 --- /dev/null +++ b/lib/opus/tests/test_opus_padding.c @@ -0,0 +1,90 @@ +/* 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 + +void 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"); + test_failed(); + } + 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"); +} + +int main(void) +{ + const char *oversion; + + iseed = 0; + oversion = opus_get_version_string(); + if (!oversion) test_failed(); + fprintf(stderr, "Testing %s padding.\n", oversion); + + test_overflow(); + + fprintf(stderr, "All padding tests passed.\n"); + + return 0; +} diff --git a/lib/opus/tests/test_opus_projection.c b/lib/opus/tests/test_opus_projection.c new file mode 100644 index 00000000..4e06613e --- /dev/null +++ b/lib/opus/tests/test_opus_projection.c @@ -0,0 +1,393 @@ +/* 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 <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; +} + |
