Ralph Giles | 3a9b354 | 2012-08-17 10:16:24 -0700 | [diff] [blame] | 1 | /* Copyright (c) 2012 Xiph.Org Foundation |
Jean-Marc Valin | 6696a14 | 2011-08-22 10:40:38 -0400 | [diff] [blame] | 2 | Written by Jean-Marc Valin */ |
| 3 | /* |
| 4 | Redistribution and use in source and binary forms, with or without |
| 5 | modification, are permitted provided that the following conditions |
| 6 | are met: |
| 7 | |
| 8 | - Redistributions of source code must retain the above copyright |
| 9 | notice, this list of conditions and the following disclaimer. |
| 10 | |
| 11 | - Redistributions in binary form must reproduce the above copyright |
| 12 | notice, this list of conditions and the following disclaimer in the |
| 13 | documentation and/or other materials provided with the distribution. |
| 14 | |
| 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 16 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 17 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
Jean-Marc Valin | cb05e7c | 2012-04-20 16:40:24 -0400 | [diff] [blame] | 18 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER |
| 19 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
Jean-Marc Valin | 6696a14 | 2011-08-22 10:40:38 -0400 | [diff] [blame] | 20 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| 23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| 24 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | */ |
| 27 | |
| 28 | |
| 29 | #ifndef OPUS_PRIVATE_H |
| 30 | #define OPUS_PRIVATE_H |
| 31 | |
Jean-Marc Valin | d4e9340 | 2011-08-27 00:52:26 -0400 | [diff] [blame] | 32 | #include "arch.h" |
| 33 | #include "opus.h" |
Jean-Marc Valin | 51f4a32 | 2013-02-20 04:08:04 -0500 | [diff] [blame] | 34 | #include "celt.h" |
Jean-Marc Valin | d4e9340 | 2011-08-27 00:52:26 -0400 | [diff] [blame] | 35 | |
Jonathan Lennox | ef86768 | 2015-08-04 12:04:20 -0400 | [diff] [blame] | 36 | #include <stddef.h> /* offsetof */ |
| 37 | |
Jean-Marc Valin | c8649d0 | 2011-10-27 22:25:33 -0400 | [diff] [blame] | 38 | struct OpusRepacketizer { |
| 39 | unsigned char toc; |
| 40 | int nb_frames; |
| 41 | const unsigned char *frames[48]; |
Jean-Marc Valin | 3593069 | 2013-05-18 02:50:40 -0400 | [diff] [blame] | 42 | opus_int16 len[48]; |
Jean-Marc Valin | c8649d0 | 2011-10-27 22:25:33 -0400 | [diff] [blame] | 43 | int framesize; |
| 44 | }; |
| 45 | |
Jean-Marc Valin | ae0e2ca | 2012-11-07 19:57:33 -0500 | [diff] [blame] | 46 | typedef struct ChannelLayout { |
| 47 | int nb_channels; |
| 48 | int nb_streams; |
| 49 | int nb_coupled_streams; |
| 50 | unsigned char mapping[256]; |
| 51 | } ChannelLayout; |
| 52 | |
| 53 | int validate_layout(const ChannelLayout *layout); |
| 54 | int get_left_channel(const ChannelLayout *layout, int stream_id, int prev); |
| 55 | int get_right_channel(const ChannelLayout *layout, int stream_id, int prev); |
| 56 | int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev); |
| 57 | |
| 58 | |
Jean-Marc Valin | c8649d0 | 2011-10-27 22:25:33 -0400 | [diff] [blame] | 59 | |
Jean-Marc Valin | 9977497 | 2011-08-28 15:49:32 -0400 | [diff] [blame] | 60 | #define MODE_SILK_ONLY 1000 |
| 61 | #define MODE_HYBRID 1001 |
| 62 | #define MODE_CELT_ONLY 1002 |
| 63 | |
Jean-Marc Valin | e6a0be8 | 2011-10-27 13:43:43 -0400 | [diff] [blame] | 64 | #define OPUS_SET_VOICE_RATIO_REQUEST 11018 |
| 65 | #define OPUS_GET_VOICE_RATIO_REQUEST 11019 |
| 66 | |
| 67 | /** Configures the encoder's expected percentage of voice |
| 68 | * opposed to music or other signals. |
| 69 | * |
| 70 | * @note This interface is currently more aspiration than actuality. It's |
| 71 | * ultimately expected to bias an automatic signal classifier, but it currently |
| 72 | * just shifts the static bitrate to mode mapping around a little bit. |
| 73 | * |
| 74 | * @param[in] x <tt>int</tt>: Voice percentage in the range 0-100, inclusive. |
| 75 | * @hideinitializer */ |
| 76 | #define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __opus_check_int(x) |
| 77 | /** Gets the encoder's configured voice ratio value, @see OPUS_SET_VOICE_RATIO |
| 78 | * |
| 79 | * @param[out] x <tt>int*</tt>: Voice percentage in the range 0-100, inclusive. |
| 80 | * @hideinitializer */ |
| 81 | #define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __opus_check_int_ptr(x) |
| 82 | |
| 83 | |
Jean-Marc Valin | 07dceb7 | 2011-09-08 13:53:20 -0400 | [diff] [blame] | 84 | #define OPUS_SET_FORCE_MODE_REQUEST 11002 |
| 85 | #define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x) |
| 86 | |
Jean-Marc Valin | 3ab03e0 | 2013-09-06 16:00:39 -0400 | [diff] [blame] | 87 | typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int); |
| 88 | void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); |
| 89 | void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); |
Jean-Marc Valin | 10a34a5 | 2012-12-20 00:23:01 -0500 | [diff] [blame] | 90 | |
Jean-Marc Valin | 9f555bc | 2011-08-23 02:56:12 -0400 | [diff] [blame] | 91 | int encode_size(int size, unsigned char *data); |
| 92 | |
Jean-Marc Valin | 51f4a32 | 2013-02-20 04:08:04 -0500 | [diff] [blame] | 93 | opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs); |
| 94 | |
Jean-Marc Valin | b90e63b | 2013-09-16 13:08:52 -0400 | [diff] [blame] | 95 | opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size, |
| 96 | int variable_duration, int C, opus_int32 Fs, int bitrate_bps, |
Jean-Marc Valin | c2b3441 | 2013-10-28 21:48:50 -0400 | [diff] [blame] | 97 | int delay_compensation, downmix_func downmix |
| 98 | #ifndef DISABLE_FLOAT_API |
Jean-Marc Valin | 8848171 | 2013-11-13 11:57:31 -0500 | [diff] [blame] | 99 | , float *subframe_mem |
Jean-Marc Valin | c2b3441 | 2013-10-28 21:48:50 -0400 | [diff] [blame] | 100 | #endif |
| 101 | ); |
Jean-Marc Valin | b90e63b | 2013-09-16 13:08:52 -0400 | [diff] [blame] | 102 | |
Jean-Marc Valin | b3eba24 | 2012-12-20 23:11:53 -0500 | [diff] [blame] | 103 | opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, |
Jean-Marc Valin | 91904a4 | 2013-09-05 21:34:43 -0400 | [diff] [blame] | 104 | unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, |
Jean-Marc Valin | c94e4bb | 2013-12-08 03:31:50 -0500 | [diff] [blame] | 105 | const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, |
| 106 | int analysis_channels, downmix_func downmix, int float_api); |
Jean-Marc Valin | b3eba24 | 2012-12-20 23:11:53 -0500 | [diff] [blame] | 107 | |
Jean-Marc Valin | 59354a7 | 2012-03-08 12:19:07 -0500 | [diff] [blame] | 108 | int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, |
Jean-Marc Valin | 32c4a0c | 2013-03-01 15:18:23 -0500 | [diff] [blame] | 109 | opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, |
Jean-Marc Valin | dabdb32 | 2013-10-14 13:58:51 -0400 | [diff] [blame] | 110 | opus_int32 *packet_offset, int soft_clip); |
Jean-Marc Valin | d4e9340 | 2011-08-27 00:52:26 -0400 | [diff] [blame] | 111 | |
Jean-Marc Valin | e90adb0 | 2015-08-03 21:40:46 -0400 | [diff] [blame] | 112 | /* Make sure everything is properly aligned. */ |
Gregory Maxwell | 7830cf1 | 2013-10-17 15:56:52 -0700 | [diff] [blame] | 113 | static OPUS_INLINE int align(int i) |
Jean-Marc Valin | 6696a14 | 2011-08-22 10:40:38 -0400 | [diff] [blame] | 114 | { |
Jonathan Lennox | ef86768 | 2015-08-04 12:04:20 -0400 | [diff] [blame] | 115 | struct foo {char c; union { void* p; opus_int32 i; opus_val32 v; } u;}; |
| 116 | |
Mark Harris | 348e694 | 2015-08-04 17:53:07 -0700 | [diff] [blame] | 117 | unsigned int alignment = offsetof(struct foo, u); |
Jonathan Lennox | ef86768 | 2015-08-04 12:04:20 -0400 | [diff] [blame] | 118 | |
| 119 | /* Optimizing compilers should optimize div and multiply into and |
| 120 | for all sensible alignment values. */ |
| 121 | return ((i + alignment - 1) / alignment) * alignment; |
Jean-Marc Valin | 6696a14 | 2011-08-22 10:40:38 -0400 | [diff] [blame] | 122 | } |
| 123 | |
Jean-Marc Valin | ed46323 | 2013-10-11 18:06:00 -0400 | [diff] [blame] | 124 | int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, |
| 125 | int self_delimited, unsigned char *out_toc, |
Jean-Marc Valin | 58042ad | 2013-10-14 13:45:58 -0400 | [diff] [blame] | 126 | const unsigned char *frames[48], opus_int16 size[48], |
Jean-Marc Valin | dabdb32 | 2013-10-14 13:58:51 -0400 | [diff] [blame] | 127 | int *payload_offset, opus_int32 *packet_offset); |
Jean-Marc Valin | ed46323 | 2013-10-11 18:06:00 -0400 | [diff] [blame] | 128 | |
Jean-Marc Valin | c5635d2 | 2013-11-13 14:08:22 -0500 | [diff] [blame] | 129 | opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, |
| 130 | unsigned char *data, opus_int32 maxlen, int self_delimited, int pad); |
Jean-Marc Valin | 131d888 | 2011-09-09 13:56:09 -0400 | [diff] [blame] | 131 | |
Jean-Marc Valin | eab134c | 2013-10-14 15:01:36 -0400 | [diff] [blame] | 132 | int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len); |
| 133 | |
Ralph Giles | 120800f | 2011-11-25 13:02:00 -0800 | [diff] [blame] | 134 | #endif /* OPUS_PRIVATE_H */ |