📄 sphelper.h
字号:
0xCC, 0x01, 0x30, 0xFF, 0x88, 0x01, 0x18, 0xFF
};
static const BYTE Extra44[32] =
{
0xF4, 0x07, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00,
0x00, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0xC0, 0x00, 0x40, 0x00, 0xF0, 0x00, 0x00, 0x00,
0xCC, 0x01, 0x30, 0xFF, 0x88, 0x01, 0x18, 0xFF
};
static const BYTE* Extra[4] = { Extra811, Extra811, Extra22, Extra44 };
memset( pwfex, 0, NumBytes );
DWORD dwIndex = eFormat - SPSF_ADPCM_8kHzMono;
DWORD dwKHZ = dwIndex / 2;
BOOL bIsStereo = dwIndex & 0x1;
pwfex->wFormatTag = WAVE_FORMAT_ADPCM;
pwfex->nChannels = (WORD)(bIsStereo ? 2 : 1);
pwfex->nSamplesPerSec = adwKHZ[dwKHZ];
pwfex->nAvgBytesPerSec = BytesPerSec[dwIndex];
pwfex->nBlockAlign = (WORD)(BlockAlign[dwKHZ] * pwfex->nChannels);
pwfex->wBitsPerSample = 4;
pwfex->cbSize = 32;
BYTE* pExtra = ((BYTE*)pwfex) + sizeof( WAVEFORMATEX );
memcpy( pExtra, Extra[dwKHZ], 32 );
pFmtGuid = &SPDFID_WaveFormatEx;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else if( (eFormat >= SPSF_GSM610_8kHzMono ) &&
(eFormat <= SPSF_GSM610_44kHzMono ) )
{
int NumBytes = sizeof( WAVEFORMATEX ) + 2;
WAVEFORMATEX * pwfex = (WAVEFORMATEX *)::CoTaskMemAlloc( NumBytes );
*ppCoMemWaveFormatEx = pwfex;
if( pwfex )
{
//--- Some of these values seem odd. We used what the codec told us.
static const DWORD adwKHZ[] = { 8000, 11025, 22050, 44100 };
static const DWORD BytesPerSec[] = { 1625, 2239, 4478, 8957 };
memset( pwfex, 0, NumBytes );
DWORD dwIndex = eFormat - SPSF_GSM610_8kHzMono;
pwfex->wFormatTag = WAVE_FORMAT_GSM610;
pwfex->nChannels = 1;
pwfex->nSamplesPerSec = adwKHZ[dwIndex];
pwfex->nAvgBytesPerSec = BytesPerSec[dwIndex];
pwfex->nBlockAlign = 65;
pwfex->wBitsPerSample = 0;
pwfex->cbSize = 2;
BYTE* pExtra = ((BYTE*)pwfex) + sizeof( WAVEFORMATEX );
pExtra[0] = 0x40;
pExtra[1] = 0x01;
pFmtGuid = &SPDFID_WaveFormatEx;
}
else
{
hr = E_OUTOFMEMORY;
}
}
else
{
*ppCoMemWaveFormatEx = NULL;
switch (eFormat)
{
case SPSF_NoAssignedFormat:
break;
case SPSF_Text:
pFmtGuid = &SPDFID_Text;
break;
default:
hr = E_INVALIDARG;
break;
}
}
*pFormatId = *pFmtGuid;
return hr;
}
class CSpStreamFormat
{
public:
GUID m_guidFormatId;
WAVEFORMATEX * m_pCoMemWaveFormatEx;
static int CoMemCopyWFEX(const WAVEFORMATEX * pSrc, WAVEFORMATEX ** ppCoMemWFEX)
{
ULONG cb = sizeof(WAVEFORMATEX) + pSrc->cbSize;
*ppCoMemWFEX = (WAVEFORMATEX *)::CoTaskMemAlloc(cb);
if (*ppCoMemWFEX)
{
memcpy(*ppCoMemWFEX, pSrc, cb);
return S_OK;
}
else
{
return E_OUTOFMEMORY;
}
}
CSpStreamFormat()
{
m_guidFormatId = GUID_NULL;
m_pCoMemWaveFormatEx = NULL;
}
CSpStreamFormat(SPSTREAMFORMAT eFormat, HRESULT * phr)
{
*phr = SpConvertStreamFormatEnum(eFormat, &m_guidFormatId, &m_pCoMemWaveFormatEx);
}
CSpStreamFormat(const WAVEFORMATEX * pWaveFormatEx, HRESULT * phr)
{
SPDBG_ASSERT(pWaveFormatEx);
*phr = CoMemCopyWFEX(pWaveFormatEx, &m_pCoMemWaveFormatEx);
m_guidFormatId = SUCCEEDED(*phr) ? SPDFID_WaveFormatEx : GUID_NULL;
}
~CSpStreamFormat()
{
::CoTaskMemFree(m_pCoMemWaveFormatEx);
}
void Clear()
{
::CoTaskMemFree(m_pCoMemWaveFormatEx);
m_pCoMemWaveFormatEx = NULL;
memset(&m_guidFormatId, 0, sizeof(m_guidFormatId));
}
const GUID & FormatId() const
{
return m_guidFormatId;
}
const WAVEFORMATEX * WaveFormatExPtr() const
{
return m_pCoMemWaveFormatEx;
}
HRESULT AssignFormat(SPSTREAMFORMAT eFormat)
{
::CoTaskMemFree(m_pCoMemWaveFormatEx);
return SpConvertStreamFormatEnum(eFormat, &m_guidFormatId, &m_pCoMemWaveFormatEx);
}
HRESULT AssignFormat(ISpStreamFormat * pStream)
{
::CoTaskMemFree(m_pCoMemWaveFormatEx);
m_pCoMemWaveFormatEx = NULL;
return pStream->GetFormat(&m_guidFormatId, &m_pCoMemWaveFormatEx);
}
HRESULT AssignFormat(const WAVEFORMATEX * pWaveFormatEx)
{
::CoTaskMemFree(m_pCoMemWaveFormatEx);
HRESULT hr = CoMemCopyWFEX(pWaveFormatEx, &m_pCoMemWaveFormatEx);
m_guidFormatId = SUCCEEDED(hr) ? SPDFID_WaveFormatEx : GUID_NULL;
return hr;
}
HRESULT AssignFormat(REFGUID rguidFormatId, const WAVEFORMATEX * pWaveFormatEx)
{
HRESULT hr = S_OK;
m_guidFormatId = rguidFormatId;
::CoTaskMemFree(m_pCoMemWaveFormatEx);
m_pCoMemWaveFormatEx = NULL;
if (rguidFormatId == SPDFID_WaveFormatEx)
{
if (::IsBadReadPtr(pWaveFormatEx, sizeof(*pWaveFormatEx)))
{
hr = E_INVALIDARG;
}
else
{
hr = CoMemCopyWFEX(pWaveFormatEx, &m_pCoMemWaveFormatEx);
}
if (FAILED(hr))
{
m_guidFormatId = GUID_NULL;
}
}
return hr;
}
BOOL IsEqual(REFGUID rguidFormatId, const WAVEFORMATEX * pwfex) const
{
if (rguidFormatId == m_guidFormatId)
{
if (m_pCoMemWaveFormatEx)
{
if (pwfex &&
pwfex->cbSize == m_pCoMemWaveFormatEx->cbSize &&
memcmp(m_pCoMemWaveFormatEx, pwfex, sizeof(WAVEFORMATEX) + pwfex->cbSize) == 0)
{
return TRUE;
}
}
else
{
return (pwfex == NULL);
}
}
return FALSE;
}
HRESULT ParamValidateAssignFormat(REFGUID rguidFormatId, const WAVEFORMATEX * pWaveFormatEx, BOOL fRequireWaveFormat = FALSE)
{
if ((pWaveFormatEx && (::IsBadReadPtr(pWaveFormatEx, sizeof(*pWaveFormatEx)) || rguidFormatId != SPDFID_WaveFormatEx)) ||
(fRequireWaveFormat && pWaveFormatEx == NULL))
{
return E_INVALIDARG;
}
return AssignFormat(rguidFormatId, pWaveFormatEx);
}
SPSTREAMFORMAT ComputeFormatEnum()
{
if (m_guidFormatId == GUID_NULL)
{
return SPSF_NoAssignedFormat;
}
if (m_guidFormatId == SPDFID_Text)
{
return SPSF_Text;
}
if (m_guidFormatId != SPDFID_WaveFormatEx)
{
return SPSF_NonStandardFormat;
}
//
// It is a WAVEFORMATEX. Now determine which type it is and convert.
//
DWORD dwIndex = 0;
switch (m_pCoMemWaveFormatEx->wFormatTag)
{
case WAVE_FORMAT_PCM:
{
switch (m_pCoMemWaveFormatEx->nChannels)
{
case 1:
break;
case 2:
dwIndex |= 1;
break;
default:
return SPSF_ExtendedAudioFormat;
}
switch (m_pCoMemWaveFormatEx->wBitsPerSample)
{
case 8:
break;
case 16:
dwIndex |= 2;
break;
default:
return SPSF_ExtendedAudioFormat;
}
switch (m_pCoMemWaveFormatEx->nSamplesPerSec)
{
case 48000:
dwIndex += 4; // Fall through
case 44100:
dwIndex += 4; // Fall through
case 32000:
dwIndex += 4; // Fall through
case 24000:
dwIndex += 4; // Fall through
case 22050:
dwIndex += 4; // Fall through
case 16000:
dwIndex += 4; // Fall through
case 12000:
dwIndex += 4; // Fall through
case 11025:
dwIndex += 4; // Fall through
case 8000:
break;
default:
return SPSF_ExtendedAudioFormat;
}
return static_cast<SPSTREAMFORMAT>(SPSF_8kHz8BitMono + dwIndex);
}
case WAVE_FORMAT_DSPGROUP_TRUESPEECH:
{
return SPSF_TrueSpeech_8kHz1BitMono;
}
case WAVE_FORMAT_ALAW: // fall through
case WAVE_FORMAT_MULAW:
case WAVE_FORMAT_ADPCM:
{
switch (m_pCoMemWaveFormatEx->nChannels)
{
case 1:
break;
case 2:
dwIndex |= 1;
break;
default:
return SPSF_ExtendedAudioFormat;
}
if(m_pCoMemWaveFormatEx->wFormatTag == WAVE_FORMAT_ADPCM)
{
if(m_pCoMemWaveFormatEx->wBitsPerSample != 4)
{
return SPSF_ExtendedAudioFormat;
}
}
else if(m_pCoMemWaveFormatEx->wBitsPerSample != 8)
{
return SPSF_ExtendedAudioFormat;
}
switch (m_pCoMemWaveFormatEx->nSamplesPerSec)
{
case 44100:
dwIndex += 2; // Fall through
case 22050:
dwIndex += 2; // Fall through
case 11025:
dwIndex += 2; // Fall through
case 8000:
break;
default:
return SPSF_ExtendedAudioFormat;
}
switch( m_pCoMemWaveFormatEx->wFormatTag )
{
case WAVE_FORMAT_ALAW:
return static_cast<SPSTREAMFORMAT>(SPSF_CCITT_ALaw_8kHzMono + dwIndex);
case WAVE_FORMAT_MULAW:
return static_cast<SPSTREAMFORMAT>(SPSF_CCITT_uLaw_8kHzMono + dwIndex);
case WAVE_FORMAT_ADPCM:
return static_cast<SPSTREAMFORMAT>(SPSF_ADPCM_8kHzMono + dwIndex);
}
}
case WAVE_FORMAT_GSM610:
{
if( m_pCoMemWaveFormatEx->nChannels != 1 )
{
return SPSF_ExtendedAudioFormat;
}
switch (m_pCoMemWaveFormatEx->nSamplesPerSec)
{
case 44100:
dwIndex = 3;
break;
case 22050:
dwIndex = 2;
break;
case 11025:
dwIndex = 1;
break;
case 8000:
dwIndex = 0;
break;
default:
return SPSF_ExtendedAudioFormat;
}
return static_cast<SPSTREAMFORMAT>(SPSF_GSM610_8kHzMono + dwIndex);
}
default:
return SPSF_ExtendedAudioFormat;
break;
}
}
void DetachTo(CSpStreamFormat & Other)
{
::CoTaskMemFree(Other.m_pCoMemWaveFormatEx);
Other.m_guidFormatId = m_guidFormatId;
Other.m_pCoMemWaveFormatEx = m_pCoMemWaveFormatEx;
m_pCoMemWaveFormatEx = NULL;
memset(&m_guidFormatId, 0, sizeof(m_guidFormatId));
}
void DetachTo(GUID * pFormatId, WAVEFORMATEX ** ppCoMemWaveFormatEx)
{
*pFormatId = m_guidFormatId;
*ppCoMemWaveFormatEx = m_pCoMemWaveFormatEx;
m_pCoMemWaveFormatEx = NULL;
memset(&m_guidFormatId, 0, sizeof(m_guidFormatId));
}
HRESULT CopyTo(GUID * pFormatId, WAVEFORMATEX ** ppCoMemWFEX) const
{
HRESULT hr = S_OK;
*pFormatId = m_guidFormatId;
if (m_pCoMemWaveFormatEx)
{
hr = CoMemCopyWFEX(m_pCoMemWaveFormatEx, ppCoMemWFEX);
if (FAILED(hr))
{
memset(pFormatId, 0, sizeof(*pFormatId));
}
}
else
{
*ppCoMemWFEX = NULL;
}
return hr;
}
HRESULT CopyTo(CSpStreamFormat & Other) const
{
::CoTaskMemFree(Other.m_pCoMemWaveFormatEx);
return CopyTo(&Other.m_guidFormatId, &Other.m_pCoMemWaveFormatEx);
}
HRESULT AssignFormat(const CSpStreamFormat & Src)
{
return Src.CopyTo(*this);
}
HRESULT ParamValidateCopyTo(GUID * pFormatId, WAVEFORMATEX ** ppCoMemWFEX) const
{
if (::IsBadWritePtr(pFormatId, sizeof(*pFormatId)) ||
::IsBadWritePtr(ppCoMemWFEX, sizeof(*ppCoMemWFEX)))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -