* 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:
parent
7de9382792
commit
2a3d3b7ad6
@ -5,6 +5,9 @@ uint32 num_cards;
|
|||||||
|
|
||||||
pci_module_info* pci;
|
pci_module_info* pci;
|
||||||
|
|
||||||
|
const char** publish_devices(void); /* Just to silence compiler */
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
init_hardware(void)
|
init_hardware(void)
|
||||||
{
|
{
|
||||||
@ -82,7 +85,7 @@ uninit_driver (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char**
|
const char**
|
||||||
publish_devices()
|
publish_devices(void)
|
||||||
{
|
{
|
||||||
static const char* devs[MAXCARDS+1];
|
static const char* devs[MAXCARDS+1];
|
||||||
long i;
|
long i;
|
||||||
|
@ -5,10 +5,17 @@
|
|||||||
#include <drivers/Drivers.h>
|
#include <drivers/Drivers.h>
|
||||||
#include <drivers/PCI.h>
|
#include <drivers/PCI.h>
|
||||||
|
|
||||||
|
#include <multi_audio.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.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_controller_defs.h"
|
||||||
#include "hda_codec_defs.h"
|
#include "hda_codec_defs.h"
|
||||||
|
|
||||||
@ -17,7 +24,6 @@
|
|||||||
/* values for the class_sub field for class_base = 0x04 (multimedia device) */
|
/* values for the class_sub field for class_base = 0x04 (multimedia device) */
|
||||||
#define PCI_hd_audio 3
|
#define PCI_hd_audio 3
|
||||||
|
|
||||||
#define DEVFS_PATH_FORMAT "audio/multi/hda/%lu"
|
|
||||||
#define MAXWORK 16
|
#define MAXWORK 16
|
||||||
#define HDA_MAXCODECS 15
|
#define HDA_MAXCODECS 15
|
||||||
#define HDA_MAXSTREAMS 16
|
#define HDA_MAXSTREAMS 16
|
||||||
@ -38,7 +44,8 @@ typedef struct hda_stream_info_s {
|
|||||||
uint32 id; /* HDA controller stream # */
|
uint32 id; /* HDA controller stream # */
|
||||||
uint32 off; /* HDA I/O/B descriptor offset */
|
uint32 off; /* HDA I/O/B descriptor offset */
|
||||||
bool running; /* Is this stream active? */
|
bool running; /* Is this stream active? */
|
||||||
|
spinlock lock; /* Write lock */
|
||||||
|
|
||||||
uint32 pin_wid; /* PIN Widget ID */
|
uint32 pin_wid; /* PIN Widget ID */
|
||||||
uint32 io_wid; /* Input/Output Converter 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 */
|
void* buffers[STRMAXBUF]; /* Virtual addresses for buffer */
|
||||||
uint32 buffers_pa[STRMAXBUF]; /* Physical addresses for buffer */
|
uint32 buffers_pa[STRMAXBUF]; /* Physical addresses for buffer */
|
||||||
sem_id buffer_ready_sem;
|
sem_id buffer_ready_sem;
|
||||||
bigtime_t played_real_time;
|
bigtime_t real_time;
|
||||||
uint32 played_frames_count;
|
uint32 frames_count;
|
||||||
|
uint32 buffer_cycle;
|
||||||
|
|
||||||
area_id buffer_area;
|
area_id buffer_area;
|
||||||
area_id bdl_area;
|
area_id bdl_area;
|
||||||
|
@ -59,12 +59,20 @@ hda_stream_check_intr(hda_controller* ctrlr, hda_stream* s)
|
|||||||
if (s->running) {
|
if (s->running) {
|
||||||
uint8 sts = OREG8(ctrlr,s->off,STS);
|
uint8 sts = OREG8(ctrlr,s->off,STS);
|
||||||
if (sts) {
|
if (sts) {
|
||||||
|
cpu_status status;
|
||||||
int32 count;
|
int32 count;
|
||||||
|
|
||||||
OREG8(ctrlr,s->off,STS) = sts;
|
OREG8(ctrlr,s->off,STS) = sts;
|
||||||
|
|
||||||
s->played_real_time = system_time();
|
status = disable_interrupts();
|
||||||
s->played_frames_count += s->buffer_length;
|
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);
|
get_sem_count(s->buffer_ready_sem, &count);
|
||||||
if (count <= 0)
|
if (count <= 0)
|
||||||
|
@ -209,24 +209,28 @@ static status_t
|
|||||||
buffer_exchange(hda_codec* codec, multi_buffer_info* data)
|
buffer_exchange(hda_codec* codec, multi_buffer_info* data)
|
||||||
{
|
{
|
||||||
static int debug_buffers_exchanged = 0;
|
static int debug_buffers_exchanged = 0;
|
||||||
|
cpu_status status;
|
||||||
status_t rc;
|
status_t rc;
|
||||||
|
|
||||||
if (!codec->playback_stream->running)
|
if (!codec->playback_stream->running)
|
||||||
hda_stream_start(codec->ctrlr, codec->playback_stream);
|
hda_stream_start(codec->ctrlr, codec->playback_stream);
|
||||||
|
|
||||||
// if (!codec->record_stream->running)
|
|
||||||
// hda_stream_start(codec->ctrlr, codec->record_stream);
|
|
||||||
|
|
||||||
/* do playback */
|
/* do playback */
|
||||||
rc=acquire_sem(codec->playback_stream->buffer_ready_sem);
|
rc=acquire_sem_etc(codec->playback_stream->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000);
|
||||||
if (rc != B_OK) return rc;
|
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;
|
status = disable_interrupts();
|
||||||
data->played_frames_count = codec->playback_stream->played_frames_count;
|
acquire_spinlock(&codec->playback_stream->lock);
|
||||||
|
|
||||||
/* do record */
|
data->playback_buffer_cycle = codec->playback_stream->buffer_cycle;
|
||||||
data->record_buffer_cycle = 0;
|
data->played_real_time = codec->playback_stream->real_time;
|
||||||
data->recorded_frames_count = 0;
|
data->played_frames_count = codec->playback_stream->frames_count;
|
||||||
|
|
||||||
|
release_spinlock(&codec->playback_stream->lock);
|
||||||
|
restore_interrupts(status);
|
||||||
|
|
||||||
debug_buffers_exchanged++;
|
debug_buffers_exchanged++;
|
||||||
if (((debug_buffers_exchanged % 100) == 1) && (debug_buffers_exchanged < 1111)) {
|
if (((debug_buffers_exchanged % 100) == 1) && (debug_buffers_exchanged < 1111)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user