📄 speech.c
字号:
/* * 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/sphdec.h>/* Demo headers */#include <rendezvous.h>#include "decode.h"#include "speech.h"#include "loader.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/* G.711 encoded samples */#define NUMSAMPLES 80/* Number of samples to read */#define SOUNDBLKSIZE NUMSAMPLES * 2/* Raw stereo 16-bit decoded samples */#define RAWBUFSIZE SOUNDBLKSIZE * 4/* The size of the read buffer */#define READBUFSIZE 60 * 1024/* The levels of initialization */#define SPEECHFILEINITIALIZED 0x1#define SOUNDDEVICEINITIALIZED 0x2#define ENGINEOPENED 0x4#define SPEECHDECODERCREATED 0x8#define READBUFFERALLOCATED 0x10#define RAWBUFFERALLOCATED 0x20/* Local function prototypes */static int speechDecodeAlgCreate(Engine_Handle hEngine, SPHDEC_Handle *hDecodePtr);static int decodeSpeechBuffer(SPHDEC_Handle hDecode, char *inBuf, int inBufSize, char *outBuf, int *outBufSize, int *bytesProcessed, int *framesRejectedPtr);static int initSoundDevice(void);/****************************************************************************** * speechDecodeAlgCreate ******************************************************************************/static int speechDecodeAlgCreate(Engine_Handle hEngine, SPHDEC_Handle *hDecodePtr){ SPHDEC_Params params; SPHDEC_Handle hDecode; params.size = sizeof(SPHDEC_Params); params.compandingLaw = ISPEECH_ALAW; /* Create speech decoder */ hDecode = SPHDEC_create(hEngine, "g711dec", ¶ms); if (hDecode == NULL) { ERR("Can't open speech decode algorithm\n"); return FAILURE; } *hDecodePtr = hDecode; return SUCCESS;}/****************************************************************************** * decodeSpeechBuffer ******************************************************************************/static int decodeSpeechBuffer(SPHDEC_Handle hDecode, char *inBuf, int inBufSize, char *outBuf, int *outBufSize, int *bytesProcessed, int *framesRejectedPtr){ SPHDEC_DynamicParams dynamicParams; SPHDEC_Status decStatus; XDM_BufDesc inBufDesc; XDM_BufDesc outBufDesc; XDAS_Int32 inBufSizeArray[1]; XDAS_Int32 outBufSizeArray[1]; XDAS_Int32 status; SPHDEC_InArgs inArgs; SPHDEC_OutArgs outArgs; int i; inBufSizeArray[0] = inBufSize; outBufSizeArray[0] = RAWBUFSIZE; inBufDesc.bufSizes = inBufSizeArray; inBufDesc.bufs = (XDAS_Int8 **) &inBuf; inBufDesc.numBufs = 1; outBufDesc.bufSizes = outBufSizeArray; outBufDesc.bufs = (XDAS_Int8 **) &outBuf; outBufDesc.numBufs = 1; inArgs.size = sizeof(SPHDEC_InArgs); inArgs.inBufferSize = inBufSize; outArgs.size = sizeof(SPHDEC_OutArgs); /* Decode the speech buffer */ status = SPHDEC_process(hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs); if (status != SPHDEC_EOK) { decStatus.size = sizeof(SPHDEC_Status); dynamicParams.size = sizeof(SPHDEC_DynamicParams); status = SPHDEC_control(hDecode, XDM_GETSTATUS, &dynamicParams, &decStatus); if (status != SPHDEC_EOK) { ERR("XDM_GETSTATUS failed, status=%ld\n", status); return FAILURE; } if (status == SPHDEC_ERUNTIME || XDM_ISFATALERROR(decStatus.extendedError)) { ERR("SPHDEC_process() failed with a fatal error (%ld ext: %#lx\n", status, decStatus.extendedError); return FAILURE; } else { /* Make sure we don't output the corrupt samples */ *outBufSize = 0; (*framesRejectedPtr)++; return SUCCESS; } } /* Expand mono to stereo */ for (i = (inBufSize - 1); i >= 0; i--) { outBuf[4 * i] = outBuf[2 * i]; outBuf[4 * i + 1] = outBuf[2 * i + 1]; outBuf[4 * i + 2] = outBuf[2 * i]; outBuf[4 * i + 3] = outBuf[2 * i + 1]; } if (inBufSize < NUMSAMPLES) { *bytesProcessed = inBufSize; *outBufSize = inBufSize * 4; } else { *bytesProcessed = NUMSAMPLES; *outBufSize = NUMSAMPLES * 4; } return SUCCESS;}/****************************************************************************** * initSoundDevice ******************************************************************************/static int initSoundDevice(void){ int channels = NUM_CHANNELS; int sampleRate = SAMPLE_RATE; int format = AFMT_S16_LE; int soundFd; /* Open the sound device for writing */ soundFd = open(SOUND_DEVICE, O_WRONLY); 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; } gblSetSamplingFrequency(sampleRate); return soundFd;}/****************************************************************************** * speechThrFxn ******************************************************************************/void *speechThrFxn(void *arg){ Engine_Handle hEngine = NULL; unsigned int initMask = 0; SpeechEnv *envp = (SpeechEnv *) arg; void *status = THREAD_SUCCESS; char *rawBuffer = NULL; int framesRejected = 0; int outputFd = 0; SPHDEC_Handle hDecode; LoaderState lState; int frameSize; char *framePtr; int rawBufferSize; /* Initialize loader state */ lState.loop = envp->loop; lState.readBufSize = READBUFSIZE; lState.readSize = SOUNDBLKSIZE; lState.doneMask = SOUND_DONE; /* Initialize the input file */ lState.inputFd = open(envp->speechFile, O_RDONLY); if (lState.inputFd == -1) { ERR("Failed to open %s (%s)\n", envp->speechFile, strerror(errno)); cleanup(THREAD_FAILURE); } DBG("Speech file successfully opened\n"); initMask |= SPEECHFILEINITIALIZED; /* Initialize sound device */ outputFd = initSoundDevice(); if (outputFd == FAILURE) { cleanup(THREAD_FAILURE); } DBG("Sound device initialized\n"); initMask |= SOUNDDEVICEINITIALIZED; /* 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 decoder on the engine */ if (speechDecodeAlgCreate(hEngine, &hDecode) == FAILURE) { cleanup(THREAD_FAILURE); } DBG("Speech decoder created\n"); initMask |= SPEECHDECODERCREATED; /* Allocate intermediate buffer (for encoded data) */ lState.readBuffer = (char *) Memory_contigAlloc(lState.readBufSize, Memory_DEFAULTALIGNMENT); if (lState.readBuffer == NULL) { ERR("Failed to allocate contiguous memory block.\n"); cleanup(THREAD_FAILURE); } DBG("Contiguous buffer allocated with physical address %#lx\n", Memory_getPhysicalAddress(lState.readBuffer)); initMask |= READBUFFERALLOCATED; /* Allocate buffer for raw data */ rawBuffer = (char *) 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; /* Signal that initialization is done and wait for other threads */ Rendezvous_meet(envp->hRendezvous); /* Prime the file loader */ if (loaderPrime(&lState, &framePtr) == FAILURE) { cleanup(THREAD_FAILURE); } DBG("Entering speech main loop.\n"); while (!gblGetQuit()) { if (!gblGetPlay()) { usleep(PAUSE); continue; } /* Decode the encoded frame to the raw buffer */ if (decodeSpeechBuffer(hDecode, framePtr, lState.readSize, rawBuffer, &rawBufferSize, &frameSize, &framesRejected) == FAILURE) { breakLoop(THREAD_FAILURE); } /* Write samples to the device driver from contiguous buffer */ if (write(outputFd, rawBuffer, rawBufferSize) == -1) { ERR("Error writing data to %s (%s)\n", SOUND_DEVICE, strerror(errno)); breakLoop(THREAD_FAILURE); } /* Read a new frame of encoded data from disk */ if (loaderGetFrame(&lState, frameSize, &framePtr) == FAILURE) { breakLoop(THREAD_FAILURE); } if (lState.endClip) { /* Recreate the algorithm */ SPHDEC_delete(hDecode); if (speechDecodeAlgCreate(hEngine, &hDecode) == FAILURE) { breakLoop(THREAD_FAILURE); } /* Prime the file loader */ if (loaderPrime(&lState, &framePtr) == FAILURE) { cleanup(THREAD_FAILURE); } } /* Increment statistics for OSD display */ gblIncSoundBytesEncoded(frameSize); } printf("\nTotal number of speech frames rejected: %d\n", framesRejected);cleanup: /* Make sure the other threads aren't waiting for init to complete */ Rendezvous_force(envp->hRendezvous); /* Clean up the speech thread */ if (initMask & RAWBUFFERALLOCATED) { Memory_contigFree(rawBuffer, RAWBUFSIZE); } if (initMask & READBUFFERALLOCATED) { Memory_contigFree(lState.readBuffer, lState.readBufSize); } if (initMask & SPEECHDECODERCREATED) { SPHDEC_delete(hDecode); } if (initMask & ENGINEOPENED) { Engine_close(hEngine); } if (initMask & SOUNDDEVICEINITIALIZED) { close(outputFd); } if (initMask & SPEECHFILEINITIALIZED) { close(lState.inputFd); } return status;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -