mirror of
https://github.com/brunodev85/winlator.git
synced 2024-11-23 05:09:38 +00:00
Update audio_plugin
This commit is contained in:
parent
1a2d360ef6
commit
8fecfc95ae
@ -1,9 +1,9 @@
|
|||||||
@hooks [
|
@hooks [
|
||||||
{
|
{
|
||||||
func load
|
func load
|
||||||
files [
|
files [
|
||||||
"/etc/alsa/conf.d/android_aserver.conf"
|
"/etc/alsa/conf.d/android_aserver.conf"
|
||||||
]
|
]
|
||||||
errors false
|
errors false
|
||||||
}
|
}
|
||||||
]
|
]
|
@ -24,229 +24,229 @@
|
|||||||
#define DATA_TYPE_FLOATLE 3
|
#define DATA_TYPE_FLOATLE 3
|
||||||
#define DATA_TYPE_FLOATBE 4
|
#define DATA_TYPE_FLOATBE 4
|
||||||
|
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
typedef struct snd_pcm_android_aserver {
|
typedef struct snd_pcm_android_aserver {
|
||||||
snd_pcm_ioplug_t io;
|
snd_pcm_ioplug_t io;
|
||||||
int fd;
|
int fd;
|
||||||
int frame_bytes;
|
int frame_bytes;
|
||||||
unsigned int position;
|
unsigned int position;
|
||||||
void* buffer;
|
void* buffer;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
bool use_shm;
|
bool use_shm;
|
||||||
} snd_pcm_android_aserver_t;
|
} snd_pcm_android_aserver_t;
|
||||||
|
|
||||||
static int android_aserver_recv_fd(int fd) {
|
static int android_aserver_recv_fd(int fd) {
|
||||||
char zero = 0;
|
char zero = 0;
|
||||||
struct iovec iovmsg = {.iov_base = &zero, .iov_len = 1};
|
struct iovec iovmsg = {.iov_base = &zero, .iov_len = 1};
|
||||||
struct {
|
struct {
|
||||||
struct cmsghdr align;
|
struct cmsghdr align;
|
||||||
int fds[1];
|
int fds[1];
|
||||||
} ctrlmsg;
|
} ctrlmsg;
|
||||||
|
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_name = NULL,
|
.msg_name = NULL,
|
||||||
.msg_namelen = 0,
|
.msg_namelen = 0,
|
||||||
.msg_iov = &iovmsg,
|
.msg_iov = &iovmsg,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
.msg_flags = 0,
|
.msg_flags = 0,
|
||||||
.msg_control = &ctrlmsg,
|
.msg_control = &ctrlmsg,
|
||||||
.msg_controllen = sizeof(struct cmsghdr) + sizeof(int)
|
.msg_controllen = sizeof(struct cmsghdr) + sizeof(int)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
cmsg->cmsg_level = SOL_SOCKET;
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
cmsg->cmsg_type = SCM_RIGHTS;
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
cmsg->cmsg_len = msg.msg_controllen;
|
cmsg->cmsg_len = msg.msg_controllen;
|
||||||
((int*)CMSG_DATA(cmsg))[0] = -1;
|
((int*)CMSG_DATA(cmsg))[0] = -1;
|
||||||
|
|
||||||
recvmsg(fd, &msg, 0);
|
recvmsg(fd, &msg, 0);
|
||||||
return ((int*)CMSG_DATA(cmsg))[0];
|
return ((int*)CMSG_DATA(cmsg))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_close(snd_pcm_ioplug_t* io) {
|
static int android_aserver_close(snd_pcm_ioplug_t* io) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
if (!android_aserver) return 0;
|
if (!android_aserver) return 0;
|
||||||
|
|
||||||
if (android_aserver->fd >= 0) {
|
if (android_aserver->fd >= 0) {
|
||||||
int request_length = 0;
|
int request_length = 0;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_CLOSE;
|
request_data[0] = REQUEST_CODE_CLOSE;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
close(android_aserver->fd);
|
close(android_aserver->fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (android_aserver->buffer_size > 0) {
|
if (android_aserver->buffer_size > 0) {
|
||||||
munmap(android_aserver->buffer, android_aserver->buffer_size);
|
munmap(android_aserver->buffer, android_aserver->buffer_size);
|
||||||
android_aserver->buffer_size = 0;
|
android_aserver->buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(android_aserver);
|
free(android_aserver);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_start(snd_pcm_ioplug_t* io) {
|
static int android_aserver_start(snd_pcm_ioplug_t* io) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
|
|
||||||
int request_length = 0;
|
int request_length = 0;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_START;
|
request_data[0] = REQUEST_CODE_START;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return -EINVAL;
|
if (res < 0) return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_stop(snd_pcm_ioplug_t* io) {
|
static int android_aserver_stop(snd_pcm_ioplug_t* io) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
|
|
||||||
int request_length = 0;
|
int request_length = 0;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_STOP;
|
request_data[0] = REQUEST_CODE_STOP;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return -EINVAL;
|
if (res < 0) return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_pause(snd_pcm_ioplug_t* io, int enable) {
|
static int android_aserver_pause(snd_pcm_ioplug_t* io, int enable) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
|
|
||||||
int request_length = 0;
|
int request_length = 0;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_PAUSE;
|
request_data[0] = REQUEST_CODE_PAUSE;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return -EINVAL;
|
if (res < 0) return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_prepare(snd_pcm_ioplug_t* io) {
|
static int android_aserver_prepare(snd_pcm_ioplug_t* io) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
android_aserver->frame_bytes = (snd_pcm_format_physical_width(io->format) * io->channels) / 8;
|
android_aserver->frame_bytes = (snd_pcm_format_physical_width(io->format) * io->channels) / 8;
|
||||||
android_aserver->position = 0;
|
android_aserver->position = 0;
|
||||||
|
|
||||||
char channels = (char)io->channels;
|
char channels = (char)io->channels;
|
||||||
char data_type;
|
char data_type;
|
||||||
switch (io->format) {
|
switch (io->format) {
|
||||||
case SND_PCM_FORMAT_U8:
|
case SND_PCM_FORMAT_U8:
|
||||||
data_type = DATA_TYPE_U8;
|
data_type = DATA_TYPE_U8;
|
||||||
break;
|
break;
|
||||||
case SND_PCM_FORMAT_S16_LE:
|
case SND_PCM_FORMAT_S16_LE:
|
||||||
data_type = DATA_TYPE_S16LE;
|
data_type = DATA_TYPE_S16LE;
|
||||||
break;
|
break;
|
||||||
case SND_PCM_FORMAT_S16_BE:
|
case SND_PCM_FORMAT_S16_BE:
|
||||||
data_type = DATA_TYPE_S16BE;
|
data_type = DATA_TYPE_S16BE;
|
||||||
break;
|
break;
|
||||||
case SND_PCM_FORMAT_FLOAT_LE:
|
case SND_PCM_FORMAT_FLOAT_LE:
|
||||||
data_type = DATA_TYPE_FLOATLE;
|
data_type = DATA_TYPE_FLOATLE;
|
||||||
break;
|
break;
|
||||||
case SND_PCM_FORMAT_FLOAT_BE:
|
case SND_PCM_FORMAT_FLOAT_BE:
|
||||||
data_type = DATA_TYPE_FLOATBE;
|
data_type = DATA_TYPE_FLOATBE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int request_length = 10;
|
int request_length = 10;
|
||||||
char request_data[request_length + MIN_REQUEST_LENGTH];
|
char request_data[request_length + MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_PREPARE;
|
request_data[0] = REQUEST_CODE_PREPARE;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
memcpy(request_data + 5, &channels, 1);
|
memcpy(request_data + 5, &channels, 1);
|
||||||
memcpy(request_data + 6, &data_type, 1);
|
memcpy(request_data + 6, &data_type, 1);
|
||||||
memcpy(request_data + 7, &io->rate, 4);
|
memcpy(request_data + 7, &io->rate, 4);
|
||||||
memcpy(request_data + 11, &io->buffer_size, 4);
|
memcpy(request_data + 11, &io->buffer_size, 4);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, request_length + MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, request_length + MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return -EINVAL;
|
if (res < 0) return -EINVAL;
|
||||||
|
|
||||||
if (android_aserver->use_shm) {
|
if (android_aserver->use_shm) {
|
||||||
if (android_aserver->buffer_size > 0) {
|
if (android_aserver->buffer_size > 0) {
|
||||||
munmap(android_aserver->buffer, android_aserver->buffer_size);
|
munmap(android_aserver->buffer, android_aserver->buffer_size);
|
||||||
android_aserver->buffer_size = 0;
|
android_aserver->buffer_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = android_aserver_recv_fd(android_aserver->fd);
|
int fd = android_aserver_recv_fd(android_aserver->fd);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
android_aserver->buffer_size = io->buffer_size * android_aserver->frame_bytes;
|
android_aserver->buffer_size = io->buffer_size * android_aserver->frame_bytes;
|
||||||
android_aserver->buffer = mmap(NULL, android_aserver->buffer_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
|
android_aserver->buffer = mmap(NULL, android_aserver->buffer_size, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
|
||||||
|
|
||||||
if (android_aserver->buffer == MAP_FAILED) {
|
if (android_aserver->buffer == MAP_FAILED) {
|
||||||
android_aserver->buffer_size = 0;
|
android_aserver->buffer_size = 0;
|
||||||
android_aserver->use_shm = false;
|
android_aserver->use_shm = false;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_sframes_t android_aserver_pointer(snd_pcm_ioplug_t* io) {
|
static snd_pcm_sframes_t android_aserver_pointer(snd_pcm_ioplug_t* io) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
|
|
||||||
int request_length = 0;
|
int request_length = 0;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_POINTER;
|
request_data[0] = REQUEST_CODE_POINTER;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return android_aserver->position;
|
if (res < 0) return android_aserver->position;
|
||||||
|
|
||||||
int position;
|
int position;
|
||||||
res = read(android_aserver->fd, &position, 4);
|
res = read(android_aserver->fd, &position, 4);
|
||||||
if (res != 4) return android_aserver->position;
|
if (res != 4) return android_aserver->position;
|
||||||
|
|
||||||
android_aserver->position = position;
|
android_aserver->position = position;
|
||||||
return android_aserver->position;
|
return android_aserver->position;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_sframes_t android_aserver_transfer(snd_pcm_ioplug_t* io, const snd_pcm_channel_area_t* areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) {
|
static snd_pcm_sframes_t android_aserver_transfer(snd_pcm_ioplug_t* io, const snd_pcm_channel_area_t* areas, snd_pcm_uframes_t offset, snd_pcm_uframes_t size) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
|
|
||||||
char* data = (char*)areas->addr + (areas->first + areas->step * offset) / 8;
|
char* data = (char*)areas->addr + (areas->first + areas->step * offset) / 8;
|
||||||
|
|
||||||
int request_length = size * android_aserver->frame_bytes;
|
int request_length = size * android_aserver->frame_bytes;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_WRITE;
|
request_data[0] = REQUEST_CODE_WRITE;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
if (android_aserver->use_shm) memcpy(android_aserver->buffer, data, request_length);
|
if (android_aserver->use_shm) memcpy(android_aserver->buffer, data, request_length);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return 0;
|
if (res < 0) return 0;
|
||||||
|
|
||||||
if (!android_aserver->use_shm) {
|
if (!android_aserver->use_shm) {
|
||||||
res = write(android_aserver->fd, data, request_length);
|
res = write(android_aserver->fd, data, request_length);
|
||||||
if (res < 0) return 0;
|
if (res < 0) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_drain(snd_pcm_ioplug_t* io) {
|
static int android_aserver_drain(snd_pcm_ioplug_t* io) {
|
||||||
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
snd_pcm_android_aserver_t* android_aserver = io->private_data;
|
||||||
|
|
||||||
int request_length = 0;
|
int request_length = 0;
|
||||||
char request_data[MIN_REQUEST_LENGTH];
|
char request_data[MIN_REQUEST_LENGTH];
|
||||||
request_data[0] = REQUEST_CODE_DRAIN;
|
request_data[0] = REQUEST_CODE_DRAIN;
|
||||||
memcpy(request_data + 1, &request_length, 4);
|
memcpy(request_data + 1, &request_length, 4);
|
||||||
|
|
||||||
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
int res = write(android_aserver->fd, &request_data, MIN_REQUEST_LENGTH);
|
||||||
if (res < 0) return -EINVAL;
|
if (res < 0) return -EINVAL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_set_hw_constraint(snd_pcm_ioplug_t* io) {
|
static int android_aserver_set_hw_constraint(snd_pcm_ioplug_t* io) {
|
||||||
static const unsigned int access_list[] = {SND_PCM_ACCESS_RW_INTERLEAVED};
|
static const unsigned int access_list[] = {SND_PCM_ACCESS_RW_INTERLEAVED};
|
||||||
static const unsigned int format_list[] = {SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_FLOAT_LE, SND_PCM_FORMAT_FLOAT_BE};
|
static const unsigned int format_list[] = {SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S16_LE, SND_PCM_FORMAT_S16_BE, SND_PCM_FORMAT_FLOAT_LE, SND_PCM_FORMAT_FLOAT_BE};
|
||||||
int err;
|
int err;
|
||||||
@ -262,109 +262,109 @@ static int android_aserver_set_hw_constraint(snd_pcm_ioplug_t* io) {
|
|||||||
|
|
||||||
err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 48000);
|
err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_RATE, 8000, 48000);
|
||||||
if (err < 0) return err;
|
if (err < 0) return err;
|
||||||
|
|
||||||
err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 64, 64 * 1024);
|
err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIOD_BYTES, 64, 64 * 1024);
|
||||||
if (err < 0) return err;
|
if (err < 0) return err;
|
||||||
|
|
||||||
err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 64);
|
err = snd_pcm_ioplug_set_param_minmax(io, SND_PCM_IOPLUG_HW_PERIODS, 2, 64);
|
||||||
if (err < 0) return err;
|
if (err < 0) return err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static snd_pcm_ioplug_callback_t android_aserver_callback = {
|
static snd_pcm_ioplug_callback_t android_aserver_callback = {
|
||||||
.close = android_aserver_close,
|
.close = android_aserver_close,
|
||||||
.start = android_aserver_start,
|
.start = android_aserver_start,
|
||||||
.stop = android_aserver_stop,
|
.stop = android_aserver_stop,
|
||||||
.pause = android_aserver_pause,
|
.pause = android_aserver_pause,
|
||||||
.resume = android_aserver_start,
|
.resume = android_aserver_start,
|
||||||
.prepare = android_aserver_prepare,
|
.prepare = android_aserver_prepare,
|
||||||
.transfer = android_aserver_transfer,
|
.transfer = android_aserver_transfer,
|
||||||
.drain = android_aserver_drain,
|
.drain = android_aserver_drain,
|
||||||
.pointer = android_aserver_pointer,
|
.pointer = android_aserver_pointer,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int android_aserver_connect() {
|
static int android_aserver_connect() {
|
||||||
char* path = getenv("ANDROID_ALSA_SERVER");
|
char* path = getenv("ANDROID_ALSA_SERVER");
|
||||||
|
|
||||||
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (fd < 0) return -1;
|
if (fd < 0) return -1;
|
||||||
|
|
||||||
struct sockaddr_un server_addr;
|
struct sockaddr_un server_addr;
|
||||||
memset(&server_addr, 0, sizeof(server_addr));
|
memset(&server_addr, 0, sizeof(server_addr));
|
||||||
server_addr.sun_family = AF_LOCAL;
|
server_addr.sun_family = AF_LOCAL;
|
||||||
|
|
||||||
strncpy(server_addr.sun_path, path, sizeof(server_addr.sun_path) - 1);
|
strncpy(server_addr.sun_path, path, sizeof(server_addr.sun_path) - 1);
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
do {
|
do {
|
||||||
res = 0;
|
res = 0;
|
||||||
if (connect(fd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_un)) < 0) res = -errno;
|
if (connect(fd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_un)) < 0) res = -errno;
|
||||||
}
|
}
|
||||||
while (res == -EINTR);
|
while (res == -EINTR);
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int android_aserver_create(snd_pcm_t** pcmp, const char* name, snd_pcm_stream_t stream, int mode) {
|
static int android_aserver_create(snd_pcm_t** pcmp, const char* name, snd_pcm_stream_t stream, int mode) {
|
||||||
snd_pcm_android_aserver_t* android_aserver;
|
snd_pcm_android_aserver_t* android_aserver;
|
||||||
|
|
||||||
if (stream != SND_PCM_STREAM_PLAYBACK) return -ENOTSUP;
|
if (stream != SND_PCM_STREAM_PLAYBACK) return -ENOTSUP;
|
||||||
|
|
||||||
android_aserver = calloc(1, sizeof(snd_pcm_android_aserver_t));
|
android_aserver = calloc(1, sizeof(snd_pcm_android_aserver_t));
|
||||||
if (!android_aserver) return -ENOMEM;
|
if (!android_aserver) return -ENOMEM;
|
||||||
|
|
||||||
android_aserver->buffer_size = 0;
|
android_aserver->buffer_size = 0;
|
||||||
android_aserver->io.version = SND_PCM_IOPLUG_VERSION;
|
android_aserver->io.version = SND_PCM_IOPLUG_VERSION;
|
||||||
android_aserver->io.name = "ALSA <-> Android AServer PCM Plugin";
|
android_aserver->io.name = "ALSA <-> Android AServer PCM Plugin";
|
||||||
android_aserver->io.callback = &android_aserver_callback;
|
android_aserver->io.callback = &android_aserver_callback;
|
||||||
android_aserver->io.mmap_rw = 0;
|
android_aserver->io.mmap_rw = 0;
|
||||||
android_aserver->io.private_data = android_aserver;
|
android_aserver->io.private_data = android_aserver;
|
||||||
|
|
||||||
int res = -EINVAL;
|
int res = -EINVAL;
|
||||||
android_aserver->fd = android_aserver_connect();
|
android_aserver->fd = android_aserver_connect();
|
||||||
if (android_aserver->fd < 0) goto error;
|
if (android_aserver->fd < 0) goto error;
|
||||||
|
|
||||||
char* use_shm_value = getenv("ANDROID_ASERVER_USE_SHM");
|
char* use_shm_value = getenv("ANDROID_ASERVER_USE_SHM");
|
||||||
android_aserver->use_shm = use_shm_value && (strcmp(use_shm_value, "true") == 0 || strcmp(use_shm_value, "1") == 0);
|
android_aserver->use_shm = use_shm_value && (strcmp(use_shm_value, "true") == 0 || strcmp(use_shm_value, "1") == 0);
|
||||||
|
|
||||||
res = snd_pcm_ioplug_create(&android_aserver->io, name, stream, mode);
|
res = snd_pcm_ioplug_create(&android_aserver->io, name, stream, mode);
|
||||||
if (res < 0) goto error;
|
if (res < 0) goto error;
|
||||||
|
|
||||||
res = android_aserver_set_hw_constraint(&android_aserver->io);
|
res = android_aserver_set_hw_constraint(&android_aserver->io);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
snd_pcm_ioplug_delete(&android_aserver->io);
|
snd_pcm_ioplug_delete(&android_aserver->io);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pcmp = android_aserver->io.pcm;
|
*pcmp = android_aserver->io.pcm;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (android_aserver->fd >= 0) close(android_aserver->fd);
|
if (android_aserver->fd >= 0) close(android_aserver->fd);
|
||||||
free(android_aserver);
|
free(android_aserver);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
SND_PCM_PLUGIN_DEFINE_FUNC(android_aserver) {
|
SND_PCM_PLUGIN_DEFINE_FUNC(android_aserver) {
|
||||||
snd_config_iterator_t i, next;
|
snd_config_iterator_t i, next;
|
||||||
|
|
||||||
snd_config_for_each(i, next, conf) {
|
snd_config_for_each(i, next, conf) {
|
||||||
snd_config_t* n = snd_config_iterator_entry(i);
|
snd_config_t* n = snd_config_iterator_entry(i);
|
||||||
const char* id;
|
const char* id;
|
||||||
|
|
||||||
if (snd_config_get_id(n, &id) < 0) continue;
|
if (snd_config_get_id(n, &id) < 0) continue;
|
||||||
if (strcmp(id, "type") == 0 || strcmp(id, "hint") == 0) continue;
|
if (strcmp(id, "type") == 0 || strcmp(id, "hint") == 0) continue;
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int err = android_aserver_create(pcmp, name, stream, mode);
|
int err = android_aserver_create(pcmp, name, stream, mode);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
SND_PCM_PLUGIN_SYMBOL(android_aserver);
|
SND_PCM_PLUGIN_SYMBOL(android_aserver);
|
Loading…
Reference in New Issue
Block a user