# LocalAudioChannel

A locally-rendered sound: only the local player hears it.

Source: https://socketsvc.vercel.app/api/client/LocalAudioChannel
<Callout title="Generated from source">
  Interface `com.socketsvc.client.api.LocalAudioChannel` — generated from [LocalAudioChannel.java](https://github.com/HippoDev03/SocketSVC/blob/main/client/common/src/main/java/com/socketsvc/client/api/LocalAudioChannel.java). Edit the Javadoc in the Java source, then run `pnpm gen:api`.
</Callout>

```java
package com.socketsvc.client.api;

public interface LocalAudioChannel { ... }
```

A locally-rendered sound: only the local player hears it. Never sent over the network, so it
has nothing to do with the voice connection or any other player's microphone - use this for
things like a client-side ambience mod or a personal 3D notification sound.

## Methods

### getId

```java
UUID getId()
```

### play

```java
void play(short[] pcm)
```

Plays one 20 ms frame: 48 kHz, mono, signed 16-bit PCM, exactly 960 samples.

**Does not block and does not pace.** A short queue sits behind it to absorb ordinary
jitter, and a frame offered when that queue is full is _refused_ - so a caller that
hands over frames faster than 20 ms of sound per 20 ms of time loses the surplus rather than
building latency nobody can see. A frame of the wrong length is refused for the same reason:
playing it would play it at the wrong speed.

Which makes `#queued()` the thing to pace against, not a timer. See its note.

### queued

```java
int queued()
```

How many frames this channel is still holding, of the `#capacity()` it can.

The clock for anything feeding a continuous stream. A film, a radio, anything that
decodes ahead of itself has to be held back by something, and the only honest measure of
"far enough ahead" is how much the mixer has not played yet. Feed while this is below a
frame or two of target and wait while it is not, and nothing is ever refused.

Pacing against a wall clock instead is what this replaces, and it does not work: two
clocks that agree on the rate still disagree on the phase, and the difference accumulates
into exactly the surplus `#play` has to throw away.

### capacity

```java
int capacity()
```

The most `#queued()` can be. A frame offered past it is refused.

### isClosed

```java
boolean isClosed()
```

### close

```java
void close()
```

Stops playback and releases the channel; further `#play` calls are ignored.