aboutsummaryrefslogtreecommitdiffstats
path: root/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
diff options
context:
space:
mode:
Diffstat (limited to 'Demos/Device/ClassDriver/AudioOutput/AudioOutput.c')
-rw-r--r--Demos/Device/ClassDriver/AudioOutput/AudioOutput.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c b/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
index dbfd10b8b..43267b2a7 100644
--- a/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
+++ b/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
@@ -51,6 +51,9 @@ USB_ClassInfo_Audio_Device_t Speaker_Audio_Interface =
},
};
+/** Current audio sampling frequency of the streaming audio endpoint. */
+uint32_t CurrentAudioSampleFrequency = 48000;
+
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.
@@ -135,7 +138,7 @@ void EVENT_USB_Device_Connect(void)
/* Sample reload timer initialization */
TIMSK0 = (1 << OCIE0A);
- OCR0A = ((F_CPU / 8 / AUDIO_SAMPLE_FREQUENCY) - 1);
+ OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);
TCCR0A = (1 << WGM01); // CTC mode
TCCR0B = (1 << CS01); // Fcpu/8 speed
@@ -199,3 +202,72 @@ void EVENT_USB_Device_ControlRequest(void)
Audio_Device_ProcessControlRequest(&Speaker_Audio_Interface);
}
+/** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented
+ * in the user application to handle property manipulations on streaming audio endpoints.
+ *
+ * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for
+ * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations
+ * to indicate the size of the retreived data.
+ *
+ * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value
+ * of the \c DataLength parameter.
+ *
+ * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state.
+ * \param[in] EndpointProperty Property of the endpoint to get or set, a value from Audio_ClassRequests_t.
+ * \param[in] EndpointIndex Index of the streaming endpoint whose property is being referenced.
+ * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from Audio_EndpointControls_t.
+ * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum
+ * length of the retrieved data. When NULL, the function should return whether the given property
+ * and parameter is valid for the requested endpoint without reading or modifying the Data buffer.
+ * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where
+ * the retrieved data is to be stored for GET operations.
+ *
+ * \return Boolean true if the property get/set was successful, false otherwise
+ */
+bool CALLBACK_Audio_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo,
+ const uint8_t EndpointProperty,
+ const uint8_t EndpointIndex,
+ const uint8_t EndpointControl,
+ uint16_t* const DataLength,
+ uint8_t* Data)
+{
+ /* Check the requested endpoint to see if a supported endpoint is being manipulated */
+ if (EndpointIndex == Speaker_Audio_Interface.Config.DataOUTEndpointNumber)
+ {
+ /* Check the requested control to see if a supported control is being manipulated */
+ if (EndpointControl == AUDIO_EPCONTROL_SamplingFreq)
+ {
+ /* Check the requested property to see if a supported property is being manipulated */
+ if (EndpointProperty == AUDIO_REQ_SetCurrent)
+ {
+ /* Check if we are just testing for a valid property, or actually adjusting it */
+ if (DataLength != NULL)
+ {
+ /* Set the new sampling frequency to the value given by the host */
+ CurrentAudioSampleFrequency = (((uint32_t)Data[2] << 16) | ((uint32_t)Data[1] << 8) | (uint32_t)Data[0]);
+
+ /* Adjust sample reload timer to the new frequency */
+ OCR0A = ((F_CPU / 8 / CurrentAudioSampleFrequency) - 1);
+ }
+
+ return true;
+ }
+ else if (EndpointProperty == AUDIO_REQ_GetCurrent)
+ {
+ /* Check if we are just testing for a valid property, or actually reading it */
+ if (DataLength != NULL)
+ {
+ *DataLength = 3;
+
+ Data[2] = (CurrentAudioSampleFrequency >> 16);
+ Data[1] = (CurrentAudioSampleFrequency >> 8);
+ Data[0] = (CurrentAudioSampleFrequency & 0xFF);
+ }
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+}