📄 wmaudiostream.c
字号:
{
pStreamCtx->copyFunc = private_Get16BitStereo;
}
else
{
pStreamCtx->copyFunc = private_Get8BitStereo;
}
}
else
{
if ( 16 == bitsPerSample )
{
pStreamCtx->copyFunc = private_Get16BitMono;
}
else
{
pStreamCtx->copyFunc = private_Get8BitMono;
}
}
}
else
{
if ( isStereo )
{
if ( 16 == bitsPerSample )
{
pStreamCtx->copyFunc = private_Get16BitStereoFrom16BitMono;
}
else
{
pStreamCtx->copyFunc = private_Get8BitStereoFrom16BitMono;
}
}
else
{
if ( 16 == bitsPerSample )
{
pStreamCtx->copyFunc = private_Get16BitMonoFrom16BitMono;
}
else
{
pStreamCtx->copyFunc = private_Get8BitMonoFrom16BitMono;
}
}
}
}
else
{
if ( isStereoDMA )
{
if ( isStereo )
{
if ( 16 == bitsPerSample )
{
pStreamCtx->copyFunc = private_Fill16BitStereoToStereo;
}
else
{
pStreamCtx->copyFunc = private_Fill8BitStereoToStereo;
}
}
else /* ! isStereo */
{
if ( 16 == bitsPerSample )
{
pStreamCtx->copyFunc = private_Fill16BitMonoToStereo;
}
else
{
pStreamCtx->copyFunc = private_Fill8BitMonoToStereo;
}
}
}
else /* ! isStereoDMA */
{
if ( isStereo )
{
if ( 16 == bitsPerSample )
{
if ( isWideDMA )
{
pStreamCtx->copyFunc = private_Fill16BitStereoTo32BitMono;
}
else
{
pStreamCtx->copyFunc = private_Fill16BitStereoTo16BitMono;
}
}
else
{
if ( isWideDMA )
{
pStreamCtx->copyFunc = private_Fill8BitStereoTo32BitMono;
}
else
{
pStreamCtx->copyFunc = private_Fill8BitStereoTo16BitMono;
}
}
}
else /* ! isStereo */
{
if ( 16 == bitsPerSample )
{
if ( isWideDMA )
{
pStreamCtx->copyFunc = private_Fill16BitMonoTo32BitMono;
}
else
{
pStreamCtx->copyFunc = private_Fill16BitMonoTo16BitMono;
}
}
else
{
if ( isWideDMA )
{
pStreamCtx->copyFunc = private_Fill8BitMonoTo32BitMono;
}
else
{
pStreamCtx->copyFunc = private_Fill8BitMonoTo16BitMono;
}
}
}
}
}
/*
* Initialise the DMA stream.
*/
pStreamCtx->DMAChan = WMDMAInitChannel( hDevice, APIChannel, bufSize );
if ( !pStreamCtx->DMAChan )
{
status = WMS_RESOURCE_FAIL;
goto error1;
}
/*
* Make sure the stream is enabled.
*/
status = WMAudioEnableStream( hDevice, stream );
if ( WM_ERROR( status ) )
{
goto error2;
}
/*
* Set the sample rate.
*/
status = WMAudioSetSampleRate( hDevice, stream, sampleRate );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice,
( "WMAudioOpenStream(%d): couldn't set sample rate %dHz: %s",
stream,
sampleRate,
WMStatusText( status ) ) );
goto error3;
}
/*
* Get our stream handle.
*/
*pStreamHandle = STREAM_HANDLE_FROM_CONTEXT( pStreamCtx );
WM_ASSERT( hDevice, pStreamCtx == STREAM_CONTEXT_FROM_HANDLE( *pStreamHandle ) );
/*
* We're done.
*/
return WMS_SUCCESS;
/*
* Error handling.
*/
error3:
WMAudioDisableStream( hDevice, stream );
error2:
WMDMAShutdownChannel( hDevice, pStreamCtx->DMAChan );
pStreamCtx->DMAChan = (WMDMA_CHAN_HANDLE)NULL;
error1:
private_FreeStreamContext( hDevice, pStreamCtx );
error0:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioCloseStream
*
* Frees an audio stream.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* hStream handle to the stream to close (from WMAudioOpenStream).
*
* Returns: void
*---------------------------------------------------------------------------*/
void WMAudioCloseStream( WM_DEVICE_HANDLE hDevice, WM_STREAM_HANDLE hStream )
{
StreamCtx *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
/*
* Checks on the stream.
*/
WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
/*
* De-Initialise the DMA stream
*/
WMDMAShutdownChannel( hDevice, pStreamCtx->DMAChan );
pStreamCtx->DMAChan = (WMDMA_CHAN_HANDLE)NULL;
/*
* Disable the audio stream.
*/
WMAudioDisableStream( hDevice, pStreamCtx->stream );
/*
* And clear our state.
*/
private_FreeStreamContext( hDevice, pStreamCtx );
}
/*-----------------------------------------------------------------------------
* Function: WMAudioSendData
*
* This function buffers the given audio data for playing. It will add the
* data to the current DMA buffer.
* NOTE: WMAudioFinishSample must be called to fill the remainder of the
* buffer if it has not been completly filled.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* hStream handle to the stream to play on (from WMAudioOpenStream).
* This must be an output stream.
* data the audio samples in the format specified in
* WMAudioOpenStream.
* dataSize the size of the remaining data in bytes.
* pbytesCopied pointer to the number of bytes copied to the DMA buffer.
*
* Returns: WM_BOOL
* TRUE if the DMA buffer is full
* FALSE if there is still space in the DMA Buffer.
*---------------------------------------------------------------------------*/
WM_BOOL WMAudioSendData( WM_DEVICE_HANDLE hDevice,
WM_STREAM_HANDLE hStream,
void *data,
unsigned int dataSize,
unsigned int *pBytesCopied
)
{
StreamCtx *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
char *pDMABuffer;
unsigned int sampleCount;
unsigned int nUserSamples;
WM_BOOL DMABufferFull = FALSE;
char *pFreeSpace;
/*
* Checks on the stream.
*/
WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_OUTPUT );
/*
* Work out how much space is left in this buffer.
* Note there should be some space - if there isn't we should have already
* switched buffers at the time we filled it.
*/
sampleCount = pStreamCtx->samplesPerBuffer - pStreamCtx->nSamples;
WM_ASSERT( hDevice, sampleCount > 0 );
/*
* Work out how many samples to play.
*/
nUserSamples = dataSize / pStreamCtx->bytesPerUserSample;
if ( sampleCount > nUserSamples )
sampleCount = nUserSamples;
/*
* Get the DMA buffer.
*/
pDMABuffer = (char *) WMDMAGetChannelBuffer( hDevice, pStreamCtx->DMAChan );
/*
* If all buffers are full, there's not much we can do.
*/
if ( !pDMABuffer )
{
*pBytesCopied = 0;
DMABufferFull = TRUE;
goto end;
}
/*
* Work out how much free space in bytes is left in the DMA Buffer.
*/
pFreeSpace = pDMABuffer + ( pStreamCtx->nSamples * pStreamCtx->bytesPerDMASample );
/*
* Copy the audio data in to the DMA buffer
*/
pStreamCtx->copyFunc( pFreeSpace, data, sampleCount );
/*
* Update the buffer size.
*/
pStreamCtx->nSamples += sampleCount;
/*
* Work out the number of bytes we copied.
*/
*pBytesCopied = sampleCount * pStreamCtx->bytesPerUserSample;
/*
* If the number of samples we have copied is the size of the DMA buffer
* then we need to reset our sample counter and move on to the next
* available DMA buffer.
*/
if ( pStreamCtx->nSamples == pStreamCtx->samplesPerBuffer )
{
/*
* Get the next available DMA buffer now the current one is full.
*/
WMDMAMarkBufferFull( hDevice, pStreamCtx->DMAChan, pDMABuffer );
/*
* Set the flag to say that the DMA Buffer is full
*/
DMABufferFull = TRUE;
/*
* The buffer is full now so set our sample counter back to zero.
*/
pStreamCtx->nSamples = 0;
}
/*
* Return the status of the DMA Buffer.
*/
end:
return DMABufferFull;
}
/*-----------------------------------------------------------------------------
* Function: WMAudioFinishSample
*
* This function fills the remainder of the DMA buffer with silence. This will
* start the DMA if necessary.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* hStream handle to the stream to play on (from WMAudioOpenStream).
* This must be an output stream.
*
* Returns: void
*---------------------------------------------------------------------------*/
void WMAudioFinishSample( WM_DEVICE_HANDLE hDevice,
WM_STREAM_HANDLE hStream
)
{
StreamCtx *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
/*
* Checks on the stream.
*/
WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_OUTPUT );
/*
* Fill the remainder of the current DMA buffer with silence.
*/
if ( pStreamCtx->nSamples > 0 )
{
private_ClearRestOfBuffer( hDevice, pStreamCtx );
}
}
/*-----------------------------------------------------------------------------
* Function: WMAudioStartRendering
*
* WMAudioStartRendering returns a pointer to the current buffer for the
* channel, ready for rendering into directly. Once you have finished
* rendering the audio, call WMAudioFinishRendering.
*
* Note: you need to call WMAudioCheckChannelInterrupts when you receive
* an interrupt to make sure that buffers get marked as empty agin.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* hStream handle to the stream to return the buffer from
* (from WMAudioOpenStream).
*
* Returns: void *
* A pointer to the DMA buffer (of size WMAudioBufferSize).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -