⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmaudiostream.c

📁 WM9713 audio codec driver for WinCE 5.0
💻 C
📖 第 1 页 / 共 5 页
字号:
                {
                    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 + -