Skip to content
SoundSyncAudio software platform

Package guide

JUCE 0.7.3 Package

Processor-owned licensing, activation UI, audio gating, and Store/My Products for JUCE source builds.

Licensing lives in the processor

The current JUCE package is a complete source integration with a processor-owned licensing runtime and editor component. Own SoundSyncJuceProcessorLicense for the processor lifetime. The editor attaches the activation UI; it must not be the only place that refreshes or enforces licensing.

Windows package targets produce VST3. Apple package targets produce VST3 and AU. These build targets are not a claim that every host or OS version has been runtime-tested.

Offline access and startup

JUCE 0.7.3 supports signed offline access for the grace period selected in product Access settings, through 90 days. A prior successful activation or validation and the matching package verification keys are required. Startup uses a verified unexpired grant or online authorization. Zero, disabled, missing or expired grace requires online authorization; confirmed denial or deactivation locks access. Regenerate and rebuild older plugins to use this release.

SoundSync

Integrate the current package

  1. Generate for the saved product

    Download the current Windows or Apple 0.7.3 source package. Read START_HERE_FIRST.txt, README.md, Docs/LicensingSecurity.md, and Docs/OfflineGrace.md.

  2. Add the CMake target

    Load your JUCE checkout first, enable SOUNDSYNC_BUILD_JUCE_COMPONENTS, add the package subdirectory, and link soundsync_juce.

  3. Use the licensed processor base

    Derive from SoundSyncLicensedAudioProcessor and preserve your buses, parameters, state serialization, and other processor overrides.

  4. Move your DSP callbacks

    Rename processBlock to processLicensedBlock and custom bypass callbacks to processLicensedBlockBypassed. The base owns final float, double, and bypass entry points, checking before and after DSP.

  5. Attach the editor

    Keep SoundSyncJuceEditorAttachment as the last editor member and initialize it with the editor and processor.soundSyncLicense(). It manages activation, Store/My Products, bounds, and portal closing.

  6. Test without an editor

    Exercise unauthorized startup, MIDI cleanup, sidechains, and continuing revalidation with the editor closed.

  7. Rebuild old releases

    Replacing source does not update compiled binaries. Rebuild, sign where applicable, test, and distribute the updated product.

SoundSync

CMake integration

CMake integration
set(SOUNDSYNC_BUILD_JUCE_COMPONENTS ON CACHE BOOL "" FORCE)
add_subdirectory(ThirdParty/SoundSyncJuce)
target_link_libraries(YourPluginTarget PRIVATE soundsync_juce)

SoundSync

Recommended processor integration

Recommended processor integration
#include "soundsync/juce/SoundSyncLicensedAudioProcessor.h"

class PluginProcessor : public soundsync::juce::SoundSyncLicensedAudioProcessor
{
public:
    PluginProcessor()
      : SoundSyncLicensedAudioProcessor(BusesProperties()
          .withOutput("Output", juce::AudioChannelSet::stereo(), true)) {}

    void processLicensedBlock(juce::AudioBuffer<float>& buffer,
                              juce::MidiBuffer& midi) override
    {
        // Your DSP; retain the other AudioProcessor overrides.
    }
};

SoundSync

Editor attachment

Editor attachment
#include "soundsync/juce/SoundSyncJuceEditorAttachment.h"

// Last editor member:
soundsync::juce::SoundSyncJuceEditorAttachment soundSync;

// Editor constructor initializer:
// soundSync(*this, processor.soundSyncLicense())

Custom processor bases

If your existing processor must retain a custom base class, own SoundSyncJuceProcessorLicense for the processor lifetime and attach SoundSyncJuceDropIn to that same instance. Guard every float, double, and bypass callback before AND after DSP using audioGate()->processOutputs(buffer, midi, getTotalNumOutputChannels()); return when the guard reports locked access.

Pass the output channel count, not all inputs or sidechains. The older buffer-only guard is not suitable for arbitrary host buffers. The recommended licensed base supplies these guards without manual startup, timers, or an extra UI unlock boolean.

Keep blocking work off the audio thread

The guard reads the native access gate and clears unauthorized output. Do not make HTTP requests, read files, activate, validate, or deactivate from processBlock. The processor-owned worker performs renewal independently of editor visibility.

SoundSyncJucePublicState::mayOpenProduct is appropriate for protected controls, preset loading, and exports. A UI boolean is not a replacement for the processor audio guard.

SoundSync

Package areas

