Skip to content

Commit ba54ddb

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents 9cb0e1f + c10eb37 commit ba54ddb

File tree

318 files changed

+41436
-5543
lines changed

Some content is hidden

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

318 files changed

+41436
-5543
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: [alnitak]

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
name: Bug Report
33
about: Create a report to help us improve
44
title: "fix: "
5-
labels: bug
65
---
76

87
**Description**
@@ -26,4 +25,4 @@ If applicable, add screenshots to help explain your problem.
2625

2726
**Additional Context**
2827

29-
Add any other context about the problem here.
28+
Add the platform(s) where the issue arises or any other context about the problem here.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,6 @@ web/worker.dart.js.map
4545
**/android/daemon
4646
**/android/android
4747

48+
# Ignore ogg and opus directories in xiph
49+
xiph/ogg
50+
xiph/opus

.metadata

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,35 @@
44
# This file should be version controlled and should not be manually edited.
55

66
version:
7-
revision: "590ef2d402f619fd31c701553a653a6eada4ebe2"
8-
channel: "master"
7+
revision: "8495dee1fd4aacbe9de707e7581203232f591b2f"
8+
channel: "stable"
99

1010
project_type: plugin_ffi
1111

1212
# Tracks metadata for the flutter migrate command
1313
migration:
1414
platforms:
1515
- platform: root
16-
create_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
17-
base_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
16+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
17+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
1818
- platform: android
19-
create_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
20-
base_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
19+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
20+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
2121
- platform: ios
22-
create_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
23-
base_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
22+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
23+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
2424
- platform: linux
25-
create_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
26-
base_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
25+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
26+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
2727
- platform: macos
28-
create_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
29-
base_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
28+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
29+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
30+
- platform: web
31+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
32+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
3033
- platform: windows
31-
create_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
32-
base_revision: 590ef2d402f619fd31c701553a653a6eada4ebe2
34+
create_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
35+
base_revision: 8495dee1fd4aacbe9de707e7581203232f591b2f
3336

3437
# User provided section
3538

.vscode/launch.json

100755100644
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@
88
"name": "Flutter debug",
99
"type": "dart",
1010
"request": "launch",
11-
"program": "lib/wave_data/wave_data.dart",
11+
"program": "lib/main.dart",
1212
"flutterMode": "debug",
1313
"cwd": "${workspaceFolder}/example"
1414
},
1515
{
1616
"name": "Flutter profile",
1717
"type": "dart",
1818
"request": "launch",
19-
"program": "lib/filters/pitchshift.dart",
19+
"program": "lib/main.dart",
2020
"flutterMode": "profile",
2121
"cwd": "${workspaceFolder}/example"
2222
},
2323
{
2424
"name": "Flutter release",
2525
"type": "dart",
2626
"request": "launch",
27-
"program": "lib/filters/pitchshift.dart",
27+
"program": "lib/buffer_stream/websocket.dart",
2828
"flutterMode": "release",
2929
"cwd": "${workspaceFolder}/example"
3030
},
@@ -82,7 +82,7 @@
8282
{
8383
"name": "Chrome",
8484
"type": "chrome",
85-
"preLaunchTask": "compile web debug",
85+
"preLaunchTask": "compile web wasm release",
8686
"request": "launch"
8787
}
8888
]

.vscode/settings.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@
106106
"io_context": "cpp",
107107
"netfwd": "cpp",
108108
"timer": "cpp",
109-
"text_encoding": "cpp"
110-
}
109+
"text_encoding": "cpp",
110+
"coroutine": "cpp"
111+
},
112+
"java.configuration.updateBuildConfiguration": "interactive"
111113
}

