# Crystal LipSync Profile

`CrystalLipSyncProfile` is a `ScriptableObject` used to share lip-sync analysis tuning across multiple characters.

<figure><img src="https://1935854846-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuciaAIoc6XDGWTpXdIP7%2Fuploads%2F1pp2A1SbXZ166VjNzX6Y%2Fimage.png?alt=media&#x26;token=d0d8e776-1add-43ca-b51e-490878bedee5" alt=""><figcaption></figcaption></figure>

It lets you define one reusable profile for:

* Volume gate behavior
* Overall sensitivity
* Smoothing response (attack/release)
* Per-viseme multipliers

This is useful when several characters have similar voice traits and should behave consistently.

***

### Create a Profile Asset

In Unity:

1. Open the Project window.
2. Right-click in your desired folder.
3. Select **Create → Crystal LipSync → Lip Sync Profile**.

Unity creates a `LipSyncProfile` asset (from `CrystalLipSyncProfile`).

***

### Inspector Fields

### Volume

* **Volume Threshold** (`0.0001` to `0.1`, default `0.005`)
  * Minimum RMS level before visemes begin opening.
  * Lower values react to quieter audio; higher values keep mouth closed longer.
* **Sensitivity** (`0.1` to `30`, default `5`)
  * Global gain applied to volume-to-viseme mapping.
  * Increase for quiet recordings, reduce for overly strong mouth motion.

### Smoothing

* **Smoothing Attack** (`1` to `80`, default `30`)
  * How quickly visemes rise when speech appears.
  * Higher values feel more responsive.
* **Smoothing Release** (`1` to `40`, default `15`)
  * How quickly visemes fall back toward rest.
  * Higher values close faster between phonemes.

### Per-Viseme Multipliers

* An array of `15` multipliers (one per viseme).
* Default is `1.0` for all entries.
* Values:
  * `> 1.0` amplify that viseme
  * `< 1.0` suppress that viseme
  * `1.0` leaves it unchanged

Viseme order:

`SIL, PP, FF, TH, DD, KK, CH, SS, NN, RR, AA, E, I, O, U`

***

### How It Is Applied at Runtime

When a profile is assigned to `CrystalLipSyncController`:

1. Controller reads `VolumeThreshold`, `Sensitivity`, `SmoothingAttack`, and `SmoothingRelease` from the profile.
2. Analyzer computes viseme weights.
3. Each viseme weight is multiplied by `profile.GetVisemeMultiplier(index)`.

If no profile is assigned, the controller uses its own local inspector settings and no profile multipliers.

***

### API Reference

`CrystalLipSyncProfile` exposes:

* `VolumeThreshold` (read-only)
* `Sensitivity` (read-only)
* `SmoothingAttack` (read-only)
* `SmoothingRelease` (read-only)
* `GetVisemeMultiplier(int visemeIndex)`

`GetVisemeMultiplier` returns:

* The stored multiplier for valid indices
* `1.0` as a safe fallback when index is out of range or array state is invalid

***

### Validation Behavior (`OnValidate`)

The profile automatically enforces the viseme multiplier array size to match `VisemeConstants.VisemeCount` (`15`).

* If the array is missing or wrong length, it is rebuilt.
* Existing values are preserved where possible.
* New or missing entries default to `1.0`.

This keeps profiles stable if viseme array data is edited manually or serialized data changes.

***

### Recommended Workflow

1. Tune one character until lip sync quality looks correct.
2. Save those values in a `CrystalLipSyncProfile`.
3. Assign the same profile to other similar characters.
4. Adjust only per-viseme multipliers for character-specific mouth shape differences.

***

### Troubleshooting

### Profile seems ignored

* Ensure `CrystalLipSyncController` has the profile assigned in **Profile (Optional)**.
* If assigned at runtime, verify `SetProfile(...)` is called on the active controller instance.

### Mouth movement too weak

* Lower **Volume Threshold**.
* Increase **Sensitivity**.
* Raise key vowel multipliers (`AA`, `E`, `I`, `O`, `U`).

### Mouth movement too jittery

* Increase **Smoothing Attack** and/or **Smoothing Release**.
* Slightly raise **Volume Threshold** to reduce low-level noise activation.

### One phoneme family looks exaggerated

* Reduce that viseme's multiplier toward `1.0`.
* Rebalance neighboring visemes instead of globally lowering sensitivity.