PathResponsibility
START_HERE_FIRST.txtCurrent installation and release requirements
CMakeLists.txt and modules/soundsync_juceBuild target and JUCE module integration
include/soundsync/juceProcessor, client, public-state, audio-gate, and UI interfaces
srcJUCE runtime and components
nativeJUCE package native authority and local machine state
examplesPlugin and standalone wiring references
DocsSecurity, setup, storage, lifecycle, customer access, troubleshooting, and release checks

Login, serials, and customer browsing

Customer login exchanges account credentials for a hosted customer token before activation. The runtime does not persist the account password or customer session token. The protected machine activation cache is separate from Store/My Products browsing.

Opening Store or My Products does not deactivate the machine. A portal session expiring does not by itself authorize or revoke audio; diagnose the licensing state separately.

Activation and device release

Account login and serial activation are distinct customer paths. A serial requiring ownership proof can enter the email-verification flow; an existing account should sign in rather than silently creating another identity. Saved machine credentials restore without consuming a new activation while valid.

Deactivation locks locally immediately and persists the intent before contacting the server. Only confirmed server deactivation proves the device slot was released. Transient renewal failures retry with backoff; a confirmed denial or deactivation does not silently reactivate.

Place Store and My Products where they fit

The editor attachment provides packaged launchers. Custom controls can call openStore(), openMyProducts(), and closeStorefront(), or use createStoreButton() and createMyProductsButton() with the supported style settings. Hide built-in navigation when providing your own controls; do not duplicate account or catalog logic.

The renewal worker remains processor-owned and independent of the editor. Its validation interval is clamped to 5 through 120 seconds; renewal cannot be disabled. Optional licenseProcessingChanged callbacks run on the audio thread and must be realtime-safe.

Release checks

Test fresh startup, saved credentials, unavailable network, expired/revoked access, device limits, deactivation, multiple instances, float/double/bypass processing, and editor-closed operation. Check product ID and branding after regeneration.

Credentials and enforcement shipped in client software can be extracted or modified. Native enforcement raises the integration barrier; it is not a piracy-proof guarantee. Keep developer account tokens and partner secrets out of distributed plugins.

This guide describes the current implementation and package instructions. Source review does not certify every host, operating system, provider delivery, or payment lifecycle. Test the exact build and environment you intend to release.

SoundSync

JUCE login activation

The JUCE login activation screen shows the branded activation-required state and customer account path.

JUCE login activation

SoundSync

JUCE serial validation

The JUCE serial validation screen shows serial entry, customer email capture, validation action, and activation-required context.

JUCE serial activation

SoundSync

JUCE Store catalog

The JUCE Store screen shows product browsing, customer navigation, and the in-app storefront surface connected to SoundSync product records.

JUCE in-app store catalog

SoundSync

JUCE product detail

The JUCE product detail screen shows product artwork, product information, and customer navigation through the connected storefront surface.

JUCE in-app product detail

SoundSync

JUCE Store and My Products

The JUCE customer screens show in-plugin product browsing, product detail, ownership, serial state, and device deactivation controls.

JUCE My Products

Retrieve the generated ZIP through its private link

Package preparation returns a short-lived download link. Download the ZIP before the current 300-second link expires; request a fresh link rather than sharing an expired one. Generation reuses an appropriate private cached package only when its source, credentials, and branding match.

A busy generator asks you to retry. A storage/configuration error is not a valid ZIP. Keep the downloaded product configuration private, and regenerate affected packages after credential or bundled-brand changes.

SoundSync

Package response contract

Package links and uploads

JSON response shape, expiry, and retry states.

SoundSync

JUCE package management calls

Use the authenticated developer session and your own positive integer product ID. Download requires product_files.view; generation requires product_files.manage, plus product access and package-channel permission. Generation can provision or recover product credentials and record package activity; it is not a read-only health check. Keep the returned URL private.

GET /api/developer/products/:productId/juce-package

Prepare the maintained product source package

Auth
Account Bearer JWT
Scope
Workspace permissions and product assignments are checked.
Request fields
  • query platform: value
  • query releaseChannel: value
Returns
200 JSON { url, filename, expiresIn: 300 }; follow the private link to download.
Notes
Prepares or reuses a product-specific source ZIP and returns a private download link valid for 300 seconds; it is not metadata-only inspection or a read-only health check. All package-link routes can provision or recover product credentials and record package/download activity. GET and download aliases require product_files.view; POST /generate requires product_files.manage. Product assignment and package-channel access also apply. Keep the account token and returned link private. A regenerated package does not update compiled customer plugins: rebuild, test and redistribute. See /docs/juce/package-updates for signed offline-grace readiness and upgrade steps.
Request, response and error reference

Query and header parameters

[
  {
    "name": "platform",
    "in": "query",
    "required": false,
    "schema": {
      "enum": [
        "windows",
        "macos"
      ]
    }
  },
  {
    "name": "releaseChannel",
    "in": "query",
    "required": false,
    "schema": {
      "const": "stable"
    }
  }
]

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri"
    },
    "filename": {
      "type": "string"
    },
    "expiresIn": {
      "const": 300
    }
  },
  "required": [
    "url",
    "filename",
    "expiresIn"
  ],
  "additionalProperties": true
}

Documented failures: 503.

GET /api/developer/products/:productId/juce-package/download

Retrieve through the compatible download route

Auth
Account Bearer JWT
Scope
Workspace permissions and product assignments are checked.
Request fields
  • query platform: value
  • query releaseChannel: value
Returns
200 JSON { url, filename, expiresIn: 300 }. This route delegates to the maintained source-package workflow.
Notes
Prepares or reuses a product-specific source ZIP and returns a private download link valid for 300 seconds; it is not metadata-only inspection or a read-only health check. All package-link routes can provision or recover product credentials and record package/download activity. GET and download aliases require product_files.view; POST /generate requires product_files.manage. Product assignment and package-channel access also apply. Keep the account token and returned link private. A regenerated package does not update compiled customer plugins: rebuild, test and redistribute. See /docs/juce/package-updates for signed offline-grace readiness and upgrade steps.
Request, response and error reference

Query and header parameters

[
  {
    "name": "platform",
    "in": "query",
    "required": false,
    "schema": {
      "enum": [
        "windows",
        "macos"
      ]
    }
  },
  {
    "name": "releaseChannel",
    "in": "query",
    "required": false,
    "schema": {
      "const": "stable"
    }
  }
]

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri"
    },
    "filename": {
      "type": "string"
    },
    "expiresIn": {
      "const": 300
    }
  },
  "required": [
    "url",
    "filename",
    "expiresIn"
  ],
  "additionalProperties": true
}

Documented failures: 503.

POST /api/developer/products/:productId/juce-package/download

Retrieve through the compatible download route

Auth
Account Bearer JWT
Scope
Workspace permissions and product assignments are checked.
Request fields
  • platform: windows | macos
  • releaseChannel: "stable"
Returns
200 JSON { url, filename, expiresIn: 300 }. This route delegates to the maintained source-package workflow.
Notes
Prepares or reuses a product-specific source ZIP and returns a private download link valid for 300 seconds; it is not metadata-only inspection or a read-only health check. All package-link routes can provision or recover product credentials and record package/download activity. GET and download aliases require product_files.view; POST /generate requires product_files.manage. Product assignment and package-channel access also apply. Keep the account token and returned link private. A regenerated package does not update compiled customer plugins: rebuild, test and redistribute. See /docs/juce/package-updates for signed offline-grace readiness and upgrade steps.
Request, response and error reference

Request (application/json)

{
  "type": "object",
  "properties": {
    "platform": {
      "enum": [
        "windows",
        "macos"
      ]
    },
    "releaseChannel": {
      "const": "stable"
    }
  },
  "additionalProperties": true
}

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri"
    },
    "filename": {
      "type": "string"
    },
    "expiresIn": {
      "const": 300
    }
  },
  "required": [
    "url",
    "filename",
    "expiresIn"
  ],
  "additionalProperties": true
}

Documented failures: 503.

POST /api/developer/products/:productId/juce-package/generate

Generate from current saved product settings

Auth
Account Bearer JWT
Scope
Workspace permissions and product assignments are checked.
Request fields
  • platform: windows | macos
  • releaseChannel: "stable"
Returns
200 JSON { url, filename, expiresIn: 300 }.
Notes
Prepares or reuses a product-specific source ZIP and returns a private download link valid for 300 seconds; it is not metadata-only inspection or a read-only health check. All package-link routes can provision or recover product credentials and record package/download activity. GET and download aliases require product_files.view; POST /generate requires product_files.manage. Product assignment and package-channel access also apply. Keep the account token and returned link private. A regenerated package does not update compiled customer plugins: rebuild, test and redistribute. See /docs/juce/package-updates for signed offline-grace readiness and upgrade steps.
Request, response and error reference

Request (application/json)

{
  "type": "object",
  "properties": {
    "platform": {
      "enum": [
        "windows",
        "macos"
      ]
    },
    "releaseChannel": {
      "const": "stable"
    }
  },
  "additionalProperties": true
}

HTTP 200 response (application/json)

