Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion example/tests/tests/async_multi_load.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Future<OutputBuffer> 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'),
];
Expand Down
11 changes: 11 additions & 0 deletions example/tests/tests/mixer_output_capture.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -11,6 +13,15 @@ import 'common.dart';
Future<OutputBuffer> 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(
Expand Down
3 changes: 1 addition & 2 deletions example/tests/tests/mixing_bus.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ Future<OutputBuffer> 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;
Expand Down
2 changes: 1 addition & 1 deletion example/tests/tests/pull_buffer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Future<OutputBuffer> 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();

Expand Down
4 changes: 2 additions & 2 deletions lib/src/exceptions/exceptions_from_cpp.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
9 changes: 9 additions & 0 deletions src/mixeroutput/mixer_output.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 ||
Expand Down
8 changes: 8 additions & 0 deletions src/soloud/src/audiosource/wav/soloud_wavstream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -267,6 +269,7 @@ namespace SoLoud
return offset;
}
break;
#if !defined(NO_XIPH_LIBS)
case WAVSTREAM_OGG:
{
unsigned int i;
Expand All @@ -285,6 +288,7 @@ namespace SoLoud
return offset;
}
break;
#endif
case WAVSTREAM_WAV:
{
unsigned int i, j, k;
Expand Down Expand Up @@ -319,13 +323,15 @@ namespace SoLoud

switch (mParent->mFiletype)
{
#if !defined(NO_XIPH_LIBS)
case WAVSTREAM_OGG:
mCodec.mOgg->seek(pos);
mOffset = pos;
newPosition = float(pos / mBaseSamplerate);
mStreamPosition = newPosition;
mStreamEnded = false;
return 0;
#endif
case WAVSTREAM_FLAC:
drflac_seek_to_pcm_frame(mCodec.mFlac, pos);
mOffset = pos;
Expand Down Expand Up @@ -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)
{
Expand Down
Loading