Renamed .c to .cpp, and fixed all warnings.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24178 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-02-29 14:54:30 +00:00
parent 105152d1f5
commit 340dd4fe3d
8 changed files with 204 additions and 210 deletions

View File

@ -5,11 +5,11 @@ SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders media ;
KernelAddon hda :
driver.c
hooks.c
hda_multi_audio.c
hda_controller.c
hda_codec.c
driver.cpp
device.cpp
hda_multi_audio.cpp
hda_controller.cpp
hda_codec.cpp
;
Package haiku-hda-cvs :

View File

@ -14,10 +14,8 @@ static status_t
hda_open(const char *name, uint32 flags, void** cookie)
{
hda_controller* controller = NULL;
status_t rc = B_OK;
long i;
for (i = 0; i < gNumCards; i++) {
for (uint32 i = 0; i < gNumCards; i++) {
if (strcmp(gCards[i].devfs_path, name) == 0) {
controller = &gCards[i];
break;
@ -30,11 +28,11 @@ hda_open(const char *name, uint32 flags, void** cookie)
if (controller->opened)
return B_BUSY;
rc = hda_hw_init(controller);
if (rc != B_OK)
return rc;
status_t status = hda_hw_init(controller);
if (status != B_OK)
return status;
controller->opened++;
atomic_add(&controller->opened, 1);
*cookie = controller;
return B_OK;
@ -75,7 +73,7 @@ hda_close(void* cookie)
{
hda_controller* controller = (hda_controller*)cookie;
hda_hw_stop(controller);
--controller->opened;
atomic_add(&controller->opened, -1);
return B_OK;
}

View File

@ -17,7 +17,7 @@ uint32 gNumCards;
pci_module_info* gPci;
status_t
extern "C" status_t
init_hardware(void)
{
pci_info info;
@ -39,7 +39,7 @@ init_hardware(void)
}
status_t
extern "C" status_t
init_driver(void)
{
char path[B_PATH_NAME_LENGTH];
@ -76,13 +76,12 @@ init_driver(void)
}
void
extern "C" void
uninit_driver(void)
{
long i;
dprintf("IRA: %s\n", __func__);
for (i = 0; i < gNumCards; i++) {
for (uint32 i = 0; i < gNumCards; i++) {
free((void*)gCards[i].devfs_path);
gCards[i].devfs_path = NULL;
}
@ -91,15 +90,16 @@ uninit_driver(void)
}
const char**
extern "C" const char**
publish_devices(void)
{
static const char* devs[MAX_CARDS + 1];
long i;
uint32 i;
dprintf("IRA: %s\n", __func__);
for (i = 0; i < gNumCards; i++)
for (i = 0; i < gNumCards; i++) {
devs[i] = gCards[i].devfs_path;
}
devs[i] = NULL;
@ -107,7 +107,7 @@ publish_devices(void)
}
device_hooks*
extern "C" device_hooks*
find_device(const char* name)
{
dprintf("IRA: %s\n", __func__);

View File

@ -40,10 +40,6 @@
/* FIXME: Find out why we need so much! */
#define DEFAULT_FRAMES_PER_BUFFER 4096
typedef struct hda_controller hda_controller;
typedef struct hda_codec hda_codec;
typedef struct hda_audio_group hda_audio_group;
#define STREAM_MAX_BUFFERS 10
#define STREAM_MIN_BUFFERS 2
@ -52,12 +48,12 @@ enum {
STREAM_RECORD
};
/* hda_stream
*
* This structure describes a single stream of audio data,
* which is can have multiple channels (for stereo or better).
*/
typedef struct hda_stream {
struct hda_codec;
/*! This structure describes a single stream of audio data,
which is can have multiple channels (for stereo or better).
*/
struct hda_stream {
uint32 id; /* HDA controller stream # */
uint32 off; /* HDA I/O/B descriptor offset */
bool running; /* Is this stream active? */
@ -74,7 +70,7 @@ typedef struct hda_stream {
uint32 num_channels;
uint32 buffer_length; /* size of buffer in samples */
uint32 sample_size;
void* buffers[STREAM_MAX_BUFFERS];
uint8* buffers[STREAM_MAX_BUFFERS];
/* Virtual addresses for buffer */
uint32 physical_buffers[STREAM_MAX_BUFFERS];
/* Physical addresses for buffer */
@ -88,68 +84,66 @@ typedef struct hda_stream {
area_id buffer_area;
area_id buffer_descriptors_area;
uint32 physical_buffer_descriptors; /* BDL physical address */
} hda_stream;
/* hda_audio_group
*
* This structure describes a single Audio Function Group. An afg
* is a group of audio widgets which can be used to configure multiple
* streams of audio either from the HDA Link to an output device (= playback)
* or from an input device to the HDA link (= recording).
*/
struct hda_audio_group {
hda_codec* codec;
/* Multi Audio API data */
hda_stream* playback_stream;
hda_stream* record_stream;
uint32 root_node_id;
uint32 widget_start;
uint32 widget_count;
uint32 supported_formats;
uint32 supported_rates;
uint32 supported_pm;
struct {
uint32 num_inputs;
int32 active_input;
uint32 inputs[MAX_INPUTS];
uint32 flags;
hda_widget_type type;
uint32 pm;
union {
struct {
uint32 formats;
uint32 rates;
} output;
struct {
uint32 formats;
uint32 rates;
} input;
struct {
} mixer;
struct {
uint32 output;
uint32 input;
pin_dev_type device;
} pin;
} d;
} *widgets;
};
/* hda_codec
*
* This structure describes a single codec module in the
* HDA compliant device. This is a discrete component, which
* can contain both Audio Function Groups, Modem Function Groups,
* and other customized (vendor specific) Function Groups.
*
* NOTE: Atm, only Audio Function Groups are supported.
*/
struct hda_widget {
uint32 num_inputs;
int32 active_input;
uint32 inputs[MAX_INPUTS];
uint32 flags;
hda_widget_type type;
uint32 pm;
union {
struct {
uint32 formats;
uint32 rates;
} output;
struct {
uint32 formats;
uint32 rates;
} input;
struct {
} mixer;
struct {
uint32 output;
uint32 input;
pin_dev_type device;
} pin;
} d;
};
/*! This structure describes a single Audio Function Group. An afg
is a group of audio widgets which can be used to configure multiple
streams of audio either from the HDA Link to an output device (= playback)
or from an input device to the HDA link (= recording).
*/
struct hda_audio_group {
hda_codec* codec;
/* Multi Audio API data */
hda_stream* playback_stream;
hda_stream* record_stream;
uint32 root_node_id;
uint32 widget_start;
uint32 widget_count;
uint32 supported_formats;
uint32 supported_rates;
uint32 supported_pm;
hda_widget* widgets;
};
/*! This structure describes a single codec module in the
HDA compliant device. This is a discrete component, which
can contain both Audio Function Groups, Modem Function Groups,
and other customized (vendor specific) Function Groups.
NOTE: ATM, only Audio Function Groups are supported.
*/
struct hda_codec {
uint16 vendor_id;
uint16 product_id;
@ -167,16 +161,14 @@ struct hda_codec {
struct hda_controller* controller;
};
/* hda_controller
*
* This structure describes a single HDA compliant
* controller. It contains a list of available streams
* for use by the codecs contained, and the messaging queue
* (verb/response) buffers for communication.
*/
/*! This structure describes a single HDA compliant
controller. It contains a list of available streams
for use by the codecs contained, and the messaging queue
(verb/response) buffers for communication.
*/
struct hda_controller {
struct pci_info pci_info;
vuint32 opened;
vint32 opened;
const char* devfs_path;
area_id regs_area;
@ -222,7 +214,7 @@ status_t hda_hw_init(hda_controller* controller);
void hda_hw_stop(hda_controller* controller);
void hda_hw_uninit(hda_controller* controller);
status_t hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses,
int count);
uint32 count);
/* hda_controller.c: Stream support */
hda_stream* hda_stream_new(hda_controller* controller, int type);

View File

@ -174,7 +174,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
audioGroup->widget_start = resp[2] >> 16;
audioGroup->widget_count = resp[2] & 0xFF;
audioGroup->widgets = calloc(audioGroup->widget_count,
audioGroup->widgets = (hda_widget*)calloc(audioGroup->widget_count,
sizeof(*audioGroup->widgets));
if (audioGroup->widgets == NULL) {
dprintf("ERROR: Not enough memory!\n");
@ -193,7 +193,7 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
PID_CONNLIST_LEN);
hda_send_verbs(audioGroup->codec, verbs, resp, 2);
audioGroup->widgets[widx].type = resp[0] >> 20;
audioGroup->widgets[widx].type = (hda_widget_type)(resp[0] >> 20);
audioGroup->widgets[widx].num_inputs = resp[1] & 0x7F;
off = 0;
@ -272,7 +272,8 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
verbs[0] = MAKE_VERB(audioGroup->codec->addr, wid,
VID_GET_CFGDEFAULT, 0);
if (hda_send_verbs(audioGroup->codec, verbs, resp, 1) == B_OK) {
audioGroup->widgets[widx].d.pin.device = (resp[0] >> 20) & 0xF;
audioGroup->widgets[widx].d.pin.device = (pin_dev_type)
((resp[0] >> 20) & 0xf);
dprintf("\t%s, %s, %s, %s\n",
kPortConnector[resp[0] >> 30],
kDefaultDevice[audioGroup->widgets[widx].d.pin.device],
@ -304,10 +305,6 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
&audioGroup->widgets[widx].pm);
if (audioGroup->widgets[widx].num_inputs) {
int idx;
off = 0;
if (audioGroup->widgets[widx].num_inputs > 1) {
verbs[0] = MAKE_VERB(audioGroup->codec->addr, wid,
VID_GET_CONNSEL, 0);
@ -318,10 +315,12 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
} else
audioGroup->widgets[widx].active_input = -1;
for (idx = 0; idx < audioGroup->widgets[widx].num_inputs; idx ++) {
if (!(idx % 4)) {
off = 0;
for (uint32 i = 0; i < audioGroup->widgets[widx].num_inputs; i++) {
if (!(i % 4)) {
verbs[0] = MAKE_VERB(audioGroup->codec->addr, wid,
VID_GET_CONNLENTRY, idx);
VID_GET_CONNLENTRY, i);
if (hda_send_verbs(audioGroup->codec, verbs, resp, 1) != B_OK) {
dprintf("%s: Error parsing inputs for widget %ld!\n",
__func__, wid);
@ -329,16 +328,16 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
}
}
if (idx != audioGroup->widgets[widx].active_input) {
if ((int32)i != audioGroup->widgets[widx].active_input) {
off += sprintf(buf + off, "%ld ",
(resp[0] >> (8 * (idx % 4))) & 0xff);
(resp[0] >> (8 * (i % 4))) & 0xff);
} else {
off += sprintf(buf + off, "(%ld) ",
(resp[0] >> (8 * (idx % 4))) & 0xff);
(resp[0] >> (8 * (i % 4))) & 0xff);
}
audioGroup->widgets[widx].inputs[idx]
= (resp[0] >> (8 * (idx % 4))) & 0xff;
audioGroup->widgets[widx].inputs[i]
= (resp[0] >> (8 * (i % 4))) & 0xff;
}
dprintf("\t[ %s]\n", buf);
@ -349,35 +348,35 @@ hda_codec_parse_audio_group(hda_audio_group* audioGroup)
}
/*! Find path from 'wid' to a widget of type 'wtype', returning its widget id.
* Returns 0 if not found.
*/
/*! Find path from 'wid' to a widget of type \a widgetType, returning its
widget id.
Returns 0 if not found.
*/
static uint32
hda_codec_audio_group_find_path(hda_audio_group* audioGroup, uint32 widget,
uint32 widgetType, uint32 depth)
hda_widget_type widgetType, uint32 depth)
{
int widx = widget - audioGroup->widget_start;
int idx;
switch (audioGroup->widgets[widx].type) {
case WT_AUDIO_MIXER:
for (idx = 0; idx < audioGroup->widgets[widx].num_inputs; idx++) {
for (uint32 i = 0; i < audioGroup->widgets[widx].num_inputs; i++) {
if (hda_codec_audio_group_find_path(audioGroup,
audioGroup->widgets[widx].inputs[idx], widgetType,
audioGroup->widgets[widx].inputs[i], widgetType,
depth + 1)) {
if (audioGroup->widgets[widx].active_input == -1)
audioGroup->widgets[widx].active_input = idx;
audioGroup->widgets[widx].active_input = i;
return audioGroup->widgets[widx].inputs[idx];
return audioGroup->widgets[widx].inputs[i];
}
}
break;
case WT_AUDIO_SELECTOR:
{
int idx = audioGroup->widgets[widx].active_input;
if (idx != -1) {
widget = audioGroup->widgets[widx].inputs[idx];
int32 i = audioGroup->widgets[widx].active_input;
if (i != -1) {
widget = audioGroup->widgets[widx].inputs[i];
if (hda_codec_audio_group_find_path(audioGroup, widget,
widgetType, depth + 1)) {
return widget;
@ -417,49 +416,48 @@ hda_codec_delete_audio_group(hda_audio_group* audioGroup)
static status_t
hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
{
hda_audio_group* audioGroup;
status_t rc;
uint32 idx;
if ((audioGroup = calloc(1, sizeof(hda_audio_group))) == NULL) {
rc = B_NO_MEMORY;
goto done;
}
hda_audio_group* audioGroup = (hda_audio_group*)calloc(1,
sizeof(hda_audio_group));
if (audioGroup == NULL)
return B_NO_MEMORY;
/* Setup minimal info needed by hda_codec_parse_afg */
audioGroup->root_node_id = audioGroupNodeID;
audioGroup->codec = codec;
/* Parse all widgets in Audio Function Group */
rc = hda_codec_parse_audio_group(audioGroup);
if (rc != B_OK)
goto free_audio_group;
status_t status = hda_codec_parse_audio_group(audioGroup);
if (status != B_OK)
goto err;
/* Setup for worst-case scenario; we cannot find any output Pin Widgets */
rc = ENODEV;
status = ENODEV;
/* Try to locate all input/output channels */
for (idx = 0; idx < audioGroup->widget_count; idx++) {
for (uint32 i = 0; i < audioGroup->widget_count; i++) {
uint32 outputWidget = 0, inputWidget = 0;
int32 iidx;
if (audioGroup->playback_stream == NULL
&& audioGroup->widgets[idx].type == WT_PIN_COMPLEX
&& audioGroup->widgets[idx].d.pin.output) {
if (audioGroup->widgets[idx].d.pin.device == PIN_DEV_HP_OUT
|| audioGroup->widgets[idx].d.pin.device == PIN_DEV_SPEAKER
|| audioGroup->widgets[idx].d.pin.device == PIN_DEV_LINE_OUT) {
iidx = audioGroup->widgets[idx].active_input;
if (iidx != -1) {
&& audioGroup->widgets[i].type == WT_PIN_COMPLEX
&& audioGroup->widgets[i].d.pin.output) {
if (audioGroup->widgets[i].d.pin.device == PIN_DEV_HP_OUT
|| audioGroup->widgets[i].d.pin.device == PIN_DEV_SPEAKER
|| audioGroup->widgets[i].d.pin.device == PIN_DEV_LINE_OUT) {
int32 inputIndex = audioGroup->widgets[i].active_input;
if (inputIndex != -1) {
outputWidget = hda_codec_audio_group_find_path(audioGroup,
audioGroup->widgets[idx].inputs[iidx], WT_AUDIO_OUTPUT, 0);
audioGroup->widgets[i].inputs[inputIndex],
WT_AUDIO_OUTPUT, 0);
} else {
for (iidx = 0; iidx < audioGroup->widgets[idx].num_inputs; iidx++) {
for (inputIndex = 0; (uint32)inputIndex
< audioGroup->widgets[i].num_inputs; inputIndex++) {
outputWidget = hda_codec_audio_group_find_path(audioGroup,
audioGroup->widgets[idx].inputs[iidx], WT_AUDIO_OUTPUT, 0);
audioGroup->widgets[i].inputs[inputIndex],
WT_AUDIO_OUTPUT, 0);
if (outputWidget) {
corb_t verb = MAKE_VERB(codec->addr,
idx + audioGroup->widget_start, VID_SET_CONNSEL, iidx);
i + audioGroup->widget_start, VID_SET_CONNSEL,
inputIndex);
if (hda_send_verbs(codec, &verb, NULL, 1) != B_OK)
dprintf("%s: Setting output selector failed!\n", __func__);
break;
@ -477,40 +475,45 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
audioGroup->record_stream = hda_stream_new(
audioGroup->codec->controller, STREAM_RECORD);
audioGroup->playback_stream->pin_widget = idx
audioGroup->playback_stream->pin_widget = i
+ audioGroup->widget_start;
audioGroup->playback_stream->io_widget = outputWidget;
/* FIXME: Force Pin Widget to unmute; enable hp/output */
verb[0] = MAKE_VERB(codec->addr,
audioGroup->playback_stream->pin_widget, VID_SET_AMPGAINMUTE,
audioGroup->playback_stream->pin_widget,
VID_SET_AMPGAINMUTE,
(1 << 15) | (1 << 13) | (1 << 12));
verb[1] = MAKE_VERB(codec->addr,
audioGroup->playback_stream->pin_widget, VID_SET_PINWCTRL,
audioGroup->playback_stream->pin_widget,
VID_SET_PINWCTRL,
(1 << 7) | (1 << 6));
hda_send_verbs(codec, verb, NULL, 2);
dprintf("%s: Found output PIN (%s) connected to output "
"CONV wid:%ld\n", __func__,
kDefaultDevice[audioGroup->widgets[idx].d.pin.device], outputWidget);
kDefaultDevice[audioGroup->widgets[i].d.pin.device], outputWidget);
}
}
}
}
if (audioGroup->widgets[idx].type == WT_AUDIO_INPUT) {
iidx = audioGroup->widgets[idx].active_input;
if (iidx != -1) {
if (audioGroup->widgets[i].type == WT_AUDIO_INPUT) {
int32 inputIndex = audioGroup->widgets[i].active_input;
if (inputIndex != -1) {
inputWidget = hda_codec_audio_group_find_path(audioGroup,
audioGroup->widgets[idx].inputs[iidx], WT_PIN_COMPLEX, 0);
audioGroup->widgets[i].inputs[inputIndex], WT_PIN_COMPLEX,
0);
} else {
for (iidx = 0; iidx < audioGroup->widgets[idx].num_inputs; iidx++) {
for (inputIndex = 0; (uint32)inputIndex
< audioGroup->widgets[i].num_inputs; inputIndex++) {
inputWidget = hda_codec_audio_group_find_path(audioGroup,
audioGroup->widgets[idx].inputs[iidx], WT_PIN_COMPLEX, 0);
audioGroup->widgets[i].inputs[inputIndex],
WT_PIN_COMPLEX, 0);
if (inputWidget) {
corb_t verb = MAKE_VERB(codec->addr,
idx + audioGroup->widget_start, VID_SET_CONNSEL,
iidx);
i + audioGroup->widget_start, VID_SET_CONNSEL,
inputIndex);
if (hda_send_verbs(codec, &verb, NULL, 1) != B_OK) {
dprintf("%s: Setting input selector failed!\n",
__func__);
@ -529,7 +532,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
audioGroup->codec->controller, STREAM_RECORD);
audioGroup->record_stream->pin_widget = inputWidget;
audioGroup->record_stream->io_widget = idx
audioGroup->record_stream->io_widget = i
+ audioGroup->widget_start;
/* FIXME: Force Pin Widget to unmute */
@ -542,7 +545,7 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
dprintf("%s: Found input PIN (%s) connected to input CONV "
"wid:%ld\n", __func__, kDefaultDevice[audioGroup->widgets[
inputWidget - audioGroup->widget_start].d.pin.device],
idx + audioGroup->widget_start);
i + audioGroup->widget_start);
}
}
}
@ -550,15 +553,12 @@ hda_codec_new_audio_group(hda_codec* codec, uint32 audioGroupNodeID)
/* If we found any valid output channels, we're in the clear */
if (audioGroup && audioGroup->playback_stream) {
codec->audio_groups[codec->num_audio_groups++] = audioGroup;
rc = B_OK;
goto done;
return B_OK;
}
free_audio_group:
err:
free(audioGroup);
done:
return rc;
return status;
}
@ -586,7 +586,7 @@ hda_codec_delete(hda_codec* codec)
hda_codec*
hda_codec_new(hda_controller* controller, uint32 cad)
{
hda_codec* codec = calloc(1, sizeof(hda_codec));
hda_codec* codec = (hda_codec*)calloc(1, sizeof(hda_codec));
uint32 responses[3];
corb_t verbs[3];
uint32 nodeID;

View File

@ -8,7 +8,7 @@
#ifndef HDA_CODEC_H
#define HDA_CODEC_H
typedef enum {
enum hda_widget_type {
WT_AUDIO_OUTPUT = 0,
WT_AUDIO_INPUT = 1,
WT_AUDIO_MIXER = 2,
@ -18,10 +18,10 @@ typedef enum {
WT_VOLUME_KNOB = 6,
WT_BEEP_GENERATOR = 7,
WT_VENDOR_DEFINED = 15
} hda_widget_type;
};
typedef enum {
enum pin_dev_type {
PIN_DEV_LINE_OUT = 0,
PIN_DEV_SPEAKER,
PIN_DEV_HP_OUT,
@ -38,7 +38,7 @@ typedef enum {
PIN_DEV_DIGITAL_OTHER_IN,
PIN_DEV_RESERVED,
PIN_DEV_OTHER
} pin_dev_type;
};
/* Verb Helper Macro */

View File

@ -4,6 +4,7 @@
*
* Authors:
* Ithamar Adema, ithamar AT unet DOT nl
* Axel Dörfler, axeld@pinc-software.de
*/
@ -79,7 +80,7 @@ hda_stream_delete(hda_stream* stream)
hda_stream*
hda_stream_new(hda_controller* controller, int type)
{
hda_stream* stream = calloc(1, sizeof(hda_stream));
hda_stream* stream = (hda_stream*)calloc(1, sizeof(hda_stream));
if (stream == NULL)
return NULL;
@ -333,7 +334,7 @@ dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld *************
status_t
hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, int count)
hda_send_verbs(hda_codec* codec, corb_t* verbs, uint32* responses, uint32 count)
{
hda_controller *controller = codec->controller;
uint32 sent = 0;
@ -410,7 +411,7 @@ hda_interrupt_handler(hda_controller* controller)
if ((responseFlags & RESPONSE_FLAGS_UNSOLICITED) != 0) {
dprintf("hda: Unsolicited response: %08lx/%08lx\n",
response, extendedResponse);
response, responseFlags);
continue;
}
if (codec == NULL) {

View File

@ -188,11 +188,6 @@ list_mix_channels(hda_audio_group* audioGroup, multi_mix_channel_info *data)
static status_t
get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data)
{
uint32 playbackSampleSize = audioGroup->playback_stream->sample_size;
uint32 recordSampleSize = audioGroup->record_stream->sample_size;
uint32 cidx, bidx;
status_t status;
TRACE("playback: %ld buffers, %ld channels, %ld samples\n",
data->request_playback_buffers, data->request_playback_channels,
data->request_playback_buffer_size);
@ -237,8 +232,8 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data)
audioGroup->playback_stream->buffer_length
= data->return_playback_buffer_size;
status = hda_stream_setup_buffers(audioGroup, audioGroup->playback_stream,
"Playback");
status_t status = hda_stream_setup_buffers(audioGroup,
audioGroup->playback_stream, "Playback");
if (status != B_OK) {
dprintf("hda: Error setting up playback buffers: %s\n",
strerror(status));
@ -260,22 +255,27 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data)
/* Setup data structure for multi_audio API... */
for (bidx = 0; bidx < data->return_playback_buffers; bidx++) {
for (cidx = 0; cidx < data->return_playback_channels; cidx++) {
data->playback_buffers[bidx][cidx].base
= audioGroup->playback_stream->buffers[bidx]
+ playbackSampleSize * cidx;
data->playback_buffers[bidx][cidx].stride
uint32 playbackSampleSize = audioGroup->playback_stream->sample_size;
uint32 recordSampleSize = audioGroup->record_stream->sample_size;
for (int32 i = 0; i < data->return_playback_buffers; i++) {
for (int32 channelIndex = 0;
channelIndex < data->return_playback_channels; channelIndex++) {
data->playback_buffers[i][channelIndex].base
= (char*)audioGroup->playback_stream->buffers[i]
+ playbackSampleSize * channelIndex;
data->playback_buffers[i][channelIndex].stride
= playbackSampleSize * data->return_playback_channels;
}
}
for (bidx = 0; bidx < data->return_record_buffers; bidx++) {
for (cidx = 0; cidx < data->return_record_channels; cidx++) {
data->record_buffers[bidx][cidx].base
= audioGroup->record_stream->buffers[bidx]
+ recordSampleSize * cidx;
data->record_buffers[bidx][cidx].stride
for (int32 i = 0; i < data->return_record_buffers; i++) {
for (int32 channelIndex = 0;
channelIndex < data->return_record_channels; channelIndex++) {
data->record_buffers[i][channelIndex].base
= (char*)audioGroup->record_stream->buffers[i]
+ recordSampleSize * channelIndex;
data->record_buffers[i][channelIndex].stride
= recordSampleSize * data->return_record_channels;
}
}
@ -347,31 +347,34 @@ multi_audio_control(void* cookie, uint32 op, void* arg, size_t len)
audioGroup = codec->audio_groups[0];
// TODO: make userland-safe when built for Haiku!
switch (op) {
case B_MULTI_GET_DESCRIPTION:
return get_description(audioGroup, arg);
return get_description(audioGroup, (multi_description*)arg);
case B_MULTI_GET_ENABLED_CHANNELS:
return get_enabled_channels(audioGroup, arg);
return get_enabled_channels(audioGroup, (multi_channel_enable*)arg);
case B_MULTI_SET_ENABLED_CHANNELS:
return B_OK;
case B_MULTI_GET_GLOBAL_FORMAT:
return get_global_format(audioGroup, arg);
return get_global_format(audioGroup, (multi_format_info*)arg);
case B_MULTI_SET_GLOBAL_FORMAT:
return set_global_format(audioGroup, arg);
return set_global_format(audioGroup, (multi_format_info*)arg);
case B_MULTI_LIST_MIX_CHANNELS:
return list_mix_channels(audioGroup, arg);
return list_mix_channels(audioGroup, (multi_mix_channel_info*)arg);
case B_MULTI_LIST_MIX_CONTROLS:
return list_mix_controls(audioGroup, arg);
return list_mix_controls(audioGroup, (multi_mix_control_info*)arg);
case B_MULTI_LIST_MIX_CONNECTIONS:
return list_mix_connections(audioGroup, arg);
return list_mix_connections(audioGroup,
(multi_mix_connection_info*)arg);
case B_MULTI_GET_BUFFERS:
return get_buffers(audioGroup, arg);
return get_buffers(audioGroup, (multi_buffer_list*)arg);
case B_MULTI_BUFFER_EXCHANGE:
return buffer_exchange(audioGroup, arg);
return buffer_exchange(audioGroup, (multi_buffer_info*)arg);
case B_MULTI_BUFFER_FORCE_STOP:
return buffer_force_stop(audioGroup);