|
|
/******************************************************************************
* vapiIo.cpp * *------------* * I/O library functions for extended speech files (vapi format) *------------------------------------------------------------------------------ * Copyright (C) 2000 Microsoft Corporation Date: 03/02/00 * All Rights Reserved * ********************************************************************* PACOG ***/
#include "vapiIoInt.h"
#include <mmsystem.h>
#include <mmreg.h>
#include <assert.h>
#include <stdio.h>
typedef struct { int code; char* message; } ErrorMsg;
class VapiFile : VapiIO { public: VapiFile(); ~VapiFile();
int OpenFile ( const char* pszFileName, int iMode ); int OpenFile ( const WCHAR* wcsFileName, int iMode ); void CloseFile ( );
int CreateChunk ( const char* pszName ); int CloseChunk ( ); int WriteToChunk (const char* pszData, int iSize);
int GetDataSize (long* lDataSize); int Format (int* piSampFreq, int* piFormat, WAVEFORMATEX* pWaveFormatEx = NULL); int WriteFormat (int iSampFreq, int iFormat);
int ReadSamples (double dFrom, double dTo, void** ppvSamples, int* piNumSamples, bool bClosedInterval); int WriteSamples (void* pvSamples, int iNumSamples);
int ReadF0SampFreq (int* piSampFreq); int WriteF0SampFreq (int iSampFreq);
int ReadFeature (char* pszName, float** ppfSamples, int* piNumSamples); int WriteFeature (char* pszName, float* pfSamples, int iNumSamples);
int ReadEpochs (Epoch** ppEpochs, int* iNumEpochs); int WriteEpochs (Epoch* pEpochs, int iNumEpochs);
int ReadLabels (char* pszName, Label** ppLabels, int* piNumLabels); int WriteLabels (char* pszName, Label* pLabels, int iNumLabels);
char* ErrMessage (int iErrCode);
private: HMMIO m_HWav; MMCKINFO m_ParentInfo; MMCKINFO m_SubchunkInfo; int m_iSampFormat; int m_iSampFreq;
static ErrorMsg m_ErrorMsg[]; static int m_iNumErrorMsg; };
ErrorMsg VapiFile::m_ErrorMsg[] = { {VAPI_IOERR_NOERROR, 0}, {VAPI_IOERR_MODE, "Wrong opening mode."}, {VAPI_IOERR_MEMORY, "Memory error."}, {VAPI_IOERR_CANTOPEN, "Error opening file."}, {VAPI_IOERR_NOWAV, "Not RIFF-WAVE format."}, {VAPI_IOERR_NOFORMAT, "Can't find data format."}, {VAPI_IOERR_STEREO, "File is stereo\n"}, {VAPI_IOERR_FORMAT, "Unknown data format."}, {VAPI_IOERR_NOCHUNK, "Error accessing data chunk."}, {VAPI_IOERR_DATAACCESS, "Error accessing input data."}, {VAPI_IOERR_WRITEWAV, "Error creating RIFF-WAVE chunk."}, {VAPI_IOERR_CREATECHUNK, "Error creating new subchunk."}, {VAPI_IOERR_WRITECHUNK, "Error writing data in new subchunk."} };
int VapiFile::m_iNumErrorMsg = sizeof (VapiFile::m_ErrorMsg) / sizeof (VapiFile::m_ErrorMsg[0]);
/*****************************************************************************
* VapiIO::ClassFactory * *----------------------* * Description: * Class Factory, creates an object of the VapiIO implementation class. ******************************************************************* PACOG ***/ VapiIO* VapiIO::ClassFactory () { return new VapiFile(); }
/*****************************************************************************
* VapiIO::SizeOf * *----------------* * Description: * ******************************************************************* PACOG ***/ int VapiIO::SizeOf (int iType) { switch (iType) { case VAPI_PCM8: case VAPI_ALAW: case VAPI_ULAW: return 1; case VAPI_PCM16: return 2; default: return 0; } return 0; }
/*****************************************************************************
* VapiIO::TypeOf * *----------------* * Description: * ******************************************************************* PACOG ***/ int VapiIO::TypeOf (WAVEFORMATEX *pWavFormat) { int iSampFormat;
if (pWavFormat->wFormatTag == WAVE_FORMAT_PCM) { switch (pWavFormat->nBlockAlign/pWavFormat->nChannels) { case 1: iSampFormat = VAPI_PCM8; break; case 2: iSampFormat = VAPI_PCM16; break; default: iSampFormat = -1; break; } } else if (pWavFormat->wFormatTag == WAVE_FORMAT_ALAW) { iSampFormat = VAPI_ALAW; } else if (pWavFormat->wFormatTag == WAVE_FORMAT_MULAW) { iSampFormat = VAPI_ULAW; } else { iSampFormat = -1; }
return iSampFormat; }
/*****************************************************************************
* VapiIO::DataFormatConversion * *------------------------------* * Description: * ******************************************************************* PACOG ***/ int VapiIO::DataFormatConversion (char* pcInput, int iInType, char* pcOutput, int iOutType, int iNumSamples) { int i; assert (pcInput); assert (pcOutput); assert (iNumSamples>0); // Check that these are valid types
if (!SizeOf(iInType) || !SizeOf(iOutType)) { return 0; } // If same type, just copy samples
if (iInType == iOutType) { memcpy( pcOutput, pcInput, iNumSamples * SizeOf(iInType)); return 1; } // Ok, need to convert
switch (iInType) { case VAPI_PCM16: switch (iOutType) { case VAPI_PCM8: for (i=0; i<iNumSamples; i++) { pcOutput[i] = ((int)((short*)pcInput)[i] + 32768) >> 8; } break; case VAPI_ALAW: for (i=0; i<iNumSamples; i++) { pcOutput[i] = Linear2Alaw (((short*)pcInput)[i]); } break; case VAPI_ULAW: for (i=0; i<iNumSamples; i++) { pcOutput[i] = Linear2Ulaw (((short*)pcInput)[i]); } break; } break; case VAPI_PCM8: switch (iOutType) { case VAPI_PCM16: for (i=0; i<iNumSamples; i++) { ((short*)pcOutput)[i] = (((int)((char*)pcInput)[i])<<8) - 32768; } break; case VAPI_ALAW: for (i=0; i<iNumSamples; i++) { pcOutput[i] = Linear2Alaw ((short)((((int)((char*)pcInput)[i])<<8) - 32768)); } break; case VAPI_ULAW: for (i=0; i<iNumSamples; i++) { pcOutput[i] = Linear2Ulaw ((short)((((int)((char*)pcInput)[i])<<8) - 32768)); } break; } break; case VAPI_ALAW: switch (iOutType) { case VAPI_PCM16: for (i=0; i<iNumSamples; i++) { ((short*)pcOutput)[i] = (short) Alaw2Linear(((char*)pcInput)[i]); } break; case VAPI_PCM8: for (i=0; i<iNumSamples; i++) { pcOutput[i] = ((int)Alaw2Linear(((char*)pcInput)[i]) + 32768) >> 8; } break; case VAPI_ULAW: for (i=0; i<iNumSamples; i++) { pcOutput[i] = Alaw2Ulaw(((char*)pcInput)[i]); } break; } break; case VAPI_ULAW: switch (iOutType) { case VAPI_PCM16: for (i=0; i<iNumSamples; i++) { ((short*)pcOutput)[i] = (short) Ulaw2Linear(((char*)pcInput)[i]); } break; case VAPI_PCM8: for (i=0; i<iNumSamples; i++) { pcOutput[i] = ((int)Ulaw2Linear(((char*)pcInput)[i]) + 32768)>>8; } break; case VAPI_ALAW: for (i=0; i<iNumSamples; i++) { pcOutput[i] = Ulaw2Alaw(((char*)pcInput)[i]); } break; } break; } return 1; }
/*****************************************************************************
* VapiFile::ErrMessage * *----------------------* * Description: * ******************************************************************* PACOG ***/
char* VapiFile::ErrMessage (int errCode) { for (int i=0; i< m_iNumErrorMsg; i++) { if (errCode == m_ErrorMsg[i].code) { return m_ErrorMsg[i].message; } } return 0; }
/*****************************************************************************
* VapiFile::VapiFile * *--------------------* * Description: * ******************************************************************* PACOG ***/ VapiFile::VapiFile() { m_HWav = 0; memset (&m_ParentInfo, 0, sizeof(m_ParentInfo)); memset (&m_SubchunkInfo, 0, sizeof(m_SubchunkInfo)); m_iSampFormat = 0; m_iSampFreq = 0; }
/*****************************************************************************
* VapiFile::~VapiFile * *---------------------* * Description: * ******************************************************************* PACOG ***/ VapiFile::~VapiFile() { CloseFile(); }
/*****************************************************************************
* VapiFile::OpenFile * *--------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::OpenFile (const char* pszFileName, int iMode) { int iErrCode = VAPI_IOERR_NOERROR; assert (pszFileName); switch (iMode) { case VAPI_IO_READ: iMode = MMIO_READ; break; case VAPI_IO_WRITE: iMode = MMIO_WRITE|MMIO_CREATE; break; case VAPI_IO_READWRITE: iMode = MMIO_READWRITE; break; default: return VAPI_IOERR_MODE; } if ((m_HWav = mmioOpen ((char *)pszFileName, NULL, iMode)) == NULL) { iErrCode = VAPI_IOERR_CANTOPEN; goto error; } if (iMode == MMIO_READ) { m_ParentInfo.fccType = mmioFOURCC ('W', 'A', 'V', 'E'); if (mmioDescend (m_HWav, &m_ParentInfo, 0, MMIO_FINDRIFF)) { iErrCode = VAPI_IOERR_NOWAV; goto error; } } else { m_ParentInfo.fccType = mmioFOURCC ('W', 'A', 'V', 'E'); if (mmioCreateChunk (m_HWav, &m_ParentInfo, MMIO_CREATERIFF)) { iErrCode = VAPI_IOERR_WRITEWAV; goto error; } } return VAPI_IOERR_NOERROR; error: CloseFile (); return iErrCode; }
/*****************************************************************************
* VapiFile::OpenFile * *--------------------* * Description: Same as previous OpenFile, but takes WCHAR* as arg * ******************************************************************* JOEM ****/ int VapiFile::OpenFile (const WCHAR* wcsFileName, int iMode) { int iErrCode = VAPI_IOERR_NOERROR; assert (wcsFileName); switch (iMode) { case VAPI_IO_READ: iMode = MMIO_READ; break; case VAPI_IO_WRITE: iMode = MMIO_WRITE|MMIO_CREATE; break; case VAPI_IO_READWRITE: iMode = MMIO_READWRITE; break; default: return VAPI_IOERR_MODE; } if ((m_HWav = mmioOpenW ((WCHAR *)wcsFileName, NULL, iMode)) == NULL) { iErrCode = VAPI_IOERR_CANTOPEN; goto error; } if (iMode == MMIO_READ) { m_ParentInfo.fccType = mmioFOURCC ('W', 'A', 'V', 'E'); if (mmioDescend (m_HWav, &m_ParentInfo, 0, MMIO_FINDRIFF)) { iErrCode = VAPI_IOERR_NOWAV; goto error; } } else { m_ParentInfo.fccType = mmioFOURCC ('W', 'A', 'V', 'E'); if (mmioCreateChunk (m_HWav, &m_ParentInfo, MMIO_CREATERIFF)) { iErrCode = VAPI_IOERR_WRITEWAV; goto error; } } return VAPI_IOERR_NOERROR; error: CloseFile (); return iErrCode; }
/*****************************************************************************
* VapiFile::CloseFile * *---------------------* * Description: * ******************************************************************* PACOG ***/ void VapiFile::CloseFile () { if (m_HWav) { mmioAscend (m_HWav, &m_ParentInfo, 0); mmioClose (m_HWav, 0);
memset (&m_ParentInfo, 0, sizeof(m_ParentInfo)); m_HWav = 0; } }
/*****************************************************************************
* VapiFile::Format * *------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::Format (int* piSampFreq, int* piFormat, WAVEFORMATEX* pWaveFormatEx) { WAVEFORMATEX* WavFormat = NULL; WAVEFORMATEX LocalWaveFormat; MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); memset((void*)&LocalWaveFormat, 0, sizeof(WAVEFORMATEX));
if ( pWaveFormatEx ) { memset((void*)pWaveFormatEx, 0, sizeof(WAVEFORMATEX)); WavFormat = pWaveFormatEx; } else { WavFormat = &LocalWaveFormat; } mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioFOURCC ('f', 'm', 't', ' '); if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK) ) { iErrCode = VAPI_IOERR_NOFORMAT; goto error; } if (mmioRead (m_HWav, (char *)WavFormat, SubchunkInfo.cksize)!= (int)SubchunkInfo.cksize) { iErrCode = VAPI_IOERR_NOFORMAT; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); /*
* Process header info. * Files must be mono, and in one of these formats */ if (WavFormat->nChannels >1 ) { iErrCode = VAPI_IOERR_STEREO; goto error; } m_iSampFormat = TypeOf (WavFormat);
if (m_iSampFormat < 0) { iErrCode = VAPI_IOERR_FORMAT; goto error; } m_iSampFreq = WavFormat->nSamplesPerSec; if (piFormat) { *piFormat = m_iSampFormat; } if (piSampFreq) { *piSampFreq = m_iSampFreq; } error: return iErrCode; } /*****************************************************************************
* VapiFile::GetDataSize * *------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::GetDataSize (long* lDataSize) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; /*
* Go for the data */ mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioFOURCC ('d', 'a', 't', 'a'); if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK)) { iErrCode = VAPI_IOERR_NOCHUNK; goto error; } *lDataSize = SubchunkInfo.cksize;
mmioAscend (m_HWav, &SubchunkInfo, 0);
error: return iErrCode; }
/*****************************************************************************
* VapiFile::WriteFormat * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteFormat (int iSampFreq, int iFormat) { WAVEFORMATEX WavFormat; MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); assert (iSampFreq>0); switch (iFormat) { case VAPI_PCM8: WavFormat.wFormatTag = WAVE_FORMAT_PCM; WavFormat.wBitsPerSample = 8; break; case VAPI_ALAW: WavFormat.wFormatTag = WAVE_FORMAT_ALAW; WavFormat.wBitsPerSample = 8; break; case VAPI_ULAW: WavFormat.wFormatTag = WAVE_FORMAT_MULAW; WavFormat.wBitsPerSample = 8; break; case VAPI_PCM16: WavFormat.wFormatTag = WAVE_FORMAT_PCM; WavFormat.wBitsPerSample = 16; break; default: iErrCode = VAPI_IOERR_FORMAT; goto error; } WavFormat.nChannels = 1; WavFormat.nSamplesPerSec = iSampFreq; WavFormat.nBlockAlign = (WavFormat.wBitsPerSample / 8) ; WavFormat.nAvgBytesPerSec = WavFormat.nBlockAlign * WavFormat.nSamplesPerSec; WavFormat.cbSize = 0; SubchunkInfo.ckid = mmioFOURCC ('f', 'm', 't', ' '); if (mmioCreateChunk (m_HWav, &SubchunkInfo, 0) ) { iErrCode = VAPI_IOERR_CREATECHUNK; goto error; } if (mmioWrite(m_HWav, (char *)&WavFormat, sizeof(WavFormat)) != (int)sizeof(WavFormat)) { iErrCode = VAPI_IOERR_WRITECHUNK; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); m_iSampFreq = iSampFreq; m_iSampFormat = iFormat; error: return iErrCode; }
/*****************************************************************************
* VapiFile::CreateChunk * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::CreateChunk (const char* pszName) { assert (pszName); m_SubchunkInfo.ckid = mmioStringToFOURCC (pszName, 0); if (mmioCreateChunk (m_HWav, &m_SubchunkInfo, 0)) { return VAPI_IOERR_CREATECHUNK; } return VAPI_IOERR_NOERROR; }
/*****************************************************************************
* VapiFile::WriteToChunk * *------------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteToChunk (const char* pcData, int iSize) { assert (pcData); assert (iSize>0); if ( mmioWrite (m_HWav, pcData, iSize) != iSize ) { return VAPI_IOERR_WRITECHUNK; } return VAPI_IOERR_NOERROR; }
/*****************************************************************************
* VapiFile::CloseChunk * *----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::CloseChunk ( ) { assert (m_HWav); mmioAscend (m_HWav, &m_SubchunkInfo, 0); return VAPI_IOERR_NOERROR; }
/*****************************************************************************
* VapiFile::ReadSamples * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::ReadSamples (double dFrom, double dTo, void** ppvSamples, int* piNumSamples, bool bClosedInterval) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; void* pvBuffer = NULL; int iBuffLen; int iBuffLenInFile; int iSkipBytes; long lRead; double dEndOfData;
assert (m_HWav); assert (ppvSamples); assert (piNumSamples); assert (dFrom>=0.0); assert (dTo == -1.0 || dTo>=dFrom); /*
* Go for the data */ mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioFOURCC ('d', 'a', 't', 'a'); if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK)) { iErrCode = VAPI_IOERR_NOCHUNK; goto error; } iBuffLenInFile = SubchunkInfo.cksize; dEndOfData = ((double)iBuffLenInFile) / SizeOf(m_iSampFormat) / m_iSampFreq; if ( dFrom > dEndOfData ) { // nothing to read
iErrCode = VAPI_IOERR_NOCHUNK; goto error; } if ( dTo != -1.0 && dFrom >= dTo ) { // nothing to read
iErrCode = VAPI_IOERR_NOCHUNK; goto error; }
/*
* Read only the desired region */ if (dFrom < 0.0) { dFrom = 0.0; } iSkipBytes = (int)(dFrom * m_iSampFreq + 0.5) * SizeOf(m_iSampFormat); if (dTo == -1.0) { iBuffLen = iBuffLenInFile; } else { iBuffLen = (int)(dTo * m_iSampFreq + 0.5) * SizeOf(m_iSampFormat); if (iBuffLen>=iBuffLenInFile) { dTo = -1.0; iBuffLen = iBuffLenInFile; } } iBuffLen -= iSkipBytes; if (bClosedInterval && dTo != -1.0) { iBuffLen += SizeOf (m_iSampFormat); } if (iSkipBytes>0 && mmioSeek (m_HWav, iSkipBytes, SEEK_CUR) == -1) { iErrCode = VAPI_IOERR_DATAACCESS; goto error; } if ((pvBuffer = new char[iBuffLen]) == NULL) { iErrCode = VAPI_IOERR_MEMORY; goto error; } lRead = mmioRead (m_HWav, (char *)pvBuffer, iBuffLen); if ( lRead != (int)iBuffLen) { iErrCode = VAPI_IOERR_DATAACCESS; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); *ppvSamples = pvBuffer; *piNumSamples = iBuffLen/SizeOf(m_iSampFormat); return VAPI_IOERR_NOERROR; error: if (pvBuffer) { delete[] pvBuffer; } return iErrCode; }
/*****************************************************************************
* VapiFile::WriteSamples * *------------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteSamples (void* pvSamples, int iNumSamples) { MMCKINFO subchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; int iBuffLen; assert (m_HWav); assert (pvSamples); assert (iNumSamples>0); subchunkInfo.ckid = mmioFOURCC ('d', 'a', 't', 'a'); if (mmioCreateChunk (m_HWav, &subchunkInfo, 0) ) { iErrCode = VAPI_IOERR_CREATECHUNK; goto error; } iBuffLen = iNumSamples * SizeOf (m_iSampFormat); if (mmioWrite(m_HWav, (char *)pvSamples, iBuffLen) != iBuffLen) { iErrCode = VAPI_IOERR_WRITECHUNK; goto error; } mmioAscend (m_HWav, &subchunkInfo, 0); error: return iErrCode; }
/*****************************************************************************
* VapiFile::ReadF0SampFreq * *--------------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::ReadF0SampFreq (int* piSampFreq) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); assert (piSampFreq); mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioFOURCC ('f', '0', 's', 'f') ; if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK) == MMIOERR_CHUNKNOTFOUND) { iErrCode = VAPI_IOERR_NOCHUNK; } else { if (mmioRead (m_HWav, (char *)piSampFreq, SubchunkInfo.cksize) != (int)SubchunkInfo.cksize) { iErrCode = VAPI_IOERR_F0SFACCESS; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); } error: return iErrCode; }
/*****************************************************************************
* VapiFile::WriteF0SampFreq * *---------------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteF0SampFreq (int iSampFreq) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); assert (iSampFreq>0); SubchunkInfo.ckid = mmioFOURCC ('f', '0', 's', 'f') ; if (mmioCreateChunk (m_HWav, &SubchunkInfo, 0) ) { iErrCode = VAPI_IOERR_CREATECHUNK; goto error; } if (mmioWrite(m_HWav, (char *)&iSampFreq, sizeof(iSampFreq)) != sizeof(iSampFreq)) { iErrCode = VAPI_IOERR_WRITECHUNK; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); error: return iErrCode; }
/*****************************************************************************
* VapiFile::ReadFeature * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::ReadFeature (char* pszName, float** ppfSamples, int* piNumSamples) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); assert (pszName); assert (ppfSamples); assert (piNumSamples); mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioStringToFOURCC (pszName, 0); if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK) == MMIOERR_CHUNKNOTFOUND) { iErrCode = VAPI_IOERR_NOCHUNK; } else { *piNumSamples = SubchunkInfo.cksize/ sizeof(**ppfSamples); if ((*ppfSamples = new float[SubchunkInfo.cksize/sizeof(float)]) == NULL ) { iErrCode = VAPI_IOERR_MEMORY; goto error; } if (mmioRead (m_HWav, (char *)*ppfSamples, SubchunkInfo.cksize) != (int)SubchunkInfo.cksize) { iErrCode = VAPI_IOERR_FEATACCESS; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); } error: return iErrCode; }
/*****************************************************************************
* VapiFile::WriteFeature * *------------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteFeature (char* pszName, float* pfSamples, int iNumSamples) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; int iBuffLen; assert (m_HWav); assert (pszName); assert (pfSamples); assert (iNumSamples>0); SubchunkInfo.ckid = mmioStringToFOURCC (pszName, 0); if (mmioCreateChunk (m_HWav, &SubchunkInfo, 0) ) { iErrCode = VAPI_IOERR_CREATECHUNK; goto error; } iBuffLen = iNumSamples * sizeof(*pfSamples); if (mmioWrite(m_HWav, (char *)pfSamples, iBuffLen) != iBuffLen) { iErrCode = VAPI_IOERR_WRITECHUNK; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); error: return iErrCode; }
/*****************************************************************************
* VapiFile::ReadEpochs * *----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::ReadEpochs (Epoch** ppEpochs, int* piNumEpochs) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); assert (ppEpochs); assert (piNumEpochs); mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioFOURCC ('e', 'p', 'o', 'c'); if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK) == MMIOERR_CHUNKNOTFOUND) { iErrCode = VAPI_IOERR_NOCHUNK; goto error; } else { *piNumEpochs = SubchunkInfo.cksize / sizeof(**ppEpochs); if ((*ppEpochs = new Epoch[SubchunkInfo.cksize/sizeof(Epoch)]) == NULL ) { iErrCode = VAPI_IOERR_MEMORY; goto error; } if (mmioRead (m_HWav, (char *)*ppEpochs, SubchunkInfo.cksize) != (int)SubchunkInfo.cksize) { iErrCode = VAPI_IOERR_EPOCHACCESS; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); } error: return iErrCode; }
/*****************************************************************************
* VapiFile::WriteEpochs * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteEpochs (Epoch* pEpochs, int iNumEpochs) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; int iBuffLen; assert (m_HWav); assert (pEpochs); assert (iNumEpochs>0); SubchunkInfo.ckid = mmioFOURCC ('e', 'p', 'o', 'c'); if (mmioCreateChunk (m_HWav, &SubchunkInfo, 0) ) { iErrCode = VAPI_IOERR_CREATECHUNK; goto error; } iBuffLen = iNumEpochs * sizeof(*pEpochs); if (mmioWrite(m_HWav, (char *)pEpochs, iBuffLen) != iBuffLen) { iErrCode = VAPI_IOERR_WRITECHUNK; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); error: return iErrCode; }
/*****************************************************************************
* VapiFile::ReadLabels * *----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::ReadLabels (char* pszName, Label** ppLabels, int* piNumLabels) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; assert (m_HWav); assert (pszName); assert (ppLabels); assert (piNumLabels); mmioSeek (m_HWav, m_ParentInfo.dwDataOffset+4, SEEK_SET); SubchunkInfo.ckid = mmioStringToFOURCC (pszName, 0); if (mmioDescend (m_HWav, &SubchunkInfo, &m_ParentInfo, MMIO_FINDCHUNK) == MMIOERR_CHUNKNOTFOUND) { iErrCode = VAPI_IOERR_NOCHUNK; } else { *piNumLabels = SubchunkInfo.cksize/ sizeof(**ppLabels); if ((*ppLabels = new Label[SubchunkInfo.cksize/sizeof(Label)]) == NULL ) { iErrCode = VAPI_IOERR_MEMORY; goto error; } if (mmioRead (m_HWav, (char *)*ppLabels, SubchunkInfo.cksize) != (int)SubchunkInfo.cksize) { iErrCode = VAPI_IOERR_LABELACCESS; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); } error: return iErrCode; }
/*****************************************************************************
* VapiFile::WriteLabels * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiFile::WriteLabels (char* pszName, Label* pLabels, int iNumLabels) { MMCKINFO SubchunkInfo; int iErrCode = VAPI_IOERR_NOERROR; int iBuffLen; assert (m_HWav); assert (pszName); assert (pLabels); assert (iNumLabels>0); SubchunkInfo.ckid = mmioStringToFOURCC (pszName, 0); if (mmioCreateChunk (m_HWav, &SubchunkInfo, 0) ) { iErrCode = VAPI_IOERR_CREATECHUNK; goto error; } iBuffLen = iNumLabels * sizeof(*pLabels); if (mmioWrite(m_HWav, (char *)pLabels, iBuffLen) != iBuffLen) { iErrCode = VAPI_IOERR_WRITECHUNK; goto error; } mmioAscend (m_HWav, &SubchunkInfo, 0); error: return iErrCode; }
/*****************************************************************************
* VapiIO::ReadVapiFile * *----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiIO::ReadVapiFile (const char* pszFileName, short** ppnSamples, int* piNumSamples, int* piSampFreq, int* piSampFormat, int* piF0SampFreq, float** ppfF0, int* piNumF0, float** ppfRms, int* piNumRms, Epoch** ppEpochs, int* piNumEpochs, Label** ppPhones, int* piNumPhones, Label** ppWords, int* piNumWords) { VapiIO* pViof = 0; void* pvBuffer = NULL; int iErrCode = VAPI_IOERR_NOERROR; int iRetVal; assert (pszFileName);
if (( pViof = VapiIO::ClassFactory()) == 0) { iErrCode = VAPI_IOERR_MEMORY; goto error; } if ( (iRetVal = pViof->OpenFile (pszFileName, VAPI_IO_READ)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } if (ppnSamples && piNumSamples) { int sFreq; int sType; iRetVal = pViof->Format (&sFreq, &sType);
switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: sFreq = 0; break; default: iErrCode = iRetVal; goto error; } if (piSampFreq) { *piSampFreq = sFreq; } if (piSampFormat) { *piSampFormat = sType; } /*
* Read samples */ iRetVal = pViof->ReadSamples (0.0, -1.0, &pvBuffer, piNumSamples, 0); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *ppnSamples = NULL; *piNumSamples = 0; break; default: iErrCode = iRetVal; goto error; } /*
* Convert samples to PCM16 */ if ( (*ppnSamples = new short[*piNumSamples]) == 0) { iErrCode = VAPI_IOERR_MEMORY; goto error; } DataFormatConversion ((char *)pvBuffer, sType, (char*)*ppnSamples, VAPI_PCM16, *piNumSamples); delete[] pvBuffer; } if (piF0SampFreq) { iRetVal = pViof->ReadF0SampFreq (piF0SampFreq); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *piF0SampFreq = 0; break; default: iErrCode = iRetVal; goto error; } } if (ppEpochs && piNumEpochs) { iRetVal = pViof->ReadEpochs(ppEpochs, piNumEpochs); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *ppEpochs = NULL; *piNumEpochs = 0; break; default: iErrCode = iRetVal; goto error; } } if (ppfF0 && piNumF0) { iRetVal = pViof->ReadFeature ("f0", ppfF0, piNumF0); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *ppfF0 = NULL; *piNumF0 = 0; break; default: iErrCode = iRetVal; goto error; } } if (ppfRms && piNumRms) { iRetVal = pViof->ReadFeature ("rms", ppfRms, piNumRms); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *ppfRms = NULL; *piNumRms = 0; break; default: iErrCode = iRetVal; goto error; } } if (ppPhones && piNumPhones) { iRetVal = pViof->ReadLabels ("phon", ppPhones, piNumPhones); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *ppPhones = NULL; *piNumPhones = 0; break; default: iErrCode = iRetVal; goto error; } } if (ppWords && piNumWords) { iRetVal = pViof->ReadLabels ("word", ppWords, piNumWords); switch (iRetVal) { case VAPI_IOERR_NOERROR: break; case VAPI_IOERR_NOCHUNK: *ppWords = NULL; *piNumWords = 0; break; default: iErrCode = iRetVal; goto error; } } error: if (pViof) { pViof->CloseFile(); delete pViof; }
return iErrCode; } /*****************************************************************************
* VapiIO::WriteVapiFile * *-----------------------* * Description: * ******************************************************************* PACOG ***/ int VapiIO::WriteVapiFile (const char* pszFileName, short* pnSamples, int iNumSamples, int iFormat, int iSampFreq, int iF0SampFreq, float* pfF0, int iNumF0, float* pfRms, int iNumRms, Epoch* pEpochs, int iNumEpochs, Label* pPhones, int iNumPhones, Label* pWords, int iNumWords) { VapiIO* pViof = 0; void* pvBuffer = 0; int iErrCode = VAPI_IOERR_NOERROR; int iRetVal; assert (pszFileName); if (( pViof = VapiIO::ClassFactory()) == 0) { iErrCode = VAPI_IOERR_MEMORY; goto error; } if ( (iRetVal = pViof->OpenFile (pszFileName, VAPI_IO_WRITE)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } if (pnSamples && iNumSamples) { if ((iRetVal = pViof->WriteFormat (iSampFreq, iFormat)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } /*
* Convert samples to output format */ if ( (pvBuffer = new char[iNumSamples * SizeOf(iFormat)]) == NULL) { iErrCode = VAPI_IOERR_MEMORY; goto error; } DataFormatConversion ((char*)pnSamples, VAPI_PCM16, (char *)pvBuffer, iFormat, iNumSamples); /*
* Write samples */ if ((iRetVal = pViof->WriteSamples (pvBuffer, iNumSamples)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } delete[] pvBuffer; } if (iF0SampFreq) { if ((iRetVal = pViof->WriteF0SampFreq (iF0SampFreq)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } } if (pEpochs && iNumEpochs) { if ((iRetVal = pViof->WriteEpochs (pEpochs, iNumEpochs)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } } if (pfF0 && iNumF0) { if ((iRetVal = pViof->WriteFeature ("f0", pfF0, iNumF0)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } } if (pfRms && iNumRms) { if ((iRetVal = pViof->WriteFeature ("rms", pfRms, iNumRms)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } } if (pPhones && iNumPhones) { if ((iRetVal = pViof->WriteLabels ("phon", pPhones, iNumPhones))!= VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } } if (pWords && iNumWords) { if ((iRetVal = pViof->WriteLabels ("word", pWords, iNumWords)) != VAPI_IOERR_NOERROR) { iErrCode = iRetVal; goto error; } } error: if (pViof) { pViof->CloseFile (); delete pViof; }
return iErrCode; }
|