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 | |
Andrew Allen | f643c03 | 2017-11-07 13:26:23 -0800 | [diff] [blame] | 36 | #include <stdarg.h> /* va_list */ |
Jonathan Lennox | ef86768 | 2015-08-04 12:04:20 -0400 | [diff] [blame] | 37 | #include <stddef.h> /* offsetof */ |
| 38 | |
Jean-Marc Valin | c8649d0 | 2011-10-27 22:25:33 -0400 | [diff] [blame] | 39 | struct OpusRepacketizer { |
| 40 | unsigned char toc; |
| 41 | int nb_frames; |
| 42 | const unsigned char *frames[48]; |
Jean-Marc Valin | 3593069 | 2013-05-18 02:50:40 -0400 | [diff] [blame] | 43 | opus_int16 len[48]; |
Jean-Marc Valin | c8649d0 | 2011-10-27 22:25:33 -0400 | [diff] [blame] | 44 | int framesize; |
| 45 | }; |
| 46 | |
Jean-Marc Valin | ae0e2ca | 2012-11-07 19:57:33 -0500 | [diff] [blame] | 47 | typedef struct ChannelLayout { |
| 48 | int nb_channels; |
| 49 | int nb_streams; |
| 50 | int nb_coupled_streams; |
| 51 | unsigned char mapping[256]; |
| 52 | } ChannelLayout; |
| 53 | |
Andrew Allen | f643c03 | 2017-11-07 13:26:23 -0800 | [diff] [blame] | 54 | typedef enum { |
| 55 | MAPPING_TYPE_NONE, |
Jean-Marc Valin | 722a66b | 2018-07-26 12:06:35 -0400 | [diff] [blame] | 56 | MAPPING_TYPE_SURROUND, |
Andrew Allen | f643c03 | 2017-11-07 13:26:23 -0800 | [diff] [blame] | 57 | MAPPING_TYPE_AMBISONICS |
Andrew Allen | f643c03 | 2017-11-07 13:26:23 -0800 | [diff] [blame] | 58 | } MappingType; |
| 59 | |
| 60 | struct OpusMSEncoder { |
| 61 | ChannelLayout layout; |
| 62 | int arch; |
| 63 | int lfe_stream; |
| 64 | int application; |
| 65 | int variable_duration; |
| 66 | MappingType mapping_type; |
| 67 | opus_int32 bitrate_bps; |
| 68 | /* Encoder states go here */ |
| 69 | /* then opus_val32 window_mem[channels*120]; */ |
| 70 | /* then opus_val32 preemph_mem[channels]; */ |
| 71 | }; |
| 72 | |
| 73 | struct OpusMSDecoder { |
| 74 | ChannelLayout layout; |
| 75 | /* Decoder states go here */ |
| 76 | }; |
| 77 | |
| 78 | int opus_multistream_encoder_ctl_va_list(struct OpusMSEncoder *st, int request, |
| 79 | va_list ap); |
| 80 | int opus_multistream_decoder_ctl_va_list(struct OpusMSDecoder *st, int request, |
| 81 | va_list ap); |
| 82 | |
Jean-Marc Valin | ae0e2ca | 2012-11-07 19:57:33 -0500 | [diff] [blame] | 83 | int validate_layout(const ChannelLayout *layout); |
| 84 | int get_left_channel(const ChannelLayout *layout, int stream_id, int prev); |
| 85 | int get_right_channel(const ChannelLayout *layout, int stream_id, int prev); |
| 86 | int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev); |
| 87 | |
Andrew Allen | 65f11d3 | 2017-12-04 15:32:18 -0800 | [diff] [blame] | 88 | typedef void (*opus_copy_channel_in_func)( |
| 89 | opus_val16 *dst, |
| 90 | int dst_stride, |
| 91 | const void *src, |
| 92 | int src_stride, |
| 93 | int src_channel, |
| 94 | int frame_size, |
| 95 | void *user_data |
| 96 | ); |
Jean-Marc Valin | ae0e2ca | 2012-11-07 19:57:33 -0500 | [diff] [blame] | 97 | |
Andrew Allen | 65f11d3 | 2017-12-04 15:32:18 -0800 | [diff] [blame] | 98 | typedef void (*opus_copy_channel_out_func)( |
| 99 | void *dst, |
| 100 | int dst_stride, |
| 101 | int dst_channel, |
| 102 | const opus_val16 *src, |
| 103 | int src_stride, |
| 104 | int frame_size, |
| 105 | void *user_data |
| 106 | ); |
Jean-Marc Valin | c8649d0 | 2011-10-27 22:25:33 -0400 | [diff] [blame] | 107 | |
Jean-Marc Valin | 9977497 | 2011-08-28 15:49:32 -0400 | [diff] [blame] | 108 | #define MODE_SILK_ONLY 1000 |
| 109 | #define MODE_HYBRID 1001 |
| 110 | #define MODE_CELT_ONLY 1002 |
| 111 | |
Jean-Marc Valin | e6a0be8 | 2011-10-27 13:43:43 -0400 | [diff] [blame] | 112 | #define OPUS_SET_VOICE_RATIO_REQUEST 11018 |
| 113 | #define OPUS_GET_VOICE_RATIO_REQUEST 11019 |
| 114 | |
| 115 | /** Configures the encoder's expected percentage of voice |
| 116 | * opposed to music or other signals. |
| 117 | * |
| 118 | * @note This interface is currently more aspiration than actuality. It's |
| 119 | * ultimately expected to bias an automatic signal classifier, but it currently |
| 120 | * just shifts the static bitrate to mode mapping around a little bit. |
| 121 | * |
| 122 | * @param[in] x <tt>int</tt>: Voice percentage in the range 0-100, inclusive. |
| 123 | * @hideinitializer */ |
| 124 | #define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __opus_check_int(x) |
| 125 | /** Gets the encoder's configured voice ratio value, @see OPUS_SET_VOICE_RATIO |
| 126 | * |
| 127 | * @param[out] x <tt>int*</tt>: Voice percentage in the range 0-100, inclusive. |
| 128 | * @hideinitializer */ |
| 129 | #define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __opus_check_int_ptr(x) |
| 130 | |
| 131 | |
Jean-Marc Valin | 07dceb7 | 2011-09-08 13:53:20 -0400 | [diff] [blame] | 132 | #define OPUS_SET_FORCE_MODE_REQUEST 11002 |
| 133 | #define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x) |
| 134 | |
Jean-Marc Valin | 3ab03e0 | 2013-09-06 16:00:39 -0400 | [diff] [blame] | 135 | typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int); |
| 136 | void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); |
| 137 | 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] | 138 | |
Jean-Marc Valin | 9f555bc | 2011-08-23 02:56:12 -0400 | [diff] [blame] | 139 | int encode_size(int size, unsigned char *data); |
| 140 | |
Jean-Marc Valin | 51f4a32 | 2013-02-20 04:08:04 -0500 | [diff] [blame] | 141 | opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs); |
| 142 | |
Jean-Marc Valin | b3eba24 | 2012-12-20 23:11:53 -0500 | [diff] [blame] | 143 | 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] | 144 | unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, |
Jean-Marc Valin | c94e4bb | 2013-12-08 03:31:50 -0500 | [diff] [blame] | 145 | const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, |
| 146 | int analysis_channels, downmix_func downmix, int float_api); |
Jean-Marc Valin | b3eba24 | 2012-12-20 23:11:53 -0500 | [diff] [blame] | 147 | |
Jean-Marc Valin | 59354a7 | 2012-03-08 12:19:07 -0500 | [diff] [blame] | 148 | 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] | 149 | 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] | 150 | opus_int32 *packet_offset, int soft_clip); |
Jean-Marc Valin | d4e9340 | 2011-08-27 00:52:26 -0400 | [diff] [blame] | 151 | |
Jean-Marc Valin | e90adb0 | 2015-08-03 21:40:46 -0400 | [diff] [blame] | 152 | /* Make sure everything is properly aligned. */ |
Gregory Maxwell | 7830cf1 | 2013-10-17 15:56:52 -0700 | [diff] [blame] | 153 | static OPUS_INLINE int align(int i) |
Jean-Marc Valin | 6696a14 | 2011-08-22 10:40:38 -0400 | [diff] [blame] | 154 | { |
Jonathan Lennox | ef86768 | 2015-08-04 12:04:20 -0400 | [diff] [blame] | 155 | struct foo {char c; union { void* p; opus_int32 i; opus_val32 v; } u;}; |
| 156 | |
Mark Harris | 348e694 | 2015-08-04 17:53:07 -0700 | [diff] [blame] | 157 | unsigned int alignment = offsetof(struct foo, u); |
Jonathan Lennox | ef86768 | 2015-08-04 12:04:20 -0400 | [diff] [blame] | 158 | |
| 159 | /* Optimizing compilers should optimize div and multiply into and |
| 160 | for all sensible alignment values. */ |
| 161 | return ((i + alignment - 1) / alignment) * alignment; |
Jean-Marc Valin | 6696a14 | 2011-08-22 10:40:38 -0400 | [diff] [blame] | 162 | } |
| 163 | |
Jean-Marc Valin | ed46323 | 2013-10-11 18:06:00 -0400 | [diff] [blame] | 164 | int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, |
| 165 | int self_delimited, unsigned char *out_toc, |
Jean-Marc Valin | 58042ad | 2013-10-14 13:45:58 -0400 | [diff] [blame] | 166 | const unsigned char *frames[48], opus_int16 size[48], |
Jean-Marc Valin | dabdb32 | 2013-10-14 13:58:51 -0400 | [diff] [blame] | 167 | int *payload_offset, opus_int32 *packet_offset); |
Jean-Marc Valin | ed46323 | 2013-10-11 18:06:00 -0400 | [diff] [blame] | 168 | |
Jean-Marc Valin | c5635d2 | 2013-11-13 14:08:22 -0500 | [diff] [blame] | 169 | opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, |
| 170 | unsigned char *data, opus_int32 maxlen, int self_delimited, int pad); |
Jean-Marc Valin | 131d888 | 2011-09-09 13:56:09 -0400 | [diff] [blame] | 171 | |
Jean-Marc Valin | eab134c | 2013-10-14 15:01:36 -0400 | [diff] [blame] | 172 | int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len); |
| 173 | |
Andrew Allen | 65f11d3 | 2017-12-04 15:32:18 -0800 | [diff] [blame] | 174 | int opus_multistream_encode_native |
| 175 | ( |
| 176 | struct OpusMSEncoder *st, |
| 177 | opus_copy_channel_in_func copy_channel_in, |
| 178 | const void *pcm, |
| 179 | int analysis_frame_size, |
| 180 | unsigned char *data, |
| 181 | opus_int32 max_data_bytes, |
| 182 | int lsb_depth, |
| 183 | downmix_func downmix, |
| 184 | int float_api, |
| 185 | void *user_data |
| 186 | ); |
| 187 | |
| 188 | int opus_multistream_decode_native( |
| 189 | struct OpusMSDecoder *st, |
| 190 | const unsigned char *data, |
| 191 | opus_int32 len, |
| 192 | void *pcm, |
| 193 | opus_copy_channel_out_func copy_channel_out, |
| 194 | int frame_size, |
| 195 | int decode_fec, |
| 196 | int soft_clip, |
| 197 | void *user_data |
| 198 | ); |
| 199 | |
Ralph Giles | 120800f | 2011-11-25 13:02:00 -0800 | [diff] [blame] | 200 | #endif /* OPUS_PRIVATE_H */ |