<!-- Page: https://rustic-game-engine.pages.dev/docs/api/audio/get-input-devices -->

# Audio.get_input_devices()

[Audio](https://rustic-game-engine.pages.dev/markdown/api/audio.md)

## Compatibility

**Supported languages:** C, C++, C#, Python, JavaScript, Lua 5.4, Luau, Java, PHP and HTML/inline JavaScript (binding spellings and return shapes differ).

Native devices and microphone input require Windows. Game-output recording and the mixer can run headlessly. Other operating systems do not supply the Windows native device backend.

The signature below is the shared reference notation; language examples show the actual binding syntax. Question marks mark optional arguments and explicit defaults are shown where recorded. Do not copy reference notation as a typed declaration.

See [Feature status and compatibility](https://rustic-game-engine.pages.dev/markdown/reference/compatibility.md) for API 1.0/1.1 and per-method restrictions. Engine release tags and Docs v0.1 are independent versions.

## Signature

`Audio.get_input_devices()`

## Setup and usage

These engine-owned services work in Lua 5.4, Luau, JavaScript, Python, C, C++, C#, Java, PHP, and HTML inline JavaScript. Follow [Use gameplay actions](https://rustic-game-engine.pages.dev/markdown/guides/gameplay-actions.md) to create and attach a script, install external toolchains, and choose the correct language binding. PHP and HTML scripts belong under `ui/`; CSS alone runs no gameplay code.

The signatures and complete example below use JavaScript. Attach a JavaScript Object Component script to the specified target and press **Play**. Globals are supplied by the engine. Schedule actions from `Start` or a callback, rather than at script top level. Native languages use typed options and their own builder conventions; see the guide's language bindings.

## Parameters

This call has no arguments.

## Return and timing

Returns a list of device records containing string id and name fields. Empty lists are valid on hosts without devices. Enumeration currently requires Windows; headless platforms return an empty list.

## Execution behavior

Core write timing differs between immediate Lua host calls, deferred JavaScript/Web commands and external SDK query flushes. Scheduled actions advance with the scene clock; synchronous queries evaluate at the call. Follow [execution rules](https://rustic-game-engine.pages.dev/markdown/guides/scripting.md#when-mutations-take-effect) and the return/timing notes for this category.

## Language examples

Choose one snippet at a time and place it inside your language's Start/on_start callback. These are independent examples; each creates its own handles or builders. Follow [Gameplay language bindings](https://rustic-game-engine.pages.dev/markdown/guides/gameplay-actions/language-bindings.md) for imports and callback registration. Python must import the modules used in its snippet from rustic; C# uses using static Rustic; Java examples belong inside a Rustic subclass; PHP callbacks declare global $rustic. HTML snippets go inside an inline script in a ui/ HTML asset.

Use an anchored Part for transform and effect examples, an unanchored collidable Part for forces, and a perspective camera named Camera for camera examples. Create Target for follow examples. Audio examples require assets/music.ogg in the Play snapshot. Replace scene paths with those listed by Game.scene.List(). Animation playback and sequence-animation examples require the Reveal fixture on the [Animation page](https://rustic-game-engine.pages.dev/markdown/api/animation.md); marker callbacks also require its Halfway marker. Run clock controls separately; a paused clock cannot advance a timer.

C callback examples use these file-scope functions before on_start:

```c
static void on_done(void) { rustic.log("info", "done"); }
static void on_sample(RusticValue value) { (void)value; rustic.log("info", "sample received"); }
static void on_event(const RusticValue *args, size_t count) {
    (void)args; (void)count; rustic.log("info", "event received");
}
```

Native device enumeration and selection require the Windows player. Select an ID from the current enumeration of the same direction; refresh after hardware changes.

### Lua 5.4

```lua
local devices = Audio.get_input_devices()
for _, device in ipairs(devices) do
  print(device.id, device.name)
end
```

### JavaScript

```javascript
const devices = Audio.get_input_devices();
print(JSON.stringify(devices));
```

### Python

```python
devices = Audio.get_input_devices()
for device in devices:
    rustic.log("info", device["id"] + ": " + device["name"])
```

### C++

```cpp
auto devices = Audio::get_input_devices();
for (const auto &device : devices.array()) {
  rustic.log("info", device.at("id").string() + ": " + device.at("name").string());
}
```

### C#

```csharp
var devices = Audio.get_input_devices();
foreach (var device in devices.EnumerateArray()) {
  rustic.log("info", device.GetProperty("id").GetString() + ": " + device.GetProperty("name").GetString());
}
```

### Luau

```lua
local devices = Audio.get_input_devices()
for _, device in ipairs(devices) do
  print(device.id, device.name)
end
```

### C

```c
RusticAudioDevices devices = Audio.get_input_devices();
for (size_t i = 0; i < devices.count; ++i) {
  rustic.log("info", devices.items[i].name);
}
```

### Java

```java
var devices = (java.util.List<?>)Audio.get_input_devices();
for (var item : devices) {
  var device = (java.util.Map<?, ?>)item;
  rustic.log("info", device.get("id") + ": " + device.get("name"));
}
```

### PHP

```php
$devices = Audio::get_input_devices();
foreach ($devices as $device) {
  $rustic->log("info", $device["id"] . ": " . $device["name"]);
}
```

### HTML / inline JS

```javascript
const devices = Audio.get_input_devices();
print(JSON.stringify(devices));
```

## Shared Audio constraints

Native device methods work in the Windows player and are available in every supported scripting language. Lists are snapshots: another enumeration of the same direction invalidates older IDs. IDs belong to the current Play scene; do not save them in project settings. Output and input IDs are not interchangeable, and names can be duplicated. Selection is shared by scripts in the scene and resets on Stop/new Play.

Selecting on a headless platform, selecting an unknown/stale ID, a missing system default or a native driver failure raises a script error. Check the Console, refresh the list after hardware changes, and select a valid ID or null. Device removal is not automatically recovered.

Use nil in Lua/Luau, None in Python and NULL in C for the system default. Java and C require an explicit argument; other bindings also allow omitting it. C lists use RusticAudioDevices (count and items[i].id/name) and last until the next callback; C++ returns a RusticValue array, C# a JsonElement array, Java a list of maps and PHP associative arrays.

## Errors and debugging

Read the constraints above and the Console diagnostic. Invalid types, non-finite values, stale targets or unavailable native services can fail validation. A failed callback disables the behavior; a failed source reload keeps the last good instance. Exact error messages depend on the language adapter. See [Troubleshooting](https://rustic-game-engine.pages.dev/markdown/troubleshooting.md).

## Related APIs

- [Audio.get_output_devices()](https://rustic-game-engine.pages.dev/markdown/api/audio/get-output-devices.md)
- [Audio.set_output_device()](https://rustic-game-engine.pages.dev/markdown/api/audio/set-output-device.md)
- [Audio.set_input_device()](https://rustic-game-engine.pages.dev/markdown/api/audio/set-input-device.md)
- [Audio.load()](https://rustic-game-engine.pages.dev/markdown/api/audio/load.md)
- [audio.load()](https://rustic-game-engine.pages.dev/markdown/api/audio/audio-load.md)

[All audio APIs](https://rustic-game-engine.pages.dev/markdown/api/audio.md)
