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

📄 wmaudiostream.c

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
 *      NULL if all buffers are currently full.
 *---------------------------------------------------------------------------*/
void *WMAudioStartRendering( WM_DEVICE_HANDLE hDevice,
                             WM_STREAM_HANDLE hStream
                           )
{
    StreamCtx       *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
    void            *pDMABuffer;
    
    /*
     * Checks on the stream.
     */
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );

    /*
     * Get the buffer from the DMA.
     */
    pDMABuffer = WMDMAGetChannelBuffer( hDevice, pStreamCtx->DMAChan );
    
    return pDMABuffer;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioFinishRendering
 *
 * WMAudioFinishRendering tells the library that the application has finished with
 * the current buffer.  This will start the DMA if necessary.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      hStream         handle to the stream whose buffer it is
 *                      (from WMAudioOpenStream).
 *      pBuffer         the buffer to complete (from WMAudioStartRendering).
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
void WMAudioFinishRendering( WM_DEVICE_HANDLE hDevice,
                             WM_STREAM_HANDLE hStream,
                             void *pBuffer
                           )
{
    StreamCtx       *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
    
    /*
     * Checks on the stream.
     */
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );

    if( STREAM_OUTPUT & pStreamCtx->flags )
    {
        /*
         * And now tell the DMA this buffer's full.
         */
        WMDMAMarkBufferFull( hDevice, pStreamCtx->DMAChan, pBuffer );
    }
    else
    {
        WMDMAMarkBufferEmpty( hDevice, pStreamCtx->DMAChan, pBuffer );
    }
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioClearBuffer
 *
 * This function fills the whole 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 WMAudioClearBuffer( 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 );

    /*
     * Completely fill the current DMA buffer with silence.
     */
	pStreamCtx->nSamples = 0;
    private_ClearRestOfBuffer( hDevice, pStreamCtx );
}

/*-----------------------------------------------------------------------------
 * Function:    private_ClearRestOfBuffer
 *
 * This function fills the DMA buffer with silence.
 * It works out the starting point by checking how many samples have already
 * been written in to this buffer. It will then fill up the rest of the buffer
 * with silence and start the DMA if necessary.
 *
 * Parameters:
 *      hDevice	    handle to the device (from WMOpenDevice)
 *      pStreamCtx  pointer to the StreamCtx for the stream.  This must be an
 *                  output channel and have been initialised using WMAudioOpenStream.
 *
 * Returns:     void
 *---------------------------------------------------------------------------*/
static void private_ClearRestOfBuffer( WM_DEVICE_HANDLE hDevice,
                                       StreamCtx        *pStreamCtx
                                     )
{
    char            *pDMABuffer;
    char            *pFreeSpace;
    unsigned int    sampleCount;
    
    /*
     * Checks on the stream.
     */
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_OUTPUT );

    /* 
     * Work out how many samples to clear in the DMA buffer.
     */
	sampleCount = pStreamCtx->samplesPerBuffer - pStreamCtx->nSamples;

    /* 
     * Get the current DMA Buffer
     */
	pDMABuffer = (char *) WMDMAGetChannelBuffer( hDevice, 
                                                 pStreamCtx->DMAChan
                                               );
    if ( !pDMABuffer )
    {
        goto end;
    }

    /* 
     * Work out how much free space in bytes is left in the DMA Buffer.
     */
    pFreeSpace = pDMABuffer + ( pStreamCtx->nSamples * pStreamCtx->bytesPerDMASample );

    /* 
     * Set the remainder of the DMA buffer to zero 
     */
	memset( pFreeSpace, 
            0, 
            sampleCount * pStreamCtx->bytesPerDMASample 
          );

    /* 
     * Mark this buffer as full.
     */
    WMDMAMarkBufferFull( hDevice, pStreamCtx->DMAChan, pDMABuffer );

    /* 
     * The buffer is full now so set our sample counter back to zero.
     */
    pStreamCtx->nSamples = 0;

end:
    return;
}

#if defined ( WM_TESTING ) || defined( WM_AUDIO_WAVEGEN )
/*-----------------------------------------------------------------------------
 * Function:    WMAudioPlaySineWave
 *
 * This function fills a DMA buffer with a sine wave and plays it.
 * Note: it will overwrite a partially filled buffer.
 *
 * Parameters:
 *      hDevice	    handle to the device (from WMOpenDevice)
 *      hStream     handle to the stream to play on (from WMAudioOpenStream).
 *                  This must be an output stream.
 *      frequency   the fequency of the sine wave in Hz.
 *      amplitude   the peak amplitude of the sine wave (0-32768).
 *      pRestart    pointer to a restart context - position after previous
 *                  call. Used to restart the wave where the previous call
 *                  left off. Updated to the start position for the next call.
 *
 * Returns:     WM_BOOL
 *      TRUE if data was transmitted.
 *      FALSE if there were no buffers available.
 *---------------------------------------------------------------------------*/
WM_BOOL WMAudioPlaySineWave( WM_DEVICE_HANDLE hDevice,
                             WM_STREAM_HANDLE hStream,
                             unsigned short frequency,
                             unsigned short amplitude,
                             WM_WAVEGEN_CTX *pRestart
                           )
{
    StreamCtx           *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
    void                *pDMABuffer;
    WM_BOOL             dataTransmitted = FALSE;
    WM_WAVEGEN_FORMAT   format;
    
    /*
     * Checks on the stream.
     */
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_OUTPUT );

    /*
     * Get the DMA buffer.
     */
    pDMABuffer = WMDMAGetChannelBuffer( hDevice, pStreamCtx->DMAChan );
    if ( !pDMABuffer )
    {
        goto end;
    }
    
    /*
     * Now fill it.
     */
	if ( pStreamCtx->flags & STREAM_STEREO_DMA )
	{
        format = WM_WAVEGEN_STEREO;
    }
    else if ( pStreamCtx->flags & STREAM_MONO_DMA )
    {
        format = WM_WAVEGEN_CONTIGUOUS;
    }
    else if ( pStreamCtx->flags & STREAM_MONO_DMA_WIDE )
    {
        format = WM_WAVEGEN_CONTIGUOUS_WIDE;
    }
    else 
    {
        WM_ASSERT( hDevice, FALSE );
    }
	WMGenerateSineWave( (WM_AUDIO_STEREO_SAMPLE *) pDMABuffer,
						pStreamCtx->samplesPerBuffer,
						pStreamCtx->sampleRate,
						frequency,
						amplitude,
						format,
						pRestart
					  );

    /*
     * Now mark the buffer as full.  This will start the DMA if necessary.
     */
    WMDMAMarkBufferFull( hDevice, pStreamCtx->DMAChan, pDMABuffer );
    pStreamCtx->nSamples = 0;
    dataTransmitted = TRUE;
    
end:
    return dataTransmitted;
}

/*-----------------------------------------------------------------------------
 * Function:    WMAudioPlaySquareWave
 *
 * This function fills a DMA buffer with a square wave and plays it.
 * Note: it will overwrite a partially filled buffer.
 *
 * Parameters:
 *      hDevice     handle to the device (from WMOpenDevice)
 *      hStream     handle to the stream to play on (from WMAudioOpenStream).
 *                  This must be an output stream.
 *      frequency   the fequency of the square wave in Hz.
 *      amplitude   the peak amplitude of the square wave (0-32767).
 *      pRestart    pointer to a restart context - position after previous call.
 *                  Used to restart the wave where the previous call left off.
 *                  Updated to the start position for the next call.
 *
 * Returns:     WM_BOOL
 *      TRUE if data was transmitted.
 *      FALSE if there were no buffers available.
 *---------------------------------------------------------------------------*/
WM_BOOL WMAudioPlaySquareWave( WM_DEVICE_HANDLE hDevice,
                               WM_STREAM_HANDLE hStream,
                               unsigned short frequency,
                               unsigned short amplitude,
                               WM_WAVEGEN_CTX *pRestart
                             )
{
    StreamCtx           *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
    void                *pDMABuffer;
    WM_BOOL             dataTransmitted = FALSE;
    WM_WAVEGEN_FORMAT   format;
    
    /*
     * Checks on the stream.
     */
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_OUTPUT );

    /*
     * Get the DMA buffer.
     */
    pDMABuffer = WMDMAGetChannelBuffer( hDevice, pStreamCtx->DMAChan );
    if ( !pDMABuffer )
    {
        goto end;
    }
    
    /*
     * Now fill it.
     */
    if ( pStreamCtx->flags & STREAM_STEREO_DMA )
    {
        format = WM_WAVEGEN_STEREO;
    }
    else
    {
        format = WM_WAVEGEN_CONTIGUOUS;
    }
    WMGenerateSquareWave( (WM_AUDIO_STEREO_SAMPLE *) pDMABuffer,
                          pStreamCtx->samplesPerBuffer,
                          pStreamCtx->sampleRate,
                          frequency,
                          amplitude,
                          format,
                          pRestart
                          );
                                      
    /*
     * Now switch buffers.  This will start the DMA if necessary.
     */
    WMDMAMarkBufferFull( hDevice, pStreamCtx->DMAChan, pDMABuffer );
    pStreamCtx->nSamples = 0;
    dataTransmitted = TRUE;
    
end:
    return dataTransmitted;
}
#endif /* WM_TESTING  || WM_AUDIO_WAVEGEN */

/*-----------------------------------------------------------------------------
 * Function:    WMAudioReceiveData
 *
 * This function returns the recorded audio data from the buffer.
 *
 * Parameters:
 *      hDevice         handle to the device (from WMOpenDevice)
 *      hStream         handle to the stream to record (from WMAudioOpenStream).
 *                      This must be an input stream.
 *      buffer          the buffer to receive the audio samples in the format
 *                      specified in WMAudioOpenStream.
 *      dataSize        the size of the buffer in bytes.
 *      pBytesCopied    pointer to the number of bytes copied from the DMA
 *                      buffer.
 *
 * Returns:     WM_BOOL
 *          TRUE if all the data in the DMA buffer has been copied.
 *          FALSE if there is still data left in the DMA Buffer.
 *---------------------------------------------------------------------------*/
WM_BOOL WMAudioReceiveData( WM_DEVICE_HANDLE hDevice,
                            WM_STREAM_HANDLE hStream,
                            void *buffer,
                            unsigned int dataSize,
                            unsigned int *pBytesCopied
                          )
{
    StreamCtx       *pStreamCtx = STREAM_CONTEXT_FROM_HANDLE( hStream );
    char            *pDMABuffer;
    unsigned int    sampleCount;
    unsigned int    nUserSamples;
    WM_BOOL         DMABufferEmpty = FALSE;
    char            *pFreeSpace;
    
    /*
     * Checks on the stream.
     */
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_ACTIVE );
    WM_ASSERT( hDevice, pStreamCtx->flags & STREAM_INPUT );
    WM_ASSERT( hDevice,
               pStreamCtx->bytesPerDMASample == pStreamCtx->bytesPerUserSample
             );

    /*
     * Work out how much data is left in this buffer.
     * Note there should be some data - 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 record.
     */
    nUserSamples = dataSize / pStreamCtx->bytesPerUserSample;
    if ( sampleCount > nUserSamples )
        sampleCount = nUserSamples;

    /*
     * Get the DMA buffer and copy it to the application buffer.
     */
    pDMABuffer = (char *) WMDMAGetChannelBuffer( hDevice, pStreamCtx->DMAChan );

    /*
     * If there's no data, there's not much we can do...
     */
    if ( !pDMABuffer )
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -