📄 class-d.c
字号:
//
g_ulClassDLength--;
}
//
// This should never be reached, where the Class-D audio flags are set
// to something that is not recognized. In this case, clear the
// Class-D audio flags so that playback stops.
//
else
{
g_ulClassDFlags = 0;
}
}
}
//*****************************************************************************
//
//! Initializes the Class-D audio driver.
//!
//! \param ulPWMClock is the rate of the clock supplied to the PWM module.
//!
//! This function initializes the Class-D audio driver, preparing it to output
//! audio data to the speaker. The startup ramp of the speaker is started but
//! will not complete until after this function returns (use ClassDBusy() to
//! determine when it has completed).
//!
//! The PWM module clock should be as high as possible; lower clock rates
//! reduces the quality of the produced audio. For the best quality audio, the
//! PWM module should be clocked at 50 MHz.
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \note In order for the Class-D audio driver to function properly, the
//! Class-D audio driver interrupt handler (ClassDPWMHandler()) must be
//! installed into the vector table for the PWM1 interrupt.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDInit(unsigned long ulPWMClock)
{
//
// Enable the peripherals used by the Class-D audio driver.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
//
// Set GPIO H0 and H1 as PWM pins. They are used to output the PWM2 and
// PWM3 signals.
//
GPIOPinTypePWM(GPIO_PORTH_BASE, GPIO_PIN_0 | GPIO_PIN_1);
GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_0 | GPIO_PIN_1,
GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD);
//
// Compute the PWM period based on the system clock.
//
g_ulClassDPeriod = ulPWMClock / 64000;
//
// Set the PWM period to 64 KHz.
//
PWMGenConfigure(PWM_BASE, PWM_GEN_1,
PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, g_ulClassDPeriod);
//
// Start the PWM outputs with one clock long pulses.
//
PWMPulseWidthSet(PWM_BASE, PWM_OUT_2, 1);
PWMDeadBandEnable(PWM_BASE, PWM_GEN_1, 0, g_ulClassDPeriod - 2);
//
// Enable the PWM2 and PWM3 output signals.
//
PWMOutputState(PWM_BASE, PWM_OUT_2_BIT | PWM_OUT_3_BIT, true);
//
// Enable the PWM generator.
//
PWMGenEnable(PWM_BASE, PWM_GEN_1);
//
// Set the length of the startup processing.
//
g_ulClassDLength = g_ulClassDPeriod - 2;
//
// Clear the Class-D audio flags and enable the startup processing.
//
g_ulClassDFlags = 0;
HWREGBITW(&g_ulClassDFlags, CLASSD_FLAG_STARTUP) = 1;
//
// Enable the PWM generator interrupt.
//
PWMGenIntTrigEnable(PWM_BASE, PWM_GEN_1, PWM_INT_CNT_ZERO);
IntEnable(INT_PWM1);
}
//*****************************************************************************
//
//! Plays a buffer of 8 KHz, 8-bit, unsigned PCM data.
//!
//! \param pucBuffer is a pointer to the buffer containing 8-bit, unsigned PCM
//! data.
//! \param ulLength is the number of bytes in the buffer.
//!
//! This function starts playback of a stream of 8-bit, unsigned PCM data.
//! Since the data is unsigned, a value of 128 represents the mid-point of the
//! speaker's travel (that is, corresponds to no DC offset).
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDPlayPCM(const unsigned char *pucBuffer, unsigned long ulLength)
{
//
// Return without playing the buffer if something is already playing.
//
if(g_ulClassDFlags)
{
return;
}
//
// Save a pointer to the buffer.
//
g_pucClassDBuffer = pucBuffer;
g_ulClassDLength = ulLength;
//
// Initialize the sample buffer with silence.
//
g_pusClassDSamples[0] = 32768;
g_pusClassDSamples[1] = 32768;
//
// Reset the audio step to zero.
//
g_ulClassDStep = 0;
//
// Start playback of a PCM stream.
//
HWREGBITW(&g_ulClassDFlags, CLASSD_FLAG_PCM) = 1;
}
//*****************************************************************************
//
//! Plays a buffer of 8 KHz IMA ADPCM data.
//!
//! \param pucBuffer is a pointer to the buffer containing the IMA ADPCM
//! encoded data.
//! \param ulLength is the number of bytes in the buffer.
//!
//! This function starts playback of a stream of IMA ADPCM encoded data. The
//! data is decoded as needed and therefore does not require a large buffer in
//! SRAM. This provides a 2:1 compression ratio relative to raw 8-bit PCM with
//! little to no loss in audio quality.
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDPlayADPCM(const unsigned char *pucBuffer, unsigned long ulLength)
{
//
// Return without playing the buffer if something is already playing.
//
if(g_ulClassDFlags)
{
return;
}
//
// Save a pointer to the buffer.
//
g_pucClassDBuffer = pucBuffer;
g_ulClassDLength = ulLength;
//
// Initialize the sample buffer with silence.
//
g_pusClassDSamples[0] = 32768;
g_pusClassDSamples[1] = 32768;
//
// Reset the audio step to zero.
//
g_ulClassDStep = 0;
//
// Initialize the ADPCM step index.
//
g_lClassDADPCMStepIndex = 0;
//
// Start playback of an ADPCM stream.
//
HWREGBITW(&g_ulClassDFlags, CLASSD_FLAG_ADPCM) = 1;
}
//*****************************************************************************
//
//! Determines if the Class-D audio driver is busy.
//!
//! This function determines if the Class-D audio driver is busy, either
//! performing the startup ramp for the speaker or playing a stream.
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return Returns \b true if the Class-D audio driver is busy and \b false
//! otherwise.
//
//*****************************************************************************
tBoolean
ClassDBusy(void)
{
//
// The Class-D audio driver is busy if the Class-D audio flags are not
// zero.
//
return(g_ulClassDFlags != 0);
}
//*****************************************************************************
//
//! Stops playback of the current audio stream.
//!
//! This function immediately stops playback of the current audio stream. As
//! a result, the output is changed directly to the mid-point, possibly
//! resulting in a pop or click.
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDStop(void)
{
//
// Immediately stop all playback.
//
g_ulClassDFlags = 0;
}
//*****************************************************************************
//
//! Sets the volume of the audio playback.
//!
//! \param ulVolume is the volume of the audio playback, specified as a value
//! between 0 (for silence) and 256 (for full volume).
//!
//! This function sets the volume of the audio playback. Setting the volume to
//! 0 will mute the output, while setting the volume to 256 will play the audio
//! stream without any volume adjustment (that is, full volume).
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDVolumeSet(unsigned long ulVolume)
{
//
// Set the volume mulitplier to be used.
//
g_lClassDVolume = ulVolume;
}
//*****************************************************************************
//
//! Increases the volume of the audio playback.
//!
//! \param ulVolume is the amount by which to increase the volume of the audio
//! playback, specified as a value between 0 (for no adjustment) and 256
//! maximum adjustment).
//!
//! This function increases the volume of the audio playback relative to the
//! current volume.
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDVolumeUp(unsigned long ulVolume)
{
//
// Compute the new volume, limiting to the maximum if required.
//
ulVolume = g_lClassDVolume + ulVolume;
if(ulVolume > 256)
{
ulVolume = 256;
}
//
// Set the new volume.
//
g_lClassDVolume = ulVolume;
}
//*****************************************************************************
//
//! Decreases the volume of the audio playback.
//!
//! \param ulVolume is the amount by which to decrease the volume of the audio
//! playback, specified as a value between 0 (for no adjustment) and 256
//! maximum adjustment).
//!
//! This function decreases the volume of the audio playback relative to the
//! current volume.
//!
//! This function is contained in <tt>class-d.c</tt>, with <tt>class-d.h</tt>
//! containing the API definition for use by applications.
//!
//! \return None.
//
//*****************************************************************************
void
ClassDVolumeDown(unsigned long ulVolume)
{
//
// Compute the new volume, limiting to the minimum if required.
//
ulVolume = g_lClassDVolume - ulVolume;
if(ulVolume & 0x80000000)
{
ulVolume = 0;
}
//
// Set the new volume.
//
g_lClassDVolume = ulVolume;
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -