Working version tested with a Gina3G

* Mixer interface for outputs
* Recording fixed
* Only outputs 1/2 and 3/4 are wired (use the Haiku Media preferences app to select one or the other)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12428 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2005-04-17 22:08:13 +00:00
parent fd5ac83a1a
commit 5608ef1a9e
2 changed files with 64 additions and 32 deletions
+10 -6
View File
@@ -140,7 +140,7 @@ echo_stream_set_audioparms(echo_stream *stream, uint8 channels,
status = stream->card->pEG->CloseAudio(&close_params); status = stream->card->pEG->CloseAudio(&close_params);
if(status!=ECHOSTATUS_OK && status!=ECHOSTATUS_CHANNEL_NOT_OPEN) { if(status!=ECHOSTATUS_OK && status!=ECHOSTATUS_CHANNEL_NOT_OPEN) {
PRINT(("echo_stream_set_audioparms : CloseAudio failed\n")); PRINT(("echo_stream_set_audioparms : CloseAudio failed\n"));
PRINT(("  status: %s \n", pStatusStrs[status])); PRINT((" status: %s \n", pStatusStrs[status]));
return B_ERROR; return B_ERROR;
} }
@@ -276,14 +276,16 @@ void
echo_stream_start(echo_stream *stream, void (*inth) (void *), void *inthparam) echo_stream_start(echo_stream *stream, void (*inth) (void *), void *inthparam)
{ {
LOG(("echo_stream_start\n")); LOG(("echo_stream_start\n"));
ECHOSTATUS status;
stream->inth = inth; stream->inth = inth;
stream->inthparam = inthparam; stream->inthparam = inthparam;
stream->state |= ECHO_STATE_STARTED; stream->state |= ECHO_STATE_STARTED;
if(stream->card->pEG->Start(stream->pipe)!=ECHOSTATUS_OK) { status = stream->card->pEG->Start(stream->pipe);
PRINT(("echo_stream_start : Could not start the pipe\n")); if (status!=ECHOSTATUS_OK) {
PRINT(("echo_stream_start : Could not start the pipe %s\n", pStatusStrs[status]));
} }
} }
@@ -291,11 +293,13 @@ void
echo_stream_halt(echo_stream *stream) echo_stream_halt(echo_stream *stream)
{ {
LOG(("echo_stream_halt\n")); LOG(("echo_stream_halt\n"));
ECHOSTATUS status;
stream->state &= ~ECHO_STATE_STARTED; stream->state &= ~ECHO_STATE_STARTED;
if(stream->card->pEG->Stop(stream->pipe)!=ECHOSTATUS_OK) { status = stream->card->pEG->Stop(stream->pipe);
PRINT(("echo_stream_halt : Could not stop the pipe\n")); if (status!=ECHOSTATUS_OK) {
PRINT(("echo_stream_halt : Could not stop the pipe %s\n", pStatusStrs[status]));
} }
} }
@@ -324,7 +328,7 @@ echo_stream_new(echo_dev *card, uint8 use, uint32 bufframes, uint8 bufcount)
stream->trigblk = 0; stream->trigblk = 0;
stream->blkmod = 0; stream->blkmod = 0;
stream->pipe = card->pEG->MakePipeIndex(0, (use == ECHO_USE_RECORD)); stream->pipe = -1;
stream->frames_count = 0; stream->frames_count = 0;
stream->real_time = 0; stream->real_time = 0;
+51 -23
View File
@@ -54,15 +54,26 @@ static void
echo_channel_get_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float *values) { echo_channel_get_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float *values) {
echo_dev *dev = (echo_dev*) card; echo_dev *dev = (echo_dev*) card;
MIXER_FUNCTION function; MIXER_MULTI_FUNCTION multi_function[2];
INT32 size; PMIXER_FUNCTION function = multi_function[0].MixerFunction;
function.Channel = channel; INT32 size = ComputeMixerMultiFunctionSize(2);
function.iFunction = type == B_MIX_GAIN ? MXF_GET_LEVEL : MXF_GET_MUTE; function[0].Channel = channel;
dev->pEG->ProcessMixerFunction(&function, size); function[1].Channel = channel;
function[1].Channel.wChannel++;
function[0].iFunction = type == B_MIX_GAIN ? MXF_GET_LEVEL : MXF_GET_MUTE;
function[1].iFunction = type == B_MIX_GAIN ? MXF_GET_LEVEL : MXF_GET_MUTE;
if (function.RtnStatus == ECHOSTATUS_OK) { multi_function[0].iCount = 2;
values[0] = function.Data.iLevel; dev->pEG->ProcessMixerMultiFunction(multi_function, size);
PRINT(("echo_channel_get_mix iLevel: %d\n", function.Data.iLevel));
if (function[0].RtnStatus == ECHOSTATUS_OK) {
if (type == B_MIX_GAIN) {
values[0] = (float)function[0].Data.iLevel / 256;
values[1] = (float)function[1].Data.iLevel / 256;
} else {
values[0] = function[0].Data.bMuteOn ? 1.0 : 0.0;
}
PRINT(("echo_channel_get_mix iLevel: %d, %d, %d\n", function[0].Data.iLevel, channel.wChannel, channel.dwType));
} }
} }
@@ -70,15 +81,29 @@ echo_channel_get_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float
static void static void
echo_channel_set_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float *values) { echo_channel_set_mix(void *card, MIXER_AUDIO_CHANNEL channel, int32 type, float *values) {
echo_dev *dev = (echo_dev*) card; echo_dev *dev = (echo_dev*) card;
MIXER_FUNCTION function; MIXER_MULTI_FUNCTION multi_function[2];
INT32 size; PMIXER_FUNCTION function = multi_function[0].MixerFunction;
function.Channel = channel; INT32 size = ComputeMixerMultiFunctionSize(2);
function.Data.iLevel = values[0]; function[0].Channel = channel;
function.iFunction = type == B_MIX_GAIN ? MXF_SET_LEVEL : MXF_SET_MUTE; function[1].Channel = channel;
dev->pEG->ProcessMixerFunction(&function, size); function[1].Channel.wChannel++;
if (type == B_MIX_GAIN) {
function[0].Data.iLevel = (int)(values[0] * 256);
function[0].iFunction = MXF_SET_LEVEL;
function[1].Data.iLevel = (int)(values[1] * 256);
function[1].iFunction = MXF_SET_LEVEL;
} else {
function[0].Data.bMuteOn = values[0] == 1.0;
function[0].iFunction = MXF_SET_MUTE;
function[1].Data.bMuteOn = values[0] == 1.0;
function[1].iFunction = MXF_SET_MUTE;
}
if (function.RtnStatus == ECHOSTATUS_OK) { multi_function[0].iCount = 2;
PRINT(("echo_channel_set_mix OK\n")); dev->pEG->ProcessMixerMultiFunction(multi_function, size);
if (function[0].RtnStatus == ECHOSTATUS_OK) {
PRINT(("echo_channel_set_mix OK: %d, %d, %d\n", function[0].Data.iLevel, channel.wChannel, channel.dwType));
} }
} }
@@ -113,7 +138,7 @@ echo_create_channel_control(multi_dev *multi, uint32 *index, int32 parent, int32
control.set = &echo_channel_set_mix; control.set = &echo_channel_set_mix;
control.mix_control.gain.min_gain = -128; control.mix_control.gain.min_gain = -128;
control.mix_control.gain.max_gain = 6; control.mix_control.gain.max_gain = 6;
control.mix_control.gain.granularity = 1; control.mix_control.gain.granularity = 0.5;
control.mix_control.id = MULTI_CONTROL_FIRSTID + i; control.mix_control.id = MULTI_CONTROL_FIRSTID + i;
control.mix_control.flags = B_MULTI_MIX_ENABLE; control.mix_control.flags = B_MULTI_MIX_ENABLE;
@@ -152,7 +177,7 @@ echo_create_controls_list(multi_dev *multi)
MIXER_AUDIO_CHANNEL channel; MIXER_AUDIO_CHANNEL channel;
channel.dwType = ECHO_BUS_OUT; channel.dwType = ECHO_BUS_OUT;
for (i=0; i < card->caps.wNumBussesOut / 2; i++) { for (i=0; i < card->caps.wNumBussesOut / 2; i++) {
channel.wChannel = i; channel.wChannel = i * 2;
parent2 = echo_create_group_control(multi, &index, parent, S_null, "Output"); parent2 = echo_create_group_control(multi, &index, parent, S_null, "Output");
echo_create_channel_control(multi, &index, parent2, 0, channel); echo_create_channel_control(multi, &index, parent2, 0, channel);
@@ -162,7 +187,7 @@ echo_create_controls_list(multi_dev *multi)
channel.dwType = ECHO_BUS_IN; channel.dwType = ECHO_BUS_IN;
for (i=0; i < card->caps.wNumBussesIn / 2; i++) { for (i=0; i < card->caps.wNumBussesIn / 2; i++) {
channel.wChannel = i; channel.wChannel = i * 2;
parent2 = echo_create_group_control(multi, &index, parent, S_null, "Input"); parent2 = echo_create_group_control(multi, &index, parent, S_null, "Input");
@@ -615,7 +640,7 @@ echo_record_inth(void* inthparams)
stream->real_time = system_time(); stream->real_time = system_time();
stream->frames_count += BUFFER_FRAMES; stream->frames_count += BUFFER_FRAMES;
stream->buffer_cycle = (stream->trigblk stream->buffer_cycle = (stream->trigblk
+ stream->blkmod) % stream->blkmod; + stream->blkmod - 1) % stream->blkmod;
stream->update_needed = true; stream->update_needed = true;
release_spinlock(&slock); release_spinlock(&slock);
@@ -814,6 +839,8 @@ echo_open(const char *name, uint32 flags, void** cookie)
return B_ERROR; return B_ERROR;
if (card->rstream != NULL) if (card->rstream != NULL)
return B_ERROR; return B_ERROR;
if (card->pstream2 != NULL)
return B_ERROR;
*cookie = card; *cookie = card;
card->multi.card = card; card->multi.card = card;
@@ -821,18 +848,19 @@ echo_open(const char *name, uint32 flags, void** cookie)
LOG(("stream_new\n")); LOG(("stream_new\n"));
card->rstream = echo_stream_new(card, ECHO_USE_RECORD, BUFFER_FRAMES, BUFFER_COUNT); card->rstream = echo_stream_new(card, ECHO_USE_RECORD, BUFFER_FRAMES, BUFFER_COUNT);
card->pstream = echo_stream_new(card, ECHO_USE_PLAY, BUFFER_FRAMES, BUFFER_COUNT);
card->pstream2= echo_stream_new(card, ECHO_USE_PLAY, BUFFER_FRAMES, BUFFER_COUNT); card->pstream2= echo_stream_new(card, ECHO_USE_PLAY, BUFFER_FRAMES, BUFFER_COUNT);
card->pstream = echo_stream_new(card, ECHO_USE_PLAY, BUFFER_FRAMES, BUFFER_COUNT);
card->buffer_ready_sem = create_sem(0, "pbuffer ready"); card->buffer_ready_sem = create_sem(0, "pbuffer ready");
LOG(("stream_setaudio\n")); LOG(("stream_setaudio\n"));
echo_stream_set_audioparms(card->pstream, 2, 16, 48000, 2); echo_stream_set_audioparms(card->pstream, 2, 16, 48000, 0);
echo_stream_set_audioparms(card->pstream2, 2, 16, 48000, 0); echo_stream_set_audioparms(card->pstream2, 2, 16, 48000, 2);
echo_stream_set_audioparms(card->rstream, 2, 16, 48000, 0); echo_stream_set_audioparms(card->rstream, 2, 16, 48000, 0);
card->pstream->first_channel = 0; card->pstream->first_channel = 0;
card->pstream2->first_channel = 2;
card->rstream->first_channel = 4; card->rstream->first_channel = 4;
echo_create_channels_list(&card->multi); echo_create_channels_list(&card->multi);