📄 audio_input_output.c
字号:
/* * audio_cap_disp.c *//* Standard Linux headers */#include <stdio.h> // always include stdio.h#include <stdlib.h> // always include stdlib.h#include <unistd.h> // defines open, close, read, write#include <sys/ioctl.h> // defines ioctl#include <fcntl.h> // defines standard flags, O_RDONLY, O_WRONLY#include <linux/soundcard.h> // defines OSS driver/* Application headers */#include "audio_input_output.h" // audio i/o methods and types #include "debug.h" // defines debug routines/* The number of channels of the audio codec.*/#define NUM_CHANNELS 2/****************************************************************************** * init_mixer ******************************************************************************//* input parameters: *//* char *device -- string value for mixer device node, *//* such as "/dev/mixer" *//* int recmask -- mask specifying input sources, definitions are *//* provided in soundcard.h, such as SOUND_MASK_LINE *//* for line input or SOUND_MASK_MIC for microphone *//* int vol -- left and right packed volume for input, *//* 8 bits each with right volume most significant pos *//* *//* *//* return value: *//* int -- AUDIO_SUCCESS or AUDIO_FAILURE as defined in *//* audio_input_output.h *//* *//******************************************************************************/int init_mixer(char *device, int recmask, int vol){ int mixerFd; // file descriptor for mixer DBG("Initializing mixer device: %s\n", device); /* Open the mixer device */ if ((mixerFd = open(device, O_RDONLY)) == -1) { ERR("Failed to open %s\n", device); return AUDIO_FAILURE; } /* Report mixer input settings and warn user if neither mic nor line */ if(recmask & SOUND_MASK_LINE) DBG("\tLine input enabled to mixer (record mask: %#0x)\n", recmask); if(recmask & SOUND_MASK_MIC) DBG("\tMic input enabled to mixer (record mask: %#0x)\n", recmask); if(!(recmask & (SOUND_MASK_LINE | SOUND_MASK_MIC))){ ERR("Neither supported input (mic, line) to the mixer has been set!\n"); ERR("\tThere may be no mixer input provided to OSS driver!\n"); ERR("\t(record mask: %#0x)\n", recmask); } /* Set the mixer input source */ if (ioctl(mixerFd, SOUND_MIXER_WRITE_RECSRC, &recmask) == -1) { ERR("Failed to set mixer record mask (file descriptor %d)\n", mixerFd); close(mixerFd); return AUDIO_FAILURE; }#if 0 // Currently this ioctl is not supported in the Davinci driver if (ioctl(mixerFd, SOUND_MIXER_WRITE_IGAIN, &vol) == -1) { ERR("Failed to set the volume of line in.\n"); return -1; }#endif close(mixerFd); /* return AUDIO_SUCCESSS if all steps execute correctly */ return AUDIO_SUCCESS;}/****************************************************************************** * init_sound_device ******************************************************************************//* input parameters: *//* int *fdByRef -- file descriptor passed by reference. Used to return *//* the file descriptor of the newly opened device *//* char *device -- string value for OSS driver device node, *//* such as "/dev/dsp" *//* int format -- data format, only AFMT_S16_LE = *//* Stereo 16-bit Little Endian format is supported *//* int numchannels -- must be 2 since only stereo format supported *//* int samplerate -- sample rate in Hertz, i.e. 44100 *//* int mode -- O_RDONLY for input, O_WRONLY for output *//* *//* *//* return value: *//* int -- AUDIO_SUCCESS or AUDIO_FAILURE as per audio_input_output.h *//* *//******************************************************************************/int init_sound_device(int *fdByRef, char *device, int format, int numchannels, int samplerate, int mode){ int fd; // file descriptor for OSS audio stream /* Define a macro to handle the cleanup procedure for failures */#define isd_failure_procedure() close(fd); \ *fdByRef = -1; \ return AUDIO_FAILURE DBG("Initializing %s sound device: %s\n", mode == O_RDONLY ? "input" : "output", device); /* Open the sound device */ if ((fd = open(device, mode)) == -1) { ERR("Failed to open the sound device (%s)\n", device); return AUDIO_FAILURE; } DBG("\tSound device opened with file descriptor: %d\n", fd); /* Set the sound format (only AFMT_S16_LE currently supported) */ if (ioctl(fd, SNDCTL_DSP_SETFMT, &format) == -1) { ERR("Could not set format %d\n", format); isd_failure_procedure(); } /* Currently only AFMT_S16_LE is supported, so cheat and just report this */ DBG("\tFormat set to AFMT_S16_LE (%#0x)\n", format); /* Set the number of channels */ if (ioctl(fd, SNDCTL_DSP_CHANNELS, &numchannels) == -1) { ERR("Could not set mixer to %d channels\n", numchannels); isd_failure_procedure(); } DBG("\tNumber of channels set to %d\n", numchannels); /* Set the sample rate */ if (ioctl(fd, SNDCTL_DSP_SPEED, &samplerate) == -1) { ERR("Could not set sample rate (%d)\n\n", samplerate); isd_failure_procedure(); } DBG("\tSample rate set to %d Hz.\n", samplerate); /* return AUDIO_SUCCESS and file descriptor of newly opened device */ *fdByRef = fd; return AUDIO_SUCCESS;}/****************************************************************************** * audio_input_setup ******************************************************************************//* input parameters: *//* int *fdByRef -- file descriptor passed by reference. Used to *//* return file descriptor of newly opened device *//* char *soundDevice -- string value for OSS driver device node, *//* such as "/dev/dsp" *//* char *mixerDevice -- string value for mixer device node, *//* such as "/dev/mixer" *//* int audioSource -- mask specifying input sources, definitions *//* are provided in soundcard.h, such as *//* SOUND_MASK_LINE for line input or *//* SOUND_MASK_MIC for microphone input *//* int vol -- left and right packed volume for input, *//* 8 bits each with right volume most significant pos *//* int samplerate -- sample rate in Hertz, i.e. 44100 *//* int *blockSizeByRef -- pointer to a blocksize value, used to return *//* the driver's native blocksize *//* *//* *//* return value: *//* int -- AUDIO_SUCCESS or AUDIO_FAILURE as per audio_input_output.h *//* *//******************************************************************************/int audio_input_setup(int *fdByRef, char *soundDevice, char *mixerDevice, int audioSource, int vol, int sampleRate, int *blockSizeByRef){ int inputFd; // file descriptor for OSS input stream /* Define a macro to handle the cleanup procedure for failures */#define ais_failure_procedure() *blockSizeByRef = 0; \ *fdByRef = -1; \ return AUDIO_FAILURE /* Initialize the mixer for line input */ if( init_mixer(mixerDevice, audioSource, vol) < 0){ ERR("init_mixer failed in audio_input_setup\n"); ais_failure_procedure(); } /* Initialize the input OSS device */ /* AFMT_S16_LE = Stereo 16-bit Little Endian data format */ /* (LEFT_CHAN 0, 16bit)(RIGHT_CHAN 0, 16bit)(LEFT_CHAN 1, 16 bit)... */ /* This is the only currently supported format for this driver on DaVinci */ if( init_sound_device(&inputFd, soundDevice, AFMT_S16_LE, NUM_CHANNELS, sampleRate, O_RDONLY) == AUDIO_FAILURE ){ ERR("init_sound_device failed in audio_input_setup\n"); ais_failure_procedure(); } /* Query the input OSS driver for the optimal block size to use */ if (ioctl(inputFd, SNDCTL_DSP_GETBLKSIZE, blockSizeByRef) == -1) { ERR("Failed to get optimal block size from device: %s\n",soundDevice); ais_failure_procedure(); } /* return AUDIO_SUCCESS and file descriptor of newly opened device */ /* *blockSizeByRef return value has already been set */ *fdByRef = inputFd; return AUDIO_SUCCESS;}/****************************************************************************** * audio_input_cleanup ******************************************************************************//* input parameters: *//* int inputFd -- file descriptor for the sound device as returned by *//* audio_input_setup *//* *//* return value: *//* int -- AUDIO_SUCCESS or AUDIO_FAILURE as per audio_input_output.h *//* *//******************************************************************************/int audio_input_cleanup(int inputFd){ if(close(inputFd) == -1){ ERR("Failed close on OSS audio input device (file descriptor %d) \n", inputFd); return AUDIO_FAILURE; } DBG("Closed audio input device (file descriptor %d)\n", inputFd); return AUDIO_SUCCESS;}/****************************************************************************** * audio_output_setup ******************************************************************************//* input parameters: *//* int *fdByRef -- file descriptor passed by reference. Used to *//* return file descriptor of newly opened device *//* char *soundDevice -- string value for OSS driver device node, *//* such as "/dev/dsp" *//* int samplerate -- sample rate in Hertz, i.e. 44100 *//* *//* *//* return value: *//* int -- AUDIO_SUCCESS or AUDIO_FAILURE as per audio_input_output.h *//* *//******************************************************************************/int audio_output_setup(int *fdByRef, char *soundDevice, int sampleRate){ int outputFd; // file descriptor for OSS output stream /* Initialize the output OSS device */ /* AFMT_S16_LE = Stereo 16-bit Little Endian data format */ /* (LEFT_CHAN 0, 16bit)(RIGHT_CHAN 0, 16bit)(LEFT_CHAN 1, 16 bit)... */ /* This is the only currently supported format for this driver on DaVinci */ if( init_sound_device(&outputFd, soundDevice, AFMT_S16_LE, NUM_CHANNELS, sampleRate, O_WRONLY) == AUDIO_FAILURE ){ ERR("init_sound_device failed in audio_output_setup\n"); *fdByRef = -1; // return invalid file descriptor on failure return AUDIO_FAILURE; } /* Return status and file descriptor of newly opened device */ *fdByRef = outputFd; return AUDIO_SUCCESS;}/****************************************************************************** * audio_output_cleanup ******************************************************************************//* input parameters: *//* int outputFd -- file descriptor for the sound device as returned by *//* audio_output_setup *//* *//* return value: *//* int -- AUDIO_SUCCESS or AUDIO_FAILURE as per audio_input_output.h *//* *//******************************************************************************/int audio_output_cleanup(int outputFd){ if(close(outputFd) == -1){ ERR("Failed close on OSS audio output device (file descriptor %d) \n", outputFd); return AUDIO_FAILURE; } DBG("Closed audio output device (file descriptor %d)\n", outputFd); return AUDIO_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -