mirror of
https://github.com/gozfree/gear-lib.git
synced 2026-10-02 14:24:28 +08:00
[libuac] add pulse audio on linux, unfinished
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE := libuac
|
||||
|
||||
ifeq ($(MODE), release)
|
||||
LOCAL_CFLAGS += -O2
|
||||
endif
|
||||
|
||||
LIBRARIES_DIR := $(LOCAL_PATH)/../
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
|
||||
# Add your application source files here...
|
||||
LOCAL_SRC_FILES := libuac.c
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
@@ -0,0 +1,112 @@
|
||||
###############################################################################
|
||||
# common
|
||||
###############################################################################
|
||||
#ARCH: linux/pi/android/ios/
|
||||
ARCH ?= linux
|
||||
CROSS_PREFIX ?=
|
||||
OUTPUT ?= /usr/local
|
||||
BUILD_DIR := $(shell pwd)/../../build/
|
||||
ARCH_INC := $(BUILD_DIR)/$(ARCH).inc
|
||||
COLOR_INC := $(BUILD_DIR)/color.inc
|
||||
|
||||
ifeq ($(ARCH_INC), $(wildcard $(ARCH_INC)))
|
||||
include $(ARCH_INC)
|
||||
endif
|
||||
|
||||
CC = $(CROSS_PREFIX)gcc
|
||||
CXX = $(CROSS_PREFIX)g++
|
||||
LD = $(CROSS_PREFIX)ld
|
||||
AR = $(CROSS_PREFIX)ar
|
||||
STRIP = $(CROSS_PREFIX)strip
|
||||
|
||||
ifeq ($(COLOR_INC), $(wildcard $(COLOR_INC)))
|
||||
include $(COLOR_INC)
|
||||
else
|
||||
CC_V = $(CC)
|
||||
CXX_V = $(CXX)
|
||||
LD_V = $(LD)
|
||||
AR_V = $(AR)
|
||||
CP_V = $(CP)
|
||||
RM_V = $(RM)
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# target and object
|
||||
###############################################################################
|
||||
LIBNAME = libuac
|
||||
VERSION_SH = $(shell pwd)/version.sh $(LIBNAME)
|
||||
VER = $(shell $(VERSION_SH); awk '/define\ $(LIBNAME)_version/{print $$3}' version.h)
|
||||
TGT_LIB_H = $(LIBNAME).h
|
||||
TGT_LIB_A = $(LIBNAME).a
|
||||
TGT_LIB_SO = $(LIBNAME).so
|
||||
TGT_LIB_SO_VER = $(TGT_LIB_SO).${VER}
|
||||
TGT_UNIT_TEST = test_$(LIBNAME)
|
||||
|
||||
OBJS_LIB = $(LIBNAME).o pulseaudio.o
|
||||
OBJS_UNIT_TEST = test_$(LIBNAME).o
|
||||
|
||||
###############################################################################
|
||||
# cflags and ldflags
|
||||
###############################################################################
|
||||
ifeq ($(MODE), release)
|
||||
CFLAGS := -O2 -Wall -Werror -fPIC
|
||||
LTYPE := release
|
||||
else
|
||||
CFLAGS := -g -Wall -Werror -fPIC
|
||||
LTYPE := debug
|
||||
endif
|
||||
CFLAGS += $($(ARCH)_CFLAGS)
|
||||
CFLAGS += -I$(OUTPUT)/include
|
||||
|
||||
SHARED := -shared
|
||||
|
||||
LDFLAGS := $($(ARCH)_LDFLAGS)
|
||||
LDFLAGS += -pthread -lpulse
|
||||
|
||||
###############################################################################
|
||||
# target
|
||||
###############################################################################
|
||||
.PHONY : all clean
|
||||
|
||||
TGT := $(TGT_LIB_A)
|
||||
TGT += $(TGT_LIB_SO)
|
||||
TGT += $(TGT_UNIT_TEST)
|
||||
|
||||
OBJS := $(OBJS_LIB) $(OBJS_UNIT_TEST)
|
||||
|
||||
all: $(TGT)
|
||||
|
||||
%.o:%.c
|
||||
$(CC_V) -c $(CFLAGS) $< -o $@
|
||||
|
||||
$(TGT_LIB_A): $(OBJS_LIB)
|
||||
$(AR_V) rcs $@ $^
|
||||
|
||||
$(TGT_LIB_SO): $(OBJS_LIB)
|
||||
$(CC_V) -o $@ $^ $(SHARED)
|
||||
@mv $(TGT_LIB_SO) $(TGT_LIB_SO_VER)
|
||||
@ln -sf $(TGT_LIB_SO_VER) $(TGT_LIB_SO)
|
||||
|
||||
$(TGT_UNIT_TEST): $(OBJS_UNIT_TEST) $(ANDROID_MAIN_OBJ)
|
||||
$(CC_V) -o $@ $^ $(TGT_LIB_A) $(LDFLAGS)
|
||||
|
||||
clean:
|
||||
$(RM_V) -f $(OBJS)
|
||||
$(RM_V) -f $(TGT)
|
||||
$(RM_V) -f version.h
|
||||
$(RM_V) -f $(TGT_LIB_SO)*
|
||||
$(RM_V) -f $(TGT_LIB_SO_VER)
|
||||
|
||||
install:
|
||||
$(MAKEDIR_OUTPUT)
|
||||
@if [ "$(MODE)" = "release" ];then $(STRIP) $(TGT); fi
|
||||
$(CP_V) -r $(TGT_LIB_H) $(OUTPUT)/include/gear-lib
|
||||
$(CP_V) -r $(TGT_LIB_A) $(OUTLIBPATH)/lib/gear-lib
|
||||
$(CP_V) -r $(TGT_LIB_SO) $(OUTLIBPATH)/lib/gear-lib
|
||||
$(CP_V) -r $(TGT_LIB_SO_VER) $(OUTLIBPATH)/lib/gear-lib
|
||||
|
||||
uninstall:
|
||||
cd $(OUTPUT)/include/gear-lib/ && rm -f $(TGT_LIB_H)
|
||||
$(RM_V) -f $(OUTLIBPATH)/lib/gear-lib/$(TGT_LIB_A)
|
||||
$(RM_V) -f $(OUTLIBPATH)/lib/gear-lib/$(TGT_LIB_SO)
|
||||
$(RM_V) -f $(OUTLIBPATH)/lib/gear-lib/$(TGT_LIB_SO_VER)
|
||||
@@ -0,0 +1,54 @@
|
||||
###############################################################################
|
||||
# common
|
||||
###############################################################################
|
||||
#ARCH: linux/pi/android/ios/win
|
||||
LD = link
|
||||
AR = lib
|
||||
RM = del
|
||||
###############################################################################
|
||||
# target and object
|
||||
###############################################################################
|
||||
LIBNAME = libuac
|
||||
TGT_LIB_A = $(LIBNAME).lib
|
||||
TGT_LIB_SO = $(LIBNAME).dll
|
||||
TGT_UNIT_TEST = test_$(LIBNAME).exe
|
||||
|
||||
OBJS_LIB = $(LIBNAME).obj
|
||||
OBJS_UNIT_TEST = test_$(LIBNAME).obj
|
||||
|
||||
###############################################################################
|
||||
# cflags and ldflags
|
||||
###############################################################################
|
||||
CFLAGS = /Iinclude /I.
|
||||
!IF "$(MODE)"=="release"
|
||||
CFLAGS = $(CFLAGS) /O2 /GF
|
||||
!ELSE
|
||||
CFLAGS = $(CFLAGS) /Od /W3 /Zi
|
||||
!ENDIF
|
||||
|
||||
LDFLAGS = /NOLOGO
|
||||
|
||||
LIBS = ws2_32.lib
|
||||
|
||||
###############################################################################
|
||||
# target
|
||||
###############################################################################
|
||||
TGT = $(TGT_LIB_A) $(TGT_LIB_SO) $(TGT_UNIT_TEST)
|
||||
|
||||
OBJS = $(OBJS_LIB) $(OBJS_UNIT_TEST)
|
||||
|
||||
all: $(TGT)
|
||||
|
||||
$(TGT_LIB_A): $(OBJS_LIB)
|
||||
$(AR) $(OBJS_LIB) $(LIBS) /o:$(TGT_LIB_A)
|
||||
|
||||
$(TGT_LIB_SO): $(OBJS_LIB)
|
||||
$(LD) $(LDFLAGS) /Dll $(OBJS_LIB) $(LIBS) /o:$(TGT_LIB_SO)
|
||||
|
||||
$(TGT_UNIT_TEST): $(OBJS_UNIT_TEST)
|
||||
$(CC) $(TGT_LIB_A) $(OBJS_UNIT_TEST) /o $(TGT_UNIT_TEST)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS)
|
||||
$(RM) $(TGT)
|
||||
$(RM) $(TGT_LIB_SO)*
|
||||
@@ -0,0 +1,3 @@
|
||||
## libuac
|
||||
This is a simple libuac library.
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2014-2020 Zhifeng Gong <gozfree@163.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#include "libuac.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined (OS_LINUX)
|
||||
extern struct uac_ops pa_ops;
|
||||
#elif defined (OS_WINDOWS)
|
||||
#endif
|
||||
|
||||
static struct uac_ops *uac_ops[] = {
|
||||
#if defined (OS_LINUX)
|
||||
&pa_ops,
|
||||
#elif defined (OS_WINDOWS)
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
struct uac_ctx *uac_open(const char *dev, struct uac_config *conf)
|
||||
{
|
||||
struct uac_ctx *uac;
|
||||
if (!dev || !conf) {
|
||||
printf("invalid paraments!\n");
|
||||
return NULL;
|
||||
}
|
||||
uac = (struct uac_ctx *)calloc(1, sizeof(struct uac_ctx));
|
||||
if (!uac) {
|
||||
printf("malloc failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
uac->ops = uac_ops[0];
|
||||
uac->opaque = uac->ops->open(uac, dev, conf);
|
||||
if (!uac->opaque) {
|
||||
printf("open %s failed!\n", dev);
|
||||
goto failed;
|
||||
}
|
||||
return uac;
|
||||
failed:
|
||||
free(uac);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void uac_close(struct uac_ctx *uac)
|
||||
{
|
||||
if (!uac) {
|
||||
printf("invalid paraments!\n");
|
||||
return;
|
||||
}
|
||||
uac->ops->close(uac);
|
||||
free(uac);
|
||||
}
|
||||
|
||||
int uac_query_frame(struct uac_ctx *uac, struct audio_frame *frame)
|
||||
{
|
||||
if (!uac || !frame) {
|
||||
printf("invalid paraments!\n");
|
||||
return -1;
|
||||
}
|
||||
return uac->ops->query_frame(uac, frame);
|
||||
}
|
||||
|
||||
int uac_start_stream(struct uac_ctx *uac, audio_frame_cb *cb)
|
||||
{
|
||||
if (!uac) {
|
||||
printf("invalid paraments!\n");
|
||||
return -1;
|
||||
}
|
||||
uac->on_audio_frame = cb;
|
||||
return uac->ops->start_stream(uac);
|
||||
}
|
||||
|
||||
int uac_stop_stream(struct uac_ctx *uac)
|
||||
{
|
||||
if (!uac) {
|
||||
printf("invalid paraments!\n");
|
||||
return -1;
|
||||
}
|
||||
return uac->ops->stop_stream(uac);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2014-2020 Zhifeng Gong <gozfree@163.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#ifndef LIBUAC_H
|
||||
#define LIBUAC_H
|
||||
|
||||
#include <gear-lib/libposix.h>
|
||||
#include <gear-lib/libmedia-io.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct uac_ctx;
|
||||
struct uac_ops;
|
||||
typedef int (audio_frame_cb)(struct uac_ctx *c, struct audio_frame *frame);
|
||||
|
||||
struct uac_config {
|
||||
};
|
||||
|
||||
struct uac_ctx {
|
||||
int fd;
|
||||
struct uac_config conf;
|
||||
struct uac_ops *ops;
|
||||
audio_frame_cb *on_audio_frame;
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
struct uac_ops {
|
||||
void *(*open)(struct uac_ctx *uac, const char *dev, struct uac_config *conf);
|
||||
void (*close)(struct uac_ctx *c);
|
||||
int (*ioctl)(struct uac_ctx *c, unsigned long int cmd, ...);
|
||||
int (*start_stream)(struct uac_ctx *c);
|
||||
int (*stop_stream)(struct uac_ctx *c);
|
||||
int (*query_frame)(struct uac_ctx *c, struct audio_frame *frame);
|
||||
};
|
||||
|
||||
struct uac_ctx *uac_open(const char *dev, struct uac_config *conf);
|
||||
int uac_ioctl(struct uac_ctx *c, unsigned long int cmd, ...);
|
||||
void uac_close(struct uac_ctx *c);
|
||||
|
||||
/*
|
||||
* active query frame one by one
|
||||
*/
|
||||
int uac_query_frame(struct uac_ctx *c, struct audio_frame *frame);
|
||||
|
||||
/*
|
||||
* passive get frame when cb is set, otherwise need query frame one by one
|
||||
*/
|
||||
int uac_start_stream(struct uac_ctx *uac, audio_frame_cb *cb);
|
||||
int uac_stop_stream(struct uac_ctx *uac);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,194 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2014-2020 Zhifeng Gong <gozfree@163.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#include "libuac.h"
|
||||
#include <gear-lib/libthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
struct pulse_ctx {
|
||||
int fd;
|
||||
struct uac_ctx *parent;
|
||||
bool is_streaming;
|
||||
pa_threaded_mainloop *mainloop;
|
||||
pa_context *ctx;
|
||||
pa_context_state_t state;
|
||||
};
|
||||
|
||||
#define timeval2ns(tv) \
|
||||
(((uint64_t)tv.tv_sec * 1000000000) + ((uint64_t)tv.tv_usec * 1000))
|
||||
|
||||
|
||||
static void on_pulse_state(pa_context *ctx, void *userdata)
|
||||
{
|
||||
struct pulse_ctx *c = userdata;
|
||||
|
||||
if (c->ctx != ctx) {
|
||||
printf("c->ctx=%p, ctx=%p\n", c->ctx, ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pa_context_get_state(ctx)) {
|
||||
case PA_CONTEXT_UNCONNECTED:
|
||||
printf("%s:%d PA_CONTEXT_UNCONNECTED\n", __func__, __LINE__);
|
||||
break;
|
||||
case PA_CONTEXT_CONNECTING:
|
||||
printf("%s:%d PA_CONTEXT_CONNECTING\n", __func__, __LINE__);
|
||||
break;
|
||||
case PA_CONTEXT_AUTHORIZING:
|
||||
printf("%s:%d PA_CONTEXT_AUTHORIZING\n", __func__, __LINE__);
|
||||
break;
|
||||
case PA_CONTEXT_SETTING_NAME:
|
||||
printf("%s:%d PA_CONTEXT_SETTING_NAME\n", __func__, __LINE__);
|
||||
break;
|
||||
case PA_CONTEXT_READY:
|
||||
printf("%s:%d PA_CONTEXT_READY\n", __func__, __LINE__);
|
||||
break;
|
||||
case PA_CONTEXT_FAILED:
|
||||
printf("%s:%d PA_CONTEXT_FAILED\n", __func__, __LINE__);
|
||||
break;
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
printf("%s:%d PA_CONTEXT_TERMINATED\n", __func__, __LINE__);
|
||||
break;
|
||||
default:
|
||||
printf("%s:%d xxxx\n", __func__, __LINE__);
|
||||
break;
|
||||
}
|
||||
pa_threaded_mainloop_signal(c->mainloop, 0);
|
||||
}
|
||||
|
||||
static void pa_server_info_cb(pa_context *ctx, const pa_server_info *info, void *data)
|
||||
{
|
||||
struct pulse_ctx *c = data;
|
||||
|
||||
if (c->ctx != ctx) {
|
||||
printf("c->ctx=%p, ctx=%p\n", c->ctx, ctx);
|
||||
return;
|
||||
}
|
||||
printf("========pulse audio information========\n");
|
||||
printf(" Server Version: %s\n", info->server_version);
|
||||
printf(" Server Name: %s\n", info->server_name);
|
||||
printf(" Default Source Name: %s\n", info->default_source_name);
|
||||
printf(" Default Sink Name: %s\n", info->default_sink_name);
|
||||
printf(" Host Name: %s\n", info->host_name);
|
||||
printf(" User Name: %s\n", info->user_name);
|
||||
printf(" Channels: %hhu\n", info->sample_spec.channels);
|
||||
printf(" Rate: %u\n", info->sample_spec.rate);
|
||||
printf(" Frame Size: %lu\n", pa_frame_size(&info->sample_spec));
|
||||
printf(" Sample Size: %lu\n", pa_sample_size(&info->sample_spec));
|
||||
printf(" ChannelMap Channels: %hhu\n", info->channel_map.channels);
|
||||
|
||||
pa_threaded_mainloop_signal(c->mainloop, 0);
|
||||
}
|
||||
|
||||
static void *uac_pa_open(struct uac_ctx *uac, const char *dev, struct uac_config *conf)
|
||||
{
|
||||
pa_mainloop_api *mainloop_api;
|
||||
struct pulse_ctx *c = calloc(1, sizeof(struct pulse_ctx));
|
||||
|
||||
c->mainloop = pa_threaded_mainloop_new();
|
||||
if (!c->mainloop) {
|
||||
printf("pa_threaded_mainloop_new failed!\n");
|
||||
}
|
||||
mainloop_api = pa_threaded_mainloop_get_api(c->mainloop);
|
||||
if (!mainloop_api) {
|
||||
printf("pa_threaded_mainloop_get_api failed!\n");
|
||||
}
|
||||
|
||||
c->ctx = pa_context_new(mainloop_api, "libuac");
|
||||
if (!c->ctx) {
|
||||
printf("pa_context_new failed!\n");
|
||||
}
|
||||
|
||||
pa_context_set_state_callback(c->ctx, on_pulse_state, c);
|
||||
pa_context_connect(c->ctx, NULL, PA_CONTEXT_NOFLAGS, NULL);
|
||||
pa_threaded_mainloop_start(c->mainloop);
|
||||
|
||||
pa_threaded_mainloop_lock(c->mainloop);
|
||||
while ((c->state = pa_context_get_state(c->ctx)) != PA_CONTEXT_READY) {
|
||||
if (c->state == PA_CONTEXT_FAILED || c->state == PA_CONTEXT_TERMINATED) {
|
||||
printf("pa_context_state is invalid!\n");
|
||||
break;
|
||||
}
|
||||
pa_threaded_mainloop_wait(c->mainloop);
|
||||
}
|
||||
pa_threaded_mainloop_unlock(c->mainloop);
|
||||
pa_context_set_state_callback(c->ctx, NULL, c);
|
||||
|
||||
|
||||
pa_operation *op = NULL;
|
||||
pa_operation_state_t op_state;
|
||||
|
||||
pa_threaded_mainloop_lock(c->mainloop);
|
||||
op = pa_context_get_server_info(c->ctx, pa_server_info_cb, c);
|
||||
while ((op_state = pa_operation_get_state(op)) != PA_OPERATION_DONE) {
|
||||
if (op_state == PA_OPERATION_CANCELLED) {
|
||||
printf("Get server info operation cancelled!");
|
||||
break;
|
||||
}
|
||||
printf("%s:%d xxxx\n", __func__, __LINE__);
|
||||
pa_threaded_mainloop_wait(c->mainloop);
|
||||
}
|
||||
pa_operation_unref(op);
|
||||
pa_threaded_mainloop_unlock(c->mainloop);
|
||||
|
||||
c->parent = uac;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static int uac_pa_start_stream(struct uac_ctx *uac)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uac_pa_stop_stream(struct uac_ctx *uac)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uac_pa_query_frame(struct uac_ctx *uac, struct audio_frame *frame)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uac_pa_close(struct uac_ctx *uac)
|
||||
{
|
||||
}
|
||||
|
||||
struct uac_ops pa_ops = {
|
||||
.open = uac_pa_open,
|
||||
.close = uac_pa_close,
|
||||
.ioctl = NULL,
|
||||
.start_stream = uac_pa_start_stream,
|
||||
.stop_stream = uac_pa_stop_stream,
|
||||
.query_frame = uac_pa_query_frame,
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
/******************************************************************************
|
||||
* Copyright (C) 2014-2020 Zhifeng Gong <gozfree@163.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
******************************************************************************/
|
||||
#include "libuac.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static int foo()
|
||||
{
|
||||
struct uac_config conf = {
|
||||
};
|
||||
struct uac_ctx *uac = uac_open("xxx", &conf);
|
||||
if (!uac) {
|
||||
printf("uac_open failed!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
foo();
|
||||
return 0;
|
||||
}
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
major=0
|
||||
minor=1
|
||||
patch=0
|
||||
|
||||
libname=$1
|
||||
output=version.h
|
||||
|
||||
LIBNAME=`echo ${libname} | tr 'a-z' 'A-Z'`
|
||||
export version=${major}.${minor}.${patch}
|
||||
export buildid=`git log -1 --pretty=format:"git-%cd-%h" --date=short 2>/dev/null`
|
||||
autogen_version_h()
|
||||
{
|
||||
cat > version.h <<!
|
||||
/* Automatically generated by version.sh - do not modify! */
|
||||
#ifndef ${LIBNAME}_VERSION_H
|
||||
#define ${LIBNAME}_VERSION_H
|
||||
|
||||
#define ${libname}_version ${version}
|
||||
#define ${libname}_buildid ${buildid}
|
||||
|
||||
#endif
|
||||
|
||||
!
|
||||
}
|
||||
|
||||
autogen_version_h
|
||||
Reference in New Issue
Block a user