* 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
This commit is contained in:
Ithamar R. Adema 2007-05-14 01:23:36 +00:00
parent 7de9382792
commit 2a3d3b7ad6
4 changed files with 41 additions and 18 deletions

View File

@ -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;

View File

@ -5,10 +5,17 @@
#include <drivers/Drivers.h>
#include <drivers/PCI.h>
#include <multi_audio.h>
#include <string.h>
#include <stdlib.h>
#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;

View File

@ -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)

View File

@ -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)) {