diff --git a/Demos/Device/ClassDriver/AudioInput/AudioInput.c b/Demos/Device/ClassDriver/AudioInput/AudioInput.c
index b197588a8efc988820ee105c19372aaeb293abed..58a3668e8403b1fcbc96b8256f7cd9303d68f97b 100644
--- a/Demos/Device/ClassDriver/AudioInput/AudioInput.c
+++ b/Demos/Device/ClassDriver/AudioInput/AudioInput.c
@@ -51,6 +51,9 @@ USB_ClassInfo_Audio_Device_t Microphone_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.
@@ -133,7 +136,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
 }
@@ -163,3 +166,72 @@ void EVENT_USB_Device_ControlRequest(void)
 	Audio_Device_ProcessControlRequest(&Microphone_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 == Microphone_Audio_Interface.Config.DataINEndpointNumber)
+	{
+		/* 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;
+}
diff --git a/Demos/Device/ClassDriver/AudioInput/Descriptors.c b/Demos/Device/ClassDriver/AudioInput/Descriptors.c
index bd31bdb0efd88b39c55ef0ec4e6785e20b2f0c7b..6fffd05d4dfdbee838a9235bfbc2bb631254d803 100644
--- a/Demos/Device/ClassDriver/AudioInput/Descriptors.c
+++ b/Demos/Device/ClassDriver/AudioInput/Descriptors.c
@@ -54,7 +54,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
 	.Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
 	.VendorID               = 0x03EB,
-	.ProductID              = 0x2047,
+	.ProductID              = 0x206B,
 	.ReleaseNumber          = VERSION_BCD(00.01),
 
 	.ManufacturerStrIndex   = 0x01,
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
 	.Audio_AudioFormat =
 		{
-			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+			                                     sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+			                             .Type = DTYPE_CSInterface},
 			.Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
 			.FormatType               = 0x01,
@@ -199,12 +201,17 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
 			.SubFrameSize             = 0x02,
 			.BitResolution            = 16,
-			.TotalDiscreteSampleRates = 1,
+
+			.TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t))
 		},
 	
 	.Audio_AudioFormatSampleRates =
 		{
-			AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)
+			AUDIO_SAMPLE_FREQ(8000),
+			AUDIO_SAMPLE_FREQ(11025),
+			AUDIO_SAMPLE_FREQ(22050),
+			AUDIO_SAMPLE_FREQ(44100),
+			AUDIO_SAMPLE_FREQ(48000),
 		},
 
 	.Audio_StreamEndpoint =
@@ -228,7 +235,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Spc_t), .Type = DTYPE_CSEndpoint},
 			.Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
 
-			.Attributes               = AUDIO_EP_ACCEPTS_SMALL_PACKETS,
+			.Attributes               = (AUDIO_EP_ACCEPTS_SMALL_PACKETS | AUDIO_EP_SAMPLE_FREQ_CONTROL),
 
 			.LockDelayUnits           = 0x00,
 			.LockDelay                = 0x0000
diff --git a/Demos/Device/ClassDriver/AudioInput/Descriptors.h b/Demos/Device/ClassDriver/AudioInput/Descriptors.h
index 82dbd517f033c97b8ca978d0b3d0c98fc4273639..05d1fee36ae7ae40ea986b2a2f98ba51b92a31a2 100644
--- a/Demos/Device/ClassDriver/AudioInput/Descriptors.h
+++ b/Demos/Device/ClassDriver/AudioInput/Descriptors.h
@@ -51,9 +51,6 @@
 		 */
 		#define AUDIO_STREAM_EPSIZE          ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
 
-		/** Sample frequency of the data being transmitted through the streaming endpoint. */
-		#define AUDIO_SAMPLE_FREQUENCY       48000
-
 	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
@@ -70,7 +67,7 @@
 			USB_Descriptor_Interface_t                Audio_StreamInterface_Alt1;
 			USB_Audio_Descriptor_Interface_AS_t       Audio_StreamInterface_SPC;
 			USB_Audio_Descriptor_Format_t             Audio_AudioFormat;
-			USB_Audio_SampleFreq_t                    Audio_AudioFormatSampleRates[1];
+			USB_Audio_SampleFreq_t                    Audio_AudioFormatSampleRates[5];
 			USB_Audio_Descriptor_StreamEndpoint_Std_t Audio_StreamEndpoint;
 			USB_Audio_Descriptor_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
 		} USB_Descriptor_Configuration_t;
diff --git a/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c b/Demos/Device/ClassDriver/AudioOutput/AudioOutput.c
index dbfd10b8bbca0d89468b10dd4a6444e9343a51e0..43267b2a7a2313a16e227d3f7986eac7b689275a 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;
+}
diff --git a/Demos/Device/ClassDriver/AudioOutput/Descriptors.c b/Demos/Device/ClassDriver/AudioOutput/Descriptors.c
index e46c3c023e2e9186163b3388f771671c901edcf8..5bb0e9f116efeaf94dad723cb8820c00825a2cea 100644
--- a/Demos/Device/ClassDriver/AudioOutput/Descriptors.c
+++ b/Demos/Device/ClassDriver/AudioOutput/Descriptors.c
@@ -54,7 +54,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
 	.Endpoint0Size          = FIXED_CONTROL_ENDPOINT_SIZE,
 
 	.VendorID               = 0x03EB,
-	.ProductID              = 0x2046,
+	.ProductID              = 0x206C,
 	.ReleaseNumber          = VERSION_BCD(00.01),
 
 	.ManufacturerStrIndex   = 0x01,
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
 	.Audio_AudioFormat =
 		{
-			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+			                                     sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+			                             .Type = DTYPE_CSInterface},
 			.Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
 			.FormatType               = 0x01,
@@ -200,12 +202,16 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.SubFrameSize             = 0x02,
 			.BitResolution            = 16,
 
-			.TotalDiscreteSampleRates = 1,
+			.TotalDiscreteSampleRates = (sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates) / sizeof(USB_Audio_SampleFreq_t)),
 		},
 	
 	.Audio_AudioFormatSampleRates =
 		{
-			AUDIO_SAMPLE_FREQ(AUDIO_SAMPLE_FREQUENCY)
+			AUDIO_SAMPLE_FREQ(8000),
+			AUDIO_SAMPLE_FREQ(11025),
+			AUDIO_SAMPLE_FREQ(22050),
+			AUDIO_SAMPLE_FREQ(44100),
+			AUDIO_SAMPLE_FREQ(48000),
 		},
 
 	.Audio_StreamEndpoint =
@@ -229,7 +235,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_StreamEndpoint_Spc_t), .Type = DTYPE_CSEndpoint},
 			.Subtype                  = AUDIO_DSUBTYPE_CSEndpoint_General,
 
-			.Attributes               = AUDIO_EP_ACCEPTS_SMALL_PACKETS,
+			.Attributes               = (AUDIO_EP_ACCEPTS_SMALL_PACKETS | AUDIO_EP_SAMPLE_FREQ_CONTROL),
 
 			.LockDelayUnits           = 0x00,
 			.LockDelay                = 0x0000
diff --git a/Demos/Device/ClassDriver/AudioOutput/Descriptors.h b/Demos/Device/ClassDriver/AudioOutput/Descriptors.h
index b4b8db6a4ad5f9ea2d05d474b239b3781e6550f4..ca5c87386685e9a5fb88b39c24bbde1cffb26c00 100644
--- a/Demos/Device/ClassDriver/AudioOutput/Descriptors.h
+++ b/Demos/Device/ClassDriver/AudioOutput/Descriptors.h
@@ -51,9 +51,6 @@
 		 */
 		#define AUDIO_STREAM_EPSIZE          ENDPOINT_MAX_SIZE(AUDIO_STREAM_EPNUM)
 
-		/** Sample frequency of the data being transmitted through the streaming endpoint. */
-		#define AUDIO_SAMPLE_FREQUENCY       48000
-
 	/* Type Defines: */
 		/** Type define for the device configuration descriptor structure. This must be defined in the
 		 *  application code, as the configuration descriptor contains several sub-descriptors which
@@ -70,7 +67,7 @@
 			USB_Descriptor_Interface_t                Audio_StreamInterface_Alt1;
 			USB_Audio_Descriptor_Interface_AS_t       Audio_StreamInterface_SPC;
 			USB_Audio_Descriptor_Format_t             Audio_AudioFormat;
-			USB_Audio_SampleFreq_t                    Audio_AudioFormatSampleRates[1];
+			USB_Audio_SampleFreq_t                    Audio_AudioFormatSampleRates[5];
 			USB_Audio_Descriptor_StreamEndpoint_Std_t Audio_StreamEndpoint;
 			USB_Audio_Descriptor_StreamEndpoint_Spc_t Audio_StreamEndpoint_SPC;
 		} USB_Descriptor_Configuration_t;
diff --git a/Demos/Device/LowLevel/AudioInput/Descriptors.c b/Demos/Device/LowLevel/AudioInput/Descriptors.c
index 6c8323c56d3185e5260f285457cfd8622a76c42d..8a63d77361cb428146b650142fed6668f4a71bc1 100644
--- a/Demos/Device/LowLevel/AudioInput/Descriptors.c
+++ b/Demos/Device/LowLevel/AudioInput/Descriptors.c
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
 	.Audio_AudioFormat =
 		{
-			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+			                                     sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+			                             .Type = DTYPE_CSInterface},
 			.Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
 			.FormatType               = 0x01,
diff --git a/Demos/Device/LowLevel/AudioOutput/Descriptors.c b/Demos/Device/LowLevel/AudioOutput/Descriptors.c
index 9c57a421f129057fbd2b4b2defb441432fc14bc6..59e3af1dd6e8d93c0a2d30040b48dc8f798a3ebf 100644
--- a/Demos/Device/LowLevel/AudioOutput/Descriptors.c
+++ b/Demos/Device/LowLevel/AudioOutput/Descriptors.c
@@ -191,7 +191,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 
 	.Audio_AudioFormat =
 		{
-			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t), .Type = DTYPE_CSInterface},
+			.Header                   = {.Size = sizeof(USB_Audio_Descriptor_Format_t) +
+			                                     sizeof(ConfigurationDescriptor.Audio_AudioFormatSampleRates),
+			                             .Type = DTYPE_CSInterface},
 			.Subtype                  = AUDIO_DSUBTYPE_CSInterface_FormatType,
 
 			.FormatType               = 0x01,
diff --git a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
index 9b6125e6c6baa4baea42e202e47fe07587640214..38af3a7c53f0fa2d19a41e82838aa8070921e3f8 100644
--- a/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/ClassDriver/KeyboardHost/KeyboardHost.c
@@ -137,9 +137,13 @@ int main(void)
 							PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
 						}
 						else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
-						         (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+						         (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
 						{
-							PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+							PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+						}
+						else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+						{
+							PressedKey = '0';
 						}
 						else if (KeyCode == HID_KEYBOARD_SC_SPACE)
 						{
diff --git a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
index abb391ceef2ed71f9926bccec664c25ab0a858e9..d7df58f07f3bc2c102583ac997763f62ddd8eea6 100644
--- a/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/ClassDriver/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -157,9 +157,13 @@ int main(void)
 									PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
 								}
 								else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
-										 (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+										 (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
 								{
-									PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+									PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+								}
+								else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+								{
+									PressedKey = '0';
 								}
 								else if (KeyCode == HID_KEYBOARD_SC_SPACE)
 								{
diff --git a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
index 84e6145fb1be67ef4eb2dd4eb86809d5127bbd32..6df052d72040633cd6b289675f4ece320b43016f 100644
--- a/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
+++ b/Demos/Host/LowLevel/KeyboardHost/KeyboardHost.c
@@ -173,9 +173,13 @@ void ReadNextReport(void)
 				PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
 			}
 			else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
-					 (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+					 (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
 			{
-				PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+				PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+			}
+			else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+			{
+				PressedKey = '0';
 			}
 			else if (KeyCode == HID_KEYBOARD_SC_SPACE)
 			{
diff --git a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
index 512cc1ae21132372a8b621fee0a91104b37e9882..6ef7a96776f7f4e3df1105108347baf6417b4ba8 100644
--- a/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
+++ b/Demos/Host/LowLevel/KeyboardHostWithParser/KeyboardHostWithParser.c
@@ -287,9 +287,13 @@ void ProcessKeyboardReport(uint8_t* KeyboardReport)
 					PressedKey = (KeyCode - HID_KEYBOARD_SC_A) + 'A';
 				}
 				else if ((KeyCode >= HID_KEYBOARD_SC_1_AND_EXCLAMATION) &
-						 (KeyCode <= HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
+						 (KeyCode  < HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS))
 				{
-					PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '0';
+					PressedKey = (KeyCode - HID_KEYBOARD_SC_1_AND_EXCLAMATION) + '1';
+				}
+				else if (KeyCode == HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS)
+				{
+					PressedKey = '0';						
 				}
 				else if (KeyCode == HID_KEYBOARD_SC_SPACE)
 				{
diff --git a/LUFA/Drivers/USB/Class/Common/Audio.h b/LUFA/Drivers/USB/Class/Common/Audio.h
index cc6e8e52d9dfa2ce9ec2c1ff7148ec7409c4c341..fd9a3a92ba88448d43e4fb98727bbf3564412110 100644
--- a/LUFA/Drivers/USB/Class/Common/Audio.h
+++ b/LUFA/Drivers/USB/Class/Common/Audio.h
@@ -197,7 +197,7 @@
 		 *
 		 *  \param[in] freq  Required audio sampling frequency in HZ
 		 */
-		#define AUDIO_SAMPLE_FREQ(freq)           {.Byte1 = ((uint32_t)freq & 0x0000FF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)}
+		#define AUDIO_SAMPLE_FREQ(freq)           {.Byte1 = ((uint32_t)freq & 0xFF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)}
 
 		/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
 		 *  accepts only filled endpoint packets of audio samples.
@@ -208,6 +208,16 @@
 		 *  will accept partially filled endpoint packets of audio samples.
 		 */
 		#define AUDIO_EP_ACCEPTS_SMALL_PACKETS    (0 << 7)
+
+		/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
+		 *  allows for sampling frequency adjustments to be made via control requests directed at the endpoint.
+		 */
+		#define AUDIO_EP_SAMPLE_FREQ_CONTROL      (1 << 0)
+
+		/** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint
+		 *  allows for pitch adjustments to be made via control requests directed at the endpoint.
+		 */
+		#define AUDIO_EP_PITCH_CONTROL            (1 << 1)
 		
 	/* Enums: */
 		/** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio
@@ -277,6 +287,15 @@
 			AUDIO_REQ_GetMemory     = 0x85, /**< Audio class-specific request to get the memory value of a parameter within the device. */
 			AUDIO_REQ_GetStatus     = 0xFF, /**< Audio class-specific request to get the device status. */
 		};
+		
+		/** Enum for Audio class specific Endpoint control modifiers which can be set and retrieved by a USB host, if the corresponding
+		 *  endpoint control is indicated to be supported in the Endpoint's Audio-class specific endpoint descriptor.
+		 */
+		enum Audio_EndpointControls_t
+		{
+			AUDIO_EPCONTROL_SamplingFreq = 0x01, /**< Sampling frequency adjustment of the endpoint. */
+			AUDIO_EPCONTROL_Pitch        = 0x02, /**< Pitch adjustment of the endpoint. */
+		};
 
 	/* Type Defines: */
 		/** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions).
@@ -538,18 +557,6 @@
 			uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */
 		} ATTR_PACKED USB_Audio_StdDescriptor_Interface_AS_t;
 
-		/** \brief 24-Bit Audio Frequency Structure.
-		 *
-		 *  Type define for a 24bit audio sample frequency structure. GCC does not contain a built in 24bit datatype,
-		 *  this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro.
-		 */
-		typedef struct
-		{
-			uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */
-			uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */
-			uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */
-		} ATTR_PACKED USB_Audio_SampleFreq_t;
-
 		/** \brief Audio class-specific Format Descriptor (LUFA naming conventions).
 		 *
 		 *  Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
@@ -581,6 +588,18 @@
 			                                                   */
 		} ATTR_PACKED USB_Audio_Descriptor_Format_t;
 
+		/** \brief 24-Bit Audio Frequency Structure.
+		 *
+		 *  Type define for a 24bit audio sample frequency structure. As GCC does not contain a built in 24-bit datatype,
+		 *  this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro.
+		 */
+		typedef struct
+		{
+			uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */
+			uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */
+			uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */
+		} ATTR_PACKED USB_Audio_SampleFreq_t;
+
 		/** \brief Audio class-specific Format Descriptor (USB-IF naming conventions).
 		 *
 		 *  Type define for an Audio class-specific audio format descriptor. This is used to give the host full details
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.c b/LUFA/Drivers/USB/Class/Device/Audio.c
index 8c5c9960d5a62fa4bb02f50472f83fc732860e00..f183fdedd2796b40bf6f03038740082f02babe4f 100644
--- a/LUFA/Drivers/USB/Class/Device/Audio.c
+++ b/LUFA/Drivers/USB/Class/Device/Audio.c
@@ -45,6 +45,22 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi
 	if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
 	  return;
 
+	if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE)
+	{
+		if (USB_ControlRequest.wIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)
+		  return;
+	}
+	else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT)
+	{
+		if (!((AudioInterfaceInfo->Config.DataINEndpointNumber &&
+		       (USB_ControlRequest.wIndex == AudioInterfaceInfo->Config.DataINEndpointNumber)) ||
+		      (AudioInterfaceInfo->Config.DataOUTEndpointNumber &&
+		       (USB_ControlRequest.wIndex == AudioInterfaceInfo->Config.DataOUTEndpointNumber))))
+		{
+			return;
+		}
+	}	
+
 	switch (USB_ControlRequest.bRequest)
 	{
 		case REQ_SetInterface:
@@ -64,6 +80,53 @@ void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const Audi
 				Endpoint_ClearSETUP();
 				Endpoint_ClearStatusStage();
 			}
+
+			break;
+		case AUDIO_REQ_SetCurrent:
+		case AUDIO_REQ_SetMinimum:
+		case AUDIO_REQ_SetMaximum:
+		case AUDIO_REQ_SetResolution:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))
+			{
+				uint8_t EndpointProperty = USB_ControlRequest.bRequest;
+				uint8_t EndpointIndex    = (uint8_t)USB_ControlRequest.wIndex;
+				uint8_t EndpointControl  = (USB_ControlRequest.wValue >> 8);
+			
+				if (CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, NULL, NULL))
+				{
+					uint16_t ValueLength = USB_ControlRequest.wLength;
+					uint8_t  Value[ValueLength];
+					
+					Endpoint_ClearSETUP();
+					Endpoint_Read_Control_Stream_LE(Value, ValueLength);
+					Endpoint_ClearIN();					
+
+					CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, &ValueLength, Value);
+				}				
+			}
+
+			break;
+		case AUDIO_REQ_GetCurrent:
+		case AUDIO_REQ_GetMinimum:
+		case AUDIO_REQ_GetMaximum:
+		case AUDIO_REQ_GetResolution:
+			if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))
+			{
+				uint8_t  EndpointProperty = USB_ControlRequest.bRequest;
+				uint8_t  EndpointIndex    = (uint8_t)USB_ControlRequest.wIndex;
+				uint8_t  EndpointControl  = (USB_ControlRequest.wValue >> 8);
+				uint16_t ValueLength      = USB_ControlRequest.wLength;
+				uint8_t  Value[ValueLength];
+
+				if (CALLBACK_Audio_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointIndex, EndpointControl, &ValueLength, Value))
+				{
+					Endpoint_ClearSETUP();
+					Endpoint_Write_Control_Stream_LE(Value, ValueLength);
+					Endpoint_ClearOUT();					
+				}
+			}
+
+			break;
 	}
 }
 
diff --git a/LUFA/Drivers/USB/Class/Device/Audio.h b/LUFA/Drivers/USB/Class/Device/Audio.h
index a50bd97cc431802777b0ad299a9dea7457d6de24..a09076341b693981e1138087c4216b13f9191d7d 100644
--- a/LUFA/Drivers/USB/Class/Device/Audio.h
+++ b/LUFA/Drivers/USB/Class/Device/Audio.h
@@ -130,6 +130,35 @@
 			 *  \param[in,out] AudioInterfaceInfo  Pointer to a structure containing an Audio Class configuration and state.
 			 */
 			void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1);
+			
+			/** 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 \ref 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 \ref 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);
 
 		/* Inline Functions: */
 			/** General management task for a given Audio class interface, required for the correct operation of the interface. This should
diff --git a/LUFA/Drivers/USB/Core/StdRequestType.h b/LUFA/Drivers/USB/Core/StdRequestType.h
index e3e30f95f56d1502edb73a04b5f47c87aab35f07..83f59afc62dda7261dd026e48c164b3bd13fd270 100644
--- a/LUFA/Drivers/USB/Core/StdRequestType.h
+++ b/LUFA/Drivers/USB/Core/StdRequestType.h
@@ -74,8 +74,8 @@
 			 */
 			#define CONTROL_REQTYPE_TYPE       0x60
 
-			/** Mask for the request type parameter, to indicate the recipient of the request (Standard, Class
-			 *  or Vendor Specific). The result of this mask should then be compared to the request recipient
+			/** Mask for the request type parameter, to indicate the recipient of the request (Device, Interface
+			 *  Endpoint or Other). The result of this mask should then be compared to the request recipient
 			 *  masks.
 			 *
 			 *  \see REQREC_* macros for masks indicating the request recipient.
diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt
index 27a25e75f1871b2d4327eaa520256ebeaf0cf64f..f0683039b27aa624d57ba4967f03cd413725ad73 100644
--- a/LUFA/ManPages/ChangeLog.txt
+++ b/LUFA/ManPages/ChangeLog.txt
@@ -13,6 +13,7 @@
   *     tokens as an alternative to tokens defined in the project makefile
   *   - Added new USB_Host_SetInterfaceAltSetting() convenience function for the selection of an interface's alternative setting
   *   - Added Audio class control request definitions
+  *   - Added new callback to the Audio Class driver to allow for endpoint control manipulations such as data sample rates
   *  - Library Applications:
   *   - Added RNDIS device mode to the Webserver project
   *   - Added new MediaControl project
@@ -27,13 +28,14 @@
   *     the supported audio sampling rates, to allow for multiple audio interfaces with different numbers of supported rates and/or
   *     continuous sample rates
   *  - Library Applications:
-  *   - <i>None</i>
+  *   - Modified the Class Driver AudioInput and AudioOutput demos to support multiple sample rates
   *
   *  <b>Fixed:</b>
   *  - Core:
   *   - <i>None</i>
   *  - Library Applications:
   *   - Fixed incorrect signature in the CDC and DFU class bootloaders for the ATMEGA8U2
+  *   - Fixed KeyboardHost and KeyboardHostWithParser demos displaying incorrect values when numerical keys were pressed
   *
   *  \section Sec_ChangeLog110528 Version 110528
   *  <b>New:</b>
diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt
index 4016bf52b6734cc850436795c5c20d2f5094af7d..75dd9e72921c66df83180fbbc41ae4f0665bfc0d 100644
--- a/LUFA/ManPages/FutureChanges.txt
+++ b/LUFA/ManPages/FutureChanges.txt
@@ -28,10 +28,11 @@
   *      -# Write LUFA tutorials
   *  - Demos/Projects
   *      -# Device/Host USB bridge
-  *      -# Alternative (USB-IF endorsed) USB-CDC Ethernet Class
   *      -# Finish incomplete demos and projects
   *      -# Add class driver support for Audio Host class
   *      -# Add class driver support for Test and Measurement class
+  *      -# Add class driver support for EEM class
+  *      -# Add class driver support for ECM class
   *      -# Fix up Audio class support - add support for mixers, etc., add support for GET/SET commands
   *  - Ports
   *      -# Complete AVR32 port for existing devices, add UC3C support
diff --git a/LUFA/ManPages/VIDAndPIDValues.txt b/LUFA/ManPages/VIDAndPIDValues.txt
index 17d9e1782d3b17575077f0cfe40e9bd66986a689..d05334d9a05388d070fe96d2326efebb505cc106 100644
--- a/LUFA/ManPages/VIDAndPIDValues.txt
+++ b/LUFA/ManPages/VIDAndPIDValues.txt
@@ -361,7 +361,7 @@
  *     0x206B
  *    </td>
  *    <td>
- *     <i>Currently Unallocated</i>
+ *     Class Driver Audio Input Demo (Multiple Sample Rates)
  *    </td>
  *   </tr>
  *
@@ -373,7 +373,7 @@
  *     0x206C
  *    </td>
  *    <td>
- *     <i>Currently Unallocated</i>
+ *     Class Driver Audio Output Demo (Multiple Sample Rates)
  *    </td>
  *   </tr>
  *
diff --git a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
index 42e436cdf3081f94383790d343b47a127204de00..e9e92f99a0950d17acb38d80a7b03a07fb6c93c3 100644
--- a/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
+++ b/Projects/AVRISP-MKII/Lib/ISP/ISPProtocol.c
@@ -236,12 +236,12 @@ void ISPProtocol_ProgramMemory(uint8_t V2Command)
 		
 		/* EEPROM just increments the address each byte, flash needs to increment on each word and
 		 * also check to ensure that a LOAD EXTENDED ADDRESS command is issued each time the extended
-		 * address boundary has been crossed */
+		 * address boundary has been crossed during FLASH memory programming */
 		if ((CurrentByte & 0x01) || (V2Command == CMD_PROGRAM_EEPROM_ISP))
 		{
 			CurrentAddress++;
 
-			if ((V2Command != CMD_PROGRAM_EEPROM_ISP) && !(CurrentAddress & 0xFFFF))
+			if ((V2Command == CMD_PROGRAM_FLASH_ISP) && !(CurrentAddress & 0xFFFF))
 			  MustLoadExtendedAddress = true;
 		}
 	}