📄 strmctxt.h
字号:
#pragma once
//-----------------------------------------------------------------------------
// Copyright (c) Wolfson Microelectronics plc. All rights reserved.
//
// This software as well as any related documentation is furnished under
// license and may only be used or copied in accordance with the terms of the
// license. The information in this file is furnished for informational use
// only, is subject to change without notice, and should not be construed as
// a commitment by Wolfson Microelectronics plc. Wolfson Microelectronics plc
// assumes no responsibility or liability for any errors or inaccuracies that
// may appear in this document or any software that may be provided in
// association with this document.
//
// Except as permitted by such license, no part of this document may be
// reproduced, stored in a retrieval system, or transmitted in any form or by
// any means without the express written consent of Wolfson Microelectronics plc.
//
// $Id: strmctxt.h 1796 2005-06-10 15:46:04Z ian $
//
// This file declares the stream context structures for the WaveDev2 driver for
// Wolfson codecs.
//
// Warning:
// This driver is specifically written for Wolfson Audio Codecs. It is
// not a general audio CODEC device driver.
//-----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// -----------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// -----------------------------------------------------------------------------
// Define how much to shift the output after applying volume
#define VOLSHIFT (32-BITSPERSAMPLE)
// Define the format of the m_Delta value. By default, we'll use
// 17.15 format. This may seem weird, but there's a problem using
// 16.16 format with the SRC code-- in the following equation where
// we use the fractional part to calculate the interpolated sample:
// OutSamp0 = PrevSamp0 + (((CurrSamp0 - PrevSamp0) * CurrT) >> DELTAFRAC);
// If CurrT is a 16-bit fraction value, and if (CurrSamp0-PrevSamp0) overflow a
// signed 16-bit number (which they can), then the result can overflow a 32-bit
// value and cause an bad-sounding click.
// We could use 64-bit math to overcome that, but it would be a few extra instructions in the inner loop.
//
// On the other hand, we want as much accuracy in the fractional part as possible,
// as that determines how close we are to the target rate during sample rate conversion.
// Therefore, using 17.15 format is the best we can do.
#define DELTAINT (17)
#define DELTAFRAC (32 - DELTAINT)
// Define 1.0 value for Delta
#define DELTA_OVERFLOW (1<<DELTAFRAC)
class StreamContext
{
public:
LIST_ENTRY m_Link; // Link into list of streams
StreamContext() {};
virtual ~StreamContext() {};
LONG AddRef();
LONG Release();
virtual HRESULT Open(DeviceContext *pDeviceContext, LPWAVEOPENDESC lpWOD, DWORD dwFlags);
virtual DWORD Close();
virtual DWORD GetPos(PMMTIME pmmt);
virtual DWORD Run();
virtual DWORD Stop();
virtual DWORD Reset();
virtual PBYTE Render(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast)=0;
BOOL StillPlaying() {return (m_lpWaveHdrHead!=NULL);}
DWORD GetByteCount() {return m_dwByteCount;}
WAVEFORMATEX *GetWaveFormat() {return &m_WaveFormat;}
DeviceContext *GetDeviceContext() { return m_pDeviceContext; }
void DoDriverCallback(UINT msg, DWORD dwParam1, DWORD dwParam2)
{
m_pfnCallback(m_hWave,msg,m_dwInstance,dwParam1,dwParam2);
}
virtual DoCallbackReturnBuffer(LPWAVEHDR lpHdr)
{
DoDriverCallback(WOM_DONE,(DWORD)lpHdr,0);
}
virtual DoCallbackStreamOpened()
{
DoDriverCallback(WOM_OPEN,0,0);
}
virtual DoCallbackStreamClosed()
{
DoDriverCallback(WOM_CLOSE,0,0);
}
virtual DWORD QueueBuffer(LPWAVEHDR lpWaveHdr);
PBYTE GetNextBuffer();
// Default implementation
void ReturnBuffer(LPWAVEHDR lpHdr)
{
lpHdr->dwFlags &= ~WHDR_INQUEUE;
lpHdr->dwFlags |= WHDR_DONE;
DoCallbackReturnBuffer(lpHdr);
}
DWORD GetGain()
{
return m_dwGain;
}
DWORD SetGain(DWORD dwGain)
{
m_dwGain = dwGain;
GainChange();
return MMSYSERR_NOERROR;
}
DWORD SetSecondaryGainClass(DWORD GainClass)
{
if (GainClass>=SECONDARYGAINCLASSMAX)
{
return MMSYSERR_ERROR;
}
m_SecondaryGainClass=GainClass;
GainChange();
return MMSYSERR_NOERROR;
}
DWORD MapGain(DWORD Gain, DWORD Channel);
virtual void GainChange()
{
for (int i=0; i<2; i++)
{
#if defined (MONO_GAIN)
m_fxpGain[i] = MapGain(m_dwGain,0);
#else
m_fxpGain[i] = MapGain(m_dwGain,i);
#endif
}
}
static void ClearBuffer(PBYTE pStart, PBYTE pEnd) {memset(pStart,0,pEnd-pStart);}
DWORD BreakLoop();
DWORD ForceSpeaker (BOOL bForceSpeaker);
unsigned int NumChannels() const { return m_pDeviceContext->NumChannels(); }
unsigned int SampleRate() const { return m_pDeviceContext->SampleRate(); }
UINT32 InverseSampleRate() const { return m_pDeviceContext->InverseSampleRate(); }
protected:
LONG m_RefCount;
BOOL m_bRunning; // Is stream running or stopped
DWORD m_dwFlags; // allocation flags
HWAVE m_hWave; // handle for stream
DRVCALLBACK* m_pfnCallback; // client's callback
DWORD m_dwInstance; // client's instance data
WAVEFORMATEX m_WaveFormat; // Format of wave data
LPWAVEHDR m_lpWaveHdrHead;
LPWAVEHDR m_lpWaveHdrCurrent;
LPWAVEHDR m_lpWaveHdrTail;
PBYTE m_lpCurrData; // position in current buffer
PBYTE m_lpCurrDataEnd; // end of current buffer
DWORD m_dwByteCount; // byte count since last reset
DeviceContext *m_pDeviceContext; // Device which this stream renders to
// Loopcount shouldn't really be here, since it's really for wave output only, but it makes things easier
DWORD m_dwLoopCount; // Number of times left through loop
DWORD m_dwGain;
DWORD m_SecondaryGainClass;
DWORD m_fxpGain[2];
BOOL m_bForceSpeaker;
};
class WaveStreamContext : public StreamContext
{
public:
HRESULT Open(DeviceContext *pDeviceContext, LPWAVEOPENDESC lpWOD, DWORD dwFlags);
DWORD GetRate(DWORD *pdwMultiplier);
virtual DWORD SetRate(DWORD dwMultiplier) = 0;
PBYTE Render(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
virtual PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast)=0;
protected:
PCM_TYPE m_SampleType; // Enum of sample type, e.g. M8, M16, S8, S16
ULONG m_SampleSize; // # of bytes per sample in client buffer
DWORD m_DeltaT; // Sample rate conversion factor
DWORD m_dwMultiplier;
LONG m_PrevSamp[2]; // Allow for stereo
LONG m_CurrSamp[2]; // Allow for stereo
LONG m_CurrT;
};
class InputStreamContext : public WaveStreamContext
{
public:
DWORD SetRate(DWORD dwMultiplier);
DWORD Stop(); // On input, stop has special handling
virtual DoCallbackReturnBuffer(LPWAVEHDR lpHdr)
{
DoDriverCallback(WIM_DATA,(DWORD)lpHdr,0);
}
virtual DoCallbackStreamOpened()
{
DoDriverCallback(WIM_OPEN,0,0);
}
virtual DoCallbackStreamClosed()
{
DoDriverCallback(WIM_CLOSE,0,0);
}
};
class MonoInputStreamContext : public InputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class StereoInputStreamContext : public InputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContext : public WaveStreamContext
{
public:
HRESULT Open(DeviceContext *pDeviceContext, LPWAVEOPENDESC lpWOD, DWORD dwFlags);
DWORD Reset();
DWORD SetRate(DWORD dwMultiplier);
};
class OutputStreamContextM8M : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextM8MW : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextM8S : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextM16M : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextM16MW : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextM16S : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextS8M : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextS8MW : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextS8S : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextS16M : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextS16MW : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
class OutputStreamContextS16S : public OutputStreamContext
{
public:
PBYTE Render2(PBYTE pBuffer, PBYTE pBufferEnd, PBYTE pBufferLast);
};
//------------------------------- END OF FILE ----------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -