WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+typedef struct StreamData
+{
+ DWORD dwSampleSize;
+ FLOAT fSamplesPerSec;
+ DWORD dwLength;
+} StreamData;
+
typedef struct AVISplitterImpl
{
ParserImpl Parser;
LONGLONG CurrentChunkOffset; /* in media time */
LONGLONG EndOfFile;
AVIMAINHEADER AviHeader;
+ StreamData *streams;
} AVISplitterImpl;
static HRESULT AVISplitter_NextChunk(LONGLONG * pllCurrentChunkOffset, RIFFCHUNK * pCurrentChunk, const REFERENCE_TIME * tStart, const REFERENCE_TIME * tStop, const BYTE * pbSrcStream, int inner)
if (SUCCEEDED(hr))
{
REFERENCE_TIME tAviStart, tAviStop;
+ StreamData *stream = This->streams + streamId;
/* FIXME: hack */
if (pOutputPin->dwSamplesProcessed == 0)
pOutputPin->dwSamplesProcessed++;
- if (pOutputPin->dwSampleSize)
- tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+ if (stream->dwSampleSize)
+ tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)stream->dwSampleSize * stream->fSamplesPerSec));
else
- tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)pOutputPin->fSamplesPerSec);
- if (pOutputPin->dwSampleSize)
- tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+ tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)stream->fSamplesPerSec);
+ if (stream->dwSampleSize)
+ tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)stream->dwSampleSize * stream->fSamplesPerSec));
else
- tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)pOutputPin->fSamplesPerSec);
+ tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)stream->fSamplesPerSec);
IMediaSample_SetTime(This->pCurrentSample, &tAviStart, &tAviStop);
DWORD dwLength = 0;
ALLOCATOR_PROPERTIES props;
static const WCHAR wszStreamTemplate[] = {'S','t','r','e','a','m',' ','%','0','2','d',0};
+ StreamData *stream;
props.cbAlign = 1;
props.cbPrefix = 0;
TRACE("fSamplesPerSec = %f\n", (double)fSamplesPerSec);
TRACE("dwSampleSize = %x\n", dwSampleSize);
TRACE("dwLength = %x\n", dwLength);
+ This->streams = CoTaskMemRealloc(This->streams, sizeof(StreamData) * (This->Parser.cStreams+1));
+ stream = This->streams + This->Parser.cStreams;
+ stream->fSamplesPerSec = fSamplesPerSec;
+ stream->dwSampleSize = dwSampleSize;
+ stream->dwLength = dwLength; /* TODO: Use this for mediaseeking */
- hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt, fSamplesPerSec, dwSampleSize, dwLength);
+ hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt);
return hr;
}
This = CoTaskMemAlloc(sizeof(AVISplitterImpl));
This->pCurrentSample = NULL;
+ This->streams = NULL;
hr = Parser_Create(&(This->Parser), &CLSID_AviSplitter, AVISplitter_Sample, AVISplitter_QueryAccept, AVISplitter_InputPin_PreConnect, AVISplitter_Cleanup);
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
-HRESULT MediaSeekingImpl_Init(LPVOID pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking)
+HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking)
{
assert(fnChangeStop && fnChangeStart && fnChangeRate);
BOOL bChangeRate = (dRate != This->dRate);
TRACE("(%e)\n", dRate);
-
+
This->dRate = dRate;
-
if (bChangeRate)
return This->fnChangeRate(This->pUserData);
else
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-typedef HRESULT (* CHANGEPROC)(LPVOID pUserData);
+typedef HRESULT (* CHANGEPROC)(IBaseFilter *pUserData);
typedef struct MediaSeekingImpl
{
const IMediaSeekingVtbl * lpVtbl;
ULONG refCount;
- LPVOID pUserData;
+ IBaseFilter *pUserData;
CHANGEPROC fnChangeStop;
CHANGEPROC fnChangeStart;
CHANGEPROC fnChangeRate;
LONGLONG llDuration; /* FIXME: needed? */
} MediaSeekingImpl;
-HRESULT MediaSeekingImpl_Init(LPVOID pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking);
+HRESULT MediaSeekingImpl_Init(IBaseFilter *pUserData, CHANGEPROC fnChangeStop, CHANGEPROC fnChangeStart, CHANGEPROC fnChangeRate, MediaSeekingImpl * pSeeking);
HRESULT WINAPI MediaSeekingImpl_GetCapabilities(IMediaSeeking * iface, DWORD * pCapabilities);
HRESULT WINAPI MediaSeekingImpl_CheckCapabilities(IMediaSeeking * iface, DWORD * pCapabilities);
SendFilterMessage(iface, SendStop);
This->state = State_Stopped;
LeaveCriticalSection(&This->cs);
- return S_FALSE;
+ return S_OK;
}
static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
#define MPEG_AUDIO_HEADER 1
#define MPEG_NO_HEADER 0
-
typedef struct MPEGSplitterImpl
{
ParserImpl Parser;
IMediaSample *pCurrentSample;
LONGLONG EndOfFile;
+ DWORD dwSampleSize, dwLength;
+ FLOAT fSamplesPerSec;
} MPEGSplitterImpl;
static int MPEGSplitter_head_check(const BYTE *header)
{
REFERENCE_TIME tMPEGStart, tMPEGStop;
- pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / pOutputPin->dwSampleSize;
+ pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / This->dwSampleSize;
tMPEGStart = (tStart + MEDIATIME_FROM_BYTES(used_bytes-bytes_written)) /
- (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+ (This->fSamplesPerSec*This->dwSampleSize);
tMPEGStop = (tStart + MEDIATIME_FROM_BYTES(used_bytes)) /
- (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+ (This->fSamplesPerSec*This->dwSampleSize);
/* If the start of the sample has a valid MPEG header, it's a
* sync point */
{
REFERENCE_TIME tMPEGStart, tMPEGStop;
- pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / pOutputPin->dwSampleSize;
+ pOutputPin->dwSamplesProcessed = (BYTES_FROM_MEDIATIME(tStart)+used_bytes) / This->dwSampleSize;
tMPEGStart = (tStart + MEDIATIME_FROM_BYTES(used_bytes-bytes_written)) /
- (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+ (This->fSamplesPerSec*This->dwSampleSize);
tMPEGStop = (tStart + MEDIATIME_FROM_BYTES(used_bytes)) /
- (pOutputPin->fSamplesPerSec*pOutputPin->dwSampleSize);
+ (This->fSamplesPerSec*This->dwSampleSize);
if (MPEGSplitter_head_check(pbDstStream) == MPEG_AUDIO_HEADER)
IMediaSample_SetSyncPoint(This->pCurrentSample, TRUE);
props.cbBuffer = 0x4000 / format->nBlockAlign *
format->nBlockAlign;
props.cBuffers = 1;
-
- hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt,
- (float)format->nAvgBytesPerSec /
- (float)format->nBlockAlign,
- format->nBlockAlign,
- total);
+ This->fSamplesPerSec = (float)format->nAvgBytesPerSec / (float)format->nBlockAlign;
+ This->dwSampleSize = format->nBlockAlign;
+ This->dwLength = total;
+ hr = Parser_AddPin(&(This->Parser), &piOutput, &props, &amt);
}
if (FAILED(hr))
static const IPinVtbl Parser_InputPin_Vtbl;
static HRESULT Parser_OutputPin_QueryAccept(LPVOID iface, const AM_MEDIA_TYPE * pmt);
-static HRESULT Parser_ChangeStart(LPVOID iface);
-static HRESULT Parser_ChangeStop(LPVOID iface);
-static HRESULT Parser_ChangeRate(LPVOID iface);
+static HRESULT Parser_ChangeStart(IBaseFilter *iface);
+static HRESULT Parser_ChangeStop(IBaseFilter *iface);
+static HRESULT Parser_ChangeRate(IBaseFilter *iface);
static HRESULT Parser_InputPin_Construct(const PIN_INFO * pPinInfo, SAMPLEPROC pSampleProc, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
-static inline Parser_OutputPin *impl_from_IMediaSeeking( IMediaSeeking *iface )
+static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
{
- return (Parser_OutputPin *)((char*)iface - FIELD_OFFSET(Parser_OutputPin, mediaSeeking.lpVtbl));
+ return (ParserImpl *)((char*)iface - FIELD_OFFSET(ParserImpl, mediaSeeking.lpVtbl));
}
piInput.pFilter = (IBaseFilter *)pParser;
lstrcpynW(piInput.achName, wcsInputPinName, sizeof(piInput.achName) / sizeof(piInput.achName[0]));
+ MediaSeekingImpl_Init((IBaseFilter*)pParser, Parser_ChangeStop, Parser_ChangeStart, Parser_ChangeRate, &pParser->mediaSeeking);
+ pParser->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
+
hr = Parser_InputPin_Construct(&piInput, fnProcessSample, (LPVOID)pParser, fnQueryAccept, &pParser->csFilter, (IPin **)&pParser->pInputPin);
if (SUCCEEDED(hr))
return hr;
}
-static HRESULT Parser_OutputPin_Init(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, float fSamplesPerSec, LPCRITICAL_SECTION pCritSec, Parser_OutputPin * pPinImpl)
+static HRESULT Parser_OutputPin_Init(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, LPCRITICAL_SECTION pCritSec, Parser_OutputPin * pPinImpl)
{
pPinImpl->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(pPinImpl->pmt, pmt);
pPinImpl->dwSamplesProcessed = 0;
- pPinImpl->dwSampleSize = 0;
- pPinImpl->fSamplesPerSec = fSamplesPerSec;
-
- MediaSeekingImpl_Init((LPVOID)pPinInfo->pFilter, Parser_ChangeStop, Parser_ChangeStart, Parser_ChangeRate, &pPinImpl->mediaSeeking);
- pPinImpl->mediaSeeking.lpVtbl = &Parser_Seeking_Vtbl;
return OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pCritSec, &pPinImpl->pin);
}
-static HRESULT Parser_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, float fSamplesPerSec, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
+static HRESULT Parser_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES * props, LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, const AM_MEDIA_TYPE * pmt, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
Parser_OutputPin * pPinImpl;
if (!pPinImpl)
return E_OUTOFMEMORY;
- if (SUCCEEDED(Parser_OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pmt, fSamplesPerSec, pCritSec, pPinImpl)))
+ if (SUCCEEDED(Parser_OutputPin_Init(pPinInfo, props, pUserData, pQueryAccept, pmt, pCritSec, pPinImpl)))
{
pPinImpl->pin.pin.lpVtbl = &Parser_OutputPin_Vtbl;
*ppv = (LPVOID)This;
else if (IsEqualIID(riid, &IID_IBaseFilter))
*ppv = (LPVOID)This;
+ else if (IsEqualIID(riid, &IID_IMediaSeeking))
+ *ppv = (LPVOID)&This->mediaSeeking;
if (*ppv)
{
{
for (i = 1; i < This->cStreams + 1; i++)
{
- Parser_OutputPin* StreamPin = (Parser_OutputPin *)This->ppPins[i];
- OutputPin_DeliverNewSegment((OutputPin *)This->ppPins[i], 0, (LONGLONG)ceil(10000000.0 * (float)StreamPin->dwLength / StreamPin->fSamplesPerSec), 1.0);
- StreamPin->mediaSeeking.llDuration = (LONGLONG)ceil(10000000.0 * (float)StreamPin->dwLength / StreamPin->fSamplesPerSec);
- StreamPin->mediaSeeking.llStop = (LONGLONG)ceil(10000000.0 * (float)StreamPin->dwLength / StreamPin->fSamplesPerSec);
+ LONGLONG duration;
+ DOUBLE speed;
+
+ IMediaSeeking_GetDuration((IMediaSeeking *)&This->mediaSeeking, &duration);
+ IMediaSeeking_GetRate((IMediaSeeking *)&This->mediaSeeking, &speed);
+ OutputPin_DeliverNewSegment((OutputPin *)This->ppPins[i], 0, duration, speed);
OutputPin_CommitAllocator((OutputPin *)This->ppPins[i]);
}
Parser_QueryVendorInfo
};
-HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props,
- const AM_MEDIA_TYPE * amt, float fSamplesPerSec, DWORD dwSampleSize, DWORD dwLength)
+HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt)
{
IPin ** ppOldPins;
HRESULT hr;
This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *));
- hr = Parser_OutputPin_Construct(piOutput, props, NULL, Parser_OutputPin_QueryAccept, amt, fSamplesPerSec, &This->csFilter, This->ppPins + This->cStreams + 1);
+ hr = Parser_OutputPin_Construct(piOutput, props, NULL, Parser_OutputPin_QueryAccept, amt, &This->csFilter, This->ppPins + This->cStreams + 1);
if (SUCCEEDED(hr))
{
- ((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->dwSampleSize = dwSampleSize;
- ((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->dwLength = dwLength;
((Parser_OutputPin *)(This->ppPins[This->cStreams + 1]))->pin.pin.pUserData = (LPVOID)This->ppPins[This->cStreams + 1];
This->cStreams++;
CoTaskMemFree(ppOldPins);
return S_OK;
}
-static HRESULT Parser_ChangeStart(LPVOID iface)
+static HRESULT Parser_ChangeStart(IBaseFilter *iface)
{
FIXME("(%p)\n", iface);
return S_OK;
}
-static HRESULT Parser_ChangeStop(LPVOID iface)
+static HRESULT Parser_ChangeStop(IBaseFilter *iface)
{
FIXME("(%p)\n", iface);
return S_OK;
}
-static HRESULT Parser_ChangeRate(LPVOID iface)
+static HRESULT Parser_ChangeRate(IBaseFilter *iface)
{
FIXME("(%p)\n", iface);
return S_OK;
static HRESULT WINAPI Parser_Seeking_QueryInterface(IMediaSeeking * iface, REFIID riid, LPVOID * ppv)
{
- Parser_OutputPin *This = impl_from_IMediaSeeking(iface);
+ ParserImpl *This = impl_from_IMediaSeeking(iface);
return IUnknown_QueryInterface((IUnknown *)This, riid, ppv);
}
static ULONG WINAPI Parser_Seeking_AddRef(IMediaSeeking * iface)
{
- Parser_OutputPin *This = impl_from_IMediaSeeking(iface);
+ ParserImpl *This = impl_from_IMediaSeeking(iface);
return IUnknown_AddRef((IUnknown *)This);
}
static ULONG WINAPI Parser_Seeking_Release(IMediaSeeking * iface)
{
- Parser_OutputPin *This = impl_from_IMediaSeeking(iface);
+ ParserImpl *This = impl_from_IMediaSeeking(iface);
return IUnknown_Release((IUnknown *)This);
}
else if (IsEqualIID(riid, &IID_IPin))
*ppv = (LPVOID)iface;
else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = (LPVOID)&This->mediaSeeking;
+ {
+ return IBaseFilter_QueryInterface((IBaseFilter*)&This->pin.pin.pinInfo.pFilter, &IID_IMediaSeeking, ppv);
+ }
if (*ppv)
{
PullPin * pInputPin;
IPin ** ppPins;
ULONG cStreams;
+ MediaSeekingImpl mediaSeeking;
};
typedef struct Parser_OutputPin
OutputPin pin;
AM_MEDIA_TYPE * pmt;
- float fSamplesPerSec;
DWORD dwSamplesProcessed;
- DWORD dwSampleSize;
- DWORD dwLength;
- MediaSeekingImpl mediaSeeking;
} Parser_OutputPin;
-HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props,
- const AM_MEDIA_TYPE * amt, float fSamplesPerSec, DWORD dwSampleSize, DWORD dwLength);
+HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt);
+
HRESULT Parser_Create(ParserImpl*, const CLSID*, PFN_PROCESS_SAMPLE, PFN_QUERY_ACCEPT, PFN_PRE_CONNECT, PFN_CLEANUP);
IMediaSample * pCurrentSample;
LONGLONG StartOfFile; /* in media time */
LONGLONG EndOfFile;
+ DWORD dwSampleSize;
+ FLOAT fSamplesPerSec;
+ DWORD dwLength;
} WAVEParserImpl;
static HRESULT WAVEParser_Sample(LPVOID iface, IMediaSample * pSample)
pOutputPin->dwSamplesProcessed++;
- if (pOutputPin->dwSampleSize)
- tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+ if (This->dwSampleSize)
+ tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)This->dwSampleSize * This->fSamplesPerSec));
else
- tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)pOutputPin->fSamplesPerSec);
- if (pOutputPin->dwSampleSize)
- tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)pOutputPin->dwSampleSize * pOutputPin->fSamplesPerSec));
+ tAviStart = (LONGLONG)ceil(10000000.0 * (float)(pOutputPin->dwSamplesProcessed - 1) / (float)This->fSamplesPerSec);
+ if (This->dwSampleSize)
+ tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed * (float)IMediaSample_GetActualDataLength(This->pCurrentSample) / ((float)This->dwSampleSize * This->fSamplesPerSec));
else
- tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)pOutputPin->fSamplesPerSec);
+ tAviStop = (LONGLONG)ceil(10000000.0 * (float)pOutputPin->dwSamplesProcessed / (float)This->fSamplesPerSec);
IMediaSample_SetTime(This->pCurrentSample, &tAviStart, &tAviStop);
PIN_INFO piOutput;
ALLOCATOR_PROPERTIES props;
AM_MEDIA_TYPE amt;
- float fSamplesPerSec = 0.0f;
- DWORD dwSampleSize = 0;
- DWORD dwLength = 0;
WAVEParserImpl * pWAVEParser = (WAVEParserImpl *)This->pin.pinInfo.pFilter;
+ LONGLONG length, avail;
piOutput.dir = PINDIR_OUTPUT;
piOutput.pFilter = (IBaseFilter *)This;
props.cbPrefix = 0;
props.cbBuffer = 4096;
props.cBuffers = 2;
-
- hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, &props, &amt, fSamplesPerSec, dwSampleSize, dwLength);
+ pWAVEParser->dwSampleSize = ((WAVEFORMATEX*)amt.pbFormat)->nBlockAlign;
+ IAsyncReader_Length(This->pReader, &length, &avail);
+ pWAVEParser->dwLength = length / (ULONGLONG)pWAVEParser->dwSampleSize;
+ pWAVEParser->fSamplesPerSec = ((WAVEFORMATEX*)amt.pbFormat)->nAvgBytesPerSec / ((WAVEFORMATEX*)amt.pbFormat)->nBlockAlign;
+ hr = Parser_AddPin(&(pWAVEParser->Parser), &piOutput, &props, &amt);
TRACE("WAVE File ok\n");