Skip to content

Commit

Permalink
Merge pull request #103 from alnitak/web
Browse files Browse the repository at this point in the history
Web
  • Loading branch information
alnitak committed Jul 15, 2024
2 parents 95e3671 + c0ad160 commit 7f6c134
Show file tree
Hide file tree
Showing 87 changed files with 8,663 additions and 2,506 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ images/
lib/flutter_soloud_FFIGEN.dart

web/build
web/worker.dart.js.deps
web/worker.dart.js.map

**/android/caches
**/android/.tmp
Expand Down
14 changes: 14 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@
"intelliSenseMode": "linux-clang-x64",
"configurationProvider": "ms-vscode.cmake-tools"
},
{
"name": "Chrome",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/src",
"/usr/lib/emscripten/system/include"
],
"defines": ["WITH_MINIAUDIO", "DR_MP3_IMPLEMENTATION", "__EMSCRIPTEN__"], // to see the code in between "#if defined"
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "${default}",
"configurationProvider": "ms-vscode.cmake-tools"
},
{
"name": "Win32",
"includePath": [
Expand Down
6 changes: 6 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@
"request": "launch",
"program": "${workspaceFolder}/example/build/linux/x64/debug/bundle/flutter_soloud_example",
"cwd": "${workspaceFolder}"
},
{
"name": "Chrome",
"type": "chrome",
"preLaunchTask": "compile web debug",
"request": "launch"
}
]
}
28 changes: 3 additions & 25 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,27 @@
{
"label": "compile linux debug",
"command": "cd ${workspaceFolder}/example; flutter build linux -t lib/main.dart --debug",
// "args": ["build", "linux"],
"type": "shell"
},
{
"label": "compile linux test debug",
"command": "cd ${workspaceFolder}/example; flutter build linux -t tests/tests.dart --debug",
// "args": ["build", "linux"],
"type": "shell"
},
{
"label": "compile windows debug verbose",
"command": "cd ${workspaceFolder}/example; flutter build windows -t lib/main.dart --debug --verbose",
// "args": ["build", "linux"],
"type": "shell"
},
{
"label": "compile windows debug",
"command": "cd ${workspaceFolder}/example; flutter build windows -t lib/main.dart --debug",
// "args": ["build", "linux"],
"type": "shell"
},
{
"type": "cppbuild",
"label": "C/C++: gcc build active file",
"command": "/usr/bin/gcc",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
"label": "compile web debug",
"command": "cd ${workspaceFolder}/example; flutter run -d chrome --web-renderer canvaskit --web-browser-flag '--disable-web-security' -t lib/main.dart --release",
"type": "shell"
}
]
}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
### 2.1.0
- added `getPan()`, `setPan()` and `setPanAbsolute()`.
- added support for the Web platform.
- added `loadMem()` to read the give audio file bytes buffer (not RAW data). Useful for the Web platform.
- fixed `getFilterParamNames()`.
- added `AudioData` class to manage audio samples.

### 2.0.2 (23 May 2024)
- Fixed wrong exception raised by `setVolume()` when a handle is no more valid.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ A low-level audio plugin for Flutter.

|Linux|Windows|Android|MacOS|iOS|web|
|:-:|:-:|:-:|:-:|:-:|:-:|
|💙|💙|💙|💙|💙| <abbr title="Work in Progress">WIP</abbr> |
|💙|💙|💙|💙|💙|💙|

### Select features:

