From 2a3d3b7ad6380159f02b6ee5af3101e0d12ec67b Mon Sep 17 00:00:00 2001 From: "Ithamar R. Adema" Date: Mon, 14 May 2007 01:23:36 +0000 Subject: [PATCH] * More buffer (cycle) handling * Locking of stream info. * Add compile-time support for Haiku/BeOS multi_audio API. TODO: Need to check out why we have multiple (different) multi_audio.h files floating around in the source tree.... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21135 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/drivers/audio/hda/driver.c | 5 +++- src/add-ons/kernel/drivers/audio/hda/driver.h | 18 ++++++++++---- .../kernel/drivers/audio/hda/hda_controller.c | 12 ++++++++-- .../drivers/audio/hda/hda_multi_audio.c | 24 +++++++++++-------- 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.c b/src/add-ons/kernel/drivers/audio/hda/driver.c index dc9af63d0a..77acc9be85 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.c +++ b/src/add-ons/kernel/drivers/audio/hda/driver.c @@ -5,6 +5,9 @@ uint32 num_cards; pci_module_info* pci; +const char** publish_devices(void); /* Just to silence compiler */ + + status_t init_hardware(void) { @@ -82,7 +85,7 @@ uninit_driver (void) } const char** -publish_devices() +publish_devices(void) { static const char* devs[MAXCARDS+1]; long i; diff --git a/src/add-ons/kernel/drivers/audio/hda/driver.h b/src/add-ons/kernel/drivers/audio/hda/driver.h index 49d9662f22..5e5bffc722 100644 --- a/src/add-ons/kernel/drivers/audio/hda/driver.h +++ b/src/add-ons/kernel/drivers/audio/hda/driver.h @@ -5,10 +5,17 @@ #include #include +#include + #include #include -#include "multi_audio.h" +#ifdef COMPILED_FOR_R5 + #define DEVFS_PATH_FORMAT "audio/multi/hda/%lu" +#else + #define DEVFS_PATH_FORMAT "audio/hmulti/hda/%lu" +#endif + #include "hda_controller_defs.h" #include "hda_codec_defs.h" @@ -17,7 +24,6 @@ /* values for the class_sub field for class_base = 0x04 (multimedia device) */ #define PCI_hd_audio 3 -#define DEVFS_PATH_FORMAT "audio/multi/hda/%lu" #define MAXWORK 16 #define HDA_MAXCODECS 15 #define HDA_MAXSTREAMS 16 @@ -38,7 +44,8 @@ typedef struct hda_stream_info_s { uint32 id; /* HDA controller stream # */ uint32 off; /* HDA I/O/B descriptor offset */ bool running; /* Is this stream active? */ - + spinlock lock; /* Write lock */ + uint32 pin_wid; /* PIN Widget ID */ uint32 io_wid; /* Input/Output Converter Widget ID */ @@ -52,8 +59,9 @@ typedef struct hda_stream_info_s { void* buffers[STRMAXBUF]; /* Virtual addresses for buffer */ uint32 buffers_pa[STRMAXBUF]; /* Physical addresses for buffer */ sem_id buffer_ready_sem; - bigtime_t played_real_time; - uint32 played_frames_count; + bigtime_t real_time; + uint32 frames_count; + uint32 buffer_cycle; area_id buffer_area; area_id bdl_area; diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_controller.c b/src/add-ons/kernel/drivers/audio/hda/hda_controller.c index 0ee3dc1875..1b744550f0 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_controller.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_controller.c @@ -59,12 +59,20 @@ hda_stream_check_intr(hda_controller* ctrlr, hda_stream* s) if (s->running) { uint8 sts = OREG8(ctrlr,s->off,STS); if (sts) { + cpu_status status; int32 count; OREG8(ctrlr,s->off,STS) = sts; - s->played_real_time = system_time(); - s->played_frames_count += s->buffer_length; + status = disable_interrupts(); + acquire_spinlock(&s->lock); + + s->real_time = system_time(); + s->frames_count += s->buffer_length; + s->buffer_cycle = (s->buffer_cycle +1) % s->num_buffers; + + release_spinlock(&s->lock); + restore_interrupts(status); get_sem_count(s->buffer_ready_sem, &count); if (count <= 0) diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c index 746aba1717..b85f0a7bbc 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.c @@ -209,24 +209,28 @@ static status_t buffer_exchange(hda_codec* codec, multi_buffer_info* data) { static int debug_buffers_exchanged = 0; + cpu_status status; status_t rc; if (!codec->playback_stream->running) hda_stream_start(codec->ctrlr, codec->playback_stream); -// if (!codec->record_stream->running) -// hda_stream_start(codec->ctrlr, codec->record_stream); - /* do playback */ - rc=acquire_sem(codec->playback_stream->buffer_ready_sem); - if (rc != B_OK) return rc; + rc=acquire_sem_etc(codec->playback_stream->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000); + if (rc != B_OK) { + dprintf("%s: Timeout waiting for playback buffer to finish!\n", __func__); + return rc; + } - data->played_real_time = codec->playback_stream->played_real_time; - data->played_frames_count = codec->playback_stream->played_frames_count; + status = disable_interrupts(); + acquire_spinlock(&codec->playback_stream->lock); - /* do record */ - data->record_buffer_cycle = 0; - data->recorded_frames_count = 0; + data->playback_buffer_cycle = codec->playback_stream->buffer_cycle; + data->played_real_time = codec->playback_stream->real_time; + data->played_frames_count = codec->playback_stream->frames_count; + + release_spinlock(&codec->playback_stream->lock); + restore_interrupts(status); debug_buffers_exchanged++; if (((debug_buffers_exchanged % 100) == 1) && (debug_buffers_exchanged < 1111)) {