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 .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
name: Test
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main
with:
linux_build_command: "cd Guest && ./build.sh"
linux_build_command: "cd AudioWorkstation/Guest && ./build.sh"
linux_exclude_swift_versions: '[{"swift_version": "5.9"}, {"swift_version": "5.10"}]'
enable_windows_checks: false
soundness:
Expand Down
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
106 changes: 106 additions & 0 deletions AudioWorkstation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Swift Audio Workstation

This example demonstrates support for WebAssembly in latest development snapshots of the Swift toolchain, in combination
with the [Embedded Swift mode](https://github.com/apple/swift/blob/main/docs/EmbeddedSwift/UserManual.md).
With foundational building blocks written in Swift, it utilizes C++ interop for calling into a
[DSP](https://en.wikipedia.org/wiki/Digital_signal_processing) library for synthesizing simple musical sequences. It is
written with a multi-platform approach, which makes it easy to integrate into Wasm-based serverless environment or
native applications and libraries.

It is split into three packages: `Guest` with Wasm modules built with Embedded Swift, `ServerHost` that embeds these modules, and `WATExample` that demonstrates compilation of WebAssembly Text Format to binary Wasm modules using Swift.

## Requirements

WebAssembly support in Swift is available for preview in latest Trunk Development (main) snapshots at
[swift.org/download](https://www.swift.org/download).

### macOS

1. Install [Xcode](https://apps.apple.com/us/app/xcode/id497799835?mt=12).
2. Verify selected Xcode path by running `xcode-select -p` in the terminal. If the incorrect Xcode is selected, follow
the steps provided in ["How do I select the default version of Xcode"](https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-HOW_DO_I_SELECT_THE_DEFAULT_VERSION_OF_XCODE_TO_USE_FOR_MY_COMMAND_LINE_TOOLS_) section of
["Building from the Command Line with Xcode FAQ"](https://developer.apple.com/library/archive/technotes/tn2339/_index.html).
3. Download latest `main` development snapshot, you can use [`DEVELOPMENT-SNAPSHOT-2024-04-01-a`](https://download.swift.org/development/xcode/swift-DEVELOPMENT-SNAPSHOT-2024-04-01-a/swift-DEVELOPMENT-SNAPSHOT-2024-04-01-a-osx.pkg) or a later version.
4. Run the downloaded installer. Select "Install for me only" option during installation.
5. Select the newly installed snapshot in terminal:

```sh
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw \
~/Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
```

### Linux

Follow Linux-specific instructions provided on [swift.org/install](https://www.swift.org/install/#linux) to install the
latest development toolchain for your specific distribution.

### Docker

1. Start a docker container in a clone of this repository using the nightly swiftlang Ubuntu image, with a `/root/build`
mount to the current directory:

```sh
docker run --rm -it -v $(pwd):/root/build swiftlang/swift:nightly-jammy /bin/bash
```

2. Navigate to the package directory within the container:

```sh
cd /root/build
```

## How to Build and Run

Assuming you're within the cloned repository and have the latest development snapshots selected per the instructions
above, first build the package:

```sh
swift build --triple wasm32-unknown-none-wasm -c release --product swift-audio
```

Then start the HTTP server:

```sh
python3 -m http.server
```

Open http://localhost:8000 in your browser to see the project running.

## License

Copyright 2024 Apple Inc. and the Swift project authors. Licensed under Apache License v2.0 with Runtime Library Exception.

See [https://swift.org/LICENSE.txt](https://swift.org/LICENSE.txt) for license information.

See [https://swift.org/CONTRIBUTORS.txt](https://swift.org/CONTRIBUTORS.txt) for Swift project authors.

See [`LICENSE-vendored.md`](https://github.com/swiftlang/swift-for-wasm-examples/blob/main/AudioWorkstation/LICENSE-vendored.md) for exact licenses of code vendored in this repository. Specifically:

* Code in `Guest/Sources/dlmalloc` directory is derived from wasi-libc: https://github.com/WebAssembly/wasi-libc

> wasi-libc as a whole is multi-licensed under the Apache License v2.0 with LLVM Exceptions, the Apache License v2.0, and the MIT License. See the LICENSE-APACHE-LLVM, LICENSE-APACHE and LICENSE-MIT files, respectively, for details.
>
> Portions of this software are derived from third-party works covered by their own licenses:
>
> dlmalloc/ - CC0; see the notice in malloc.c for details emmalloc/ - MIT; see the notice in emmalloc.c for details libc-bottom-half/cloudlibc/ - BSD-2-Clause; see the LICENSE file for details libc-top-half/musl/ - MIT; see the COPYRIGHT file for details
>
> wasi-libc's changes to these files are multi-licensed under the Apache License v2.0 with LLVM Exceptions, the Apache License v2.0, the MIT License, and the original licenses of the third-party works.

* .wav format encoding implementation is derived from WavAudioEncoder.js library https://github.com/higuma/wav-audio-encoder-js and is licensed as following:

> The MIT License (MIT)
>
> Copyright (c) 2015 Yuji Miyane

* Code in `Guest/Sources/VultDSP` directory is derived from https://github.com/vult-dsp/vult and is licensed as following:

> MIT License
>
> Copyright (c) 2017 Leonardo Laguna Ruiz

* Web server starter template code is derived from [the Hummingbird template package](https://github.com/hummingbird-project/template) and is licensed as following:

> Copyright (c) 2024 Adam Fowler.
> Licensed under Apache License v2.0.
>
> See https://github.com/hummingbird-project/template/blob/main/LICENSE for license information
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 0 additions & 1 deletion Guest/.build/.gitkeep

This file was deleted.

90 changes: 9 additions & 81 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,89 +1,16 @@
# Swift for WebAssembly Examples
# Swift for WebAssembly Example Projects

A repository with a "Swift Audio Workstation" example built with Swift for WebAssembly running in the browser.
A collection of example projects using Swift's WebAssembly support. To learn more, see:

This example demonstrates support for WebAssembly in latest development snapshots of the Swift toolchain, in combination
with the [Embedded Swift mode](https://github.com/apple/swift/blob/main/docs/EmbeddedSwift/UserManual.md).
With foundational building blocks written in Swift, it utilizes C++ interop for calling into a
[DSP](https://en.wikipedia.org/wiki/Digital_signal_processing) library for synthesizing simple musical sequences. It is
written with a multi-platform approach, which makes it easy to integrate into Wasm-based serverless environment or
native applications and libraries.
- [Getting Started with Swift SDKs for WebAssembly](https://www.swift.org/documentation/articles/wasm-getting-started.html)
- [WebAssembly Support in Swift Vision Document](https://github.com/swiftlang/swift-evolution/blob/main/visions/webassembly.md)

The repository is split into three packages: `Guest` with Wasm modules built with Embedded Swift, `ServerHost` that embeds these modules, and `WATExample` that demonstrates compilation of WebAssembly Text Format to binary Wasm modules using Swift.

## Requirements
## Contributing to this repository

WebAssembly support in Swift is available for preview in latest Trunk Development (main) snapshots at
[swift.org/download](https://www.swift.org/download).

### macOS

1. Install [Xcode](https://apps.apple.com/us/app/xcode/id497799835?mt=12).
2. Verify selected Xcode path by running `xcode-select -p` in the terminal. If the incorrect Xcode is selected, follow
the steps provided in ["How do I select the default version of Xcode"](https://developer.apple.com/library/archive/technotes/tn2339/_index.html#//apple_ref/doc/uid/DTS40014588-CH1-HOW_DO_I_SELECT_THE_DEFAULT_VERSION_OF_XCODE_TO_USE_FOR_MY_COMMAND_LINE_TOOLS_) section of
["Building from the Command Line with Xcode FAQ"](https://developer.apple.com/library/archive/technotes/tn2339/_index.html).
3. Download latest `main` development snapshot, you can use [`DEVELOPMENT-SNAPSHOT-2024-04-01-a`](https://download.swift.org/development/xcode/swift-DEVELOPMENT-SNAPSHOT-2024-04-01-a/swift-DEVELOPMENT-SNAPSHOT-2024-04-01-a-osx.pkg) or a later version.
4. Run the downloaded installer:

```sh
installer -target CurrentUserHomeDirectory -pkg ~/Downloads/swift-DEVELOPMENT-SNAPSHOT-2024-04-01-a-osx.pkg
```

5. Select the newly installed snapshot:

```sh
export TOOLCHAINS=$(plutil -extract CFBundleIdentifier raw \
~/Library/Developer/Toolchains/swift-latest.xctoolchain/Info.plist)
```

### Linux

Follow Linux-specific instructions provided on [swift.org/install](https://www.swift.org/install/#linux) to install the
latest development toolchain for your specific distribution.

### Docker

1. Start a docker container in a clone of this repository using the nightly swiftlang Ubuntu image, with a `/root/build`
mount to the current directory:

```sh
docker run --rm -it -v $(pwd):/root/build swiftlang/swift:nightly-jammy /bin/bash
```

2. Navigate to the package directory within the container:

```sh
cd /root/build
```

## How to Build and Run

Assuming you're within the cloned repository and have the latest development snapshots selected per the instructions
above, build modules from the `Guest` package (this will copy `.wasm` modules to the home directory of the current user):

```sh
cd Guest; ./build.sh
```


Then build and start the HTTP server:

```sh
cd ../ServerHost; swift run Server
```

Open http://localhost:8080 in your browser to see the project running. Use the web interface to upload previously built
`Guest` modules from the home directory.

## Contributing to this example
Contributions to Swift are welcomed and encouraged! Please see the
[Contributing to Swift guide](https://swift.org/contributing/).

Before submitting the pull request, please make sure you have [tested your
changes](https://github.com/apple/swift/blob/main/docs/ContinuousIntegration.md)
and that they follow the Swift project [guidelines for contributing
code](https://swift.org/contributing/#contributing-code).

To be a truly great community, [Swift.org](https://swift.org/) needs to welcome
developers from all walks of life, with different backgrounds, and with a wide
range of experience. A diverse and friendly community will have more great
Expand All @@ -95,8 +22,9 @@ code of conduct defined by the Contributor Covenant. This document is used
across many open source communities, and we think it articulates our values
well. For more, see the [Code of Conduct](https://swift.org/code-of-conduct/).

## License

See [https://swift.org/LICENSE.txt](https://swift.org/LICENSE.txt) for license information.
## Code of Conduct

See [`LICENSE-vendored.md`](https://github.com/apple/swift-for-wasm-examples/blob/main/LICENSE-vendored.md) for exact licenses of code vendored in this repository.
Like all Swift.org projects, we would like these example projects to foster a diverse and friendly
community. We expect contributors to adhere to the [Swift.org Code of
Conduct](https://swift.org/code-of-conduct/).
10 changes: 10 additions & 0 deletions WebGPUDemo/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
xcode_trim_whitespace_on_empty_lines = true
5 changes: 5 additions & 0 deletions WebGPUDemo/.sourcekit-lsp/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"swiftPM": {
"swiftSDK": "swift-DEVELOPMENT-SNAPSHOT-2025-06-03-a_wasm"
}
}
18 changes: 18 additions & 0 deletions WebGPUDemo/.swift-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"version": 1,
"lineLength": 120,
"indentation": {
"spaces": 2
},
"lineBreakBeforeEachArgument": true,
"indentConditionalCompilationBlocks": false,
"prioritizeKeepingFunctionOutputTogether": true,
"rules": {
"AlwaysUseLowerCamelCase": false,
"AmbiguousTrailingClosureOverload": false,
"NoBlockComments": false,
"OrderedImports": true,
"UseLetInEveryBoundCaseVariable": false,
"UseSynthesizedInitializer": false
}
}
33 changes: 33 additions & 0 deletions WebGPUDemo/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions WebGPUDemo/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// swift-tools-version: 6.1

import PackageDescription

let package = Package(
name: "WebGPUDemo",
dependencies: [
.package(
url: "https://github.com/swiftwasm/WebAPIKit.git",
branch: "main",
),
.package(
url: "https://github.com/swiftwasm/JavaScriptKit.git",
branch: "main",
),
],
targets: [
.executableTarget(
name: "WebGPUDemo",
dependencies: [
.product(name: "JavaScriptKit", package: "JavaScriptKit"),
.product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
.product(name: "DOM", package: "WebAPIKit"),
.product(name: "WebGPU", package: "WebAPIKit"),
],
)
]
)
17 changes: 17 additions & 0 deletions WebGPUDemo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# WebGPU Example

Install a development snapshot and Swift SDK for Wasm by following
https://www.swift.org/documentation/articles/wasm-getting-started.html.

Build with the installed SDK using JavaScriptKit's `PackageToJSPlugin` plugin. Make sure to update
the Swift SDK to the installed version.
```
swift package --swift-sdk swift-DEVELOPMENT-SNAPSHOT-2025-06-03-a_wasm js --use-cdn
```

Start a HTTP server with eg. `python -m http.server` or `npx serve`. And then open
http://localhost:8000 to view the render of Swift using WebGPU.

> [!NOTE]
> If using an editor with SourceKit-LSP, make sure to update `.sourcekit-lsp/config.json` with the
> Swift SDK used in your build command.
7 changes: 7 additions & 0 deletions WebGPUDemo/Resources/SwiftLogo/Swift3DLogo.mtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
newmtl Swift3DLogo:mat_swift3Dlogo
illum 4
Kd 0.00 0.00 0.00
Ka 0.00 0.00 0.00
Tf 1.00 1.00 1.00
Ni 0.00
map_Ka T_M_swiftLogo_BaseColor.png
Loading