ref: d4744e0ba0013beb745f8ae1aef990eda5c79299
parent: f7495d4af192c511fe4afe8002a9bafe904f6558
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Wed Jun 12 12:15:46 EDT 2024
Adds 24-bit multistream encode/decode API
--- a/include/opus_multistream.h
+++ b/include/opus_multistream.h
@@ -382,6 +382,44 @@
opus_int32 max_data_bytes
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+/** Encodes a multistream Opus frame.
+ * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
+ * @param[in] pcm <tt>const opus_int32*</tt>: The input signal as interleaved
+ * samples representing (or slightly exceeding) 24-bit values.
+ * This must contain
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: Number of samples per channel in the input
+ * signal.
+ * This must be an Opus frame size for the
+ * encoder's sampling rate.
+ * For example, at 48 kHz the permitted values
+ * are 120, 240, 480, 960, 1920, and 2880.
+ * Passing in a duration of less than 10 ms
+ * (480 samples at 48 kHz) will prevent the
+ * encoder from using the LPC or hybrid modes.
+ * @param[out] data <tt>unsigned char*</tt>: Output payload.
+ * This must contain storage for at
+ * least \a max_data_bytes.
+ * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
+ * memory for the output
+ * payload. This may be
+ * used to impose an upper limit on
+ * the instant bitrate, but should
+ * not be used as the only bitrate
+ * control. Use #OPUS_SET_BITRATE to
+ * control the bitrate.
+ * @returns The length of the encoded packet (in bytes) on success or a
+ * negative error code (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode24(
+ OpusMSEncoder *st,
+ const opus_int32 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
+
/** Encodes a multistream Opus frame from floating point input.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
* @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
@@ -587,6 +625,44 @@
const unsigned char *data,
opus_int32 len,
opus_int16 *pcm,
+ int frame_size,
+ int decode_fec
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
+
+/** Decode a multistream Opus packet.
+ * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
+ * @param[in] data <tt>const unsigned char*</tt>: Input payload.
+ * Use a <code>NULL</code>
+ * pointer to indicate packet
+ * loss.
+ * @param len <tt>opus_int32</tt>: Number of bytes in payload.
+ * @param[out] pcm <tt>opus_int32*</tt>: Output signal, with interleaved
+ * samples representing (or slightly exceeding) 24-bit values.
+ * This must contain room for
+ * <code>frame_size*channels</code>
+ * samples.
+ * @param frame_size <tt>int</tt>: The number of samples per channel of
+ * available space in \a pcm.
+ * If this is less than the maximum packet duration
+ * (120 ms; 5760 for 48kHz), this function will not be capable
+ * of decoding some packets. In the case of PLC (data==NULL)
+ * or FEC (decode_fec=1), then frame_size needs to be exactly
+ * the duration of audio that is missing, otherwise the
+ * decoder will not be in the optimal state to decode the
+ * next incoming packet. For the PLC and FEC cases, frame_size
+ * <b>must</b> be a multiple of 2.5 ms.
+ * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
+ * forward error correction data be decoded.
+ * If no such data is available, the frame is
+ * decoded as if it were lost.
+ * @returns Number of samples decoded on success or a negative error code
+ * (see @ref opus_errorcodes) on failure.
+ */
+OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode24(
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int32 *pcm,
int frame_size,
int decode_fec
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
--- a/src/opus_multistream_decoder.c
+++ b/src/opus_multistream_decoder.c
@@ -360,6 +360,32 @@
}
}
+static void opus_copy_channel_out_int24(
+ void *dst,
+ int dst_stride,
+ int dst_channel,
+ const opus_res *src,
+ int src_stride,
+ int frame_size,
+ void *user_data
+)
+{
+ opus_int32 *short_dst;
+ opus_int32 i;
+ (void)user_data;
+ short_dst = (opus_int32*)dst;
+ if (src != NULL)
+ {
+ for (i=0;i<frame_size;i++)
+ short_dst[i*dst_stride+dst_channel] = RES2INT24(src[i*src_stride]);
+ }
+ else
+ {
+ for (i=0;i<frame_size;i++)
+ short_dst[i*dst_stride+dst_channel] = 0;
+ }
+}
+
#ifdef FIXED_POINT
#define OPTIONAL_CLIP 0
#else
@@ -377,6 +403,19 @@
{
return opus_multistream_decode_native(st, data, len,
pcm, opus_copy_channel_out_short, frame_size, decode_fec, OPTIONAL_CLIP, NULL);
+}
+
+int opus_multistream_decode24(
+ OpusMSDecoder *st,
+ const unsigned char *data,
+ opus_int32 len,
+ opus_int32 *pcm,
+ int frame_size,
+ int decode_fec
+)
+{
+ return opus_multistream_decode_native(st, data, len,
+ pcm, opus_copy_channel_out_int24, frame_size, decode_fec, 0, NULL);
}
#ifndef DISABLE_FLOAT_API
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -1050,6 +1050,23 @@
dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]);
}
+static void opus_copy_channel_in_int24(
+ opus_res *dst,
+ int dst_stride,
+ const void *src,
+ int src_stride,
+ int src_channel,
+ int frame_size,
+ void *user_data
+)
+{
+ const opus_int32 *short_src;
+ opus_int32 i;
+ (void)user_data;
+ short_src = (const opus_int32 *)src;
+ for (i=0;i<frame_size;i++)
+ dst[i*dst_stride] = INT24TORES(short_src[i*src_stride+src_channel]);
+}
int opus_multistream_encode(
OpusMSEncoder *st,
@@ -1061,6 +1078,18 @@
{
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
+}
+
+int opus_multistream_encode24(
+ OpusMSEncoder *st,
+ const opus_int32 *pcm,
+ int frame_size,
+ unsigned char *data,
+ opus_int32 max_data_bytes
+)
+{
+ return opus_multistream_encode_native(st, opus_copy_channel_in_int24,
+ pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_int24, 0, NULL);
}
#ifndef DISABLE_FLOAT_API
--
⑨