> ## Documentation Index
> Fetch the complete documentation index at: https://developer.sanas.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Processor State Handling

> Wait for kReady before sending audio — via callback or polling

A processor connects to the Sanas cloud asynchronously. You must wait for `kReady` before sending audio. If you call `ProcessSamples` before the processor is ready, the output buffer is filled with silence.

## States

| State           | Meaning                                                                |
| --------------- | ---------------------------------------------------------------------- |
| `kInitializing` | Connecting to the server — do not send audio yet.                      |
| `kReady`        | Connected and ready — safe to call `ProcessSamples`.                   |
| `kFailed`       | Connection or processing error. Destroy and recreate the processor.    |
| `kDisconnected` | Was connected; the connection dropped. Destroy and recreate if needed. |
| `kUnknown`      | Initial state before connection begins.                                |

## Option A — State callback (recommended)

Pass a `ProcessorStateCallback` when creating the processor. It fires on a background thread — keep it fast and thread-safe.

```cpp theme={null}
std::atomic<bool> ready{false}, failed{false};

auto onState = [&](ProcessorState s, std::string reason) {
    if (s == ProcessorState::kReady)          ready  = true;
    else if (s == ProcessorState::kFailed ||
             s == ProcessorState::kDisconnected) failed = true;
};

auto p = sdk->CreateAudioProcessor(params, rc, onState);
while (!ready && !failed)
    std::this_thread::sleep_for(std::chrono::milliseconds(50));
```

## Option B — Polling

Useful if you prefer not to use callbacks.

```cpp theme={null}
// Instant check
if (processor->GetState() == ProcessorState::kReady) { /* ... */ }

// Drain all queued state changes (non-blocking)
ProcessorStateChange change;
while (processor->GetNextStateChange(change))
    handle(change.state, change.reason);

// Block until the next change (use a dedicated monitor thread)
if (processor->WaitForStateChange(change, /*timeoutMs=*/5000)) { /* ... */ }
```

<Warning>Do not call `WaitForStateChange` from your audio thread. Use a dedicated monitor thread or the callback approach instead.</Warning>
