| #include <errno.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <netdb.h> | |
| #include <fcntl.h> | |
| #include <sys/socket.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <netinet/in.h> | |
| #include <alsa/asoundlib.h> | |
| #define UDP_TARGET_HOST "127.0.0.1" | |
| #define UDP_TARGET_PORT "4001" | |
| #define UDP_PACKET_SIZE 64 | |
| #define ALSA_SAMPLE_RATE 8000 | |
| #define ALSA_CHANNELS 1 | |
| main (int argc, char *argv[]) { | |
| int err; | |
| int buffer_frames = 128; | |
| struct addrinfo hints; | |
| memset(&hints,0,sizeof(hints)); | |
| hints.ai_family = AF_UNSPEC; | |
| hints.ai_socktype = SOCK_DGRAM; | |
| hints.ai_protocol = 0; | |
| hints.ai_flags = AI_ADDRCONFIG; | |
| struct addrinfo* res=0; | |
| getaddrinfo(UDP_TARGET_HOST, UDP_TARGET_PORT, &hints, &res); | |
| int sock = socket(res->ai_family,res->ai_socktype,res->ai_protocol); | |
| if (sock==-1) { | |
| fprintf(stderr, "cannot create udp socket (%s)\n", strerror(errno)); | |
| return -1; | |
| } | |
| snd_pcm_t *capture_handle; | |
| snd_pcm_hw_params_t *hw_params; | |
| snd_pcm_format_t format = SND_PCM_FORMAT_A_LAW; | |
| if ((err = snd_pcm_open(&capture_handle, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) { | |
| fprintf(stderr, "cannot open audio device %s (%s)\n", argv[1], snd_strerror(err)); | |
| exit (1); | |
| } | |
| if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) { | |
| fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror(err)); | |
| exit (1); | |
| } | |
| snd_pcm_hw_params_any(capture_handle, hw_params); | |
| snd_pcm_hw_params_set_access(capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); | |
| snd_pcm_hw_params_set_format(capture_handle, hw_params, format); | |
| snd_pcm_hw_params_set_rate(capture_handle, hw_params, ALSA_SAMPLE_RATE, 0); | |
| snd_pcm_hw_params_set_channels(capture_handle, hw_params, ALSA_CHANNELS); | |
| snd_pcm_hw_params_set_period_size(capture_handle, hw_params, 32, 0); | |
| snd_pcm_hw_params(capture_handle, hw_params); | |
| snd_pcm_hw_params_free(hw_params); | |
| if ((err = snd_pcm_prepare(capture_handle)) < 0) { | |
| fprintf(stderr, "cannot prepare audio interface for use (%s)\n", snd_strerror(err)); | |
| exit (1); | |
| } | |
| uint8_t buffer[UDP_PACKET_SIZE]; | |
| while (1) { | |
| if ((err = snd_pcm_readi(capture_handle, buffer, sizeof(buffer))) != sizeof(buffer)) { | |
| fprintf(stderr, "read from audio interface failed (%s)\n", snd_strerror(err)); | |
| break; | |
| } | |
| if (sendto(sock, buffer, sizeof(buffer), 0, res->ai_addr,res->ai_addrlen)==-1) { | |
| fprintf(stderr, "udp sendto failed(%s)\n", strerror(errno)); | |
| break; | |
| } | |
| } | |
| snd_pcm_close(capture_handle); | |
| exit(0); | |
| } |
| #include <errno.h> | |
| #include <string.h> | |
| #include <unistd.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <netdb.h> | |
| #include <fcntl.h> | |
| #include <sys/socket.h> | |
| #include <sys/types.h> | |
| #include <sys/stat.h> | |
| #include <netinet/in.h> | |
| #include <time.h> | |
| #define UDP_TARGET_HOST "127.0.0.1" | |
| #define UDP_TARGET_PORT "4001" | |
| #define UDP_PACKET_SIZE 64 | |
| #define FILE_SAMPLE_RATE 8000 | |
| int8_t alaw_encode(int16_t number) | |
| { | |
| /* | |
| * Taken from: | |
| * http://dystopiancode.blogspot.de/2012/02/pcm-law-and-u-law-companding-algorithms.html | |
| */ | |
| const uint16_t ALAW_MAX = 0xFFF; | |
| uint16_t mask = 0x800; | |
| uint8_t sign = 0; | |
| uint8_t position = 11; | |
| uint8_t lsb = 0; | |
| if (number < 0) { | |
| number = -number; | |
| sign = 0x80; | |
| } | |
| if (number > ALAW_MAX) { | |
| number = ALAW_MAX; | |
| } | |
| for (; ((number & mask) != mask && position >= 5); mask >>= 1, position--); | |
| lsb = (number >> ((position == 4) ? (1) : (position - 4))) & 0x0f; | |
| return (sign | ((position - 4) << 4) | lsb) ^ 0x55; | |
| } | |
| int main(int argc, char **argv) { | |
| struct addrinfo hints; | |
| memset(&hints,0,sizeof(hints)); | |
| hints.ai_family = AF_UNSPEC; | |
| hints.ai_socktype = SOCK_DGRAM; | |
| hints.ai_protocol = 0; | |
| hints.ai_flags = AI_ADDRCONFIG; | |
| struct addrinfo* res=0; | |
| getaddrinfo(UDP_TARGET_HOST, UDP_TARGET_PORT, &hints, &res); | |
| int fd=socket(res->ai_family,res->ai_socktype,res->ai_protocol); | |
| if (fd==-1) { | |
| puts(strerror(errno)); | |
| return -1; | |
| } | |
| int readfd = open(argv[1], O_RDONLY); | |
| if (!readfd) { perror("could not open file"); } | |
| struct timespec t_next_send; | |
| clock_gettime(CLOCK_MONOTONIC, &t_next_send); | |
| int frame_inteval_us = 1000000 / FILE_SAMPLE_RATE; | |
| int frames_per_packet = UDP_PACKET_SIZE; | |
| int packet_interval_us = frames_per_packet * frame_inteval_us; | |
| int16_t readbuf[UDP_PACKET_SIZE]; | |
| int8_t sendbuf[UDP_PACKET_SIZE]; | |
| while (1) { | |
| int bytes_read = read(readfd, readbuf, sizeof(readbuf)); | |
| if (bytes_read<=0) { break; } | |
| int i; | |
| for (i=0; i<UDP_PACKET_SIZE; i++) { | |
| sendbuf[i] = alaw_encode(readbuf[i]/8); | |
| } | |
| if (sendto(fd, sendbuf, bytes_read/2, 0, res->ai_addr,res->ai_addrlen)==-1) { | |
| puts(strerror(errno)); | |
| break; | |
| } | |
| t_next_send.tv_nsec += 1000*packet_interval_us; | |
| while (t_next_send.tv_nsec>1000000000UL) { | |
| t_next_send.tv_nsec -= 1000000000UL; | |
| t_next_send.tv_sec += 1; | |
| } | |
| clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t_next_send, NULL); | |
| } | |
| close(readfd); | |
| return 0; | |
| } |
| /* | |
| * udp-alaw-sink.c | |
| * | |
| * Created on: 14.03.2015 | |
| * Author: hd | |
| */ | |
| #define ALSA_PCM_NEW_HW_PARAMS_API | |
| #include <alsa/asoundlib.h> | |
| #include <sys/socket.h> | |
| #include <netinet/in.h> | |
| #define ALSA_SAMPLE_RATE 8000 | |
| #define ALSA_CHANNELS 1 | |
| #define UDP_ALAW_PORT 4001 | |
| #define UDP_MAX_PACKET_SIZE 1024 | |
| int main() { | |
| /* create UDP socket */ | |
| int sock = socket(AF_INET, SOCK_DGRAM, 0); | |
| if (sock < 0) { | |
| perror("Opening datagram socket"); | |
| exit(1); | |
| } | |
| struct sockaddr_in server_addr; | |
| bzero((char *) &server_addr, sizeof(server_addr)); | |
| server_addr.sin_family = AF_INET; | |
| server_addr.sin_addr.s_addr = htonl(INADDR_ANY); | |
| server_addr.sin_port = htons(UDP_ALAW_PORT); | |
| if (bind(sock, (struct sockaddr *) &server_addr, sizeof(server_addr))) { | |
| perror("binding datagram socket"); | |
| exit(1); | |
| } | |
| /* open PCM device */ | |
| snd_pcm_t *pcm_handle; | |
| int rc = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); | |
| if (rc < 0) { | |
| fprintf(stderr, "unable to open pcm device: %s\n", snd_strerror(rc)); | |
| exit(1); | |
| } | |
| /* set hardware paramters */ | |
| snd_pcm_hw_params_t *hw_params; | |
| snd_pcm_hw_params_alloca(&hw_params); | |
| snd_pcm_hw_params_any(pcm_handle, hw_params); | |
| snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); | |
| snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_A_LAW); | |
| snd_pcm_hw_params_set_channels(pcm_handle, hw_params, ALSA_CHANNELS); | |
| snd_pcm_hw_params_set_rate(pcm_handle, hw_params, ALSA_SAMPLE_RATE, 0); | |
| snd_pcm_hw_params_set_period_size(pcm_handle, hw_params, 32, 0); | |
| rc = snd_pcm_hw_params(pcm_handle, hw_params); | |
| if (rc < 0) { | |
| fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); | |
| exit(1); | |
| } | |
| /* set software paramters */ | |
| snd_pcm_sw_params_t *sw_params; | |
| snd_pcm_sw_params_malloc(&sw_params); | |
| snd_pcm_sw_params_current(pcm_handle, sw_params); | |
| snd_pcm_sw_params_set_start_threshold(pcm_handle, sw_params, 64); | |
| rc = snd_pcm_sw_params(pcm_handle, sw_params); | |
| if (rc < 0) { | |
| fprintf(stderr, "unable to set hw parameters: %s\n", snd_strerror(rc)); | |
| exit(1); | |
| } | |
| snd_pcm_sw_params_free(sw_params); | |
| uint8_t buffer[UDP_MAX_PACKET_SIZE]; | |
| struct sockaddr_in client_addr; | |
| while (1) { | |
| socklen_t client_addr_len = sizeof(client_addr); | |
| int send_bytes_avail = recvfrom(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)&client_addr, &client_addr_len); | |
| int send_pos = 0; | |
| while (send_bytes_avail>0) { | |
| int rc = snd_pcm_writei(pcm_handle, &buffer[send_pos], send_bytes_avail); | |
| if (rc>0) { | |
| send_bytes_avail -= rc; | |
| send_pos += rc; | |
| } else if (rc == -EPIPE) { | |
| /* EPIPE means underrun */ | |
| snd_pcm_prepare(pcm_handle); | |
| } else { // other error | |
| break; | |
| } | |
| } | |
| } | |
| close(sock); | |
| snd_pcm_drain(pcm_handle); | |
| snd_pcm_close(pcm_handle); | |
| return 0; | |
| } |
本文介绍了一种使用 UDP 和 ALAW 编码进行流媒体传输的方法,包括创建 UDP 套接字、配置 ALSA PCM 设备、设置硬件参数、发送 ALAW 编码的音频数据。
8352

被折叠的 条评论
为什么被折叠?



