,audio_linux.c
来自「speech signal process tools」· C语言 代码 · 共 382 行
C
382 行
/* * This material contains unpublished, proprietary software of Entropic * Research Laboratory, Inc. Any reproduction, distribution, or publication * of this work must be authorized in writing by Entropic Research * Laboratory, Inc., and must bear the notice: * * "Copyright (c) 1995 Entropic Research Laboratory, Inc. All rights reserved" * * The copyright notice above does not evidence any actual or intended * publication of this source code. * * Written by: Checked by: Revised by: * * Brief description: * */static char *sccs_id = "%W% %G% ERL";#include <stdio.h>#include <linux/soundcard.h>#include <fcntl.h>#include <math.h>#include <sys/ioctl.h>#include <sys/time.h>#define AUDIODEV "/dev/dsp"char audio_error_msg[100];static int play_fd = -1, rec_fd = -1; static unsigned long sample_rate, rec_sample_rate;static int channels, rec_channels, rec_buffsize;static int playPortBufSize;static struct timeval playBgnTime;static unsigned long samps_sent;static int abuf_size;static int rbuf_size;static int sample_rates[] = {48000, 44100, 37800, 32000, 22050, 18900, 16000, 11025, 9600, 8000, 0};extern int debug_level;static doubleTimeDiff (a, b) struct timeval *a, *b;{ double at, bt; bt = b->tv_sec + b->tv_usec * 1E-6; at = a->tv_sec + a->tv_usec * 1E-6; return (bt - at);}static voidnap (usec) int usec;{ struct timeval timer_val; timer_val.tv_sec = 0; timer_val.tv_usec = usec; select (0, NULL, NULL, NULL, &timer_val);}intPortIsAvailable (){ if (play_fd > 0) return 0; if ((play_fd = open (AUDIODEV, O_RDWR)) < 0) { sprintf (audio_error_msg, "Cannot open Linux audio port.\n"); return 1; } else { if (close (play_fd) < 0) perror ("PortIsAvailable"); play_fd = -1; return 0; }}intInitAudioPlay (srate, channel, nSampsPerChan) double srate; int channel; int nSampsPerChan;{ unsigned long sample_size = 16; int stereo = (channel == 2); if (debug_level) fprintf (stderr, "InitAudioPlay: srate: %lf, channel: %d, nSampsPerChan: %d\n", srate, channel, nSampsPerChan); channels = channel; playPortBufSize = nSampsPerChan * sizeof (short) * channel; sample_rate = srate; if (play_fd < 0) { if ((play_fd = open (AUDIODEV, O_WRONLY)) < 0) { sprintf (audio_error_msg, "Cannot open audio port in Init\n"); fprintf (stderr, "Cannot open audio port in Init\n"); return 1; } } if (ioctl (play_fd, SNDCTL_DSP_GETBLKSIZE, &abuf_size) < 0) { sprintf (audio_error_msg, "Unable to get buffer size\n"); close (play_fd); play_fd = -1; return 1; } if (ioctl (play_fd, SNDCTL_DSP_SAMPLESIZE, &sample_size) < 0) { sprintf (audio_error_msg, "Unable to set sample size\n"); close (play_fd); play_fd = -1; return 1; } if (ioctl (play_fd, SNDCTL_DSP_STEREO, &stereo) < 0) { sprintf (audio_error_msg, "Unable to set stereo flag\n"); close (play_fd); play_fd = -1; return 1; } if (ioctl (play_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0) { sprintf (audio_error_msg, "Unable to set sample rate\n"); close (play_fd); play_fd = -1; return 1; } return (0);}intGetPlayFilled (){ int samps_not_played, samps_played; struct timeval current_time; gettimeofday (¤t_time, NULL); samps_played = sample_rate * TimeDiff (&playBgnTime, ¤t_time) * channels; samps_not_played = samps_sent - samps_played; if (samps_not_played < 0) samps_not_played = 0; return (samps_not_played);}intCanWriteAudio (){ int samps_not_played; int can_write_samps; can_write_samps = playPortBufSize / sizeof (short) - GetPlayFilled (); if (can_write_samps < 0) can_write_samps = 0; return (can_write_samps);}intPlayAudioDrain (){ char *io_buff, *calloc (); int filled = GetPlayFilled () * sizeof (short); int buf_size = abuf_size - filled; if (play_fd < 0) return 0; if (buf_size < 0) return 0; io_buff = calloc (buf_size, sizeof (char)); write (play_fd, io_buff, buf_size); free (io_buff); return 0;}intCloseAudioPlay (hold_port) int hold_port; /* if non-zero, hold port open */{ if (play_fd < 0) return 0; if (debug_level) fprintf (stderr, "CloseAudioPlay: remaining: %d", GetPlayFilled ()); if (close (play_fd) < 0) perror ("close"); if (debug_level) fputc ('.', stderr); play_fd = -1; return 0;}intStartAudioPlay (){ samps_sent = 0; gettimeofday (&playBgnTime, NULL); return 0;}intPlayAudio (buffer, nSamps) short *buffer; int nSamps;{ int i, n; if (debug_level) fprintf (stderr, "PlayAudio: %d\n", nSamps); if (play_fd < 0) return 0; n = nSamps * sizeof (short); if (write (play_fd, buffer, n) != n) fprintf (stderr, "write error to audio dev\n"); samps_sent += nSamps; return 0;}voidSendAudioZeros (){ static short buff[400]; if (play_fd > -1) write (play_fd, buff, 800);}intInitAudioRecord (srate, channel, buffsize) double srate; int channel; int buffsize;{ long buflen; unsigned long sample_size = 16; int stereo = (channel == 2); if (debug_level) fprintf (stderr, "InitAudioRecord: srate: %lf, channel: %d, buffsize: %d\n", srate, channel, buffsize); if (rec_fd < 0) { if ((rec_fd = open (AUDIODEV, O_RDONLY)) < 0) { sprintf (audio_error_msg, "Cannot open audio port in Init\n"); fprintf (stderr, "Cannot open audio port in Init\n"); return 1; } } rec_channels = channel; rec_sample_rate = srate; rec_buffsize = buffsize; if (ioctl (rec_fd, SNDCTL_DSP_SAMPLESIZE, &sample_size) < 0) { sprintf (audio_error_msg, "Unable to set sample size\n"); close (rec_fd); rec_fd = -1; return 1; } if (ioctl (rec_fd, SNDCTL_DSP_STEREO, &stereo) < 0) { sprintf (audio_error_msg, "Unable to set stereo flag\n"); close (rec_fd); rec_fd = -1; return 1; } if (ioctl (rec_fd, SNDCTL_DSP_SPEED, &rec_sample_rate) < 0) { sprintf (audio_error_msg, "Unable to set sample rate\n"); close (rec_fd); rec_fd = -1; return 1; } if (ioctl (rec_fd, SNDCTL_DSP_GETBLKSIZE, &rbuf_size) < 0) { sprintf (audio_error_msg, "Unable to get buffer size\n"); close (play_fd); play_fd = -1; return 1; } return 0;}intStartAudioRecord (){ return 0;}intCloseAudioRecord (){ if (rec_fd < 0) return 0; if (close (rec_fd) < 0) perror ("close"); rec_fd = -1; return 0;}int *AudioGetRates(){ return sample_rates;}intAudioMaxChannels(){ return 2;}intCanRead(){ static struct timeval timeout = {0L, 0L}; static fd_set fds; FD_ZERO(&fds); FD_SET(rec_fd, &fds); return(select(rec_fd+1, &fds, NULL, NULL, &timeout));}intPauseAudioRecord(){ return 1;}intContAudioRecord(){ return 1;}intRecordAudio(buffer)short *buffer;{ int haveread; haveread = read(rec_fd, buffer, rbuf_size)/sizeof(short); return haveread;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?