* Playback can now be restarted after B_MULTI_BUFFER_FORCE_STOP again; the
hda_stream::buffer_ready_sem was deleted but not recreated again. Moved its maintenance to hda_stream_{start|stop}(). * Replaced snooze(10) with spin(10) because that's probably what's wanted here. * Added hda_stream::type field. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24122 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1cf41b6de1
commit
629ab634f5
@ -52,17 +52,17 @@ enum {
|
||||
STREAM_RECORD
|
||||
};
|
||||
|
||||
/* hda_stream_info
|
||||
/* 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_info {
|
||||
typedef struct hda_stream {
|
||||
uint32 id; /* HDA controller stream # */
|
||||
uint32 off; /* HDA I/O/B descriptor offset */
|
||||
bool running; /* Is this stream active? */
|
||||
spinlock lock; /* Write lock */
|
||||
uint32 type;
|
||||
|
||||
uint32 pin_widget; /* PIN Widget ID */
|
||||
uint32 io_widget; /* Input/Output Converter Widget ID */
|
||||
|
@ -35,21 +35,19 @@ hda_stream_new(hda_controller* controller, int type)
|
||||
if (stream == NULL)
|
||||
return NULL;
|
||||
|
||||
stream->buffer_ready_sem = B_ERROR;
|
||||
stream->buffer_area = B_ERROR;
|
||||
stream->buffer_descriptors_area = B_ERROR;
|
||||
stream->type = type;
|
||||
|
||||
switch (type) {
|
||||
case STREAM_PLAYBACK:
|
||||
stream->buffer_ready_sem = create_sem(0, "hda_playback_sem");
|
||||
stream->id = 1;
|
||||
stream->off = (controller->num_input_streams * HDAC_SDSIZE);
|
||||
controller->streams[controller->num_input_streams] = stream;
|
||||
break;
|
||||
|
||||
case STREAM_RECORD:
|
||||
stream->buffer_area = B_ERROR;
|
||||
stream->buffer_descriptors_area = B_ERROR;
|
||||
stream->buffer_ready_sem = create_sem(0, "hda_record_sem");
|
||||
stream->id = 2;
|
||||
stream->off = 0;
|
||||
controller->streams[0] = stream;
|
||||
@ -69,6 +67,11 @@ hda_stream_new(hda_controller* controller, int type)
|
||||
status_t
|
||||
hda_stream_start(hda_controller* controller, hda_stream* stream)
|
||||
{
|
||||
stream->buffer_ready_sem = create_sem(0,
|
||||
stream->type == STREAM_PLAYBACK ? "hda_playback_sem" : "hda_record_sem");
|
||||
if (stream->buffer_ready_sem < B_OK)
|
||||
return stream->buffer_ready_sem;
|
||||
|
||||
OREG8(controller, stream->off, CTL0) |= CTL0_RUN;
|
||||
|
||||
while (!(OREG8(controller, stream->off, CTL0) & CTL0_RUN))
|
||||
@ -121,6 +124,8 @@ hda_stream_stop(hda_controller* controller, hda_stream* stream)
|
||||
snooze(1);
|
||||
|
||||
stream->running = false;
|
||||
delete_sem(stream->buffer_ready_sem);
|
||||
stream->buffer_ready_sem = -1;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -211,11 +216,12 @@ dprintf("HDA: sample size %ld, num channels %ld, buffer length %ld *************
|
||||
dprintf("%s(%s): Allocated %ld bytes for %ld BDLEs\n", __func__, desc,
|
||||
alloc, stream->num_buffers);
|
||||
|
||||
/* Setup BDL entries */
|
||||
/* Setup buffer descriptor list (BDL) entries */
|
||||
for (index = 0; index < stream->num_buffers; index++, bufferDescriptors++) {
|
||||
bufferDescriptors->address = stream->physical_buffers[index];
|
||||
bufferDescriptors->length = bufferSize;
|
||||
bufferDescriptors->ioc = 1;
|
||||
// we want an interrupt after every buffer
|
||||
}
|
||||
|
||||
/* Configure stream registers */
|
||||
@ -502,7 +508,7 @@ hda_hw_corb_rirb_init(hda_controller* controller)
|
||||
/* NOTE: See HDA011 for corrected procedure! */
|
||||
REG16(controller, CORBRP) = CORBRP_RST;
|
||||
do {
|
||||
snooze(10);
|
||||
spin(10);
|
||||
} while ( !(REG16(controller, CORBRP) & CORBRP_RST) );
|
||||
REG16(controller, CORBRP) = 0;
|
||||
|
||||
@ -631,9 +637,10 @@ hda_hw_stop(hda_controller* controller)
|
||||
int index;
|
||||
|
||||
/* Stop all audio streams */
|
||||
for (index = 0; index < HDA_MAX_STREAMS; index++)
|
||||
for (index = 0; index < HDA_MAX_STREAMS; index++) {
|
||||
if (controller->streams[index] && controller->streams[index]->running)
|
||||
hda_stream_stop(controller, controller->streams[index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -140,6 +140,13 @@ get_global_format(hda_audio_group* audioGroup, multi_format_info* data)
|
||||
static status_t
|
||||
set_global_format(hda_audio_group* audioGroup, multi_format_info* data)
|
||||
{
|
||||
// TODO: it looks like we're not supposed to fail; fix this!
|
||||
#if 0
|
||||
if ((data->output.format & audioGroup->supported_formats) == 0)
|
||||
|| (data->output.rate & audioGroup->supported_rates) == 0)
|
||||
return B_BAD_VALUE;
|
||||
#endif
|
||||
|
||||
audioGroup->playback_stream->sample_format = data->output.format;
|
||||
audioGroup->playback_stream->sample_rate = data->output.rate;
|
||||
audioGroup->playback_stream->sample_size = format2size(
|
||||
@ -181,8 +188,8 @@ 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 playback_sample_size = audioGroup->playback_stream->sample_size;
|
||||
uint32 record_sample_size = audioGroup->record_stream->sample_size;
|
||||
uint32 playbackSampleSize = audioGroup->playback_stream->sample_size;
|
||||
uint32 recordSampleSize = audioGroup->record_stream->sample_size;
|
||||
uint32 cidx, bidx;
|
||||
status_t status;
|
||||
|
||||
@ -257,9 +264,9 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data)
|
||||
for (cidx = 0; cidx < data->return_playback_channels; cidx++) {
|
||||
data->playback_buffers[bidx][cidx].base
|
||||
= audioGroup->playback_stream->buffers[bidx]
|
||||
+ (playback_sample_size * cidx);
|
||||
+ playbackSampleSize * cidx;
|
||||
data->playback_buffers[bidx][cidx].stride
|
||||
= playback_sample_size * data->return_playback_channels;
|
||||
= playbackSampleSize * data->return_playback_channels;
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,9 +274,9 @@ get_buffers(hda_audio_group* audioGroup, multi_buffer_list* data)
|
||||
for (cidx = 0; cidx < data->return_record_channels; cidx++) {
|
||||
data->record_buffers[bidx][cidx].base
|
||||
= audioGroup->record_stream->buffers[bidx]
|
||||
+ (record_sample_size * cidx);
|
||||
+ recordSampleSize * cidx;
|
||||
data->record_buffers[bidx][cidx].stride
|
||||
= record_sample_size * data->return_record_channels;
|
||||
= recordSampleSize * data->return_record_channels;
|
||||
}
|
||||
}
|
||||
|
||||
@ -323,9 +330,6 @@ buffer_force_stop(hda_audio_group* audioGroup)
|
||||
hda_stream_stop(audioGroup->codec->controller, audioGroup->playback_stream);
|
||||
//hda_stream_stop(audioGroup->codec->controller, audioGroup->record_stream);
|
||||
|
||||
delete_sem(audioGroup->playback_stream->buffer_ready_sem);
|
||||
// delete_sem(audioGroup->record_stream->buffer_ready_sem);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user