?? speech.c
字號(hào):
/* * speech.c * * ============================================================================ * Copyright (c) Texas Instruments Inc 2005 * * Use of this software is controlled by the terms and conditions found in the * license agreement under which this software has been supplied or provided. * ============================================================================ *//* Standard Linux headers */#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/ioctl.h>#include <linux/soundcard.h>/* Codec Engine headers */#include <xdc/std.h>#include <ti/sdo/ce/Engine.h>#include <ti/sdo/ce/osal/Memory.h>#include <ti/sdo/ce/speech/sphenc.h>/* Demo headers */#include <rendezvous.h>#include "encode.h"#include "speech.h"/* The number of channels of the audio codec */#define NUM_CHANNELS 2/* The sample rate of the audio codec */#define SAMPLE_RATE 8000/* The gain (0-100) of the left and right channels */#define LEFT_GAIN 100#define RIGHT_GAIN 100/* Number of samples to process at once */#define NUMSAMPLES 80/* Mono 16 bit */#define RAWBUFSIZE NUMSAMPLES * 2/* Stereo 16 bit */#define INPUTBUFSIZE RAWBUFSIZE * 2/* The max amount of bytes of speech data to process at once */#define ENCODEDBUFSIZE RAWBUFSIZE / 2/* The levels of initialization */#define SPEECHFILEINITIALIZED 0x1#define SOUNDINPUTINITIALIZED 0x2#define ENGINEOPENED 0x4#define SPEECHENCODERCREATED 0x8#define ENCODEDBUFFERALLOCATED 0x10#define RAWBUFFERALLOCATED 0x20#define INPUTBUFFERALLOCATED 0x40/* Local function prototypes */static void stereoToMono(short *stereoSamples, short *monoSamples, int numSamples);static int speechEncodeAlgCreate(Engine_Handle hEngine, SPHENC_Handle *hEncodePtr);static int encodeSpeechBuffer(SPHENC_Handle hEncode, short *inBuf, int inBufSize, short *outBuf, int *outBufSize);static int initSoundDevice(SoundInput soundInput);/****************************************************************************** * stereoToMono ******************************************************************************/static void stereoToMono(short *stereoSamples, short *monoSamples, int numSamples){ int i; int val; for (i=0; i<numSamples; i++) { val = *stereoSamples++; *monoSamples++ = (val + *stereoSamples++) / 2; }}/****************************************************************************** * speechEncodeAlgCreate ******************************************************************************/static int speechEncodeAlgCreate(Engine_Handle hEngine, SPHENC_Handle *hEncodePtr){ SPHENC_Params params; SPHENC_Handle hEncode; params.size = sizeof(SPHENC_Params); params.compandingLaw = ISPEECH_ALAW; params.frameSize = 0; /* Create speech encoder */ hEncode = SPHENC_create(hEngine, "g711enc", ¶ms); if (hEncode == NULL) { ERR("Can't open speech encode algorithm\n"); return FAILURE; } *hEncodePtr = hEncode; return SUCCESS;}/****************************************************************************** * encodeSpeechBuffer ******************************************************************************/static int encodeSpeechBuffer(SPHENC_Handle hEncode, short *inBuf, int inBufSize, short *outBuf, int *outBufSize){ XDAS_Int32 inBufSizeArray[1]; XDAS_Int32 outBufSizeArray[1]; XDM_BufDesc inBufDesc; XDM_BufDesc outBufDesc; SPHENC_InArgs inArgs; SPHENC_OutArgs outArgs; XDAS_Int32 status; inBufSizeArray[0] = inBufSize; outBufSizeArray[0] = inBufSize / 2; inBufDesc.numBufs = 1; inBufDesc.bufSizes = inBufSizeArray; inBufDesc.bufs = (XDAS_Int8 **) &inBuf; outBufDesc.numBufs = 1; outBufDesc.bufSizes = outBufSizeArray; outBufDesc.bufs = (XDAS_Int8 **) &outBuf; inArgs.size = sizeof(SPHENC_InArgs); outArgs.size = sizeof(SPHENC_OutArgs); /* Encode the speech buffer */ status = SPHENC_process(hEncode, &inBufDesc, &outBufDesc, &inArgs, &outArgs); if (status != SPHENC_EOK) { ERR("SPHENC_process() failed, status=%ld\n", status); return FAILURE; } *outBufSize = inBufSize / 2; return SUCCESS;}/****************************************************************************** * initSoundDevice ******************************************************************************/static int initSoundDevice(SoundInput soundInput){ int vol = LEFT_GAIN | (RIGHT_GAIN << 8); int sampleRate = SAMPLE_RATE; int channels = NUM_CHANNELS; int format = AFMT_S16_LE; int soundFd; int mixerFd; int recMask; int recorder; if (soundInput == MIC_SOUND_INPUT) { printf("Microphone recorder selected\n"); recorder = SOUND_MASK_MIC; } else { printf("Line in recorder selected\n"); recorder = SOUND_MASK_LINE; } /* Select the right capture device and volume */ mixerFd = open(MIXER_DEVICE, O_RDONLY); if (mixerFd == -1) { ERR("Failed to open %s\n", MIXER_DEVICE); return FAILURE; } if (ioctl(mixerFd, SOUND_MIXER_READ_RECMASK, &recMask) == -1) { ERR("Failed to ask mixer for available recorders.\n"); return FAILURE; } if ((recMask & recorder) == 0) { ERR("Recorder not supported\n"); return FAILURE; } if (ioctl(mixerFd, SOUND_MIXER_WRITE_RECSRC, &recorder) == -1) { ERR("Failed to set recorder.\n"); return FAILURE; } if (ioctl(mixerFd, SOUND_MIXER_WRITE_IGAIN, &vol) == -1) { ERR("Failed to set the volume of line in.\n"); return FAILURE; } close(mixerFd); /* Open the sound device for writing */ soundFd = open(SOUND_DEVICE, O_RDONLY); if (soundFd == -1) { ERR("Failed to open the sound device (%s)\n", SOUND_DEVICE); return FAILURE; } /* Set the sound format (only AFMT_S16_LE supported) */ if (ioctl(soundFd, SNDCTL_DSP_SETFMT, &format) == -1) { ERR("Could not set format %d\n", format); return FAILURE; } /* Set the number of channels */ if (ioctl(soundFd, SNDCTL_DSP_CHANNELS, &channels) == -1) { ERR("Could not set mixer to %d channels\n", channels); return FAILURE; } /* Set the sample rate */ if (ioctl(soundFd, SNDCTL_DSP_SPEED, &sampleRate) == -1) { ERR("Could not set sample rate (%d)\n", sampleRate); return FAILURE; } return soundFd;}/****************************************************************************** * speechThrFxn ******************************************************************************/void *speechThrFxn(void *arg){ Engine_Handle hEngine = NULL; unsigned int initMask = 0; SpeechEnv *envp = (SpeechEnv *) arg; void *status = THREAD_SUCCESS; short *encodedBuffer = NULL; unsigned short *inputBuffer = NULL; short *rawBuffer = NULL; int inputFd = 0; SPHENC_Handle hEncode; FILE *outputFp; int numBytes; int encodedBufferSize; /* Initialize the output file */ outputFp = fopen(envp->speechFile, "w"); if (outputFp == NULL) { ERR("Failed to open %s for writing\n", envp->speechFile); cleanup(THREAD_FAILURE); } DBG("Speech file successfully opened\n"); initMask |= SPEECHFILEINITIALIZED; /* Initialize the sound device for reading */ inputFd = initSoundDevice(envp->soundInput); if (inputFd == FAILURE) { cleanup(THREAD_FAILURE); } DBG("Sound device initialized\n"); initMask |= SOUNDINPUTINITIALIZED; /* Reset, load, and start DSP Engine */ hEngine = Engine_open(ENGINE_NAME, NULL, NULL); if (hEngine == NULL) { ERR("Failed to open codec engine %s\n", ENGINE_NAME); cleanup(THREAD_FAILURE); } DBG("Codec Engine opened in speech thread\n"); initMask |= ENGINEOPENED; /* Allocate and initialize speech encoder on the engine */ if (speechEncodeAlgCreate(hEngine, &hEncode) == FAILURE) { cleanup(THREAD_FAILURE); } DBG("Speech encoder created\n"); initMask |= SPEECHENCODERCREATED; /* Allocate intermediate buffer (for encoded data) */ encodedBuffer = (short *) Memory_contigAlloc(ENCODEDBUFSIZE, Memory_DEFAULTALIGNMENT); if (encodedBuffer == NULL) { ERR("Failed to allocate contiguous memory block.\n"); cleanup(THREAD_FAILURE); } DBG("Contiguous buffer allocated with physical address %#lx\n", Memory_getPhysicalAddress(encodedBuffer)); initMask |= ENCODEDBUFFERALLOCATED; /* Allocate buffer for raw data */ rawBuffer = (short *) Memory_contigAlloc(RAWBUFSIZE, Memory_DEFAULTALIGNMENT); if (rawBuffer == NULL) { ERR("Failed to allocate contiguous memory block.\n"); cleanup(THREAD_FAILURE); } DBG("Contiguous buffer allocated with physical address %#lx\n", Memory_getPhysicalAddress(rawBuffer)); initMask |= RAWBUFFERALLOCATED; /* Allocate input buffer */ inputBuffer = malloc(INPUTBUFSIZE); if (inputBuffer == NULL) { ERR("Failed to allocate input buffer\n"); cleanup(THREAD_FAILURE); } DBG("Input buffer allocated\n"); initMask |= INPUTBUFFERALLOCATED; /* Signal that initialization is done and wait for other threads */ Rendezvous_meet(envp->hRendezvous); DBG("Entering speech main loop.\n"); while (!gblGetQuit()) { if (!gblGetRecord()) { usleep(PAUSE); continue; } /* Read stereo data from codec */ numBytes = read(inputFd, inputBuffer, INPUTBUFSIZE); if (numBytes == -1) { ERR("Error reading the data from speech file\n"); breakLoop(THREAD_FAILURE); } /* Convert the stereo buffer to mono */ stereoToMono(inputBuffer, rawBuffer, NUMSAMPLES); /* Encode the buffer */ if (encodeSpeechBuffer(hEncode, rawBuffer, RAWBUFSIZE, encodedBuffer, &encodedBufferSize) == FAILURE) { breakLoop(THREAD_FAILURE); } /* Write encoded buffer to the speech file */ if (encodedBufferSize) { if (fwrite(encodedBuffer, encodedBufferSize, 1, outputFp) != 1) { ERR("Error writing the encoded data to speech file.\n"); breakLoop(THREAD_FAILURE); } } /* Increment statistics for OSD display */ gblIncSoundBytesEncoded(encodedBufferSize); }cleanup: /* Make sure the other threads aren't waiting for init to complete */ Rendezvous_force(envp->hRendezvous); /* Clean up the speech thread */ if (initMask & INPUTBUFFERALLOCATED) { free(inputBuffer); } if (initMask & RAWBUFFERALLOCATED) { Memory_contigFree(rawBuffer, RAWBUFSIZE); } if (initMask & ENCODEDBUFFERALLOCATED) { Memory_contigFree(encodedBuffer, ENCODEDBUFSIZE); } if (initMask & SPEECHENCODERCREATED) { SPHENC_delete(hEncode); } if (initMask & ENGINEOPENED) { Engine_close(hEngine); } if (initMask & SOUNDINPUTINITIALIZED) { close(inputFd); } if (initMask & SPEECHFILEINITIALIZED) { fclose(outputFp); } return status;}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -