(Created page with "'''IOAudio2Device''' is a kernel-extension for playing audio. It's interacted with exclusively by CoreAudio, so it can't be used directly if CoreAudio is in the picture. == M...") |
(Not sure why I'm updating this, but I am. The "(Info on this page may not be perfectly accurate)" disclaimer should retroactively apply to any page I edited previously, TBH.) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
'''IOAudio2Device''' is a kernel-extension for playing audio. | '''IOAudio2Device''' is a kernel-extension for playing (and recording?) audio. | ||
It's interacted with exclusively by CoreAudio, so it can't be used directly if CoreAudio is in the picture. | It's interacted with exclusively by CoreAudio, so it can't be used directly if CoreAudio is in the picture. | ||
(Info on this page may not be perfectly accurate) | |||
== Service properties == | |||
The most important ones are "input streams", "output streams" and "controls" which specify which streams/controls the driver provides. | |||
See ioreg dumps for full information. | |||
== Methods == | == Methods == | ||
Line 12: | Line 20: | ||
|- | |- | ||
| 2 || setControlValue || uint32_t ''controlId'', uint32_t ''value'' || - | | 2 || setControlValue || uint32_t ''controlId'', uint32_t ''value'' || - | ||
|- | |||
| 3 || ? acknowledge config change ? || struct IOAudio2DeviceEvent || - | |||
|- | |- | ||
| 4 || setSampleRate || uint64_t ''sampleRate'' (fixed-point 32.32) || - | | 4 || setSampleRate || uint64_t ''sampleRate'' (fixed-point 32.32) || - | ||
Line 53: | Line 63: | ||
|- | |- | ||
| 'cval' || Sent after control value is changed || control id || new value | | 'cval' || Sent after control value is changed || control id || new value | ||
|- | |||
| 'conf' || Sent after any configuration changed (in addition to above notifications) || 0 || ??? | |||
|} | |} | ||
Line 64: | Line 76: | ||
| 0 || Single page? || struct IOAudio2DeviceStatus | | 0 || Single page? || struct IOAudio2DeviceStatus | ||
|- | |- | ||
| | | 0x10000000 + streamId || from service property "io buffer frame size", multiplied by sample size || stream's sound buffer | ||
|} | |} | ||
Note: Typically, streamId is 1 for input (sound recording) and 2 for output (sound playback). | |||
where | |||
<source lang="C"> | <source lang="C"> | ||
struct IOAudio2DeviceStatus { | struct IOAudio2DeviceStatus { | ||
uint64_t | uint64_t bufferSampleStart; // the sample that the stream buffer starts with | ||
uint64_t bufferTime; | uint64_t bufferTime; // the timestamp of the stream buffer's start. (mach_absolute_time) | ||
uint64_t ???; | uint64_t ???; | ||
}; | }; | ||
Line 80: | Line 93: | ||
Once audio is started, the driver periodically reads some data from the output buffer and plays it. It zeroes the data after reading it (so that silence is played if the buffer is being neglected by user-land) | Once audio is started, the driver periodically reads some data from the output buffer and plays it. It zeroes the data after reading it (so that silence is played if the buffer is being neglected by user-land) | ||
Once the driver finishes going over the entire output buffer, it adds the amount of samples in the buffer to '' | Once the driver finishes going over the entire output buffer, it adds the amount of samples in the buffer to ''bufferSampleStart'' and updates ''bufferTime'' to the current time. | ||
The output buffer sample format is typically 16-bit PCM stereo. | The output buffer sample format is typically 16-bit PCM stereo. |
Latest revision as of 23:54, 26 May 2017
IOAudio2Device is a kernel-extension for playing (and recording?) audio.
It's interacted with exclusively by CoreAudio, so it can't be used directly if CoreAudio is in the picture.
(Info on this page may not be perfectly accurate)
Service properties
The most important ones are "input streams", "output streams" and "controls" which specify which streams/controls the driver provides.
See ioreg dumps for full information.
Methods
Selector | Action | Input | Output |
---|---|---|---|
0 | start | - | - |
1 | end | - | - |
2 | setControlValue | uint32_t controlId, uint32_t value | - |
3 | ? acknowledge config change ? | struct IOAudio2DeviceEvent | - |
4 | setSampleRate | uint64_t sampleRate (fixed-point 32.32) | - |
5 | setStreamFormat | uint32_t streamId, struct AudioStreamBasicDescription (officially documented) | - |
6 | setStreamActive | uint32_t streamId, uint32_t active | - |
Notifications
Notifications are registered via IOConnectSetNotificationPort, they are sent on any audio event.
struct IOAudio2DeviceNotification {
<standard message header (ID is unknown, ignored by CoreAudio)>
// note: no NDR
uint32_t refCon; // passed to IOConnectSetNotificationPort
uint32_t numEvents;
IOAudio2DeviceEvent events[numEvents];
};
struct IOAudio2DeviceEvent {
uint32_t id;
uint32_t type; // 4cc, e.g. 'goin'
uint32_t args[6];
};
Some known events are:
Type | Description | Id | Args |
---|---|---|---|
'goin' | Sent after start is called | 0 | - |
'halt' | Sent after end is called | 0 | - |
'prop' | Sent after property is changed | 0 or stream id | property (?), scope (?), 0 (?) |
'cval' | Sent after control value is changed | control id | new value |
'conf' | Sent after any configuration changed (in addition to above notifications) | 0 | ??? |
Mapped memory
The following memory can be mapped via IOConnectMapMemory:
Type | Size | Description |
---|---|---|
0 | Single page? | struct IOAudio2DeviceStatus |
0x10000000 + streamId | from service property "io buffer frame size", multiplied by sample size | stream's sound buffer |
Note: Typically, streamId is 1 for input (sound recording) and 2 for output (sound playback).
where
struct IOAudio2DeviceStatus {
uint64_t bufferSampleStart; // the sample that the stream buffer starts with
uint64_t bufferTime; // the timestamp of the stream buffer's start. (mach_absolute_time)
uint64_t ???;
};
Operation
Once audio is started, the driver periodically reads some data from the output buffer and plays it. It zeroes the data after reading it (so that silence is played if the buffer is being neglected by user-land)
Once the driver finishes going over the entire output buffer, it adds the amount of samples in the buffer to bufferSampleStart and updates bufferTime to the current time.
The output buffer sample format is typically 16-bit PCM stereo.
(input sound buffer operation is likely similar but with writing instead of reading).
|