日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux bluez语音传输,Linux BlueZ PCM 音频播放器

發(fā)布時(shí)間:2024/9/27 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux bluez语音传输,Linux BlueZ PCM 音频播放器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

自己寫的簡單的實(shí)驗(yàn)代碼,貼上來看看,有興趣的話,大家可以交流

/******************************************************************************/

/**?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/**???????????????????????? MODULES USED????????????????????????????????????????????????????????????????? **/

/**??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/******************************************************************************/

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "msgqueue.h"

/******************************************************************************/

/**?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/**???????????????????????? DEFINITIONS AND MACROS????????????????????????????????????????????? **/

/**???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????**/

/******************************************************************************/

#define DONGLE_ADDR??"00:11:67:58:D1:0F"???? /*ISSC*/

#define HEAD_SET_ADDR?"83:82:5B:00:A5:A3"???? /*NK-808 channel 1*/

#define HEAD_SET_CHAN?? 1

//#define PCM_DATA_PATH?? "/tmp/sco.dat"

//#define PCM_DATA_PATH?? "/mnt/heart.pcm"

#define PCM_DATA_PATH?? "/mnt/tianhou.pcm"

#define RECV_BUFFER???? 64

#define SEND_BUFFER???? 64

typedef pthread_t thread_T;

typedef void *(*pthread_startroutine_t) (void *);

typedef void *pthread_addr_t;

typedef void threadArg_T;

typedef void (*threadFunc_T)(void *);

/*debugging micro*/

#ifdef ENABLE_DEBUG

int DebugEnabled = 0;

#else

#define DebugEnabled??? 1

#endif

#define DDBG(fmts)? if(DebugEnabled)printf(fmts)

#define DBG(fmts,args) if(DebugEnabled)printf(fmts,args)

#define DBG2(fmts,arg1,arg2) if(DebugEnabled)printf(fmts,arg1,arg2)

/******************************************************************************/

/**?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/**??????????????????????????? TYPEDEF AND STRUCTURE????????????????????????????????????????? **/

/**??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/******************************************************************************/

struct _dongle_priv {

int hci_sock;

int sco_sock;

int device_channel;

char ag_addr[20];??/* adddress of adapter */

char hs_addr[20];

unsigned char isServiceConnected;

char isScoConnected;

char isRunning;

char callSetup;

char callAccept;

};

typedef struct _dongle_priv bt_data;

/******************************************************************************/

/**?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/**??????????????????????????? GLOBAL VARIABLES???????????????????????????????????????????????????????? **/

/**??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/******************************************************************************/

bt_data * BTd;

static sem_t?? Sem;

/******************************************************************************/

/**?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? **/

/**???????????????????????? LOCAL FUNCTIONS?????????????????????????????????????????????????????????????**/

/**?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?**/

/******************************************************************************/

thread_T thread_create(int priority, threadFunc_T startFunc, threadArg_T *arg)

{

thread_T???????????? thread;

pthread_attr_t?????? thread_attr;

struct sched_param?? param;

pthread_attr_init(&thread_attr);

/* pthread_attr_setinheritsched(PTHREAD_EXPLICT_SCHED); */

pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);

param.sched_priority = priority;

pthread_attr_setschedparam(&thread_attr, &param);

pthread_create(&thread, &thread_attr, (pthread_startroutine_t)startFunc,

(pthread_addr_t)arg);

return(thread);

}

void set_bit(int offset)

{

BTd->isServiceConnected |= (0x01

static int rfcomm_connect(bdaddr_t * src, bdaddr_t * dst, uint8_t channel)

{

struct sockaddr_rc addr;

int s;

if ((s = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {

return -1;

}

memset(&addr, 0, sizeof(addr));

addr.rc_family = AF_BLUETOOTH;

bacpy(&addr.rc_bdaddr, src);

addr.rc_channel = 0;

if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {

printf("rfcomm bind error\n");

close(s);

return -1;

}

memset(&addr, 0, sizeof(addr));

addr.rc_family = AF_BLUETOOTH;

bacpy(&addr.rc_bdaddr, dst);

addr.rc_channel = channel;

if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {

printf("rfcomm connect error\n");

close(s);

return -1;

} else{

printf("connecting successfully sock %d\n",s);

}

return s;

}

static int sco_connect(bdaddr_t *src, bdaddr_t *dst)

{

struct sockaddr_sco addr;

//struct sco_conninfo conn;

//struct sco_options opts;

int s;

if ((s = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO)) < 0) {

return -1;

}

memset(&addr, 0, sizeof(addr));

addr.sco_family = AF_BLUETOOTH;

bacpy(&addr.sco_bdaddr, src);

if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {

close(s);

return -1;

}

memset(&addr, 0, sizeof(addr));

addr.sco_family = AF_BLUETOOTH;

bacpy(&addr.sco_bdaddr, dst);

if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){

close(s);

printf("sco connecting failed\n");

return -1;

}

return s;

}

static int start_rfcomm_link(char *dst , char *src , int channel)

{

bdaddr_t usb_dongle_addr,head_set_addr;

int fd;

if (!dst||!src){

return -1;

}

str2ba(src,&usb_dongle_addr);

str2ba(dst,&head_set_addr);

fd = rfcomm_connect(&usb_dongle_addr,&head_set_addr,channel);

return fd;

}

static int start_sco_link(char *dst , char *src)

{

bdaddr_t usb_dongle_addr,head_set_addr;

int fd;

//uint16_t sco_handle, sco_mtu;

if (!dst||!src){

return -1;

}

str2ba(src,&usb_dongle_addr);

str2ba(dst,&head_set_addr);

fd = sco_connect(&usb_dongle_addr,&head_set_addr);

return fd;

}

static int cind_cmd_str(char *cmd)

{

if (!cmd){

return -1;

}

memset(cmd,0,sizeof(cmd));

strcpy(cmd,"\r\n+CIND:(\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0,3)),(\"signal\",(0-5)),(\"roam\",(0-1))\r\n");

return 0;

}

static int at_rx(int fd_at, char *receive)

{

int retval,ret;

fd_set rfds;

struct timeval tv;

FD_ZERO(&rfds);

FD_SET(fd_at, &rfds);

tv.tv_sec = 0;

tv.tv_usec = 5000;

if (!receive){

return -1;

}

memset(receive,0,sizeof(receive));

if ((retval = select(fd_at+1, &rfds, NULL, NULL, &tv)) > 0){

memset(receive,0,RECV_BUFFER);

ret = read(fd_at,receive,RECV_BUFFER);

if (ret > 0){

DBG("recving from headset %s\n",receive);

} else if (-1 == ret){

close(fd_at);

BTd->isRunning = 0;

}

} else if (!retval){

//DDBG("time out\n");

}

return 0;

}

static int at_tx(int fd_at,char* send)

{

if (strlen(send)){

DBG("AG Sending %s\n",send);

write(fd_at,send,strlen(send));

}

return 0;

}

static int at_txrx(int fd_at,char* send, char *receive)

{

int ret = 0;

fd_set rfds;

struct timeval tv;

int retval;

FD_ZERO(&rfds);

FD_SET(fd_at, &rfds);

tv.tv_sec = 3;

tv.tv_usec = 0;

memset(receive,0,sizeof(receive));

if (strlen(send)){

DBG("AG Sending %s\n",send);

write(fd_at,send,strlen(send));

}

if ((retval = select(fd_at+1, &rfds, NULL, NULL, &tv)) > 0){

memset(receive,0,RECV_BUFFER);

ret = read(fd_at,receive,RECV_BUFFER);

if (ret){

DBG("[at_rxtx]recving from headset %s\n",receive);

}

} else if (!retval){

//DDBG("time out\n");

}

return 0;

}

static void monitor_headset(int fd_rfcomm)

{

char recv_buf[RECV_BUFFER] = {0};

char send_buf[SEND_BUFFER] = {0};

while (1 == BTd->isRunning){

at_rx(fd_rfcomm, recv_buf);

if (strstr(recv_buf,"AT+BRSF")){

at_tx(fd_rfcomm,"\r\n+BRSF:49\r");

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(0);

continue;

}

if (strstr(recv_buf,"AT+CIND=?")){

cind_cmd_str(send_buf);

at_tx(fd_rfcomm,send_buf);

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(1);

continue;

}

if (strstr(recv_buf,"AT+CIND")){

at_tx(fd_rfcomm,"\r\n+CIND:1,0,0,2,0\r\n");

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(2);

continue;

}

if (strstr(recv_buf,"AT+CMER")){

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(3);

continue;

}

//Standard call hold and multiparty handling AT command

if (strstr(recv_buf,"AT+CHLD")){

at_tx(fd_rfcomm,"\r\n+CHLD:0\r\n");

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(4);

continue;

}

//Standard “Call Waiting notification” AT command

if (strstr(recv_buf,"AT+CCWA")){

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(5);

continue;

}

//volume setting

if (strstr(recv_buf,"AT+VGS")){

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(6);

continue;

}

//volume setting

if (strstr(recv_buf,"AT+VGM")){

at_tx(fd_rfcomm,"\r\nOK\r\n");

set_bit(7);

continue;

}

if (strstr(recv_buf,"ATA")){

//CallingAccept = 1;

BTd->callAccept = 1;

DDBG("ATA is received\n");

at_tx(fd_rfcomm,"\r\nOK\r\n");

at_tx(fd_rfcomm,"\r\n+CIEV=2,1\r\n");

continue;

}

}

}

static void audio_loop(int fd_sco)

{

char recv_buf[RECV_BUFFER] = {0};

int retval,ret;

fd_set rfds;

struct timeval tv;

FD_ZERO(&rfds);

FD_SET(fd_sco, &rfds);

tv.tv_sec = 3;

tv.tv_usec = 0;

memset(recv_buf,0,RECV_BUFFER);

if ((retval = select(fd_sco+1, &rfds, NULL, NULL, &tv)) > 0){

ret = read(fd_sco,recv_buf,1023);

if (ret){

//DBG("recving from headset %s\n",receive);

//DBG("recv_length %d\n",ret);

//DBG("%x\n",recv_buf);

}

write(fd_sco,recv_buf,ret);

} else if (!retval){

//DDBG("time out\n");

}

}

static int get_file_size(char *file_path)

{

FILE * fd;

int start,end,fileLen;

fd = fopen(file_path,"r");

if (fd){

fseek(fd, 0, SEEK_SET);

start = ftell(fd);

fseek(fd, 0, SEEK_END);

end = ftell(fd);

fileLen = end - start + 1;

/*move to the head*/

fseek(fd, 0, SEEK_SET);

DBG("audio fileLength %d\n",fileLen);

fclose(fd);

return fileLen;

} else{

return -1;

}

}

static unsigned char * fill_pcm_buffer(char * pcm_file_path,int *length)

{

int size = 0;

FILE *fd;

unsigned char * pcmDataPtr;

if (!pcm_file_path){

return NULL;

}

size = get_file_size(pcm_file_path);

if (size > 0){

*length = size;

pcmDataPtr = (unsigned char *)malloc(size);

if (!pcmDataPtr){

DDBG("can't allocate memory\n");

return NULL;

}

memset(pcmDataPtr,0,size);

fd = fopen(pcm_file_path,"r");

if (!fd){

return NULL;

}

fread(pcmDataPtr,1,size,fd);

fclose(fd);

return pcmDataPtr;

} else{

return NULL;

}

}

static bt_data * init_bt_para()

{

bt_data * btd;

btd = (bt_data *)malloc(sizeof(bt_data));

if (!btd){

printf("opps can't allocate resource!\n");

exit(-1);

}

memset(btd,0,sizeof(*btd));

strcpy(btd->ag_addr,DONGLE_ADDR);

strcpy(btd->hs_addr,HEAD_SET_ADDR);

btd->device_channel = HEAD_SET_CHAN;

btd->callSetup = 0;

btd->callAccept = 0;

btd->isRunning = 0;

btd->isServiceConnected = 0;

btd->isScoConnected = 0;

btd->hci_sock = -1;

btd->sco_sock = -1;

return btd;

}

static int ring_headset(int fd_rfcomm)

{

char recv_buf[RECV_BUFFER] = {0};

sem_wait(&Sem);

at_txrx(fd_rfcomm,"\r\nRING\r\n",recv_buf);

while (!strstr(recv_buf,"ATA")&&!BTd->callAccept){

at_txrx(fd_rfcomm,"\r\nRING\r\n",recv_buf);

}

at_tx(fd_rfcomm,"\r\nOK\r\n");

at_tx(fd_rfcomm,"\r\n+CIEV:2,1\r\n");

sem_destroy(&Sem);

return 0;

}

static void play_pcm_audio(int fd_sco,unsigned char * pcm_buffer,int max_length,int times)

{

#define OFFSET? 48

int i;

int cur = 0;

int retval;

unsigned char *pdata;

unsigned char buffer[64];

fd_set rfds,wfds;

struct timeval tv;

unsigned int sector = 300*1024;

if (!pcm_buffer){

return -1;

}

FD_ZERO(&rfds);

FD_SET(fd_sco, &rfds);

FD_ZERO(&wfds);

FD_SET(fd_sco, &wfds);

tv.tv_sec = 0;

tv.tv_usec =8000;

pdata = pcm_buffer;

for (i = 0 ; i < times ; i++){

while (cur < max_length){

if ((retval = select(fd_sco+1, NULL, &wfds, NULL, &tv)) > 0){

//fread(receive,1,OFFSET,fd_music);

//memset(buffer,0,sizeof(buffer));

//memcpy(buffer,pdata,OFFSET);

printf("twins\r\n");

//printf("twins\r\n");

//usleep(1);

//printf("\r\n");

write(fd_sco,pdata,48);

cur += OFFSET;

pdata += OFFSET;

if (cur > sector){

sleep(5);

sector += 300*1024;

}

}

}

printf("music data is finished\n");

sleep(2);

pdata = pcm_buffer;

cur = 0;

sector = 300*1024;

}

//close(fd_sco);

free(pcm_buffer);

printf("audio transfer over\n");

return;

}

void init_hcid_conf()

{

system("hcid -f /etc/bluetooth/hcid.conf");

}

int main()

{

int fd_rfcomm,fd_sco;

unsigned char * pcm_buffer;

int max_length;

bt_data *btd;

init_hcid_conf();

btd = init_bt_para();

BTd = btd;

fd_rfcomm = start_rfcomm_link(btd->hs_addr, btd->ag_addr, btd->device_channel);

if (fd_rfcomm < 0){

exit(-1);

}

btd->isRunning = 1;

btd->hci_sock = fd_rfcomm;

thread_create(50, (threadFunc_T)monitor_headset, (threadArg_T *)btd->hci_sock);

thread_create(50, (threadFunc_T)ring_headset, (threadArg_T *)btd->hci_sock);

pcm_buffer = fill_pcm_buffer(PCM_DATA_PATH, &max_length);

while (1){

if (btd->isServiceConnected == 0xff&&!btd->callSetup){

//printf("service level connection finished\n");

//ready to make/accept a call

at_tx(fd_rfcomm,"\r\n+CIEV=3,1\r\n");

sem_post(&Sem);

//CallSetup = 1;

btd->callSetup = 1;

}

if (0 == btd->isScoConnected){

fd_sco = start_sco_link(btd->hs_addr,btd->ag_addr);

}

if (fd_sco > 0){

//printf("sco link successfully!\n");

btd->sco_sock = fd_sco;

btd->isScoConnected = 1;

}

if (btd->callAccept == 1){

play_pcm_audio(btd->sco_sock, pcm_buffer, max_length,1);

break;

}

}

//sleep(80);

close(btd->sco_sock);

close(btd->hci_sock);

}

總結(jié)

以上是生活随笔為你收集整理的linux bluez语音传输,Linux BlueZ PCM 音频播放器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。