.vscode/tasks.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
"tasks": [
44
{
55
"label": "compile linux debug verbose",
6-
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/main.dart --debug --verbose",
6+
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/filters/limiter.dart --debug --verbose",
77
// "args": ["build", "linux", "--verbose"],
88
"type": "shell"
99
},
1010
{
1111
"label": "compile linux debug",
12-
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/wave_data/wave_data.dart --debug",
12+
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/main.dart --debug",
1313
"type": "shell"
1414
},
1515
{
@@ -19,17 +19,22 @@
1919
},
2020
{
2121
"label": "compile windows debug verbose",
22-
"command": "cd ${workspaceFolder}/example; flutter build windows -t lib/filters/pitchshift.dart --debug --verbose",
22+
"command": "cd ${workspaceFolder}/example; flutter build windows -t lib/main.dart --debug --verbose",
2323
"type": "shell"
2424
},
2525
{
2626
"label": "compile windows debug",
27-
"command": "cd ${workspaceFolder}/example; flutter build windows -t lib/filters/pitchshift.dart --debug",
27+
"command": "cd ${workspaceFolder}/example; flutter build windows -t lib/main.dart --debug",
2828
"type": "shell"
2929
},
3030
{
31-
"label": "compile web debug",
32-
"command": "cd ${workspaceFolder}/example; flutter run -d chrome --web-renderer canvaskit --web-browser-flag '--disable-web-security' -t lib/wave_data/wave_data.dart --release",
31+
"label": "compile web wasm release",
32+
"command": "cd ${workspaceFolder}/example; flutter run -d chrome --wasm --web-browser-flag '--disable-web-security' -t lib/audio_data/audio_data.dart --release",
33+
"type": "shell"
34+
},
35+
{
36+
"label": "compile WASM",
37+
"command": "sh ${workspaceFolder}/wasm.sh",
3338
"type": "shell"
3439
}
3540
]

CHANGELOG.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
### 3.0.2 (25 Feb 2025)
2+
- fixed crash when trying to play a sound after deactivating its active filter #189
3+
4+
### 3.0.1 (20 Feb 2025)
5+
- fix: error while calling listPlaybackDevices() #186.
6+
- android example folder recreated.
7+
8+
### 3.0.0 (13 Feb 2025)
9+
- `BufferStream` now supports 2 type of buffering:
10+
- `BufferingType.preserved` (default): preserve the data already in the buffer while playing.
11+
- `BufferingType.released`: free the memory of the already played data for longer playback.
12+
- breaking change: splitted [maxBufferSize] to [maxBufferSizeBytes] and [maxBufferSizeDuration] in `SoLoud.setBufferStream`. This gives the user a way to choose the maximum buffer size using bytes or time.
13+
- breaking change: removed `initialized` getter in favor of `isInitialized`
14+
- removed deprecated `timeout` parameter in `SoLoud.init`.
15+
- removed deprecated `filter_params.dart`.
16+
- fixed biquad resonant filter `frequency` default parameter #179
17+
- fix: on some unclear conditions `isInitialized` returning false on MacOS after engine starts with no error #177
18+
- fix: Call `loadMem` will crash the application #174.
19+
20+
### 3.0.0-pre.0 (2 Feb 2025)
21+
- fix: clicks and pops when changing waveform frequency #156.
22+
- added `Limiter` and `Compressor` filters (see `example/lib/filters/`).
23+
- added BufferStream #148. Now it's possible to add audio data and listen to them. It provides a customizable buffering length which automatycally pauses the playing handle if there is not enough data, for example when receiving audio data from the web. It also provides a callback that allows you to know when the buffering is started and stopped. The audio data can of of the following formats:
24+
- `s8` signed 8 bit
25+
- `s16le` signed 16 bit little endian
26+
- `s32le` signed 32 bit little endian
27+
- `f32le` float 32 bit little endian
28+
- `opus` Opus codec compressed audio with Ogg container. Useful for streaming from the Web (ie using OpenAI APIs).
29+
- fixed Web Worker initialization non fatal error that could occur on Web.
30+
- fixed sound distortion using single pitchShift filter and changing relative play speed #154.
31+
- fixed the use of `LoadMode.disk` on the Web platform which in some cases caused the `allInstancesFinished` event to not be emitted.
32+
- improved performance on Web, MacOS and iOS.
33+
- get wave and FFT samples is now simpler and faster.
34+
- To avoid future incompatibilities when using other WASM compiled plugins, it is now necessary to add a new script to `index.html`:
35+
```
36+
<script src="assets/packages/flutter_soloud/web/libflutter_soloud_plugin.js" defer></script>
37+
<script src="assets/packages/flutter_soloud/web/init_module.dart.js" defer></script>
38+
```
39+
40+
### 2.1.7 (29 Oct 2024)
41+
- added `listPlaybackDevices` to get all the OS output devices available.
42+
- added `deviceId` parameter to the `init()` method. You can choose which device is delegated to output the audio.
43+
- added `changeDevice` method to change the output playback device on-the-fly.
44+
- fix: now throws when loading a file that might be corrupt #145.
45+
146
### 2.1.6 (17 Oct 2024)
247
- fixed a bug that caused an error when loading a sound more than twice.
348

