Skip to content

Commit 43a6878

Browse files
authored
Merge pull request #264 from alnitak/oggReadSamples
feat: add OGG support for `readSamplesFrom*` methods
2 parents 69785f4 + 5af17eb commit 43a6878

File tree

88 files changed

+4077
-237
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+4077
-237
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"name": "Flutter debug",
99
"type": "dart",
1010
"request": "launch",
11-
"program": "lib/audio_context/audio_context.dart",
11+
"program": "lib/wave_data/wave_data.dart",
1212
"flutterMode": "debug",
1313
// "env": {
1414
// "NO_OPUS_OGG_LIBS": "1"

.vscode/tasks.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
},
1010
{
1111
"label": "compile linux debug",
12-
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/buffer_stream/simple_noise_stream.dart --debug",
12+
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/wave_data/wave_data.dart --debug",
1313
"type": "shell"
1414
},
1515
{
@@ -29,7 +29,7 @@
2929
},
3030
{
3131
"label": "compile web wasm release",
32-
"command": "cd ${workspaceFolder}/example; flutter run -d chrome --wasm --web-browser-flag '--disable-web-security' -t lib/buffer_stream/simple_noise_stream.dart --release",
32+
"command": "cd ${workspaceFolder}/example; flutter run -d chrome --wasm --web-browser-flag '--disable-web-security' -t lib/wave_data/wave_data.dart --release",
3333
"type": "shell"
3434
},
3535
{

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#### 3.2.2 (16 Jul 2025)
2+
- OGG is now also supported using `readSamplesFrom*` methods.
3+
- fix getPosition and bufferirg for released buffer.
4+
15
#### 3.2.1 (28 Jun 2025)
26
- fix #104, #245, #249. It is now possible to use a 3rd party plugin like `audio_session` to manage audio context.
37
- new audio context example in `example/lib/audio_context/audio_context.dart`.

android/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ list(APPEND PLUGIN_SOURCES
4141
"${SRC_DIR}/analyzer.cpp"
4242
"${SRC_DIR}/synth/basic_wave.cpp"
4343
"${SRC_DIR}/waveform/waveform.cpp"
44+
"${SRC_DIR}/waveform/miniaudio_libvorbis.cpp"
4445
"${SRC_DIR}/audiobuffer/audiobuffer.cpp"
4546
"${SRC_DIR}/filters/filters.cpp"
4647
"${SRC_DIR}/filters/pitch_shift_filter.cpp"
@@ -82,6 +83,12 @@ if(NOT DEFINED ENV{NO_OPUS_OGG_LIBS})
8283
target_link_libraries(${PLUGIN_NAME} PRIVATE ${OGG_LIBRARY})
8384
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
8485

86+
# Add vorbis library
87+
set(VORBIS_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI}/libvorbis.so)
88+
target_link_libraries(${PLUGIN_NAME} PRIVATE ${VORBIS_LIBRARY})
89+
set(VORBISFILE_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/libs/${ANDROID_ABI}/libvorbisfile.so)
90+
target_link_libraries(${PLUGIN_NAME} PRIVATE ${VORBISFILE_LIBRARY})
91+
8592
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
8693
else()
8794
message("NO_OPUS_OGG_LIBS has been set. Not linking Opus and Ogg libraries!")

android/include/opus/opus.h

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,42 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode(
268268
opus_int32 max_data_bytes
269269
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
270270

271+
/** Encodes an Opus frame.
272+
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
273+
* @param [in] pcm <tt>opus_int32*</tt>: Input signal (interleaved if 2 channels) representing (or slightly exceeding) 24-bit values. length is frame_size*channels*sizeof(opus_int32)
274+
* @param [in] frame_size <tt>int</tt>: Number of samples per channel in the
275+
* input signal.
276+
* This must be an Opus frame size for
277+
* the encoder's sampling rate.
278+
* For example, at 48 kHz the permitted
279+
* values are 120, 240, 480, 960, 1920,
280+
* and 2880.
281+
* Passing in a duration of less than
282+
* 10 ms (480 samples at 48 kHz) will
283+
* prevent the encoder from using the LPC
284+
* or hybrid modes.
285+
* @param [out] data <tt>unsigned char*</tt>: Output payload.
286+
* This must contain storage for at
287+
* least \a max_data_bytes.
288+
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
289+
* memory for the output
290+
* payload. This may be
291+
* used to impose an upper limit on
292+
* the instant bitrate, but should
293+
* not be used as the only bitrate
294+
* control. Use #OPUS_SET_BITRATE to
295+
* control the bitrate.
296+
* @returns The length of the encoded packet (in bytes) on success or a
297+
* negative error code (see @ref opus_errorcodes) on failure.
298+
*/
299+
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode24(
300+
OpusEncoder *st,
301+
const opus_int32 *pcm,
302+
int frame_size,
303+
unsigned char *data,
304+
opus_int32 max_data_bytes
305+
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
306+
271307
/** Encodes an Opus frame from floating point input.
272308
* @param [in] st <tt>OpusEncoder*</tt>: Encoder state
273309
* @param [in] pcm <tt>float*</tt>: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0.
@@ -483,6 +519,31 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode(
483519
int decode_fec
484520
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
485521

522+
/** Decode an Opus packet.
523+
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
524+
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
525+
* @param [in] len <tt>opus_int32</tt>: Number of bytes in payload*
526+
* @param [out] pcm <tt>opus_int32*</tt>: Output signal (interleaved if 2 channels) representing (or slightly exceeding) 24-bit values. length
527+
* is frame_size*channels*sizeof(opus_int32)
528+
* @param [in] frame_size Number of samples per channel of available space in \a pcm.
529+
* If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will
530+
* not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1),
531+
* then frame_size needs to be exactly the duration of audio that is missing, otherwise the
532+
* decoder will not be in the optimal state to decode the next incoming packet. For the PLC and
533+
* FEC cases, frame_size <b>must</b> be a multiple of 2.5 ms.
534+
* @param [in] decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band forward error correction data be
535+
* decoded. If no such data is available, the frame is decoded as if it were lost.
536+
* @returns Number of decoded samples or @ref opus_errorcodes
537+
*/
538+
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode24(
539+
OpusDecoder *st,
540+
const unsigned char *data,
541+
opus_int32 len,
542+
opus_int32 *pcm,
543+
int frame_size,
544+
int decode_fec
545+
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
546+
486547
/** Decode an Opus packet with floating point output.
487548
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
488549
* @param [in] data <tt>char*</tt>: Input payload. Use a NULL pointer to indicate packet loss
@@ -596,7 +657,7 @@ OPUS_EXPORT int opus_dred_parse(OpusDREDDecoder *dred_dec, OpusDRED *dred, const
596657
*/
597658
OPUS_EXPORT int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src, OpusDRED *dst);
598659

599-
/** Decode audio from an Opus DRED packet with floating point output.
660+
/** Decode audio from an Opus DRED packet with 16-bit output.
600661
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
601662
* @param [in] dred <tt>OpusDRED*</tt>: DRED state
602663
* @param [in] dred_offset <tt>opus_int32</tt>: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet).
@@ -608,6 +669,18 @@ OPUS_EXPORT int opus_dred_process(OpusDREDDecoder *dred_dec, const OpusDRED *src
608669
*/
609670
OPUS_EXPORT int opus_decoder_dred_decode(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int16 *pcm, opus_int32 frame_size);
610671

672+
/** Decode audio from an Opus DRED packet with 24-bit output.
673+
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
674+
* @param [in] dred <tt>OpusDRED*</tt>: DRED state
675+
* @param [in] dred_offset <tt>opus_int32</tt>: position of the redundancy to decode (in samples before the beginning of the real audio data in the packet).
676+
* @param [out] pcm <tt>opus_int32*</tt>: Output signal (interleaved if 2 channels). length
677+
* is frame_size*channels*sizeof(opus_int16)
678+
* @param [in] frame_size Number of samples per channel to decode in \a pcm.
679+
* frame_size <b>must</b> be a multiple of 2.5 ms.
680+
* @returns Number of decoded samples or @ref opus_errorcodes
681+
*/
682+
OPUS_EXPORT int opus_decoder_dred_decode24(OpusDecoder *st, const OpusDRED *dred, opus_int32 dred_offset, opus_int32 *pcm, opus_int32 frame_size);
683+
611684
/** Decode audio from an Opus DRED packet with floating point output.
612685
* @param [in] st <tt>OpusDecoder*</tt>: Decoder state
613686
* @param [in] dred <tt>OpusDRED*</tt>: DRED state

android/include/opus/opus_multistream.h

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,44 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
382382
opus_int32 max_data_bytes
383383
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
384384

385+
/** Encodes a multistream Opus frame.
386+
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
387+
* @param[in] pcm <tt>const opus_int32*</tt>: The input signal as interleaved
388+
* samples representing (or slightly exceeding) 24-bit values.
389+
* This must contain
390+
* <code>frame_size*channels</code>
391+
* samples.
392+
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
393+
* signal.
394+
* This must be an Opus frame size for the
395+
* encoder's sampling rate.
396+
* For example, at 48 kHz the permitted values
397+
* are 120, 240, 480, 960, 1920, and 2880.
398+
* Passing in a duration of less than 10 ms
399+
* (480 samples at 48 kHz) will prevent the
400+
* encoder from using the LPC or hybrid modes.
401+
* @param[out] data <tt>unsigned char*</tt>: Output payload.
402+
* This must contain storage for at
403+
* least \a max_data_bytes.
404+
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
405+
* memory for the output
406+
* payload. This may be
407+
* used to impose an upper limit on
408+
* the instant bitrate, but should
409+
* not be used as the only bitrate
410+
* control. Use #OPUS_SET_BITRATE to
411+
* control the bitrate.
412+
* @returns The length of the encoded packet (in bytes) on success or a
413+
* negative error code (see @ref opus_errorcodes) on failure.
414+
*/
415+
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode24(
416+
OpusMSEncoder *st,
417+
const opus_int32 *pcm,
418+
int frame_size,
419+
unsigned char *data,
420+
opus_int32 max_data_bytes
421+
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
422+
385423
/** Encodes a multistream Opus frame from floating point input.
386424
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
387425
* @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
@@ -591,6 +629,44 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
591629
int decode_fec
592630
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
593631

632+
/** Decode a multistream Opus packet.
633+
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
634+
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
635+
* Use a <code>NULL</code>
636+
* pointer to indicate packet
637+
* loss.
638+
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
639+
* @param[out] pcm <tt>opus_int32*</tt>: Output signal, with interleaved
640+
* samples representing (or slightly exceeding) 24-bit values.
641+
* This must contain room for
642+
* <code>frame_size*channels</code>
643+
* samples.
644+
* @param frame_size <tt>int</tt>: The number of samples per channel of
645+
* available space in \a pcm.
646+
* If this is less than the maximum packet duration
647+
* (120 ms; 5760 for 48kHz), this function will not be capable
648+
* of decoding some packets. In the case of PLC (data==NULL)
649+
* or FEC (decode_fec=1), then frame_size needs to be exactly
650+
* the duration of audio that is missing, otherwise the
651+
* decoder will not be in the optimal state to decode the
652+
* next incoming packet. For the PLC and FEC cases, frame_size
653+
* <b>must</b> be a multiple of 2.5 ms.
654+
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
655+
* forward error correction data be decoded.
656+
* If no such data is available, the frame is
657+
* decoded as if it were lost.
658+
* @returns Number of samples decoded on success or a negative error code
659+
* (see @ref opus_errorcodes) on failure.
660+
*/
661+
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode24(
662+
OpusMSDecoder *st,
663+
const unsigned char *data,
664+
opus_int32 len,
665+
opus_int32 *pcm,
666+
int frame_size,
667+
int decode_fec
668+
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
669+
594670
/** Decode a multistream Opus packet with floating point output.
595671
* @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
596672
* @param[in] data <tt>const unsigned char*</tt>: Input payload.

android/include/opus/opus_projection.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,44 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode(
260260
opus_int32 max_data_bytes
261261
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
262262

263+
/** Encodes a projection Opus frame.
264+
* @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
265+
* @param[in] pcm <tt>const opus_int32*</tt>: The input signal as interleaved
266+
* samples representing (or slightly exceeding) 24-bit values.
267+
* This must contain
268+
* <code>frame_size*channels</code>
269+
* samples.
270+
* @param frame_size <tt>int</tt>: Number of samples per channel in the input
271+
* signal.
272+
* This must be an Opus frame size for the
273+
* encoder's sampling rate.
274+
* For example, at 48 kHz the permitted values
275+
* are 120, 240, 480, 960, 1920, and 2880.
276+
* Passing in a duration of less than 10 ms
277+
* (480 samples at 48 kHz) will prevent the
278+
* encoder from using the LPC or hybrid modes.
279+
* @param[out] data <tt>unsigned char*</tt>: Output payload.
280+
* This must contain storage for at
281+
* least \a max_data_bytes.
282+
* @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
283+
* memory for the output
284+
* payload. This may be
285+
* used to impose an upper limit on
286+
* the instant bitrate, but should
287+
* not be used as the only bitrate
288+
* control. Use #OPUS_SET_BITRATE to
289+
* control the bitrate.
290+
* @returns The length of the encoded packet (in bytes) on success or a
291+
* negative error code (see @ref opus_errorcodes) on failure.
292+
*/
293+
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode24(
294+
OpusProjectionEncoder *st,
295+
const opus_int32 *pcm,
296+
int frame_size,
297+
unsigned char *data,
298+
opus_int32 max_data_bytes
299+
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
300+
263301

264302
/** Encodes a projection Opus frame from floating point input.
265303
* @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
@@ -493,6 +531,43 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode(
493531
int decode_fec
494532
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
495533

534+
/** Decode a projection Opus packet.
535+
* @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
536+
* @param[in] data <tt>const unsigned char*</tt>: Input payload.
537+
* Use a <code>NULL</code>
538+
* pointer to indicate packet
539+
* loss.
540+
* @param len <tt>opus_int32</tt>: Number of bytes in payload.
541+
* @param[out] pcm <tt>opus_int32*</tt>: Output signal, with interleaved
542+
* samples representing (or slightly exceeding) 24-bit values.
543+
* This must contain room for
544+
* <code>frame_size*channels</code>
545+
* samples.
546+
* @param frame_size <tt>int</tt>: The number of samples per channel of
547+
* available space in \a pcm.
548+
* If this is less than the maximum packet duration
549+
* (120 ms; 5760 for 48kHz), this function will not be capable
550+
* of decoding some packets. In the case of PLC (data==NULL)
551+
* or FEC (decode_fec=1), then frame_size needs to be exactly
552+
* the duration of audio that is missing, otherwise the
553+
* decoder will not be in the optimal state to decode the
554+
* next incoming packet. For the PLC and FEC cases, frame_size
555+
* <b>must</b> be a multiple of 2.5 ms.
556+
* @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
557+
* forward error correction data be decoded.
558+
* If no such data is available, the frame is
559+
* decoded as if it were lost.
560+
* @returns Number of samples decoded on success or a negative error code
561+
* (see @ref opus_errorcodes) on failure.
562+
*/
563+
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode24(
564+
OpusProjectionDecoder *st,
565+
const unsigned char *data,
566+
opus_int32 len,
567+
opus_int32 *pcm,
568+
int frame_size,
569+
int decode_fec
570+
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
496571

497572
/** Decode a projection Opus packet with floating point output.
498573
* @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.

0 commit comments

Comments
 (0)