* style fixes

* use user_memcpy in buffer exchange for Haiku


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28861 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval 2009-01-08 23:45:16 +00:00
parent b8ea3ce774
commit 6c16c42586
3 changed files with 138 additions and 84 deletions

View File

@ -28,6 +28,7 @@
*/ */
#include <OS.h> #include <OS.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <MediaDefs.h> #include <MediaDefs.h>
#include "ac97.h" #include "ac97.h"
#include "debug.h" #include "debug.h"

View File

@ -111,14 +111,16 @@ auich_mem_new(auich_dev *card, size_t size)
return mem; return mem;
} }
static void static void
auich_mem_delete(auich_mem *mem) auich_mem_delete(auich_mem *mem)
{ {
if(mem->area > B_OK) if (mem->area > B_OK)
delete_area(mem->area); delete_area(mem->area);
free(mem); free(mem);
} }
static void * static void *
auich_mem_alloc(auich_dev *card, size_t size) auich_mem_alloc(auich_dev *card, size_t size)
{ {
@ -133,6 +135,7 @@ auich_mem_alloc(auich_dev *card, size_t size)
return mem; return mem;
} }
static void static void
auich_mem_free(auich_dev *card, void *ptr) auich_mem_free(auich_dev *card, void *ptr)
{ {
@ -162,7 +165,7 @@ auich_stream_set_audioparms(auich_stream *stream, uint8 channels,
(stream->sample_rate == sample_rate)) (stream->sample_rate == sample_rate))
return B_OK; return B_OK;
if(stream->buffer) if (stream->buffer)
auich_mem_free(stream->card, stream->buffer->log_base); auich_mem_free(stream->card, stream->buffer->log_base);
stream->b16 = b16; stream->b16 = b16;
@ -181,6 +184,7 @@ auich_stream_set_audioparms(auich_stream *stream, uint8 channels,
return B_OK; return B_OK;
} }
status_t status_t
auich_stream_commit_parms(auich_stream *stream) auich_stream_commit_parms(auich_stream *stream)
{ {
@ -193,20 +197,20 @@ auich_stream_commit_parms(auich_stream *stream)
auich_reg_write_8(&stream->card->config, stream->base + AUICH_REG_X_CR, CR_RR); auich_reg_write_8(&stream->card->config, stream->base + AUICH_REG_X_CR, CR_RR);
for (i = 10000; i>=0; i--) { for (i = 10000; i>=0; i--) {
if(0 == auich_reg_read_8(&stream->card->config, stream->base + AUICH_REG_X_CR)) { if (0 == auich_reg_read_8(&stream->card->config, stream->base + AUICH_REG_X_CR)) {
LOG(("channel reset finished, %x, %d\n", stream->base, i)); LOG(("channel reset finished, %x, %d\n", stream->base, i));
break; break;
} }
spin(1); spin(1);
} }
if(i < 0) { if (i < 0) {
LOG(("channel reset failed after 10ms\n")); LOG(("channel reset failed after 10ms\n"));
} }
page = stream->dmaops_log_base; page = stream->dmaops_log_base;
for(i=0; i < AUICH_DMALIST_MAX; i++) { for (i=0; i < AUICH_DMALIST_MAX; i++) {
page[2*i] = ((uint32)stream->buffer->phy_base) + page[2*i] = ((uint32)stream->buffer->phy_base) +
(i % stream->bufcount) * stream->blksize; (i % stream->bufcount) * stream->blksize;
page[2*i + 1] = AUICH_DMAF_IOC | (stream->blksize page[2*i + 1] = AUICH_DMAF_IOC | (stream->blksize
@ -217,18 +221,19 @@ auich_stream_commit_parms(auich_stream *stream)
auich_reg_write_32(&stream->card->config, stream->base + AUICH_REG_X_BDBAR, auich_reg_write_32(&stream->card->config, stream->base + AUICH_REG_X_BDBAR,
(uint32)stream->dmaops_phy_base); (uint32)stream->dmaops_phy_base);
if(stream->use & AUICH_USE_RECORD) if (stream->use & AUICH_USE_RECORD)
auich_codec_write(&stream->card->config, AC97_PCM_L_R_ADC_RATE, (uint16)stream->sample_rate); auich_codec_write(&stream->card->config, AC97_PCM_L_R_ADC_RATE, (uint16)stream->sample_rate);
else else
auich_codec_write(&stream->card->config, AC97_PCM_FRONT_DAC_RATE, (uint16)stream->sample_rate); auich_codec_write(&stream->card->config, AC97_PCM_FRONT_DAC_RATE, (uint16)stream->sample_rate);
if(stream->use & AUICH_USE_RECORD) if (stream->use & AUICH_USE_RECORD)
LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_L_R_ADC_RATE))); LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_L_R_ADC_RATE)));
else else
LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_FRONT_DAC_RATE))); LOG(("rate : %d\n", auich_codec_read(&stream->card->config, AC97_PCM_FRONT_DAC_RATE)));
return B_OK; return B_OK;
} }
status_t status_t
auich_stream_get_nth_buffer(auich_stream *stream, uint8 chan, uint8 buf, auich_stream_get_nth_buffer(auich_stream *stream, uint8 chan, uint8 buf,
char** buffer, size_t *stride) char** buffer, size_t *stride)
@ -246,6 +251,7 @@ auich_stream_get_nth_buffer(auich_stream *stream, uint8 chan, uint8 buf,
return B_OK; return B_OK;
} }
static uint8 static uint8
auich_stream_curaddr(auich_stream *stream) auich_stream_curaddr(auich_stream *stream)
{ {
@ -254,6 +260,7 @@ auich_stream_curaddr(auich_stream *stream)
return index; return index;
} }
void void
auich_stream_start(auich_stream *stream, void (*inth) (void *), void *inthparam) auich_stream_start(auich_stream *stream, void (*inth) (void *), void *inthparam)
{ {
@ -284,6 +291,7 @@ auich_stream_start(auich_stream *stream, void (*inth) (void *), void *inthparam)
#endif #endif
} }
void void
auich_stream_halt(auich_stream *stream) auich_stream_halt(auich_stream *stream)
{ {
@ -295,6 +303,7 @@ auich_stream_halt(auich_stream *stream)
auich_reg_read_8(&stream->card->config, stream->base + AUICH_REG_X_CR) & ~CR_RPBM); auich_reg_read_8(&stream->card->config, stream->base + AUICH_REG_X_CR) & ~CR_RPBM);
} }
auich_stream * auich_stream *
auich_stream_new(auich_dev *card, uint8 use, uint32 bufframes, uint8 bufcount) auich_stream_new(auich_dev *card, uint8 use, uint32 bufframes, uint8 bufcount)
{ {
@ -320,7 +329,7 @@ auich_stream_new(auich_dev *card, uint8 use, uint32 bufframes, uint8 bufcount)
stream->trigblk = 0; stream->trigblk = 0;
stream->blkmod = 0; stream->blkmod = 0;
if(use & AUICH_USE_PLAY) { if (use & AUICH_USE_PLAY) {
stream->base = AUICH_REG_PO_BASE; stream->base = AUICH_REG_PO_BASE;
stream->sta = STA_POINT; stream->sta = STA_POINT;
} else { } else {
@ -350,6 +359,7 @@ auich_stream_new(auich_dev *card, uint8 use, uint32 bufframes, uint8 bufcount)
return stream; return stream;
} }
void void
auich_stream_delete(auich_stream *stream) auich_stream_delete(auich_stream *stream)
{ {
@ -364,14 +374,14 @@ auich_stream_delete(auich_stream *stream)
auich_reg_write_8(&stream->card->config, stream->base + AUICH_REG_X_CR, CR_RR); auich_reg_write_8(&stream->card->config, stream->base + AUICH_REG_X_CR, CR_RR);
for (i = 10000; i>=0; i--) { for (i = 10000; i>=0; i--) {
if(0 == auich_reg_read_8(&stream->card->config, stream->base + AUICH_REG_X_CR)) { if (0 == auich_reg_read_8(&stream->card->config, stream->base + AUICH_REG_X_CR)) {
LOG(("channel reset finished, %x, %d\n", stream->base, i)); LOG(("channel reset finished, %x, %d\n", stream->base, i));
break; break;
} }
spin(1); spin(1);
} }
if(i < 0) { if (i < 0) {
LOG(("channel reset failed after 10ms\n")); LOG(("channel reset failed after 10ms\n"));
} }
@ -380,7 +390,7 @@ auich_stream_delete(auich_stream *stream)
if (stream->dmaops_area > B_OK) if (stream->dmaops_area > B_OK)
delete_area(stream->dmaops_area); delete_area(stream->dmaops_area);
if(stream->buffer) if (stream->buffer)
auich_mem_free(stream->card, stream->buffer->log_base); auich_mem_free(stream->card, stream->buffer->log_base);
status = lock(); status = lock();
@ -422,7 +432,7 @@ auich_int(void *arg)
stream->base + GET_REG_SR(&stream->card->config)); stream->base + GET_REG_SR(&stream->card->config));
sr &= SR_MASK; sr &= SR_MASK;
if(!sr) if (!sr)
continue; continue;
gotone = true; gotone = true;
@ -435,7 +445,7 @@ auich_int(void *arg)
stream->trigblk = (curblk) % stream->blkmod; stream->trigblk = (curblk) % stream->blkmod;
if(stream->inth) if (stream->inth)
stream->inth(stream->inthparam); stream->inth(stream->inthparam);
} else { } else {
TRACE(("interrupt !! sta %x, sr %x\n", sta, sr)); TRACE(("interrupt !! sta %x, sr %x\n", sta, sr));
@ -504,6 +514,7 @@ map_io_memory(device_config *config)
return B_OK; return B_OK;
} }
static status_t static status_t
unmap_io_memory(device_config *config) unmap_io_memory(device_config *config)
{ {
@ -572,6 +583,7 @@ init_hardware(void)
return err; return err;
} }
static void static void
make_device_names( make_device_names(
auich_dev * card) auich_dev * card)
@ -597,6 +609,7 @@ auich_init(auich_dev * card)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_setup(auich_dev * card) auich_setup(auich_dev * card)
{ {
@ -735,7 +748,7 @@ init_driver(void)
return ENOSYS; return ENOSYS;
while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) { while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) {
if((info.vendor_id == INTEL_VENDOR_ID && if ((info.vendor_id == INTEL_VENDOR_ID &&
(info.device_id == INTEL_82443MX_AC97_DEVICE_ID (info.device_id == INTEL_82443MX_AC97_DEVICE_ID
|| info.device_id == INTEL_82801AA_AC97_DEVICE_ID || info.device_id == INTEL_82801AA_AC97_DEVICE_ID
|| info.device_id == INTEL_82801AB_AC97_DEVICE_ID || info.device_id == INTEL_82801AB_AC97_DEVICE_ID

View File

@ -56,24 +56,24 @@ auich_ac97_get_mix(void *card, const void *cookie, int32 type, float *values) {
case B_MIX_GAIN: case B_MIX_GAIN:
value = auich_codec_read(&dev->config, info->reg); value = auich_codec_read(&dev->config, info->reg);
//PRINT(("B_MIX_GAIN value : %u\n", value)); //PRINT(("B_MIX_GAIN value : %u\n", value));
if(info->type & B_MIX_STEREO) { if (info->type & B_MIX_STEREO) {
mask = ((1 << (info->bits + 1)) - 1) << 8; mask = ((1 << (info->bits + 1)) - 1) << 8;
gain = ((value & mask) >> 8) * info->granularity; gain = ((value & mask) >> 8) * info->granularity;
if(info->polarity == 1) if (info->polarity == 1)
values[0] = info->max_gain - gain; values[0] = info->max_gain - gain;
else else
values[0] = gain - info->min_gain; values[0] = gain - info->min_gain;
mask = ((1 << (info->bits + 1)) - 1); mask = ((1 << (info->bits + 1)) - 1);
gain = (value & mask) * info->granularity; gain = (value & mask) * info->granularity;
if(info->polarity == 1) if (info->polarity == 1)
values[1] = info->max_gain - gain; values[1] = info->max_gain - gain;
else else
values[1] = gain - info->min_gain; values[1] = gain - info->min_gain;
} else { } else {
mask = ((1 << (info->bits + 1)) - 1); mask = ((1 << (info->bits + 1)) - 1);
gain = (value & mask) * info->granularity; gain = (value & mask) * info->granularity;
if(info->polarity == 1) if (info->polarity == 1)
values[0] = info->max_gain - gain; values[0] = info->max_gain - gain;
else else
values[0] = gain - info->min_gain; values[0] = gain - info->min_gain;
@ -103,6 +103,7 @@ auich_ac97_get_mix(void *card, const void *cookie, int32 type, float *values) {
} }
} }
static void static void
auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) { auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
auich_dev *dev = (auich_dev*)card; auich_dev *dev = (auich_dev*)card;
@ -113,11 +114,11 @@ auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
switch(type) { switch(type) {
case B_MIX_GAIN: case B_MIX_GAIN:
value = auich_codec_read(&dev->config, info->reg); value = auich_codec_read(&dev->config, info->reg);
if(info->type & B_MIX_STEREO) { if (info->type & B_MIX_STEREO) {
mask = ((1 << (info->bits + 1)) - 1) << 8; mask = ((1 << (info->bits + 1)) - 1) << 8;
value &= ~mask; value &= ~mask;
if(info->polarity == 1) if (info->polarity == 1)
gain = info->max_gain - values[0]; gain = info->max_gain - values[0];
else else
gain = values[0] - info->min_gain; gain = values[0] - info->min_gain;
@ -125,7 +126,7 @@ auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
mask = ((1 << (info->bits + 1)) - 1); mask = ((1 << (info->bits + 1)) - 1);
value &= ~mask; value &= ~mask;
if(info->polarity == 1) if (info->polarity == 1)
gain = info->max_gain - values[1]; gain = info->max_gain - values[1];
else else
gain = values[1] - info->min_gain; gain = values[1] - info->min_gain;
@ -133,7 +134,7 @@ auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
} else { } else {
mask = ((1 << (info->bits + 1)) - 1); mask = ((1 << (info->bits + 1)) - 1);
value &= ~mask; value &= ~mask;
if(info->polarity == 1) if (info->polarity == 1)
gain = info->max_gain - values[0]; gain = info->max_gain - values[0];
else else
gain = values[0] - info->min_gain; gain = values[0] - info->min_gain;
@ -147,7 +148,7 @@ auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
value = auich_codec_read(&dev->config, info->reg); value = auich_codec_read(&dev->config, info->reg);
value &= ~mask; value &= ~mask;
value |= ((values[0] == 1.0 ? 1 : 0 ) << 15 & mask); value |= ((values[0] == 1.0 ? 1 : 0 ) << 15 & mask);
if(info->reg == AC97_SURR_VOLUME) { if (info->reg == AC97_SURR_VOLUME) {
// there is a independent mute for each channel // there is a independent mute for each channel
mask = ((1 << 1) - 1) << 7; mask = ((1 << 1) - 1) << 7;
value &= ~mask; value &= ~mask;
@ -175,6 +176,7 @@ auich_ac97_set_mix(void *card, const void *cookie, int32 type, float *values) {
} }
static int32 static int32
auich_create_group_control(multi_dev *multi, int32 *index, int32 parent, auich_create_group_control(multi_dev *multi, int32 *index, int32 parent,
int32 string, const char* name) { int32 string, const char* name) {
@ -185,12 +187,13 @@ auich_create_group_control(multi_dev *multi, int32 *index, int32 parent,
multi->controls[i].mix_control.flags = B_MULTI_MIX_GROUP; multi->controls[i].mix_control.flags = B_MULTI_MIX_GROUP;
multi->controls[i].mix_control.master = EMU_MULTI_CONTROL_MASTERID; multi->controls[i].mix_control.master = EMU_MULTI_CONTROL_MASTERID;
multi->controls[i].mix_control.string = string; multi->controls[i].mix_control.string = string;
if(name) if (name)
strcpy(multi->controls[i].mix_control.name, name); strcpy(multi->controls[i].mix_control.name, name);
return multi->controls[i].mix_control.id; return multi->controls[i].mix_control.id;
} }
static status_t static status_t
auich_create_controls_list(multi_dev *multi) auich_create_controls_list(multi_dev *multi)
{ {
@ -203,14 +206,14 @@ auich_create_controls_list(multi_dev *multi)
count = source_info_size; count = source_info_size;
//Note that we ignore first item in source_info //Note that we ignore first item in source_info
//It's for recording, but do match this with ac97.c's source_info //It's for recording, but do match this with ac97.c's source_info
for(i=1; i < count ; i++) { for (i=1; i < count ; i++) {
info = &source_info[i]; info = &source_info[i];
PRINT(("name : %s\n", info->name)); PRINT(("name : %s\n", info->name));
parent2 = auich_create_group_control(multi, &index, parent, 0, info->name); parent2 = auich_create_group_control(multi, &index, parent, 0, info->name);
if(info->type & B_MIX_GAIN) { if (info->type & B_MIX_GAIN) {
if(info->type & B_MIX_MUTE) { if (info->type & B_MIX_MUTE) {
multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index;
multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE; multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE;
multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID;
@ -238,7 +241,7 @@ auich_create_controls_list(multi_dev *multi)
id = multi->controls[index].mix_control.id; id = multi->controls[index].mix_control.id;
index++; index++;
if(info->type & B_MIX_STEREO) { if (info->type & B_MIX_STEREO) {
multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index;
multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN; multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN;
multi->controls[index].mix_control.master = id; multi->controls[index].mix_control.master = id;
@ -254,7 +257,7 @@ auich_create_controls_list(multi_dev *multi)
index++; index++;
} }
if(info->type & B_MIX_MICBOOST) { if (info->type & B_MIX_MICBOOST) {
multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index;
multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE; multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE;
multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID;
@ -277,8 +280,8 @@ auich_create_controls_list(multi_dev *multi)
parent2 = auich_create_group_control(multi, &index, parent, 0, info->name); parent2 = auich_create_group_control(multi, &index, parent, 0, info->name);
if(info->type & B_MIX_GAIN) { if (info->type & B_MIX_GAIN) {
if(info->type & B_MIX_MUTE) { if (info->type & B_MIX_MUTE) {
multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index;
multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE; multi->controls[index].mix_control.flags = B_MULTI_MIX_ENABLE;
multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID; multi->controls[index].mix_control.master = EMU_MULTI_CONTROL_MASTERID;
@ -306,7 +309,7 @@ auich_create_controls_list(multi_dev *multi)
id = multi->controls[index].mix_control.id; id = multi->controls[index].mix_control.id;
index++; index++;
if(info->type & B_MIX_STEREO) { if (info->type & B_MIX_STEREO) {
multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index;
multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN; multi->controls[index].mix_control.flags = B_MULTI_MIX_GAIN;
multi->controls[index].mix_control.master = id; multi->controls[index].mix_control.master = id;
@ -322,7 +325,7 @@ auich_create_controls_list(multi_dev *multi)
index++; index++;
} }
if(info->type & B_MIX_RECORDMUX) { if (info->type & B_MIX_RECORDMUX) {
multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index; multi->controls[index].mix_control.id = EMU_MULTI_CONTROL_FIRSTID + index;
multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX; multi->controls[index].mix_control.flags = B_MULTI_MIX_MUX;
multi->controls[index].mix_control.parent = parent2; multi->controls[index].mix_control.parent = parent2;
@ -382,37 +385,38 @@ auich_create_controls_list(multi_dev *multi)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_get_mix(auich_dev *card, multi_mix_value_info * MMVI) auich_get_mix(auich_dev *card, multi_mix_value_info * MMVI)
{ {
int32 i, id; int32 i, id;
multi_mixer_control *control = NULL; multi_mixer_control *control = NULL;
for(i=0; i<MMVI->item_count; i++) { for (i=0; i<MMVI->item_count; i++) {
id = MMVI->values[i].id - EMU_MULTI_CONTROL_FIRSTID; id = MMVI->values[i].id - EMU_MULTI_CONTROL_FIRSTID;
if(id < 0 || id >= card->multi.control_count) { if (id < 0 || id >= card->multi.control_count) {
PRINT(("auich_get_mix : invalid control id requested : %li\n", id)); PRINT(("auich_get_mix : invalid control id requested : %li\n", id));
continue; continue;
} }
control = &card->multi.controls[id]; control = &card->multi.controls[id];
if(control->mix_control.flags & B_MULTI_MIX_GAIN) { if (control->mix_control.flags & B_MULTI_MIX_GAIN) {
if(control->get) { if (control->get) {
float values[2]; float values[2];
control->get(card, control->cookie, control->type, values); control->get(card, control->cookie, control->type, values);
if(control->mix_control.master == EMU_MULTI_CONTROL_MASTERID) if (control->mix_control.master == EMU_MULTI_CONTROL_MASTERID)
MMVI->values[i].u.gain = values[0]; MMVI->values[i].u.gain = values[0];
else else
MMVI->values[i].u.gain = values[1]; MMVI->values[i].u.gain = values[1];
} }
} }
if(control->mix_control.flags & B_MULTI_MIX_ENABLE && control->get) { if (control->mix_control.flags & B_MULTI_MIX_ENABLE && control->get) {
float values[1]; float values[1];
control->get(card, control->cookie, control->type, values); control->get(card, control->cookie, control->type, values);
MMVI->values[i].u.enable = (values[0] == 1.0); MMVI->values[i].u.enable = (values[0] == 1.0);
} }
if(control->mix_control.flags & B_MULTI_MIX_MUX && control->get) { if (control->mix_control.flags & B_MULTI_MIX_MUX && control->get) {
float values[1]; float values[1];
control->get(card, control->cookie, control->type, values); control->get(card, control->cookie, control->type, values);
MMVI->values[i].u.mux = (int32)values[0]; MMVI->values[i].u.mux = (int32)values[0];
@ -421,60 +425,61 @@ auich_get_mix(auich_dev *card, multi_mix_value_info * MMVI)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_set_mix(auich_dev *card, multi_mix_value_info * MMVI) auich_set_mix(auich_dev *card, multi_mix_value_info * MMVI)
{ {
int32 i, id; int32 i, id;
multi_mixer_control *control = NULL; multi_mixer_control *control = NULL;
for(i=0; i<MMVI->item_count; i++) { for (i=0; i<MMVI->item_count; i++) {
id = MMVI->values[i].id - EMU_MULTI_CONTROL_FIRSTID; id = MMVI->values[i].id - EMU_MULTI_CONTROL_FIRSTID;
if(id < 0 || id >= card->multi.control_count) { if (id < 0 || id >= card->multi.control_count) {
PRINT(("auich_set_mix : invalid control id requested : %li\n", id)); PRINT(("auich_set_mix : invalid control id requested : %li\n", id));
continue; continue;
} }
control = &card->multi.controls[id]; control = &card->multi.controls[id];
if(control->mix_control.flags & B_MULTI_MIX_GAIN) { if (control->mix_control.flags & B_MULTI_MIX_GAIN) {
multi_mixer_control *control2 = NULL; multi_mixer_control *control2 = NULL;
if(i+1<MMVI->item_count) { if (i+1<MMVI->item_count) {
id = MMVI->values[i + 1].id - EMU_MULTI_CONTROL_FIRSTID; id = MMVI->values[i + 1].id - EMU_MULTI_CONTROL_FIRSTID;
if(id < 0 || id >= card->multi.control_count) { if (id < 0 || id >= card->multi.control_count) {
PRINT(("auich_set_mix : invalid control id requested : %li\n", id)); PRINT(("auich_set_mix : invalid control id requested : %li\n", id));
} else { } else {
control2 = &card->multi.controls[id]; control2 = &card->multi.controls[id];
if(control2->mix_control.master != control->mix_control.id) if (control2->mix_control.master != control->mix_control.id)
control2 = NULL; control2 = NULL;
} }
} }
if(control->set) { if (control->set) {
float values[2]; float values[2];
values[0] = 0.0; values[0] = 0.0;
values[1] = 0.0; values[1] = 0.0;
if(control->mix_control.master == EMU_MULTI_CONTROL_MASTERID) if (control->mix_control.master == EMU_MULTI_CONTROL_MASTERID)
values[0] = MMVI->values[i].u.gain; values[0] = MMVI->values[i].u.gain;
else else
values[1] = MMVI->values[i].u.gain; values[1] = MMVI->values[i].u.gain;
if(control2 && control2->mix_control.master != EMU_MULTI_CONTROL_MASTERID) if (control2 && control2->mix_control.master != EMU_MULTI_CONTROL_MASTERID)
values[1] = MMVI->values[i+1].u.gain; values[1] = MMVI->values[i+1].u.gain;
control->set(card, control->cookie, control->type, values); control->set(card, control->cookie, control->type, values);
} }
if(control2) if (control2)
i++; i++;
} }
if(control->mix_control.flags & B_MULTI_MIX_ENABLE && control->set) { if (control->mix_control.flags & B_MULTI_MIX_ENABLE && control->set) {
float values[1]; float values[1];
values[0] = MMVI->values[i].u.enable ? 1.0 : 0.0; values[0] = MMVI->values[i].u.enable ? 1.0 : 0.0;
control->set(card, control->cookie, control->type, values); control->set(card, control->cookie, control->type, values);
} }
if(control->mix_control.flags & B_MULTI_MIX_MUX && control->set) { if (control->mix_control.flags & B_MULTI_MIX_MUX && control->set) {
float values[1]; float values[1];
values[0] = (float)MMVI->values[i].u.mux; values[0] = (float)MMVI->values[i].u.mux;
@ -484,6 +489,7 @@ auich_set_mix(auich_dev *card, multi_mix_value_info * MMVI)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_list_mix_controls(auich_dev *card, multi_mix_control_info * MMCI) auich_list_mix_controls(auich_dev *card, multi_mix_control_info * MMCI)
{ {
@ -491,12 +497,12 @@ auich_list_mix_controls(auich_dev *card, multi_mix_control_info * MMCI)
int32 i; int32 i;
MMC = MMCI->controls; MMC = MMCI->controls;
if(MMCI->control_count < 24) if (MMCI->control_count < 24)
return B_ERROR; return B_ERROR;
if(auich_create_controls_list(&card->multi) < B_OK) if (auich_create_controls_list(&card->multi) < B_OK)
return B_ERROR; return B_ERROR;
for(i=0; i<card->multi.control_count; i++) { for (i=0; i<card->multi.control_count; i++) {
MMC[i] = card->multi.controls[i].mix_control; MMC[i] = card->multi.controls[i].mix_control;
} }
@ -504,12 +510,14 @@ auich_list_mix_controls(auich_dev *card, multi_mix_control_info * MMCI)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_list_mix_connections(auich_dev *card, multi_mix_connection_info * data) auich_list_mix_connections(auich_dev *card, multi_mix_connection_info * data)
{ {
return B_ERROR; return B_ERROR;
} }
static status_t static status_t
auich_list_mix_channels(auich_dev *card, multi_mix_channel_info *data) auich_list_mix_channels(auich_dev *card, multi_mix_channel_info *data)
{ {
@ -567,18 +575,18 @@ auich_create_channels_list(multi_dev *multi)
chans = multi->chans; chans = multi->chans;
index = 0; index = 0;
for(mode=AUICH_USE_PLAY; mode!=-1; for (mode=AUICH_USE_PLAY; mode!=-1;
mode = (mode == AUICH_USE_PLAY) ? AUICH_USE_RECORD : -1) { mode = (mode == AUICH_USE_PLAY) ? AUICH_USE_RECORD : -1) {
LIST_FOREACH(stream, &((auich_dev*)multi->card)->streams, next) { LIST_FOREACH(stream, &((auich_dev*)multi->card)->streams, next) {
if ((stream->use & mode) == 0) if ((stream->use & mode) == 0)
continue; continue;
if(stream->channels == 2) if (stream->channels == 2)
designations = B_CHANNEL_STEREO_BUS; designations = B_CHANNEL_STEREO_BUS;
else else
designations = B_CHANNEL_SURROUND_BUS; designations = B_CHANNEL_SURROUND_BUS;
for(i=0; i<stream->channels; i++) { for (i=0; i<stream->channels; i++) {
chans[index].channel_id = index; chans[index].channel_id = index;
chans[index].kind = (mode == AUICH_USE_PLAY) ? B_MULTI_OUTPUT_CHANNEL : B_MULTI_INPUT_CHANNEL; chans[index].kind = (mode == AUICH_USE_PLAY) ? B_MULTI_OUTPUT_CHANNEL : B_MULTI_INPUT_CHANNEL;
chans[index].designations = designations | chan_designations[i]; chans[index].designations = designations | chan_designations[i];
@ -587,7 +595,7 @@ auich_create_channels_list(multi_dev *multi)
} }
} }
if(mode==AUICH_USE_PLAY) { if (mode==AUICH_USE_PLAY) {
multi->output_channel_count = index; multi->output_channel_count = index;
} else { } else {
multi->input_channel_count = index - multi->output_channel_count; multi->input_channel_count = index - multi->output_channel_count;
@ -699,6 +707,7 @@ auich_get_description(auich_dev *card, multi_description *data)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_get_enabled_channels(auich_dev *card, multi_channel_enable *data) auich_get_enabled_channels(auich_dev *card, multi_channel_enable *data)
{ {
@ -716,6 +725,7 @@ auich_get_enabled_channels(auich_dev *card, multi_channel_enable *data)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_set_enabled_channels(auich_dev *card, multi_channel_enable *data) auich_set_enabled_channels(auich_dev *card, multi_channel_enable *data)
{ {
@ -726,6 +736,7 @@ auich_set_enabled_channels(auich_dev *card, multi_channel_enable *data)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_get_global_format(auich_dev *card, multi_format_info *data) auich_get_global_format(auich_dev *card, multi_format_info *data)
{ {
@ -746,6 +757,7 @@ auich_get_global_format(auich_dev *card, multi_format_info *data)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_get_buffers(auich_dev *card, multi_buffer_list *data) auich_get_buffers(auich_dev *card, multi_buffer_list *data)
{ {
@ -779,11 +791,11 @@ auich_get_buffers(auich_dev *card, multi_buffer_list *data)
data->return_playback_buffer_size = current_settings.buffer_frames; /* frames */ data->return_playback_buffer_size = current_settings.buffer_frames; /* frames */
bufcount = current_settings.buffer_count; bufcount = current_settings.buffer_count;
if(bufcount > data->request_playback_buffers) if (bufcount > data->request_playback_buffers)
bufcount = data->request_playback_buffers; bufcount = data->request_playback_buffers;
for(i=0; i<bufcount; i++) for (i=0; i<bufcount; i++)
for(j=0; j<pchannels; j++) for (j=0; j<pchannels; j++)
auich_stream_get_nth_buffer(card->pstream, j, i, auich_stream_get_nth_buffer(card->pstream, j, i,
&data->playback_buffers[i][j].base, &data->playback_buffers[i][j].base,
&data->playback_buffers[i][j].stride); &data->playback_buffers[i][j].stride);
@ -793,11 +805,11 @@ auich_get_buffers(auich_dev *card, multi_buffer_list *data)
data->return_record_buffer_size = current_settings.buffer_frames; /* frames */ data->return_record_buffer_size = current_settings.buffer_frames; /* frames */
bufcount = current_settings.buffer_count; bufcount = current_settings.buffer_count;
if(bufcount > data->request_record_buffers) if (bufcount > data->request_record_buffers)
bufcount = data->request_record_buffers; bufcount = data->request_record_buffers;
for(i=0; i<bufcount; i++) for (i=0; i<bufcount; i++)
for(j=0; j<rchannels; j++) for (j=0; j<rchannels; j++)
auich_stream_get_nth_buffer(card->rstream, j, i, auich_stream_get_nth_buffer(card->rstream, j, i,
&data->record_buffers[i][j].base, &data->record_buffers[i][j].base,
&data->record_buffers[i][j].stride); &data->record_buffers[i][j].stride);
@ -827,6 +839,7 @@ auich_play_inth(void* inthparams)
release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
} }
static void static void
auich_record_inth(void* inthparams) auich_record_inth(void* inthparams)
{ {
@ -848,11 +861,15 @@ auich_record_inth(void* inthparams)
release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); release_sem_etc(stream->card->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE);
} }
static status_t static status_t
auich_buffer_exchange(auich_dev *card, multi_buffer_info *data) auich_buffer_exchange(auich_dev *card, multi_buffer_info *data)
{ {
cpu_status status; cpu_status status;
auich_stream *pstream, *rstream; auich_stream *pstream, *rstream;
bigtime_t played_real_time, recorded_real_time;
uint64 played_frames_count, recorded_frames_count;
int32 playback_buffer_cycle, record_buffer_cycle, _reserved_0, _reserved_1;
data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;
@ -862,7 +879,7 @@ auich_buffer_exchange(auich_dev *card, multi_buffer_info *data)
if (!(card->rstream->state & AUICH_STATE_STARTED)) if (!(card->rstream->state & AUICH_STATE_STARTED))
auich_stream_start(card->rstream, auich_record_inth, card->rstream); auich_stream_start(card->rstream, auich_record_inth, card->rstream);
if(acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000) if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000)
== B_TIMED_OUT) { == B_TIMED_OUT) {
LOG(("buffer_exchange timeout ff\n")); LOG(("buffer_exchange timeout ff\n"));
} }
@ -873,7 +890,7 @@ auich_buffer_exchange(auich_dev *card, multi_buffer_info *data)
if ((pstream->use & AUICH_USE_PLAY) == 0 || if ((pstream->use & AUICH_USE_PLAY) == 0 ||
(pstream->state & AUICH_STATE_STARTED) == 0) (pstream->state & AUICH_STATE_STARTED) == 0)
continue; continue;
if(pstream->update_needed) if (pstream->update_needed)
break; break;
} }
@ -881,34 +898,51 @@ auich_buffer_exchange(auich_dev *card, multi_buffer_info *data)
if ((rstream->use & AUICH_USE_RECORD) == 0 || if ((rstream->use & AUICH_USE_RECORD) == 0 ||
(rstream->state & AUICH_STATE_STARTED) == 0) (rstream->state & AUICH_STATE_STARTED) == 0)
continue; continue;
if(rstream->update_needed) if (rstream->update_needed)
break; break;
} }
if(!pstream) if (!pstream)
pstream = card->pstream; pstream = card->pstream;
if(!rstream) if (!rstream)
rstream = card->rstream; rstream = card->rstream;
/* do playback */ /* do playback */
data->playback_buffer_cycle = pstream->buffer_cycle; playback_buffer_cycle = pstream->buffer_cycle;
data->played_real_time = pstream->real_time; played_real_time = pstream->real_time;
data->played_frames_count = pstream->frames_count; played_frames_count = pstream->frames_count;
data->_reserved_0 = pstream->first_channel; _reserved_0 = pstream->first_channel;
pstream->update_needed = false; pstream->update_needed = false;
/* do record */ /* do record */
data->record_buffer_cycle = rstream->buffer_cycle; record_buffer_cycle = rstream->buffer_cycle;
data->recorded_frames_count = rstream->frames_count; recorded_frames_count = rstream->frames_count;
data->recorded_real_time = rstream->real_time; recorded_real_time = rstream->real_time;
data->_reserved_1 = rstream->first_channel; _reserved_1 = rstream->first_channel;
rstream->update_needed = false; rstream->update_needed = false;
unlock(status); unlock(status);
#ifdef __HAIKU__
#define copy_to_user(x, y) if (user_memcpy(&x, &y, sizeof(x)) < B_OK) \
return B_BAD_ADDRESS
#else
#define copy_to_user(x, y) x = y
#endif
copy_to_user(data->playback_buffer_cycle, playback_buffer_cycle);
copy_to_user(data->played_real_time, played_real_time);
copy_to_user(data->played_frames_count, played_frames_count);
copy_to_user(data->_reserved_0, _reserved_0);
copy_to_user(data->record_buffer_cycle, record_buffer_cycle);
copy_to_user(data->recorded_real_time, recorded_real_time);
copy_to_user(data->recorded_frames_count, recorded_frames_count);
copy_to_user(data->_reserved_1, _reserved_1);
//TRACE(("buffer_exchange ended\n")); //TRACE(("buffer_exchange ended\n"));
return B_OK; return B_OK;
} }
static status_t static status_t
auich_buffer_force_stop(auich_dev *card) auich_buffer_force_stop(auich_dev *card)
{ {
@ -916,6 +950,7 @@ auich_buffer_force_stop(auich_dev *card)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_multi_control(void *cookie, uint32 op, void *data, size_t length) auich_multi_control(void *cookie, uint32 op, void *data, size_t length)
{ {
@ -1009,6 +1044,7 @@ device_hooks multi_hooks = {
NULL /* scatter-gather write to the device */ NULL /* scatter-gather write to the device */
}; };
static status_t static status_t
auich_open(const char *name, uint32 flags, void** cookie) auich_open(const char *name, uint32 flags, void** cookie)
{ {
@ -1024,7 +1060,7 @@ auich_open(const char *name, uint32 flags, void** cookie)
} }
} }
if(card == NULL) { if (card == NULL) {
LOG(("open() card not found %s\n", name)); LOG(("open() card not found %s\n", name));
for (ix=0; ix<num_cards; ix++) { for (ix=0; ix<num_cards; ix++) {
LOG(("open() card available %s\n", cards[ix].name)); LOG(("open() card available %s\n", cards[ix].name));
@ -1034,9 +1070,9 @@ auich_open(const char *name, uint32 flags, void** cookie)
LOG(("open() got card\n")); LOG(("open() got card\n"));
if(card->pstream !=NULL) if (card->pstream !=NULL)
return B_ERROR; return B_ERROR;
if(card->rstream !=NULL) if (card->rstream !=NULL)
return B_ERROR; return B_ERROR;
*cookie = card; *cookie = card;
@ -1090,6 +1126,7 @@ auich_open(const char *name, uint32 flags, void** cookie)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_close(void* cookie) auich_close(void* cookie)
{ {
@ -1099,6 +1136,7 @@ auich_close(void* cookie)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_free(void* cookie) auich_free(void* cookie)
{ {
@ -1113,7 +1151,7 @@ auich_free(void* cookie)
auich_stream_halt(stream); auich_stream_halt(stream);
} }
while(!LIST_EMPTY(&card->streams)) { while (!LIST_EMPTY(&card->streams)) {
auich_stream_delete(LIST_FIRST(&card->streams)); auich_stream_delete(LIST_FIRST(&card->streams));
} }
@ -1123,12 +1161,14 @@ auich_free(void* cookie)
return B_OK; return B_OK;
} }
static status_t static status_t
auich_control(void* cookie, uint32 op, void* arg, size_t len) auich_control(void* cookie, uint32 op, void* arg, size_t len)
{ {
return auich_multi_control(cookie, op, arg, len); return auich_multi_control(cookie, op, arg, len);
} }
static status_t static status_t
auich_read(void* cookie, off_t position, void *buf, size_t* num_bytes) auich_read(void* cookie, off_t position, void *buf, size_t* num_bytes)
{ {
@ -1136,10 +1176,10 @@ auich_read(void* cookie, off_t position, void *buf, size_t* num_bytes)
return B_IO_ERROR; return B_IO_ERROR;
} }
static status_t static status_t
auich_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) auich_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes)
{ {
*num_bytes = 0; /* tell caller nothing was written */ *num_bytes = 0; /* tell caller nothing was written */
return B_IO_ERROR; return B_IO_ERROR;
} }