📄 server.cpp
字号:
#include <sys/types.h>#include <sys/stat.h>#include <sys/socket.h>#include <sys/soundcard.h>#include <sys/ioctl.h>#include <sys/select.h>#include <string.h>#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <arpa/inet.h>#include <unistd.h>#include <fcntl.h> #include "cirqueue.h"// a Sample size defineconst int frame_size = 1024;// define server service port const int SERV_PORT = 1080;// define sound device nameconst char DEVICE_NAME[] = "/dev/audio";// Circle Queue for Sampling and SendCirQueue mQueue;// Play Sample Soundbool play_sample(int handle_sound, char * sample_buf){ audio_buf_info info; // Judge whether can get Sample without block // Only read sample when has enough data, then return true // else return false ioctl(handle_sound, SNDCTL_DSP_GETOSPACE, &info); if (info.bytes >= frame_size) { write(handle_sound, sample_buf, frame_size); return true; } else return false;}// Get Sample from receive circle queuebool get_sample(char * sample_buf, int &data_len){ return mQueue.Remove(sample_buf, data_len);}// Receive a sample frame from socketbool receive_data(int sockfd, char * sample_buf, int &data_len){ fd_set fdR; struct timeval timeout; int sock_stat; struct sockaddr client_sck; timeout.tv_sec = 0; timeout.tv_usec = 1; FD_ZERO(&fdR); FD_SET(sockfd, &fdR); //sock_stat = select(sockfd + 1, &fdR, NULL, NULL, &timeout); sock_stat = select(sockfd + 1, &fdR, NULL, NULL, NULL); if((sock_stat != -1) && (sock_stat != 0)) { if(FD_ISSET(sockfd, &fdR)) { socklen_t len; len = data_len; /* waiting for receive data */ ssize_t n; n = recvfrom(sockfd, sample_buf, frame_size, 0, &client_sck, &len); data_len = len; if(n == -1) return false; } } return true; }// Judge whether we can write sample data to sound card driver without blockedbool can_write(int sound_h, int write_size){ audio_buf_info info; ioctl(sound_h, SNDCTL_DSP_GETOSPACE, &info); if(info.bytes >= write_size) return true; else return false;}int main(void){ int sockfd; struct sockaddr_in servaddr, cliaddr; char databuf[frame_size]; int buflen; int soundfd; char soundbuf[frame_size]; /* create a socket */ sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* init servaddr */ bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); /* bind address and port to socket */ if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { perror("bind error"); exit(1); } // Open Sound Card Device if((soundfd = open(DEVICE_NAME, O_RDWR, 0)) == -1) { perror(DEVICE_NAME); close(sockfd); exit(-1); } // Reset Sound Card Device int i; i=0; ioctl (soundfd,SNDCTL_DSP_RESET,(char *)&i) ; // Disable Block Mode in Playing Mode or Recording Mode i=0; ioctl (soundfd,SNDCTL_DSP_SYNC,(char *)&i); // Enable NonBlock Mode of Sound Card Driver i=1; ioctl (soundfd,SNDCTL_DSP_NONBLOCK,(char *)&i); // Set Sampling Rate i=44100; ioctl (soundfd,SNDCTL_DSP_SPEED,(char *)&i); // Set Sound Channels Number to 1 i=1; ioctl (soundfd,SNDCTL_DSP_CHANNELS,(char *)&i); // Set Sound Card Sampling Format to 16bit little-endian format // It must be checked, wheather S3C2410 support this format i=AFMT_S16_LE; ioctl (soundfd,SNDCTL_DSP_SETFMT,(char *)&i); // Enable precise timing in recording or playback i=3; ioctl (soundfd,SNDCTL_DSP_SETTRIGGER,(char *)&i); i=1; ioctl (soundfd,SNDCTL_DSP_PROFILE,(char *)&i); for(;;) { // Receive data from socket, and insert it into circle queue if(receive_data(sockfd, databuf, buflen)) { mQueue.Insert(databuf, buflen); } // Judeg if can write sample data into sound card driver buffer if(can_write(soundfd, frame_size)) { // if can get data from receive circle queue, then write data to sound driver if(get_sample(databuf, buflen)) write(soundfd, databuf, buflen); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -