mirror of
https://github.com/libretro/RetroArch
synced 2025-04-04 04:20:29 +00:00
Try making driver a bit more full-featured
This commit is contained in:
parent
b7666b56d1
commit
57c20bdee7
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
/* See https://github.com/tinyalsa/tinyalsa */
|
/* See https://github.com/tinyalsa/tinyalsa */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../../deps/tinyalsa/pcm.h"
|
#include "../../deps/tinyalsa/pcm.h"
|
||||||
@ -37,6 +38,7 @@ typedef struct tinyalsa {
|
|||||||
typedef long pcm_sframes_t;
|
typedef long pcm_sframes_t;
|
||||||
|
|
||||||
#define BYTES_TO_FRAMES(bytes, frame_bits) ((bytes) * 8 / frame_bits)
|
#define BYTES_TO_FRAMES(bytes, frame_bits) ((bytes) * 8 / frame_bits)
|
||||||
|
#define FRAMES_TO_BYTES(frames, frame_bits) ((frames) * frame_bits / 8)
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
tinyalsa_init(const char *device, unsigned rate,
|
tinyalsa_init(const char *device, unsigned rate,
|
||||||
@ -90,20 +92,65 @@ tinyalsa_write(void *data, const void *buf_, size_t size_)
|
|||||||
{
|
{
|
||||||
tinyalsa_t *tinyalsa = (tinyalsa_t*)data;
|
tinyalsa_t *tinyalsa = (tinyalsa_t*)data;
|
||||||
const uint8_t *buf = (const uint8_t*)buf_;
|
const uint8_t *buf = (const uint8_t*)buf_;
|
||||||
pcm_sframes_t written = 0, frames = 0;
|
pcm_sframes_t written = 0;
|
||||||
pcm_sframes_t size = BYTES_TO_FRAMES(size_, tinyalsa->frame_bits);
|
pcm_sframes_t size = BYTES_TO_FRAMES(size_, tinyalsa->frame_bits);
|
||||||
size_t frames_size = tinyalsa->has_float ? sizeof(float) : sizeof(int16_t);
|
size_t frames_size = tinyalsa->has_float ? sizeof(float) : sizeof(int16_t);
|
||||||
|
|
||||||
while (size)
|
if (tinyalsa->nonblock)
|
||||||
{
|
{
|
||||||
frames = pcm_writei(tinyalsa->pcm, buf, size);
|
while (size)
|
||||||
|
{
|
||||||
|
pcm_sframes_t frames = pcm_writei(tinyalsa->pcm, buf, size);
|
||||||
|
|
||||||
if (frames < 0)
|
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||||
return -1;
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (frames == -EAGAIN)
|
||||||
|
break;
|
||||||
|
if (frames < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
written += frames;
|
written += frames;
|
||||||
buf += (frames << 1) * frames_size;
|
buf += (frames << 1) * frames_size;
|
||||||
size -= frames;
|
size -= frames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool eagain_retry = true;
|
||||||
|
|
||||||
|
while (size)
|
||||||
|
{
|
||||||
|
pcm_sframes_t frames;
|
||||||
|
int rc = pcm_wait(tinyalsa->pcm, -1);
|
||||||
|
|
||||||
|
if (rc == -EPIPE || rc == -ESTRPIPE || rc == -EINTR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
frames = pcm_writei(tinyalsa->pcm, buf, size);
|
||||||
|
|
||||||
|
if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (frames == -EAGAIN)
|
||||||
|
{
|
||||||
|
/* Definitely not supposed to happen. */
|
||||||
|
if (eagain_retry)
|
||||||
|
{
|
||||||
|
eagain_retry = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (frames < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
written += frames;
|
||||||
|
buf += (frames << 1) * frames_size;
|
||||||
|
size -= frames;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
@ -185,21 +232,23 @@ tinyalsa_free(void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static size_t tinyalsa_write_avail(void *data)
|
static size_t tinyalsa_write_avail(void *data)
|
||||||
{
|
{
|
||||||
/*TODO*/
|
tinyalsa_t *alsa = (tinyalsa_t*)data;
|
||||||
return 0;
|
pcm_sframes_t avail = pcm_avail_update(alsa->pcm);
|
||||||
|
|
||||||
|
if (avail < 0)
|
||||||
|
return alsa->buffer_size;
|
||||||
|
|
||||||
|
return FRAMES_TO_BYTES(avail, alsa->frame_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t tinyalsa_buffer_size(void *data)
|
||||||
tinyalsa_buffer_size(void *data)
|
|
||||||
{
|
{
|
||||||
tinyalsa_t *tinyalsa = (tinyalsa_t*)data;
|
tinyalsa_t *tinyalsa = (tinyalsa_t*)data;
|
||||||
|
|
||||||
return tinyalsa->buffer_size;
|
return tinyalsa->buffer_size;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
audio_driver_t audio_tinyalsa = {
|
audio_driver_t audio_tinyalsa = {
|
||||||
tinyalsa_init, /* AUDIO_init */
|
tinyalsa_init, /* AUDIO_init */
|
||||||
@ -213,6 +262,6 @@ audio_driver_t audio_tinyalsa = {
|
|||||||
"tinyalsa", /* "AUDIO" */
|
"tinyalsa", /* "AUDIO" */
|
||||||
NULL, /* AUDIO_device_list_new */ /*TODO*/
|
NULL, /* AUDIO_device_list_new */ /*TODO*/
|
||||||
NULL, /* AUDIO_device_list_free */ /*TODO*/
|
NULL, /* AUDIO_device_list_free */ /*TODO*/
|
||||||
/* tinyalsa_write_avail, AUDIO_write_avail */ /*TODO*/
|
tinyalsa_write_avail, /* AUDIO_write_avail */ /*TODO*/
|
||||||
NULL, /* AUDIO_buffer_size */ /*TODO*/
|
tinyalsa_buffer_size, /* AUDIO_buffer_size */ /*TODO*/
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user