This release primarily focuses on being the final major API breakage before 1.0, supporting Mac, improving the story
around thread safety, and closing the gaps around loading audio from non-file sources.
It is anticipated that there will be no more major API breakage before 1.0, and hopefully no more API breakage at all.
In some ways, this release is a 1.0 RC, though there are yet a few features left before 1.0 can happen.
If you find this library useful, [I have a GitHub Sponsors](https://github.com/sponsors/ahicks92). This is by no means
required. That said, this release required buying a Mac, so I have now put money into Synthizer in addition to time.
Stability of this Release
This is a weekend project and this release contains a lot of manually tested new features, so it will be astonishing if
you don't find bugs. I generally do a good job fixing them within a week, so please [report them against the Synthizer
repository](https://github.com/synthizer/synthizer/issues). There will likely be a few point releases before all of the
bugs iron themselves out.
Automated testing is on the wishlist, but is infeasible due to lack of time and is generally a massive undertaking.
New Features in this Release
Mac and Arm Support
Synthizer now supports Os X, both the Python bindings and the C library. Unlike other platforms, you will need to
install XCode for the Python bindings to work.
As a consequence, ARM is now also supported and testing is done locally on an M1 Mac.
Unfortunately, due to Apple and GitHub actions limitations, Synthizer is unable to support older versions of Mac
reliably. Testing currently happens against Big Sur locally, and CI builds against catalina. In general Synthizer will
make an effort to support the latest major release of OS X.
A New Manual
This manual has been almost entirely rewritten, and the concepts and Python tutorial sections now contain a lot more
content. You can now find more detailed information on common patterns, 3D audio, and more. Additionally, many
sections have been split into more targeted and smaller sections, which should make things easier to find.
If you're using the Python bindings, you probably still need to read the source code, but there is now more than one
tutorial.
Support for Custom Streams and In-memory Assets
Synthizer now supports:
- [Loading from custom streams](../concepts/custom_streams.md).
- Loading buffers from in-memory encoded data via `syz_createBufferFromEncodedData`.
- Loading buffers from application-generated float arrays via `syz_createBufferFromFloatArray`.
Libsndfile Support
Synthizer can now [load Libsndfile](../concepts/libsndfile.md). This adds support for all formats Libsndfile supports,
most notably Ogg, and works with all forms of getting data into Synthizer save custom streams that don't implement
seeking functionality. See the linked section for more info.
Due to licensing incompatibilities, this can't be statically linked and you will need to distribute the shared object
alongside your app.
Ability to Configure Objects to Play Until Finished
Synthizer now has a concept of [lingering](../concepts/lingering.md), which can be used to configure Synthizer
generators and sources to stick around until they've finished playing rather than dying immediately on deletion. This
replaces home-grown solutions using events with a built-in solution for fire-and-forget situations where you simply want
to play one sound and don't want to have to track it yourself.
Reference-counted Handles
For lower-level languages, Synthizer now supports reference counted handles. This allows for implementing things like
the C++ `shared_ptr` or Rust's `Arc`, where objects may be being used by multiple threads and must not be deleted until
all threads are finished.
Thread-safe Event Handling
As explained in [the new section on events](../concepts/events.md), Synthizer events now take temporary references on
the handles they refer to. This allows event handling loops to run concurrently with handle deletion without
invalidating handles out from under the event handler. This increased lifetime only extends until `syz_eventDeinit`,
but it is possible to use `syz_handleIncRef` to hold onto the handle for longer if desired.
No Property Type Overloading
Synthizer properties are always only of one type by constant. For example `SYZ_P_POSITION` is always a d3. This
required renaming `SYZ_P_POSITION` on generators to `SYZ_P_PLAYBACK_POSITION`.
The Effects API Is No Longer Provisional
At this point, it's not going to change again, so we have removed the provisional notices in this manual.
Incompatibilities in this Release
- You now destroy handles with `syz_handleDecRef` because they're reference counted.
- In Python, `.destroy` is now `.dec_ref`. Python will likely take advantage of reference counting in future.
- `syz_echoSetTaps` is now `syz_globalEchoSetTaps`.
- All of the `SYZ_P_XXX` properties on the context for configuring defaults for the 3D environment have a default
prefix, e.g. `SYZ_P_DEFAULT_PANNER_STRATEGY`. This was done to make room for future extensions.
- All generators with a position now use `SYZ_P_PLAYBACK_POSITION`.
- Configuring logging and libsndfile etc. is now done through a struct passed to a new `syz_initializeWithConfig`. All
functions for configuring these values have been dropped.
- The union containing unused/empty event payloads has been dropped from `syz_Event` because they're unused/empty
payloads.
- To bindings developers: Synthizer currently doesn't contain unions anymore, but they'll come back in future.
- It is now necessary to call `syz_eventDeinit` on events when you're done with them. Failure to do so will leak
handles