diff --git a/CHANGELOG.md b/CHANGELOG.md index b54f4767..e45c364f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ - ##### 4.1.5 (XX Xxx 2026) - fix web: crash with `--optimization-level=0` due to HEAPU8.buffer declared as JSArrayBuffer #526 +- fix: missing guard for NO_XIPH_LIBS that prevents building when using it #528 ##### 4.1.4 (31 Jul 2026) - fix: the voice-ended callback is no longer invoked while SoLoud's audio mutex is held. The symptom was a wedged engine: handles and sources still looked valid, no audio was produced, and `deinit()` never completed. Ended voices are now queued and dispatched once the mutex is released. Thanks to @Colton127 #518 diff --git a/example/tests/tests/async_multi_load.dart b/example/tests/tests/async_multi_load.dart index 8641379e..8da10a82 100644 --- a/example/tests/tests/async_multi_load.dart +++ b/example/tests/tests/async_multi_load.dart @@ -10,7 +10,7 @@ Future testAsyncMultiLoad() async { SoLoud.instance.loadAsset('assets/audio/8_bit_mentality.mp3'), SoLoud.instance.loadAsset('assets/audio/explosion.mp3'), SoLoud.instance.loadAsset('assets/audio/IveSeenThings.mp3'), - SoLoud.instance.loadAsset('assets/audio/sample-vorbis.ogg'), + SoLoud.instance.loadAsset('assets/audio/sample-MP3.mp3'), SoLoud.instance.loadAsset('assets/audio/tic-1.wav'), SoLoud.instance.loadAsset('assets/audio/tic-2.wav'), ]; diff --git a/example/tests/tests/mixer_output_capture.dart b/example/tests/tests/mixer_output_capture.dart index c3d77e07..cc4e2c9e 100644 --- a/example/tests/tests/mixer_output_capture.dart +++ b/example/tests/tests/mixer_output_capture.dart @@ -2,6 +2,8 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:flutter_soloud/flutter_soloud.dart'; +import 'package:flutter_soloud/src/bindings/soloud_controller_ffi.dart' + if (dart.library.js_interop) 'package:flutter_soloud/src/bindings/soloud_controller_web.dart'; import 'common.dart'; @@ -11,6 +13,15 @@ import 'common.dart'; Future testMixerOutputCapture() async { final output = OutputBuffer(); + final isXiphAvailable = SoLoudController().soLoudFFI.areXiphLibsAvailable(); + + if (!isXiphAvailable) { + output.writeln( + 'Skipping mixer output capture test: Xiph libraries not available', + ); + return output; + } + await initialize(); final sound = await SoLoud.instance.loadWaveform( diff --git a/example/tests/tests/mixing_bus.dart b/example/tests/tests/mixing_bus.dart index 2f8bffb5..676a724a 100644 --- a/example/tests/tests/mixing_bus.dart +++ b/example/tests/tests/mixing_bus.dart @@ -14,8 +14,7 @@ Future testMixingBus() async { await SoLoud.instance.loadAsset('assets/audio/8_bit_mentality.mp3'); final iveSeenThings = await SoLoud.instance.loadAsset('assets/audio/IveSeenThings.mp3'); - final sample = - await SoLoud.instance.loadAsset('assets/audio/sample-vorbis.ogg'); + final sample = await SoLoud.instance.loadAsset('assets/audio/sample-MP3.mp3'); // Get initial bus count final initialBusCount = Buses().buses.length; diff --git a/example/tests/tests/pull_buffer_test.dart b/example/tests/tests/pull_buffer_test.dart index 88e717c7..fb50fefd 100644 --- a/example/tests/tests/pull_buffer_test.dart +++ b/example/tests/tests/pull_buffer_test.dart @@ -19,7 +19,7 @@ Future testPullBuffer() async { final strBuf = OutputBuffer(); await initialize(); - final bytes = (await rootBundle.load('assets/audio/sample-OPUS.opus')) + final bytes = (await rootBundle.load('assets/audio/sample-MP3.mp3')) .buffer .asUint8List(); diff --git a/lib/src/exceptions/exceptions_from_cpp.dart b/lib/src/exceptions/exceptions_from_cpp.dart index 3906e69d..389c2230 100644 --- a/lib/src/exceptions/exceptions_from_cpp.dart +++ b/lib/src/exceptions/exceptions_from_cpp.dart @@ -34,8 +34,8 @@ class SoLoudFileLoadFailedException extends SoLoudCppException { @override String get description => 'File found, but could not be loaded! ' - 'Could be a permission error or the file is corrupted. ' - '(on the C++ side).'; + 'Could be a permission error, or the file is corrupted, ' + 'or the format is not supported. (on the C++ side).'; } // Note: PlayerErrors.fileAlreadyLoaded is not thrown as an exception. diff --git a/src/mixeroutput/mixer_output.cpp b/src/mixeroutput/mixer_output.cpp index 4c4e8175..e5ba34f6 100644 --- a/src/mixeroutput/mixer_output.cpp +++ b/src/mixeroutput/mixer_output.cpp @@ -39,6 +39,15 @@ PlayerErrors MixerOutput::start(MixerOutputFormat format, int sampleRate, return invalidParameter; } +#if defined(NO_XIPH_LIBS) + // Without the Xiph libraries only the PCM formats (and the WAV encoder, + // which does not depend on them) are supported. + if (format == MIXER_OUTPUT_OPUS || format == MIXER_OUTPUT_VORBIS || + format == MIXER_OUTPUT_FLAC) { + return xiphLibsNotFound; + } +#endif + const bool isCompressed = format == MIXER_OUTPUT_OPUS || format == MIXER_OUTPUT_VORBIS || format == MIXER_OUTPUT_FLAC || diff --git a/src/soloud/src/audiosource/wav/soloud_wavstream.cpp b/src/soloud/src/audiosource/wav/soloud_wavstream.cpp index a9f6b438..f4ba70ea 100644 --- a/src/soloud/src/audiosource/wav/soloud_wavstream.cpp +++ b/src/soloud/src/audiosource/wav/soloud_wavstream.cpp @@ -182,12 +182,14 @@ namespace SoLoud { switch (mParent->mFiletype) { +#if !defined(NO_XIPH_LIBS) case WAVSTREAM_OGG: if (mCodec.mOgg) { delete mCodec.mOgg; } break; +#endif case WAVSTREAM_FLAC: if (mCodec.mFlac) { @@ -267,6 +269,7 @@ namespace SoLoud return offset; } break; +#if !defined(NO_XIPH_LIBS) case WAVSTREAM_OGG: { unsigned int i; @@ -285,6 +288,7 @@ namespace SoLoud return offset; } break; +#endif case WAVSTREAM_WAV: { unsigned int i, j, k; @@ -319,6 +323,7 @@ namespace SoLoud switch (mParent->mFiletype) { +#if !defined(NO_XIPH_LIBS) case WAVSTREAM_OGG: mCodec.mOgg->seek(pos); mOffset = pos; @@ -326,6 +331,7 @@ namespace SoLoud mStreamPosition = newPosition; mStreamEnded = false; return 0; +#endif case WAVSTREAM_FLAC: drflac_seek_to_pcm_frame(mCodec.mFlac, pos); mOffset = pos; @@ -364,12 +370,14 @@ namespace SoLoud { switch (mParent->mFiletype) { +#if !defined(NO_XIPH_LIBS) case WAVSTREAM_OGG: if (mCodec.mOgg) { mCodec.mOgg->rewind(); } break; +#endif case WAVSTREAM_FLAC: if (mCodec.mFlac) {