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

📄 sound.c

📁 基于TI公司Cortex-M3的uart超级通信开发
💻 C
📖 第 1 页 / 共 3 页
字号:
//! in use in case the requested rate could not be matched exactly.
//!
//! \return The current sample rate in samples/sec.
//
//*****************************************************************************
unsigned long
SoundSampleRateGet(void)
{
    return(g_ulSampleRate);
}

//*****************************************************************************
//
//! Starts playback of a block of PCM audio samples.
//!
//! \param pvData is a pointer to the audio data to play.
//! \param ulLength is the length of the data in bytes.
//! \param pfnCallback is a function to call when this buffer has be played.
//!
//! This function starts the playback of a block of PCM audio samples.  If
//! playback of another buffer is currently ongoing, its playback is canceled
//! and the buffer starts playing immediately.
//!
//! \return 0 if the buffer was accepted, returns non-zero if there was no
//! space available for this buffer.
//
//*****************************************************************************
unsigned long
SoundBufferPlay(const void *pvData, unsigned long ulLength,
                tBufferCallback pfnCallback)
{
    unsigned long ulChannel;

    //
    // Must disable I2S interrupts during this time to prevent state problems.
    //
    IntDisable(INT_I2S0);

    //
    // Save the buffer information.
    //
    g_sOutBuffers[g_ulPlaying].pulData = (unsigned long *)pvData;
    g_sOutBuffers[g_ulPlaying].ulSize = ulLength;
    g_sOutBuffers[g_ulPlaying].pfnBufferCallback = pfnCallback;

    //
    // Handle which half of the ping-pong DMA is in use.
    //
    if(g_ulPlaying)
    {
        ulChannel = UDMA_CHANNEL_I2S0TX | UDMA_ALT_SELECT;
    }
    else
    {
        ulChannel = UDMA_CHANNEL_I2S0TX | UDMA_PRI_SELECT;
    }

    //
    // Set the DMA channel configuration.
    //
    if(g_usChannels == 1)
    {
        //
        // Handle Mono formats.
        //
        if(g_usBitsPerSample == 16)
        {
            //
            // The transfer size is 16 bits from the TX buffer to the TX FIFO.
            // Modify the DMA transfer size at it is units not bytes.
            //
            g_sOutBuffers[g_ulPlaying].ulSize >>= 1;
        }
    }
    else
    {
        //
        // Handle Stereo formats.
        //
        if(g_usBitsPerSample == 8)
        {
            //
            // The transfer size is 16 bits(stereo 8 bits) from the TX buffer
            // to the TX FIFO.  Modify the DMA transfer size at it is units
            // not bytes.
            //
            g_sOutBuffers[g_ulPlaying].ulSize >>= 1;
        }
        else
        {
            //
            // The transfer size is 32 bits(stereo 16 bits) from the TX buffer
            // to the TX FIFO. Modify the DMA transfer size at it is units not
            // bytes.
            //
            g_sOutBuffers[g_ulPlaying].ulSize >>= 2;
        }
    }

    //
    // Set the addresses and the DMA mode to ping-pong.
    //
    uDMAChannelTransferSet(ulChannel,
                           UDMA_MODE_PINGPONG,
                           (unsigned long *)g_sOutBuffers[g_ulPlaying].pulData,
                           (void *)(I2S0_BASE + I2S_O_TXFIFO),
                           g_sOutBuffers[g_ulPlaying].ulSize);

    //
    // Enable the TX channel.  At this point the uDMA controller will
    // start servicing the request from the I2S, and the transmit side
    // should start running.
    //
    uDMAChannelEnable(UDMA_CHANNEL_I2S0TX);

    //
    // Indicate that there is still a pending transfer.
    //
    HWREGBITW(&g_ulDMAFlags, FLAG_TX_PENDING) = 1;

    //
    // Toggle which ping-pong DMA setting is in use.
    //
    g_ulPlaying ^= 1;

    //
    // Enable the I2S controller to start transmitting.
    //
    I2STxEnable(I2S0_BASE);

    //
    // Re-enable I2S interrupts.
    //
    IntEnable(INT_I2S0);

    return(0);
}

//*****************************************************************************
//
//! Starts recording from the audio input.
//!
//! \param pvData is a pointer to store the data as it is received.
//! \param ulSize is the size of the buffer pointed to by pvData in bytes.
//! \param pfnCallback is a function to call when this buffer has been filled.
//!
//! This function initiates a request for the I2S controller to receive data
//! from an I2S codec.
//!
//! \return 0 if the buffer was accepted, returns non-zero if there was no
//! space available for this buffer.
//
//*****************************************************************************
unsigned long
SoundBufferRead(void *pvData, unsigned long ulSize,
                tBufferCallback pfnCallback)
{
    unsigned long ulChannel;
    unsigned long ulDMASetting;

    //
    // Must disable I2S interrupts during this time to prevent state problems.
    //
    IntDisable(INT_I2S0);

    //
    // Save the buffer information.
    //
    g_sInBuffers[g_ulRecording].pulData = (unsigned long *)pvData;
    g_sInBuffers[g_ulRecording].ulSize = ulSize;
    g_sInBuffers[g_ulRecording].pfnBufferCallback = pfnCallback;

    //
    // Configure the I2S TX DMA channel to use high priority burst mode.
    //
    uDMAChannelAttributeEnable(UDMA_CHANNEL_I2S0RX,
                               (UDMA_ATTR_USEBURST |
                                UDMA_ATTR_HIGH_PRIORITY));

    //
    // Handle which half of the ping-pong DMA is in use.
    //
    if(g_ulRecording)
    {
        ulChannel = UDMA_CHANNEL_I2S0RX | UDMA_ALT_SELECT;
    }
    else
    {
        ulChannel = UDMA_CHANNEL_I2S0RX | UDMA_PRI_SELECT;
    }

    //
    // Handle stereo recording.
    //
    if(g_usBitsPerSample == 8)
    {
        //
        // The transfer size is 16 bits(stereo 8 bits) from the RX FIFO to
        // RX buffer.
        //
        ulDMASetting = UDMA_SIZE_16 | UDMA_DST_INC_16 |
                       UDMA_SRC_INC_NONE | UDMA_ARB_2;

        //
        // Modify the DMA transfer size at it is units not bytes.
        //
        g_sInBuffers[g_ulRecording].ulSize >>= 1;
    }
    else
    {
        //
        // The transfer size is 32 bits(stereo 16 bits) from the RX FIFO to
        // RX buffer.
        //
        ulDMASetting = UDMA_SIZE_32 | UDMA_DST_INC_32 |
                       UDMA_SRC_INC_NONE | UDMA_ARB_2;

        //
        // Modify the DMA transfer size at it is units not bytes.
        //
        g_sInBuffers[g_ulRecording].ulSize >>= 2;
    }

    //
    // Configure the DMA settings for this channel.
    //
    uDMAChannelControlSet(ulChannel, ulDMASetting);

    //
    // Set the addresses and the DMA mode to ping-pong.
    //
    uDMAChannelTransferSet(ulChannel,
                           UDMA_MODE_PINGPONG,
                           (void *)(I2S0_BASE + I2S_O_RXFIFO),
                           (unsigned long *)g_sInBuffers[g_ulRecording].pulData,
                           g_sInBuffers[g_ulRecording].ulSize);

    //
    // Enable the RX DMA channel.  At this point the uDMA controller will
    // start servicing the request from the I2S, and the receive side should
    // start receiving data if any is available.
    //
    uDMAChannelEnable(UDMA_CHANNEL_I2S0RX);

    //
    // Indicate that there is still a pending transfer.
    //
    HWREGBITW(&g_ulDMAFlags, FLAG_RX_PENDING) = 1;

    //
    // Toggle which ping-pong DMA setting is in use.
    //
    g_ulRecording ^= 1;

    //
    // Enable the I2S controller to start receiving data.
    //
    I2SRxEnable(I2S0_BASE);

    //
    // Re-enable I2S interrupts.
    //
    IntEnable(INT_I2S0);

    return(0);
}

//*****************************************************************************
//
//! Sets the volume of the music/sound effect playback.
//!
//! \param ulPercent is the volume percentage, which must be between 0%
//! (silence) and 100% (full volume), inclusive.
//!
//! This function sets the volume of the sound output to a value between
//! silence (0%) and full volume (100%).
//!
//! \return None.
//
//*****************************************************************************
void
SoundVolumeSet(unsigned long ulPercent)
{
    TLV320AIC23BHeadPhoneVolumeSet(ulPercent);
}

//*****************************************************************************
//
//! Decreases the volume.
//!
//! \param ulPercent is the amount to decrease the volume, specified as a
//! percentage between 0% (silence) and 100% (full volume), inclusive.
//!
//! This function adjusts the audio output down by the specified percentage.
//! The adjusted volume will not go below 0% (silence).
//!
//! \return None.
//
//*****************************************************************************
void
SoundVolumeDown(unsigned long ulPercent)
{
    //
    // Do not let the volume go below 0%.
    //
    if(g_ucVolume < ulPercent)
    {
        //
        // Set the volume to the minimum.
        //
        g_ucVolume = 0;
    }
    else
    {
        //
        // Decrease the volume by the specified amount.
        //
        g_ucVolume -= ulPercent;
    }

    //
    // Set the new volume.
    //
    SoundVolumeSet(g_ucVolume);
}

//*****************************************************************************
//
//! Returns the current volume level.
//!
//! This function returns the current volume, specified as a percentage between
//! 0% (silence) and 100% (full volume), inclusive.
//!
//! \return Returns the current volume.
//
//*****************************************************************************
unsigned char
SoundVolumeGet(void)
{
    //
    // Return the current Audio Volume.
    //
    return(g_ucVolume);
}

//*****************************************************************************
//
//! Increases the volume.
//!
//! \param ulPercent is the amount to increase the volume, specified as a
//! percentage between 0% (silence) and 100% (full volume), inclusive.
//!
//! This function adjusts the audio output up by the specified percentage.  The
//! adjusted volume will not go above 100% (full volume).
//!
//! \return None.
//
//*****************************************************************************
void
SoundVolumeUp(unsigned long ulPercent)
{
    //
    // Increase the volume by the specified amount.
    //
    g_ucVolume += ulPercent;

    //
    // Do not let the volume go above 100%.
    //
    if(g_ucVolume > 100)
    {
        //
        // Set the volume to the maximum.
        //
        g_ucVolume = 100;
    }

    //
    // Set the new volume.
    //
    SoundVolumeSet(g_ucVolume);
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

⌨️ 快捷键说明

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