📄 sound.c
字号:
//! 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 + -