android 想尝试直接通过c去调音频接口,录音放音等。
没实现,可能他们的设备有这个驱动?
soundcard.h不存在,放弃,,,
保持这个状态啦,先放弃。。。
整个daemon 混合代码:
#include <stdio.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>// open
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/wait.h>
#include<signal.h>
#include <unistd.h>
#include <stdbool.h>
#include <android/log.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <net/if.h>
#define MAXFILE 65535
#define MAX_MSG_SIZE 1024
#define ADHOCDAEMON(fmt, ...) __android_log_print(ANDROID_LOG_WARN, "ADHOCDAEMON",
"%12s:%-5d,%s ," fmt, __FILE__, __LINE__ ,(char*)__FUNCTION__,##__VA_ARGS__)
volatile sig_atomic_t _running = 1;
char buffer[MAX_MSG_SIZE];
struct sockaddr_in addrSer; //创建一个记录地址信息的结构体
struct sockaddr_in addrCli;//创建一个记录地址信息的结构体
int Sockfd,n,fd;//client socket ,socket port SOCK_STREAM
socklen_t addrlen;
// signal handler
void sigterm_handler(int arg)
{
_running = 0;
}
void init()
{//create socket server
//创建一个套接字,并检测是否创建成功
/*SockCli = socket(AF_INET, SOCK_DGRAM, 0);*/
Sockfd = socket(AF_INET,SOCK_DGRAM , 0);
if(Sockfd == -1){
ADHOCDAEMON("adhoc socket create failed!\n");
}
// server addr
//struct sockaddr_in addrSer; //创建一个记录地址信息的结构体
addrSer.sin_family = AF_INET; //使用AF_INET协议族
addrSer.sin_port = htons(63450); //设置地址结构体中的端口号
addrSer.sin_addr.s_addr = inet_addr("127.0.0.1"); //设置通信ip
/*addrSer.sin_addr.s_addr = inet_addr("192.168.70.1"); //设置通信ip*/
//client addr
//struct sockaddr_in addrCli;//创建一个记录地址信息的结构体
addrCli.sin_family = AF_INET; //使用AF_INET协议族
addrCli.sin_port = htons(63451); //设置地址结构体中的端口号
addrCli.sin_addr.s_addr = inet_addr("127.0.0.1"); //设置通信ip
//serv port bind
//将套接字地址与所创建的套接字号联系起来,并检测是否绑定成功
/*socklen_t addrlen = sizeof(struct sockaddr);*/
addrlen = sizeof(struct sockaddr);
int res = bind(Sockfd,(struct sockaddr*)&addrSer, addrlen);
if(res == -1){
perror("bind failed!\n");
}else{
ADHOCDAEMON("adhoc socket bind done!\n");
}
}
/
/*the test of set ip*/
/
//设置IP地址
/*
* 函数名称 : int setip(char *ip)
* 函数功能 : 设置系统IP地址
* 参 数 :
*char *ip :设置的IP地址,以点分十进制的字符串方式表示,如“192.168.0.5”
* 返 回 值 : 0 : 成功 ; -1 : 失败
*/
int setip(char *ip)
{
ADHOCDAEMON("=========enter ======= ip from js=%s ",ip);
struct ifreq temp;
struct sockaddr_in *addr;
int fd = 0;
int ret = -1;
/*strcpy(temp.ifr_name, "eth0");*/
strcpy(temp.ifr_name, "wlan0");
if((fd=socket(AF_INET, SOCK_STREAM, 0))<0)
{
return -1;
}
addr = (struct sockaddr_in *)&(temp.ifr_addr);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = inet_addr(ip);
ret = ioctl(fd, SIOCSIFADDR, &temp);
ADHOCDAEMON("ret=%d,fd=%d\n",ret,fd);
close(fd);
if(ret < 0)
return -1;
return 0;
}
//获取IP地址
/*
* 函数名称 : char * getip(char *ip_buf)
* 函数功能 : 获取系統IP地址
* 参 数 :
*char *ip_buf :用来存放IP地址的内存空间
* 返 回 值 : ip_buf : 存放IP地址的内存地址
*/
char* getip(char *ip_buf)
{
struct ifreq temp;
struct sockaddr_in *myaddr;
int fd = 0;
int ret = -1;
/*strcpy(temp.ifr_name, "eth0");*/
strcpy(temp.ifr_name, "wlan0");
if((fd=socket(AF_INET, SOCK_STREAM, 0))<0)
{
return -1;
}
ret = ioctl(fd, SIOCGIFADDR, &temp);
close(fd);
if(ret < 0)
return NULL;
myaddr = (struct sockaddr_in *)&(temp.ifr_addr);
strcpy(ip_buf, inet_ntoa(myaddr->sin_addr));
ADHOCDAEMON("ipaddr=%s\n",ip_buf);
return ip_buf;
}
int ip_test(char *ip)
{
ADHOCDAEMON("=========enter ====== ip=%s ",ip);
/*char * ip = "172.20.223.117";*/
char buf[16]="";
int ret_set=setip(ip);//TODO ,got some unexpected result,why return -1
ADHOCDAEMON("ret_set=%d\n",ret_set);
ADHOCDAEMON("get ipaddr=%s\n",getip(buf));
return 0;
}
/
void sys_call(char* ip)
{
ADHOCDAEMON("=========enter ====== ip =%s ",ip);
/*system("ifconfig wlan0 192.168.0.88");*/
int ret_sys_call0=system("netcfg |grep -i wlan0");
/*char *cmd;*/
char cmd[1024];
sprintf(cmd, "ifconfig wlan0 %s",ip);
int ret_sys_call1=system("ifconfig wlan0 192.168.0.88");
system("netcfg |grep -i wlan0");
int ret_sys_call2=system(cmd);
system("netcfg |grep -i wlan0");
ADHOCDAEMON("ret_sys_call=%d",ret_sys_call2);//get a -1 here
printf("ret_sys_call=%d ,ip:%s",ret_sys_call2,cmd);//get a -1 here
}
/
/*the test of create file */
int create_file(){
int fd;
char *path="/data/test1.txt";
fd=creat(path,00777);
return fd;
}
void write_file(int fd){
char buf[]="abcdeooooooooo\n";
write(fd,buf,sizeof(buf));
close(fd);
}
void read_file(){
int fd;
char *path="/data/aaa.txt";
char result[20];
fd=open(path,O_RDONLY);
read(fd,result,10);
printf("The content is %s",result);
close(fd);
}
int file_test()
{
int fd;
fd = open("/data/aaa.txt",O_WRONLY|O_CREAT|O_APPEND,00777);
if(fd == -1)
{
printf("文件创建失败");
return -1;
}
printf("请输入要写入的句子:");
/*fgets(buf,MAX,stdin);*/
char* buf="this is a file crated by daemon!good luck!\n";//or strcpy
/*char buf[]="this is a file crated by daemon! good luck!\n";*/
write(fd,buf,strlen(buf));
printf("写入成功\n");
system("cat /data/aaa.txt");
int fd1=create_file();
write_file(fd1);
system("cat /data/test1.txt");
return 0;
}
/
/*the test of voice record*/
//give up...
//不懂,尝试失败,请自由发挥
/*
*#include <sys/soundcard.h>
*#include <stdio.h>
*#include <unistd.h>
*#include <sys/ioctl.h>
*#include <fcntl.h>
*#include <stdlib.h>
*
*int voice()
*{
* [> id:读取音频文件描述符;fd:写入的文件描述符。i,j为临时变量<]
* int id,fd,i,j;
* [> 存储音频数据的缓冲区,可以调整<]
* char testbuf[4096];
* [> 打开声卡设备,失败则退出<]
* if ( ( id = open ( "/dev/audio", O_RDWR ) ) < 0 ) {
* fprintf (stderr, " Can't open sound device!\n");
* exit ( -1 ) ;
* }
* [> 打开输出文件,失败则退出<]
* if ( ( fd = open ("/data/test.wav",O_RDWR))<0){
* fprintf ( stderr, " Can't open output file!\n");
* exit (-1 );
* }
* [> 设置适当的参数,使得声音设备工作正常<]
* [> 详细情况请参考Linux关于声卡编程的文档<]
* i=0;
* ioctl (id,SNDCTL_DSP_RESET,(char *)&i) ;
* ioctl (id,SNDCTL_DSP_SYNC,(char *)&i);
* i=1;
* ioctl (id,SNDCTL_DSP_NONBLOCK,(char *)&i);
* i=8000;
* ioctl (id,SNDCTL_DSP_SPEED,(char *)&i);
* i=1;
* ioctl (id,SNDCTL_DSP_CHANNELS,(char *)&i);
* i=8;
* ioctl (id,SNDCTL_DSP_SETFMT,(char *)&i);
* i=3;
* ioctl (id,SNDCTL_DSP_SETTRIGGER,(char *)&i);
* i=3;
* ioctl (id,SNDCTL_DSP_SETFRAGMENT,(char *)&i);
* i=1;
* ioctl (id,SNDCTL_DSP_PROFILE,(char *)&i);
* [> 读取一定数量的音频数据,并将之写到输出文件中去<]
* for ( j=0; j<100;){
* i=read(id,testbuf,4096);
* if(i>0){
* write(fd,testbuf,i);
* j++;
* }
* }
* [> 关闭输入、输出文件<]
* close(fd);
* close(id);
* exit(0);
*}
*/
/
int main()
{ pid_t pid;
char *buf = "This is a Daemon\n";
/* 屏蔽一些有关控制终端操作的信号
* 防止在守护进程没有正常运转起来时,因控制终端受到干扰退出或挂起
* */
signal(SIGINT, SIG_IGN);// 终端中断
signal(SIGHUP, SIG_IGN);// 连接挂断
signal(SIGQUIT, SIG_IGN);// 终端退出
signal(SIGPIPE, SIG_IGN);// 向无读进程的管道写数据
signal(SIGTTOU, SIG_IGN);// 后台程序尝试写操作
signal(SIGTTIN, SIG_IGN);// 后台程序尝试读操作
signal(SIGTERM, SIG_IGN);// 终止
// [1] fork child process and exit father process
pid = fork();
if(pid < 0)
{
perror("fork error!");
exit(1);
}
else if(pid > 0)
{
exit(0);
}
// [2] create a new session
setsid();
// [3] set current path
char szPath[1024];
if(getcwd(szPath, sizeof(szPath)) == NULL)
{
perror("getcwd");
exit(1);
}
else
{
chdir(szPath);
printf("set current path succ [%s]\n", szPath);
}
// [4] umask 0
umask(0);
// [5] close useless fd
int i;
//for (i = 0; i < MAXFILE; ++i)
for (i = 3; i < MAXFILE; ++i)
{
close(i);
}
// [6] set termianl signal
signal(SIGTERM, sigterm_handler);
// open file and set rw limit
if((fd = open("outfile", O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0)
{
perror("open");
exit(1);
}
printf("\nDaemon begin to work..., and use kill -9 PID to terminate\n");
init();//create socket
int test_flag=0;
// do sth in loop
while(_running)
{
n=recvfrom(Sockfd,buffer,MAX_MSG_SIZE,0,(struct sockaddr *)&addrCli,&addrlen);
ADHOCDAEMON("data from SockCli: n:%d, %s\n",n,buffer);
printf("data from SockCli: n:%d, %s\n",n,buffer);
if(test_flag==0)
{
printf("enter ip_test(): %s\n",buffer);
ADHOCDAEMON("enter ip_test(): %s\n",buffer);
ip_test(buffer);
test_flag=1;//do this whenever you like
}
if(test_flag==1)
{//system call
sys_call(buffer);
test_flag=2;//do this whenever you like
}
if(test_flag==2)
{//create file
file_test();
test_flag=3;//do this whenever you like
}
if(test_flag==3)
{//voice record
voice();
test_flag=0;//do this whenever you like
usleep(5000*1000);
}
usleep(1000*1000);// 1 s
}
close(fd);
// print data
if((fd = open("outfile", O_RDONLY)) < 0)
{
perror("open");
exit(1);
}
char szBuf[1024] = {0};
if(read(fd, szBuf, sizeof(szBuf)) == -1)
{
perror("read");
exit(1);
}
printf("read 1024 bytes:\n%s\n", szBuf);
close(fd);
return 0;
}
参考文档:
https://blog.csdn.net/zjf535214685/article/details/52180949
https://blog.csdn.net/tropicofcancer9/article/details/54016699
https://blog.csdn.net/lp542718520/article/details/70234312
linux下如何用C进行录音,录成.WAV格式,或者其他格式
https://blog.csdn.net/tropicofcancer9/article/details/54016699
http://bbs.csdn.net/topics/190024886
alsa官网上有资料,下面是个例程:
Linux下的录音编程(转摘)
/* 此文件中定义了下面所有形如SND_的变量*/
#include <sys/soundcard.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdlib.h>
int main()
{
/* id:读取音频文件描述符;fd:写入的文件描述符。i,j为临时变量*/
int id,fd,i,j;
/* 存储音频数据的缓冲区,可以调整*/
char testbuf[4096];
/* 打开声卡设备,失败则退出*/
if ( ( id = open ( "/dev/audio", O_RDWR ) ) < 0 ) {
fprintf (stderr, " Can't open sound device!\n");
exit ( -1 ) ;
}
/* 打开输出文件,失败则退出*/
if ( ( fd = open ("test.wav",O_RDWR))<0){
fprintf ( stderr, " Can't open output file!\n");
exit (-1 );
}
/* 设置适当的参数,使得声音设备工作正常*/
/* 详细情况请参考Linux关于声卡编程的文档*/
i=0;
ioctl (id,SNDCTL_DSP_RESET,(char *)&i) ;
ioctl (id,SNDCTL_DSP_SYNC,(char *)&i);
i=1;
ioctl (id,SNDCTL_DSP_NONBLOCK,(char *)&i);
i=8000;
ioctl (id,SNDCTL_DSP_SPEED,(char *)&i);
i=1;
ioctl (id,SNDCTL_DSP_CHANNELS,(char *)&i);
i=8;
ioctl (id,SNDCTL_DSP_SETFMT,(char *)&i);
i=3;
ioctl (id,SNDCTL_DSP_SETTRIGGER,(char *)&i);
i=3;
ioctl (id,SNDCTL_DSP_SETFRAGMENT,(char *)&i);
i=1;
ioctl (id,SNDCTL_DSP_PROFILE,(char *)&i);
/* 读取一定数量的音频数据,并将之写到输出文件中去*/
for ( j=0; j<100;){
i=read(id,testbuf,4096);
if(i>0){
write(fd,testbuf,i);
j++;
}
}
/* 关闭输入、输出文件*/
close(fd);
close(id);
exit(0);
}
//------------------------------------------------------------------------------------------------------------------
自己以前写的播放PCM数据的程序。
播放是往声卡些数据
录音类似的。只是从声卡读数据
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <linux/soundcard.h>
#define OPEN_DSP_FAILED 0x00000001 /*open dsp failed!*/
#define SAMPLERATE_STATUS 0x00000002 /*samplerate status failed*/
#define SET_SAMPLERATE_FAILED 0x00000003 /*set samplerate failed*/
#define CHANNELS_STATUS 0x00000004 /*Channels status failed*/
#define SET_CHANNELS_FAILED 0x00000005 /*set channels failed*/
#define FMT_STATUS 0x00000006 /*FMT status failed*/
#define SET_FMT_FAILED 0x00000007 /*set fmt failed*/
#define OPEN_FILE_FAILED 0x00000008 /*opem filed failed*/
int Audio_Play(char *pathname,int nSampleRate,int nChannels,int fmt)
{
int dsp_fd,mix_fd,status,arg;
dsp_fd = open("/dev/dsp" , O_RDWR); /*open dsp*/
if(dsp_fd < 0)
{
return OPEN_DSP_FAILED;
}
arg = nSampleRate;
status = ioctl(dsp_fd,SOUND_PCM_WRITE_RATE,&arg); /*set samplerate*/
if(status < 0)
{
close(dsp_fd);
return SAMPLERATE_STATUS;
}
if(arg != nSampleRate)
{
close(dsp_fd);
return SET_SAMPLERATE_FAILED;
}
arg = nChannels; /*set channels*/
status = ioctl(dsp_fd, SOUND_PCM_WRITE_CHANNELS, &arg);
if(status < 0)
{
close(dsp_fd);
return CHANNELS_STATUS;
}
if( arg != nChannels)
{
close(dsp_fd);
return SET_CHANNELS_FAILED;
}
arg = fmt; /*set bit fmt*/
status = ioctl(dsp_fd, SOUND_PCM_WRITE_BITS, &arg);
if(status < 0)
{
close(dsp_fd);
return FMT_STATUS;
}
if(arg != fmt)
{
close(dsp_fd);
return SET_FMT_FAILED;
}/*到此设置好了DSP的各个参数*/
FILE *file_fd = fopen(pathname,"r");
if(file_fd == NULL)
{
close(dsp_fd);
return OPEN_FILE_FAILED;
}
int num = 3*nChannels*nSampleRate*fmt/8;
int get_num;
char buf[num];
while(feof(file_fd) == 0)
{
get_num = fread(buf,1,num,file_fd);
write(dsp_fd,buf,get_num);
if(get_num != num)
{
close(dsp_fd);
fclose(file_fd);
return 0;
}
}
close(dsp_fd);
fclose(file_fd);
return 0;
}
/*
*test
*/
int main()
{
int value;
value = Audio_Play("hello.wav",44100,2,16);
fprintf(stderr,"value is %d",value);
return 0;
}