📄 audio_thread.c
字号:
/* Standard Linux headers */#include <stdio.h> // always include stdio.h#include <stdlib.h> // always include stdlib.h#include <fcntl.h> // defines open, read, write methods#include <unistd.h> // defines close and sleep methods#include <sys/ioctl.h> // defines driver ioctl method#include <linux/soundcard.h> // defines OSS driver functions#include <string.h> // defines memcpy/* Application headers */#include "debug.h" // DBG and ERR macros#include "audio_thread.h" // audio thread definitions#include "audio_input_output.h" // audio driver input and output functions/* OSS and Mixer devices */#define SOUND_DEVICE "/dev/dsp"#define MIXER_DEVICE "/dev/mixer"/* Output file name */#define OUTFILE "/tmp/audio.raw"/* The sample rate of the audio codec.*/#define SAMPLE_RATE 44100/* The gain (0-100) of the left channel.*/#define LEFT_GAIN 100/* The gain (0-100) of the right channel.*/#define RIGHT_GAIN 100/* Parameters for audio thread execution */#define BLOCKSIZE 44100/****************************************************************************** * audio_thread_fxn ******************************************************************************//* input parameters: *//* void *envByRef -- a pointer to an audio_thread_env structure *//* as defined in audio_thread.h *//* *//* envByRef.quit -- when quit != 0, thread will cleanup and exit *//* *//* return value: *//* void * -- AUDIO_THREAD_SUCCESS or AUDIO_THREAD_FAILURE as *//* defined in audio_thread.h *//******************************************************************************/void *audio_thread_fxn(void *envByRef){/* Thread parameters and return value */ audio_thread_env *envPtr = envByRef; // see above void *status = AUDIO_THREAD_SUCCESS; // see above/* The levels of initialization for initMask */#define INPUT_OSS_INITIALIZED 0x1#define OUTPUT_FILE_OPENED 0x2#define INPUT_BUFFER_ALLOCATED 0x4 unsigned int initMask = 0x0;// used to only cleanup items that were init'ed/* Input and output variables */ int inputFd = 0; // input driver file descriptor (i.e. handle) FILE *outfile = NULL; // output file pointer (i.e. handle) int blksize = BLOCKSIZE;// raw input or output frame size char *inputBuffer = NULL; // input buffer for driver to read into int vol = LEFT_GAIN | (RIGHT_GAIN << 8); // volume setting /* Thread Create Phase -- secure and initialize resources */ /* Open an OSS device channel for audio input */ if(audio_input_setup(&inputFd, SOUND_DEVICE, MIXER_DEVICE, SOUND_MASK_LINE, vol, SAMPLE_RATE, &blksize) == AUDIO_FAILURE){ ERR("audio_input_setup failed in audio_thread_fxn\n\n"); status = AUDIO_THREAD_FAILURE; goto cleanup; } /* Record that input OSS device was opened in initialization bitmask */ initMask |= INPUT_OSS_INITIALIZED; /* Create input buffer to read into from OSS input device */ if((inputBuffer = malloc(blksize)) == NULL) { ERR("Failed to allocate memory for input block (%d)\n", blksize); status = AUDIO_THREAD_FAILURE; goto cleanup; } DBG("Allocated input audio buffer of size %d to address %p\n", blksize, inputBuffer); /* Record that the input buffer was allocated in initialization bitmask*/ initMask |= INPUT_BUFFER_ALLOCATED; /* Open a file for record */ outfile = fopen(OUTFILE, "w"); if(outfile == NULL) { ERR("Failed to open file %s\n", OUTFILE); status = AUDIO_THREAD_FAILURE; goto cleanup; } DBG("Opened file %s with FILE pointer = %p\n", OUTFILE, outfile); /* Record that input OSS device was opened in initialization bitmask */ initMask |= OUTPUT_FILE_OPENED; /* Thread Execute Phase -- perform I/O and processing */ DBG("Entering audio_thread_fxn processing loop\n"); while (!envPtr->quit){ /* Read input buffer from OSS input device */ if ((int) read(inputFd, inputBuffer, blksize) < blksize) { ERR("Error reading the data from file descriptor %d\n", inputFd); status = AUDIO_THREAD_FAILURE; goto cleanup; } if(fwrite(inputBuffer, sizeof(char), blksize, outfile) < blksize) { ERR("Error writing the data to FILE pointer %p\n", outfile); status = AUDIO_THREAD_FAILURE; goto cleanup; } }cleanup: DBG("Exited audio_thread_fxn processing loop\n"); DBG("Starting audio thread cleanup to return resources to system\n"); /* Thread Delete Phase -- clean up resources used */ /* Use the initMask to only free resources that were allocated */ /* Nothing to be done for mixer device, it was closed after init */ /* Close output file */ if(initMask & OUTPUT_FILE_OPENED){ DBG("Closing output file at FILE ptr %p\n", outfile); fclose(outfile); } /* Close input OSS device */ if(initMask & INPUT_OSS_INITIALIZED) if(audio_input_cleanup(inputFd) != AUDIO_SUCCESS) { ERR("audio_output_cleanup failed for file descriptor %d\n", inputFd); status = AUDIO_THREAD_FAILURE; } /* Free input buffer */ if(initMask & INPUT_BUFFER_ALLOCATED) free(inputBuffer); DBG("Freed audio input buffer at location %p\n", inputBuffer); /* Return the status of the thread execution */ DBG("Audio thread cleanup complete. Exiting audio_thread_fxn\n"); return status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -