udp传输音频,涉及对于网络编程,音频的处理,笔者这里做一点笔记。基于OSS的音频编程需要对于/dev/dsp操作,当然,如果你使用音频sdk包的话,就需要稍微进行修改。
传输时声音的质量还可以。有时运行程序需要过一会才能听到声音。
涉及了一些api的使用,如果使用不妥,会消耗很多时间,笔者也是踩了不少坑。
服务端代码(收音并播放):
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- //#include "mi_common_datatype.h"
- //#include "mi_sys.h"
- //#include "mi_ai.h"
- //#include "mi_ao.h"
-
- //录音频率
- #define RATE 48000
- //量化位数
- #define SIZE 16
- //声道数目
- #define CHANNELS 2
- //缓冲区大小
- #define RSIZE 2048
- //保存录取的音频数据
- unsigned char buf[RSIZE];
-
- int main(int argc,char *argv[])
- {
- //声卡描述符
- int fd;
- int arg;
- int status;
-
- //socket
- struct sockaddr_in s_addr;
- struct sockaddr_in c_addr;
- int sock;
- socklen_t addr_len;
- int len;
- if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1) //使用UDP方式
- {
- perror("socket");
- exit(errno);
- }
- else
- printf("creat socket success.\n\r");
- memset(&s_addr,0,sizeof(struct sockaddr_in));
- s_addr.sin_family=AF_INET; //协议设为AF_INET
- s_addr.sin_port=htons(8888); //接受端口为8888
- s_addr.sin_addr.s_addr=INADDR_ANY; //本地任意IP
-
- if((bind(sock,(struct sockaddr *) &s_addr,sizeof(s_addr)))==-1)
- {
- perror("bind error:");
- exit(errno);
- }
- else
- printf("bind address to socket.\n\r");
- addr_len=sizeof(c_addr);
-
- //声卡正常使用就用这个
- fd = open("/dev/dsp",O_WRONLY);
- if(fd < 0)
- {
- perror("Connot open /dev/dsp device");
- return 1;
- }
- //设置采样的量化位数
- arg = SIZE;
- status = ioctl(fd,SOUND_PCM_WRITE_BITS,&arg);
- if(status == -1)
- {
- perror("Connet set SOUND_PCM_WRITE_BITS ");
- return -1;
- }
- //设置采样时的声道数目
- arg = CHANNELS;
- status = ioctl(fd,SOUND_PCM_WRITE_CHANNELS,&arg);
- if(status == -1)
- {
- perror("Connet set SOUND_PCM_WRITE_CHANNELS ");
- return -1;
- }
- //设置采样时的频率
- arg = RATE;
- status = ioctl(fd,SOUND_PCM_WRITE_RATE,&arg);
- if(status == -1)
- {
- perror("Connet set SOUND_PCM_WRITE_RATE ");
- return -1;
- }
- #endif
-
-
- //一直接受播放,直到按下ctrl+c为止
- while(1)
- {
- len=recvfrom(sock,buf,sizeof(buf),0,(struct sockaddr *)&c_addr,&addr_len);
- if(len<0)
- perror("receive error:");
- //播音
- write(fd,buf,RSIZE);
- memset(buf, 0, RSIZE);
- }
- //close(fd);
- close(sock);
- return 0;
- }
客户端代码(录音并传输)
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
-
- //录音频率
- #define RATE 48000
- //量化位数
- #define SIZE 16
- //声道数目
- #define CHANNELS 2
- //缓冲区大小
- #define RSIZE 1024
- //保存录取的音频数据
- unsigned char buf[RSIZE];
-
- int main(int argc,char *argv[])
- {
- int fd,sockfd;
- int status;
- int arg;
- struct sockaddr_in s_addr;
- if((sockfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
- {
- perror("socket");
- exit(errno);
- }
- else
- printf("creat sockfd success!.\n\r");
- // bzero(&s_addr,sizeof(struct sockaddr_in));
- s_addr.sin_family=AF_INET;
- s_addr.sin_port=htons(8888);
- if(argc!=2)
- {
- printf("用法:./udp-dsp-client IP地址。\n");
- return 1;
- }
- else
- s_addr.sin_addr.s_addr=inet_addr(argv[1]);
- bzero (&(s_addr.sin_zero),8);
-
- /*************读方式打开音频设备*******************************/
- fd= open("/dev/dsp",O_RDONLY,0777);
- if(fd < 0)
- {
- perror("Cannot open /dev/dsp device");
- return 1;
- }
- //设置采样的量化位数
- arg = SIZE;
- status = ioctl(fd,SOUND_PCM_WRITE_BITS,&arg);
- if(status == -1)
- {
- perror("Connet set SOUND_PCM_WRITE_BITS ");
- return -1;
- }
- //设置采样时的声道数目
- arg = CHANNELS;
- status = ioctl(fd,SOUND_PCM_WRITE_CHANNELS,&arg);
- if(status == -1)
- {
- perror("Connet set SOUND_PCM_WRITE_CHANNELS ");
- return -1;
- }
- //设置采样时的频率
- arg = RATE;
- status = ioctl(fd,SOUND_PCM_WRITE_RATE,&arg);
- if(status == -1)
- {
- perror("Connet set SOUND_PCM_WRITE_RATE ");
- return -1;
- }
-
- int readNum,sendNum;
- while(1)
- {
- //从声卡读语音数据
- readNum = read(fd,buf,RSIZE);
- if(readNum==-1)
- {
- perror("read wrong number of bytes\n");
- }
- //发送语音数据
- sendNum=sendto(sockfd,buf,readNum,0,(struct sockaddr * )&s_addr,sizeof(struct sockaddr));
- if(sendNum==-1){
- perror("send error:");
- exit(-1);
- }
- }
-
- close(fd);
- close(sockfd);
- return 0;
- }