Expand Down Expand Up @@ -42,6 +42,7 @@ with the [miniaudio](https://miniaud.io/) backend
through [Dart's C interop](https://dart.dev/interop/c-interop) (`dart:ffi`).
In other words, it is calling the C/C++ methods of the underlying audio engine
directly — there are no method channels in use.
To use this plugin on the **Web platform**, please refer to [WEB_NOTES](https://github.com/alnitak/flutter_soloud/blob/main/WEB_NOTES.md).


## Example
Expand Down
51 changes: 51 additions & 0 deletions WEB_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Web Notes


## Description

The web platform is now supported, but some testing is welcome.

## How to use

To add the plugin to a web app, add the following line to the `<body>` section of `web/index.html`:
```
<script src="assets/packages/flutter_soloud/web/libflutter_soloud_plugin.js" defer></script>
```

---

**`loadUrl()`** may produce the following error when the app is run:
>> Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
This is due for the default beavior of http servers which don't allow to make requests outside their domain. Refer [here](https://enable-cors.org/server.html) to learn how to enable your server to handle this situation.
Instead, if you run the app locally, you could run the app with something like the following command:
```
flutter run -d chrome --web-renderer canvaskit --web-browser-flag '--disable-web-security' -t lib/main.dart --release
```

---

***It is not possible to read a local audio file directly*** on the web. For this reason, `loadMem()` has been added, which requires the `Uint8List` byte buffer of the audio file.
***IMPORTANT***: `loadMem()` with mode `LoadMode.memory` used on web platform will freeze the UI for the time needed to decompress the audio file. Please use it with mode `LoadMode.disk` or load your sound when the app starts.

## For developers

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.

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`.

---

The `AudioIsolate` [has been removed](https://github.com/alnitak/flutter_soloud/pull/89) and all the logic has been implemented natively. Events like `voice ended` are sent from C back to Dart. However, since it is not possible to call Dart from a native thread (the audio thread), a new web worker is created using the WASM `EM_ASM` directive. This allows sending the `voice ended` event back to Dart via the worker.

Here a sketch to show the step used:
![sketch](img/wasmWorker.png)

**#1.** This function is called while initializing the player with `FlutterSoLoudWeb.setDartEventCallbacks()`.
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.
By doing this it will be easy to use the Worker to send messages from within the CPP code.
**#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.
**#3.** This is the JS used and created in #1. Every messages sent by #2 are managed here and sent to #4.
**#4.** Here when the event message has been received, a new event is added to a Stream. This Stream is listened by the SoLoud API.
**#5.** Here we listen to the event messages coming from the `WorkerController` stream. Currently, only the "voice ended" event is supported. The Stream is listened in `SoLoud._initializeNativeCallbacks()`.
16 changes: 8 additions & 8 deletions example/.metadata
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
# This file should be version controlled and should not be manually edited.

version:
revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
channel: stable
revision: "761747bfc538b5af34aa0d3fac380f1bc331ec49"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
- platform: windows
create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
- platform: web
create_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49
base_revision: 761747bfc538b5af34aa0d3fac380f1bc331ec49

# User provided section

Expand Down
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions example/assets/shaders/test9.frag
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,11 @@ void mainImage( out vec4 fragColor, in vec2 fragCoord )

// rotate view
float a;
a = -0.6;
a = -0.8;
rd = rotateX(rd, a);
ro = rotateX(ro, a);

a = 1.5;
a = 1.8;
// a = sin(iTime)*.5 + 1.570796327;
rd = rotateY(rd, a);
ro = rotateY(ro, a);
Expand Down
12 changes: 6 additions & 6 deletions example/lib/controls.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_soloud/flutter_soloud.dart';
import 'package:permission_handler/permission_handler.dart';
Expand Down Expand Up @@ -29,8 +29,8 @@ class _ControlsState extends State<Controls> {
// ignore: avoid_positional_boolean_parameters
ButtonStyle buttonStyle(bool enabled) {
return enabled
? ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.green))
: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red));
? ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.green))
: ButtonStyle(backgroundColor: WidgetStateProperty.all(Colors.red));
}

@override
Expand All @@ -49,7 +49,8 @@ class _ControlsState extends State<Controls> {
ElevatedButton(
onPressed: () async {
/// Ask recording permission on mobile
if (Platform.isAndroid || Platform.isIOS) {
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.iOS) {
final p = await Permission.microphone.isGranted;
if (!p) {
unawaited(Permission.microphone.request());
Expand All @@ -76,9 +77,8 @@ class _ControlsState extends State<Controls> {
blurSigmaX: 6,
blurSigmaY: 6,
),
linearShapeParams: LinearShapeParams(
linearShapeParams: const LinearShapeParams(
angle: -90,
space: Platform.isAndroid || Platform.isIOS ? -10 : 10,
alignment: LinearAlignment.left,
),
),
Expand Down
1 change: 0 additions & 1 deletion example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) {
return DefaultTabController(
length: 5,
initialIndex: 2,
child: SafeArea(
child: Scaffold(
body: Column(
Expand Down
5 changes: 3 additions & 2 deletions example/lib/page_3d_audio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ class _Page3DAudioState extends State<Page3DAudio> {

/// load the audio file
currentSound = await SoLoud.instance.loadUrl(
'https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3',
// From https://freetestdata.com/audio-files/mp3/
'https://marcobavagnoli.com/Free_Test_Data_500KB_MP3.mp3',
);

/// play it
await SoLoud.instance.play3d(currentSound!, 0, 0, 0);
await SoLoud.instance.play3d(currentSound!, 0, 0, 0, looping: true);

spinAround = true;

Expand Down
Loading

0 comments on commit 7f6c134

Please sign in to comment.