README.md

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,19 @@ A low-level audio plugin for Flutter.
1414
* Ability to load sounds to RAM, or play from disk
1515
* Multiple voices, playing different or even the same sound multiple times on top of each other
1616
* Faders for attributes (e.g. fade out for 2 seconds, then stop)
17+
* Oscillators for attributes
18+
* Get audio wave and/or FFT audio data in real-time (useful for visualization)
19+
* Read audio data samples from a file with a given time range
1720
* 3D positional audio, including Doppler effect
1821
* Support for MP3, WAV, OGG, and FLAC
19-
* Audio effects such as echo, reverb, filter, equalizer
20-
* Web support is still under testing. Your feedback is greatly appreciated. Please read the [web notes](https://github.com/alnitak/flutter_soloud/blob/main/WEB_NOTES.md) to start using this plugin on the Web.
22+
* Generate waveforms with the following types: `square`, `saw`, `sin`, `triangle`, `bounce`, `jaws`, `humps`, `fSquare` and `fSaw`
23+
* Audio effects such as `echo`, `reverb`, `filter`, `equalizer`, `pitch` `shifter`, `limiter`, `compressor` etc.
24+
* Stream audio from given audio data with buffering support with the following formats:
25+
- `s8` signed 8 bit
26+
- `s16le` signed 16 bit little endian
27+
- `s32le` signed 32 bit little endian
28+
- `f32le` float 32 bit little endian
29+
- `opus` Opus codec compressed audio with Ogg container. Usefull for streaming from the Web (ie using OpenAI APIs).
2130

2231

2332
## Overview
@@ -35,8 +44,31 @@ If you merely need to play audio (such as playing a single sound effect or a non
3544
The `flutter_soloud` plugin uses the [SoLoud (C++) audio engine](https://solhsa.com/soloud/) with the [miniaudio](https://miniaud.io/) backend through [Dart's C interop](https://dart.dev/interop/c-interop) (`dart:ffi`).
3645
In other words, it is calling the C/C++ methods of the underlying audio engine directly — there are no method channels in use.
3746

47+
#### Opus format for streaming
48+
When using an `AudioSource` as an audio stream to play custom audio data (ie using setBufferStream/addAudioDataStream/setDataIsEnded), it is possible to add PCM RAW audio data in *s8*, *s16le*, *s32le*, *f32le* and since it supports also the *opus* format with the Ogg codec (ie to work with OpenAI APIs), the [Opus](https://www.opus-codec.org/) and [Ogg](https://xiph.org/ogg/) libraries from [Xiph.org](https://www.xiph.org/) are needed.
49+
50+
On Linux and MacOS theese libraries must be installed if you want to use this kind of `AudioSource`:
51+
- **Linux**
52+
- install them depending on the package manager used by you distribution
53+
- **MacOS**
54+
- `brew install opus libogg`
55+
56+
if the libraries are not found the plugin will throw an exception when calling `setBufferStream` using Opus format.
57+
58+
The `SoLoud.setBufferStream` supports also `BufferingType.preserved` which behaves the same as a normal `AudioSource`, and `BufferingType.released` which will free the memory of the already played audio for longer playback. The latter will accept to play only one instance of the audio stream at the same time.
59+
|BufferingType.preserved|BufferingType.released|
60+
|------------------------------------|----------------------------------|
61+
|![preserved](https://github.com/user-attachments/assets/e8699bfd-2a40-4832-a7a8-d729d844c48b)|![released](https://github.com/user-attachments/assets/7eb57688-ab0f-4859-813f-d23fff6ca10f)|
62+
|acts as normal leaving the whole audio data available for future re-play|while playing the already listened audio is freed. It can be listened to only once and the sound must be manually disposed|
63+
3864
#### Web platform
39-
To use this plugin on the **Web platform**, please refer to [WEB_NOTES](https://github.com/alnitak/flutter_soloud/blob/main/WEB_NOTES.md).
65+
To use this plugin on the **Web platform**, please add the following scripts to the `<head>` or `<body>` section of your `index.html`:
66+
```
67+
<script src="assets/packages/flutter_soloud/web/libflutter_soloud_plugin.js" defer></script>
68+
<script src="assets/packages/flutter_soloud/web/init_module.dart.js" defer></script>
69+
```
70+
71+
refer to [WEB_NOTES](https://github.com/alnitak/flutter_soloud/blob/main/WEB_NOTES.md) for more details.
4072

4173
#### Linux
4274
Linux distributions usually install the alsa library by default. However, we've noticed that sometimes this isn't the case. For example, when installing Ubuntu Linux (24.04.1 LTS in this case) in a VM box on Windows, the alsa library is not installed. This will prevent `flutter_soloud` from building.
@@ -89,7 +121,24 @@ This handle is also added to the `AudioSource.handles` list so that you can alwa
89121

90122
The `SoundHandle` also allows you to modify the currently-playing sounds, such as changing their volume, pausing them, etc.
91123

92-
For more simple examples, check out the [example/project](https://github.com/alnitak/flutter_soloud/tree/main/example) included with the package.
124+
---
125+
126+
For more simple examples, check out the [example/project](https://github.com/alnitak/flutter_soloud/tree/main/example) included with the package:
127+
| Example | Description |
128+
|-----------------|-------------|
129+
|*lib/main.dart* |Very simple example where to start from. |
130+
|*lib/audio_data/audio_data.dart* |Simple example to show how to use the `AudioData` to visualize audio. |
131+
|*lib/buffer_stream/generate.dart* |Example of how to generate PCM audio inside an `Isolate` and play them. |
132+
|*lib/buffer_stream/websocket.dart* |Shows how to use BufferStream with a websocket to get PCM and Opus audio data. |
133+
|*lib/filters/compressor.dart* |Shows the use of the compressor filter. |
134+
|*lib/filters/limiter.dart* |Shows the use of the limiter filter. |
135+
|*lib/filters/pitchshift.dart* |Shows the use of the pitchshift filter. |
136+
|*lib/metronome/metronome.dart* |Metronome example. |
137+
|*lib/output_device/output_device.dart* |Lists available output devices. |
138+
|*lib/wave_data/wave_data.dart* |Demonstrates how to read audio samples from a file and display them. |
139+
|*lib/waveform/waveform.dart* |Demonstrates how to generate a waveform, play it, and change it's frequency on the fly. |
140+
141+
93142
For more complete examples, please look at [flutter_soloud_example](https://github.com/alnitak/flutter_soloud_example).
94143

95144
## Logging
@@ -151,10 +200,10 @@ Since I needed to modify the generated `.dart` file, I followed this flow:
151200
This plugin uses the following structure:
152201

153202
* `lib`: Contains the Dart code that defines the API of the plugin relative to all platforms.
154-
155203
* `src`: Contains the native source code. Linux, Android and Windows have their own CmakeFile.txt file in their own subdir to build the code into a dynamic library.
156-
157-
* `src/soloud`: contains the SoLoud sources of my fork
204+
* `src/soloud`: Contains the SoLoud sources of my fork
205+
* `web`: Contains the scripts to build the plugin on the web platform.
206+
* `xiph`: Contains the script to build `ogg` and `opus` libraries on Android, Windows, MacOS and iOS.
158207

159208
The `flutter_soloud` plugin utilizes a [forked](https://github.com/alnitak/soloud) repository of [SoLoud](https://github.com/jarikomppa/soloud), where the [miniaudio](https://github.com/mackron/miniaudio) audio backend (used by default) has been updated and it is located in `src/soloud/src/backend/miniaudio`.
160209

WEB_NOTES.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Please note that filters for single sounds are not supported on the web.
1111
To add the plugin to a web app, add the following line to the `<body>` section of `web/index.html`:
1212
```
1313
<script src="assets/packages/flutter_soloud/web/libflutter_soloud_plugin.js" defer></script>
14+
<script src="assets/packages/flutter_soloud/web/init_module.dart.js" defer></script>
1415
```
1516

1617
---
@@ -31,10 +32,11 @@ flutter run -d chrome --web-renderer canvaskit --web-browser-flag '--disable-web
3132

3233
## For developers
3334

34-
In the `web` directory, there is a `compile_wasm.sh` script that generates the `.js` and `.wasm` files for the native C code located in the `src` dir. Run it after installing *emscripten*. There is also a `compile_web.sh` to compile the web worker needed by native code to communicate with Dart. The generated files are already provided, but if it is needed to modify C/C++ code or the `web/worker.dart` code, the scripts must be run to reflect the changes.
35+
In the `web` directory, there is a `compile_wasm.sh` script that generates the `.js` and `.wasm` files for the native C code located in the `src` dir. Run it after installing *emscripten*. There is also a `compile_worker_and_init_module.sh` to compile the web worker needed by native code to communicate with Dart and the `init_module.dart` which initializes the WASM module. The default Module name is `Module_soloud` instead of the default `Module` to prevent some other WASM plugins from conflicting.
3536

36-
The `compile_wasm.sh` script uses the `-O3` code optimization flag.
37-
To see a better errors logs, use `-O0 -g -s ASSERTIONS=1` in `compile_wasm.sh`.
37+
The generated files are already provided, but if it is needed to modify C/C++ code or the `web/worker.dart` code, the scripts must be run to reflect the changes.
38+
39+
The `compile_wasm.sh` script uses the `-O3` code optimization flag. To see a better errors logs, use `-O0 -g -s ASSERTIONS=1` in `compile_wasm.sh`.
3840

3941
---
4042

@@ -44,10 +46,10 @@ Here a sketch to show the step used:
4446
![sketch](img/wasmWorker.png)
4547

4648
**#1.** This function is called while initializing the player with `FlutterSoLoudWeb.setDartEventCallbacks()`.
47-
It creates a Web Worker in the [WASM Module](https://emscripten.org/docs/api_reference/module.html) using the compiled `web/worker.dart`. After calling this, the WASM Module will have a new variable called `Module.wasmWorker` which will be used in Dart to receive messages.
49+
It creates a Web Worker in the [WASM Module](https://emscripten.org/docs/api_reference/module.html) using the compiled `web/worker.dart`. After calling this, the WASM Module will have a new variable called `Module_soloud.wasmWorker` which will be used in Dart to receive messages.
4850
By doing this it will be easy to use the Worker to send messages from within the CPP code.
4951

50-
**#2.** This function, like #1, uses [EM_ASM](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-javascript-from-native) to inline JS. This JS code uses the `Module.wasmWorker` created in #1 to send a message.
52+
**#2.** This function, like #1, uses [EM_ASM](https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#interacting-with-code-call-javascript-from-native) to inline JS. This JS code uses the `Module_soloud.wasmWorker` created in #1 to send a message.
5153

5254
**#3.** This is the JS used and created in #1. Every messages sent by #2 are managed here and sent to #4.
5355

0 commit comments

Comments
 (0)