{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "format": "uri"
    },
    "filename": {
      "type": "string"
    },
    "expiresIn": {
      "const": 300
    }
  },
  "required": [
    "url",
    "filename",
    "expiresIn"
  ],
  "additionalProperties": true
}

Documented failures: 503.

Signed offline access follows your product settings

Choose the grace period in product creation > Access. Successful activation or validation returns a signed grant bound to the product, activation and device. The period starts at that successful online check, not the first failed connection. The package bundles only public verification keys. Reopening the plugin or losing connectivity does not extend its signed expiry. An earlier entitlement or subscription access deadline shortens the grant.

The processor enforces access with the editor closed, including float, double and bypass processing. Confirmed revoked, refunded or deactivated access must lock the product rather than renew grace. A disconnected device learns about later server changes on reconnect or when its existing grant expires.

Regenerate the Windows or Apple source package, check manifest offlineAccess, rebuild and test your product. Existing compiled plugins are not upgraded automatically. Windows VST3 and Ableton Live 10.1.43 fixture tests cover offline playback, expiry, saved-project restart and WAV export; Apple Keychain/AU and your own product binaries require target-host testing.

offlineAccess: true describes bundled verification capability, not an active customer license or an enabled product policy. An older unsigned cache needs successful online activation or validation before offline use. After rebuilding, distribute the updated binary; replacing a ZIP in the dashboard cannot update customer installations.

Changing Access settings applies on the next successful online validation without a rebuild when the installed package already has the required public keys. A future signer change must be coordinated with replacement public keys in rebuilt clients; never add private signing material to a plugin.

SoundSync

Update an existing JUCE product

Regenerate and update JUCE

Package readiness, saved activations, offline tests, and customer distribution.

Native account login with two-factor authentication

The updated JUCE 0.7.3 and HISE Native C++ 0.5.2 sources support the customer account two-factor challenge. Regenerate the complete package, replace the matching sources and rebuild the plugin; an older installed binary does not acquire this behavior from a documentation or server update.

Sign in with the customer email and password. If two-factor authentication is enabled, the account form changes to Authenticator or recovery code. Enter a current authenticator code or an unused recovery code and choose Verify code. A challenge is not a customer session, entitlement or device activation; the plugin remains locked until verified account login and product/device activation succeed.

An invalid code can be retried. An expired challenge requires signing in again. The challenge lasts up to ten minutes and is kept only in the running native client, not the activation cache, logs or public state. Account passwords, two-factor codes and account session tokens are not saved in the license cache. Do not disable two-factor protection to integrate a plugin.

Use the serial claim helper for ownership verification

beginClaim(serial, email) starts the existing serial ownership-verification flow. Its first argument is the serial/license key, not an arbitrary web claim token. The wire request sends license_key and the current machine identity to POST /api/license/v1/claim.

A pending claim leaves the plugin locked. Keep the pending serial, email and claim ID in the native licensing flow, then use Restore or pollClaim to check /api/license/v1/claim-status. Once the server returns a claim_activation_token, the client makes the final /api/license/v1/activate request for that same serial and machine. A claim email, verified status or HTTP 200 alone does not unlock the plugin or reserve a device slot.

Pending serial/email context survives a restart in the protected cache. A temporary network failure, server error or rate limit during status checking or final activation keeps the claim pending so Restore can retry. A confirmed licensing denial is different and does not create offline permission.

SoundSync

Custom account and claim controls

Run these operations on the licensing worker, never the audio thread
auto pending = client.activateWithAccount(email, password);
if (pending.license.error.reason == "two_factor_required") {
    // Prompt for an authenticator or unused recovery code.
    auto verified = client.activateWithAccount(email, authenticatorOrRecoveryCode);
    // Consume verified.publicState; never unlock from HTTP status alone.
}
// Cancel a pending account challenge and return to password sign-in:
client.activateWithAccount("", "");

auto claim = client.beginClaim(serial, email);
// Restore checks pending ownership and completes activation after verification.
// The ready-made runtime schedules this; custom clients may call:
auto restored = client.restore();

Activation feedback and protected Windows recovery

JUCE 0.7.3 improves activation progress, failure feedback and retries for serial and account activation. On Windows, a damaged product cache can recover after fresh successful online authorization, and a damaged device-identity copy can be restored from its valid protected backup.

Conflicting identities and unreadable deactivation markers remain locked and require support. Do not delete activation proof or deactivation markers to bypass them. Regenerate the matching source package and rebuild your plugin to include the update. The selected Access grace period, signed-grant expiry and local deactivation block still apply; this recovery does not create offline permission.