diff --git a/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs b/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs
index 62ce37ea3f..68447f2146 100644
--- a/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs
+++ b/Source/Meadow.Foundation.Core/Speakers/PiezoSpeaker.cs
@@ -11,6 +11,12 @@ namespace Meadow.Foundation.Audio
///
public class PiezoSpeaker : IToneGenerator
{
+ ///
+ /// The volume from 0-1
+ /// Defined by the PWM port duty cycle from 0 to 0.5
+ ///
+ public float Volume { get; protected set; } = 1.0f;
+
///
/// Gets the port that is driving the Piezo Speaker
///
@@ -72,7 +78,7 @@ public async Task PlayTone(Frequency frequency, TimeSpan duration)
isPlaying = true;
Port.Frequency = frequency;
- Port.DutyCycle = 0.5f;
+ Port.DutyCycle = Volume / 2f;
if (duration.TotalMilliseconds > 0)
{
@@ -91,5 +97,19 @@ public void StopTone()
{
Port.DutyCycle = 0f;
}
+
+ ///
+ /// Set the playback volume
+ ///
+ /// The volume from 0 (off) to 1 (max volume)
+ public void SetVolume(float volume)
+ {
+ Volume = Math.Clamp(volume, 0, 1);
+
+ if(isPlaying)
+ {
+ Port.DutyCycle = Volume / 2f;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Audio.MicroAudio.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Audio.MicroAudio.csproj
new file mode 100644
index 0000000000..148d246885
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Audio.MicroAudio.csproj
@@ -0,0 +1,22 @@
+
+
+ true
+ Wilderness Labs, Inc
+ netstandard2.1
+ Library
+ MicroAudio
+ Wilderness Labs, Inc
+ http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/
+ Meadow.Foundation.Audio.MicroAudio
+ icon.png
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Meadow,Meadow.Foundation,Audio,Songs,Tone,Tones,Music,Sound,Effects
+ 0.1.0
+ true
+ Lightweight single-voice sound effect and music player designed for embedded applications
+
+
+
+
+
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/GameSounds.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/GameSounds.cs
new file mode 100644
index 0000000000..3c9dbc211b
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/GameSounds.cs
@@ -0,0 +1,325 @@
+using Meadow.Peripherals.Speakers;
+using Meadow.Units;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A class for playing game sounds using an IToneGenerator
+ ///
+ public class GameSounds
+ {
+ private readonly IToneGenerator toneGenerator;
+ private readonly int defaultDuration = 100;
+ private readonly int defaultPause = 50;
+
+ ///
+ /// Initializes a new instance of the class
+ ///
+ /// The object to use for audio playback
+ public GameSounds(IToneGenerator toneGenerator)
+ {
+ this.toneGenerator = toneGenerator;
+ }
+
+ ///
+ /// Plays the specified sound effect
+ ///
+ /// The sound effect to play
+ public Task PlayEffect(GameSoundEffect effect)
+ {
+ return effect switch
+ {
+ GameSoundEffect.Activation => PlayActivation(),
+ GameSoundEffect.Blip => PlayBlip(),
+ GameSoundEffect.BossBattle => PlayBossBattle(),
+ GameSoundEffect.ButtonPress => PlayButtonPress(),
+ GameSoundEffect.Coin => PlayCoin(),
+ GameSoundEffect.Collectible => PlayCollectible(),
+ GameSoundEffect.Countdown => PlayCountdown(),
+ GameSoundEffect.EnemyDeath => PlayEnemyDeath(),
+ GameSoundEffect.Explosion => PlayExplosion(),
+ GameSoundEffect.Footstep => PlayFootstep(),
+ GameSoundEffect.GameOver => PlayGameOver(),
+ GameSoundEffect.Health => PlayHealth(),
+ GameSoundEffect.Hit => PlayHit(),
+ GameSoundEffect.Jump => PlayJump(),
+ GameSoundEffect.Laser => PlayLaser(),
+ GameSoundEffect.LevelComplete => PlayLevelComplete(),
+ GameSoundEffect.MenuNavigate => PlayMenuNavigate(),
+ GameSoundEffect.PowerDown => PlayPowerDown(),
+ GameSoundEffect.PowerUp => PlayPowerUp(),
+ GameSoundEffect.SecretFound => PlaySecretFound(),
+ GameSoundEffect.Teleport => PlayTeleport(),
+ GameSoundEffect.Victory => PlayVictory(),
+ GameSoundEffect.Warning => PlayWarning(),
+ GameSoundEffect.WeaponSwitch => PlayWeaponSwitch(),
+ _ => throw new ArgumentException("Invalid game sound effect specified.", nameof(effect)),
+ };
+ }
+
+
+ ///
+ /// Plays a simple blip sound effect
+ ///
+ private async Task PlayBlip()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a power-up or item pick-up sound effect
+ ///
+ private async Task PlayPowerUp()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1760), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a coin or currency collection sound effect
+ ///
+ private async Task PlayCoin()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a jump or hop sound effect
+ ///
+ private async Task PlayJump()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a hit or damage sound effect
+ ///
+ private async Task PlayHit()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a laser or projectile firing sound effect
+ ///
+ private async Task PlayLaser()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1760), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays an explosion or destruction sound effect
+ ///
+ private async Task PlayExplosion()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(110), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(55), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a game over or failure sound effect
+ ///
+ private async Task PlayGameOver()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(110), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(55), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a victory or success sound effect
+ ///
+ private async Task PlayVictory()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(659), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(1175), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a countdown or timer sound effect
+ ///
+ private async Task PlayCountdown()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(698.46), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(587.33), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a power-down sound effect
+ ///
+ private async Task PlayPowerDown()
+ {
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(349.23), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a button press sound effect
+ ///
+ private async Task PlayButtonPress()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a menu navigation sound effect
+ ///
+ private async Task PlayMenuNavigate()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a collectible item sound effect
+ ///
+ private async Task PlayCollectible()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ ///
+ /// Plays a boss battle theme.
+ ///
+ private async Task PlayBossBattle()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(554.37), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(659.25), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a secret found sound effect
+ ///
+ private async Task PlaySecretFound()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1174.66), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1396.91), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a level complete sound effect
+ ///
+ private async Task PlayLevelComplete()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(1396.91), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(1760), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(2217.46), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a weapon switch sound effect
+ ///
+ private async Task PlayWeaponSwitch()
+ {
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(349.23), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a warning or alarm sound effect
+ ///
+ private async Task PlayWarning()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a teleport or warp sound effect
+ ///
+ private async Task PlayTeleport()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(659.25), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(523.25), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a health pickup or healing sound effect
+ ///
+ private async Task PlayHealth()
+ {
+ await toneGenerator.PlayTone(new Frequency(622.25), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(659.25), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(698.46), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a footstep or movement sound effect
+ ///
+ private async Task PlayFootstep()
+ {
+ await toneGenerator.PlayTone(new Frequency(196), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+
+ ///
+ /// Plays an item activation or use sound effect
+ ///
+ private async Task PlayActivation()
+ {
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays an enemy death or defeat sound effect
+ ///
+ private async Task PlayEnemyDeath()
+ {
+ await toneGenerator.PlayTone(new Frequency(1568), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1244.51), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1046.5), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(783.99), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a splash sound effect
+ ///
+ public async Task PlaySplash()
+ {
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(440), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(220), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.Enums.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.Enums.cs
new file mode 100644
index 0000000000..822cc76334
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.Enums.cs
@@ -0,0 +1,294 @@
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// Represents a musical note
+ ///
+ public enum Pitch : int
+ {
+ ///
+ /// The C note
+ ///
+ C = 0,
+ ///
+ /// The C sharp note
+ ///
+ CSharp = 1,
+ ///
+ /// The enharmonic equivalent of C sharp
+ ///
+ DFlat = 1,
+ ///
+ /// The D note
+ ///
+ D = 2,
+ ///
+ /// The D sharp note
+ ///
+ DSharp = 3,
+ ///
+ /// The enharmonic equivalent of D sharp
+ ///
+ EFlat = 3,
+ ///
+ /// The E note
+ ///
+ E = 4,
+ ///
+ /// The F note
+ ///
+ F = 5,
+ ///
+ /// The F sharp note
+ ///
+ FSharp = 6,
+ ///
+ /// The enharmonic equivalent of F sharp
+ ///
+ GFlat = 6,
+ ///
+ /// The G note
+ ///
+ G = 7,
+ ///
+ /// The G sharp note
+ ///
+ GSharp = 8,
+ ///
+ /// The enharmonic equivalent of G sharp
+ ///
+ AFlat = 8,
+ ///
+ /// The A note
+ ///
+ A = 9,
+ ///
+ /// The A sharp note
+ ///
+ ASharp = 10,
+ ///
+ /// The enharmonic equivalent of A sharp
+ ///
+ BFlat = 10,
+ ///
+ /// The B note
+ ///
+ B = 11,
+ ///
+ /// Represents a rest note
+ ///
+ Rest
+ }
+
+ ///
+ /// Represents the duration of a musical note
+ ///
+ public enum NoteDuration
+ {
+ ///
+ /// A whole note
+ ///
+ Whole = 4000,
+ ///
+ /// A half note
+ ///
+ Half = 2000,
+ ///
+ /// A quarter note
+ ///
+ Quarter = 1000,
+ ///
+ /// An eighth note
+ ///
+ Eighth = 500,
+ ///
+ /// A sixteenth note
+ ///
+ Sixteenth = 250,
+ ///
+ /// A thirty-second note
+ ///
+ ThirtySecond = 125,
+ ///
+ /// A whole note triplet
+ ///
+ WholeTriplet = 6000,
+ ///
+ /// A dotted half note
+ ///
+ DottedHalf = 3000
+ }
+
+ ///
+ /// Represents the different sound effects that can be played by the class
+ ///
+ public enum SystemSoundEffect
+ {
+ ///
+ /// An alarm or emergency sound effect
+ ///
+ Alarm,
+ ///
+ /// An alert or notification sound effect
+ ///
+ Alert,
+ ///
+ /// A simple beep sound effect
+ ///
+ Beep,
+ ///
+ /// A buzzing or vibrating sound effect
+ ///
+ Buzz,
+ ///
+ /// A chime or bell sound effect
+ ///
+ Chime,
+ ///
+ /// A short click sound effect
+ ///
+ Click,
+ ///
+ /// A failure or error sound effect
+ ///
+ Failure,
+ ///
+ /// A fanfare or celebratory sound effect
+ ///
+ Fanfare,
+ ///
+ /// A notification sound effect
+ ///
+ Notification,
+ ///
+ /// A popping sound effect
+ ///
+ Pop,
+ ///
+ /// A power-up sound effect
+ ///
+ PowerUp,
+ ///
+ /// A power-down sound effect
+ ///
+ PowerDown,
+ ///
+ /// A success or positive feedback sound effect
+ ///
+ Success,
+ ///
+ /// A short tick or click sound effect
+ ///
+ Tick,
+ ///
+ /// A warning or caution sound effect
+ ///
+ Warning,
+ }
+
+ ///
+ /// Represents the different sound effects that can be played by the class
+ ///
+ public enum GameSoundEffect
+ {
+ ///
+ /// A sound effect indicating the activation or use of an item or power-up
+ ///
+ Activation,
+ ///
+ /// A simple blip sound effect
+ ///
+ Blip,
+ ///
+ /// A sound effect indicating a boss battle or end challenge
+ ///
+ BossBattle,
+ ///
+ /// A button press or selection sound effect
+ ///
+ ButtonPress,
+ ///
+ /// A coin or currency collection sound effect
+ ///
+ Coin,
+ ///
+ /// A sound effect indicating the collection of an item or bonus
+ ///
+ Collectible,
+ ///
+ /// A countdown or timer sound effect
+ ///
+ Countdown,
+ ///
+ /// A sound effect indicating the death or defeat of an enemy
+ ///
+ EnemyDeath,
+ ///
+ /// An explosion or destruction sound effect
+ ///
+ Explosion,
+ ///
+ /// A sound effect indicating a footstep or movement
+ ///
+ Footstep,
+ ///
+ /// A game over or failure sound effect
+ ///
+ GameOver,
+ ///
+ /// A sound effect indicating a health pickup or healing
+ ///
+ Health,
+ ///
+ /// A hit or damage sound effect
+ ///
+ Hit,
+ ///
+ /// A jump or hop sound effect
+ ///
+ Jump,
+ ///
+ /// A laser or projectile firing sound effect
+ ///
+ Laser,
+ ///
+ /// A sound effect indicating the completion of a level or challenge
+ ///
+ LevelComplete,
+ ///
+ /// A menu navigation or selection sound effect
+ ///
+ MenuNavigate,
+ ///
+ /// A power-up or item pick-up sound effect
+ ///
+ PowerUp,
+ ///
+ /// A power-down or failure sound effect
+ ///
+ PowerDown,
+ ///
+ /// A sound effect indicating the discovery of a secret or hidden item
+ ///
+ SecretFound,
+ ///
+ /// A sound effect indicating a spash in water
+ ///
+ Splash,
+ ///
+ /// A sound effect indicating a teleport or warp
+ ///
+ Teleport,
+ ///
+ /// A victory or success sound effect
+ ///
+ Victory,
+ ///
+ /// A warning or alarm sound effect
+ ///
+ Warning,
+ ///
+ /// A sound effect indicating a weapon or tool switch
+ ///
+ WeaponSwitch,
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.cs
new file mode 100644
index 0000000000..8cf83490b5
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/MicroAudio.cs
@@ -0,0 +1,74 @@
+using Meadow.Peripherals.Speakers;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// Provide high level audio functions
+ ///
+ public partial class MicroAudio
+ {
+ readonly IToneGenerator speaker;
+
+ SystemSounds systemSounds;
+ GameSounds gameSounds;
+
+ ///
+ /// Create a new MicroAudio instance from a IToneGenerator driver instance
+ ///
+ /// An IToneGenerator object
+ public MicroAudio(IToneGenerator speaker)
+ {
+ this.speaker = speaker;
+ }
+
+ ///
+ /// Set the playback volume
+ ///
+ /// The volume from 0-1
+ public void SetVolume(float volume)
+ {
+ speaker?.SetVolume(volume);
+ }
+
+ ///
+ /// Plays the specified system sound effect
+ ///
+ /// The sound effect to play
+ /// The number of times to play the sound effect
+ public async Task PlaySystemSound(SystemSoundEffect effect, int numberOfLoops = 1)
+ {
+ systemSounds ??= new SystemSounds(speaker);
+
+ for(int i = 0; i < numberOfLoops; i++)
+ {
+ await systemSounds.PlayEffect(effect);
+ }
+ }
+
+ ///
+ /// Plays the specified game sound effect
+ ///
+ /// The sound effect to play
+ /// /// The number of times to play the sound effect
+ public async Task PlayGameSound(GameSoundEffect effect, int numberOfLoops = 1)
+ {
+ gameSounds ??= new GameSounds(speaker);
+
+ for (int i = 0; i < numberOfLoops; i++)
+ {
+ await gameSounds.PlayEffect(effect);
+ }
+ }
+
+ ///
+ /// Play the specified song
+ ///
+ /// The song object
+ public Task PlaySong(Song song)
+ {
+ return song.Play(speaker);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Note.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Note.cs
new file mode 100644
index 0000000000..93b3ca8436
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Note.cs
@@ -0,0 +1,34 @@
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// Represents a musical note, with a specific pitch, octave, and duration
+ ///
+ public class Note
+ {
+ ///
+ /// The pitch of the note
+ ///
+ public Pitch Pitch { get; }
+ ///
+ /// The octave of the note
+ ///
+ public int Octave { get; }
+ ///
+ /// The duration of the note
+ ///
+ public NoteDuration Duration { get; }
+
+ ///
+ /// Creates a new instance of the Note class, with the specified pitch, octave, and duration
+ ///
+ /// The pitch of the note
+ /// The octave of the note
+ /// The duration of the note
+ public Note(Pitch pitch, int octave, NoteDuration duration)
+ {
+ Pitch = pitch;
+ Octave = octave;
+ Duration = duration;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/NotesToFrequency.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/NotesToFrequency.cs
new file mode 100644
index 0000000000..24a2a7040e
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/NotesToFrequency.cs
@@ -0,0 +1,35 @@
+using Meadow.Units;
+using System;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A utility class for converting musical notes to their corresponding frequencies in hertz
+ ///
+ public class NotesToFrequency
+ {
+ ///
+ /// The frequency of the A4 note, in hertz
+ ///
+ public static Frequency A4Frequency { get; set; } = new Frequency(440.0, Frequency.UnitType.Hertz);
+
+ private static double SemitoneRatio { get; } = 1.059463094359;
+
+ ///
+ /// Converts the specified musical note to its frequency in hertz
+ ///
+ /// The musical note to convert
+ /// The frequency of the note in hertz
+ public static Frequency ConvertToFrequency(Note note)
+ {
+ int semitonesFromA4 = CalculateSemitonesFromA4(note.Pitch, note.Octave);
+ return A4Frequency * Math.Pow(SemitoneRatio, semitonesFromA4);
+ }
+
+ private static int CalculateSemitonesFromA4(Pitch pitch, int octave)
+ {
+ int semitonesFromC0 = (int)pitch + (octave - 1) * 12;
+ return semitonesFromC0 - 9;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Song.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Song.cs
new file mode 100644
index 0000000000..d1e5abdcb1
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/Song.cs
@@ -0,0 +1,58 @@
+using Meadow.Peripherals.Speakers;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A class for playing a sequence of musical notes
+ ///
+ public class Song
+ {
+ ///
+ /// The collection of notes in order for the song
+ ///
+ public readonly List Notes = new List();
+
+ ///
+ /// Creates a new instance of the Song class
+ ///
+ public Song()
+ {
+ }
+
+ ///
+ /// Adds a musical note to the sequence of notes to be played
+ ///
+ /// The musical note to add
+ public void AddNote(Note note)
+ {
+ Notes.Add(note);
+ }
+
+ ///
+ /// Plays the sequence of musical notes, with the specified tempo
+ ///
+ /// The IToneGenerator object to play the song
+ /// The tempo of the music, in beats per minute
+ /// A Task representing the asynchronous playback operation
+ public async Task Play(IToneGenerator speaker, int tempo = 120)
+ {
+ foreach (var note in Notes)
+ {
+ int duration = (int)(60.0 / tempo * (int)note.Duration);
+
+ if (note.Pitch == Pitch.Rest)
+ {
+ await Task.Delay(TimeSpan.FromMilliseconds(duration));
+ }
+ else
+ {
+ var frequency = NotesToFrequency.ConvertToFrequency(note);
+ await speaker.PlayTone(frequency, TimeSpan.FromMilliseconds(duration));
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/SystemSounds.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/SystemSounds.cs
new file mode 100644
index 0000000000..cc4736b9a9
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Driver/SystemSounds.cs
@@ -0,0 +1,198 @@
+using Meadow.Peripherals.Speakers;
+using Meadow.Units;
+using System;
+using System.Threading.Tasks;
+
+namespace Meadow.Foundation.Audio
+{
+ ///
+ /// A class for playing system sounds using an IToneGenerator
+ ///
+ public class SystemSounds
+ {
+ private readonly int defaultDuration;
+ private readonly int defaultPause;
+ private readonly IToneGenerator toneGenerator;
+
+ ///
+ /// Creates a new instance of the SystemSounds class, using the specified IToneGenerator for audio output
+ ///
+ /// The IToneGenerator to use for audio output
+ /// The default duration of system sounds, in milliseconds (optional; defaults to 100)
+ /// The default pause between system sounds, in milliseconds (optional; defaults to 50)
+
+ public SystemSounds(IToneGenerator toneGenerator, int defaultDuration = 100, int defaultPause = 50)
+ {
+ this.toneGenerator = toneGenerator;
+ this.defaultDuration = defaultDuration;
+ this.defaultPause = defaultPause;
+ }
+
+ ///
+ /// Plays the specified sound effect
+ ///
+ /// The sound effect to play
+ public Task PlayEffect(SystemSoundEffect effect)
+ {
+ return effect switch
+ {
+ SystemSoundEffect.Alert => PlayAlert(),
+ SystemSoundEffect.Alarm => PlayAlarm(),
+ SystemSoundEffect.Beep => PlayBeep(),
+ SystemSoundEffect.Buzz => PlayBuzz(),
+ SystemSoundEffect.Chime => PlayChime(),
+ SystemSoundEffect.Click => PlayClick(),
+ SystemSoundEffect.Failure => PlayFailure(),
+ SystemSoundEffect.Fanfare => PlayFanfare(),
+ SystemSoundEffect.Notification => PlayNotification(),
+ SystemSoundEffect.Pop => PlayPop(),
+ SystemSoundEffect.PowerDown => PlayPowerDown(),
+ SystemSoundEffect.PowerUp => PlayPowerUp(),
+ SystemSoundEffect.Success => PlaySuccess(),
+ SystemSoundEffect.Tick => PlayTick(),
+ SystemSoundEffect.Warning => PlayWarning(),
+ _ => throw new ArgumentException($"Unknown effect: {effect}"),
+ };
+ }
+
+
+ private async Task PlayBeep()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlaySuccess()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1500), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlayFailure()
+ {
+ await toneGenerator.PlayTone(new Frequency(1500), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlayWarning()
+ {
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration));
+ }
+
+ private async Task PlayAlarm()
+ {
+ for (int i = 0; i < 5; i++)
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ }
+ }
+
+ private async Task PlayTick()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ private async Task PlayChime()
+ {
+ await toneGenerator.PlayTone(new Frequency(262), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(330), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(392), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(523), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a buzzing or vibrating sound effect
+ ///
+ private async Task PlayBuzz()
+ {
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a fanfare or celebratory sound effect
+ ///
+ private async Task PlayFanfare()
+ {
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(659), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(523), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(659), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(523), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays an alert or notification sound effect
+ ///
+ private async Task PlayAlert()
+ {
+ await toneGenerator.PlayTone(new Frequency(1047), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1175), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1319), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(1397), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+
+ ///
+ /// Plays a short click sound effect
+ ///
+ private async Task PlayClick()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+
+ ///
+ /// Plays a popping sound effect
+ ///
+ private async Task PlayPop()
+ {
+ await toneGenerator.PlayTone(new Frequency(500), TimeSpan.FromMilliseconds(defaultDuration / 4));
+ }
+
+ ///
+ /// Plays a power-up sound effect
+ ///
+ private async Task PlayPowerUp()
+ {
+ await toneGenerator.PlayTone(new Frequency(200), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a power-down sound effect
+ ///
+ private async Task PlayPowerDown()
+ {
+ await toneGenerator.PlayTone(new Frequency(1000), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ await toneGenerator.PlayTone(new Frequency(200), TimeSpan.FromMilliseconds(defaultDuration / 2));
+ }
+
+ ///
+ /// Plays a notification sound effect
+ ///
+ private async Task PlayNotification()
+ {
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(698), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await Task.Delay(TimeSpan.FromMilliseconds(defaultPause));
+ await toneGenerator.PlayTone(new Frequency(880), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(784), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ await toneGenerator.PlayTone(new Frequency(698), TimeSpan.FromMilliseconds(defaultDuration / 8));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/Audio.MicroAudio_Sample.csproj b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/Audio.MicroAudio_Sample.csproj
new file mode 100644
index 0000000000..0f5262f559
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/Audio.MicroAudio_Sample.csproj
@@ -0,0 +1,20 @@
+
+
+ https://github.com/WildernessLabs/Meadow.Foundation
+ Wilderness Labs, Inc
+ Wilderness Labs, Inc
+ true
+ netstandard2.1
+ Library
+ App
+
+
+
+
+
+
+
+ Always
+
+
+
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/CScale.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/CScale.cs
new file mode 100644
index 0000000000..98acd8337f
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/CScale.cs
@@ -0,0 +1,24 @@
+using Meadow.Foundation.Audio;
+
+namespace Audio.MicroAudio_Sample
+{
+ namespace SongPlayer
+ {
+ internal class CScale : Song
+ {
+ public CScale()
+ {
+ AddNotes();
+ }
+
+ void AddNotes()
+ {
+ for (int i = 0; i < 12; i++)
+ {
+ AddNote(new Note((Pitch)(i), 3, NoteDuration.Quarter));
+ }
+ AddNote(new Note(Pitch.C, 4, NoteDuration.Quarter));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/MeadowApp.cs b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/MeadowApp.cs
new file mode 100644
index 0000000000..edd889e0a0
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/MeadowApp.cs
@@ -0,0 +1,86 @@
+using Audio.MicroAudio_Sample.SongPlayer;
+using Meadow;
+using Meadow.Devices;
+using Meadow.Foundation.Audio;
+using Meadow.Gateways.Bluetooth;
+using Meadow.Peripherals.Speakers;
+using System;
+using System.Threading.Tasks;
+
+namespace MicroAudio_Sample
+{
+ public class MeadowApp : App
+ {
+ private MicroAudio audio;
+
+ IToneGenerator speaker;
+
+ public override Task Initialize()
+ {
+ Resolver.Log.Info("Initialize...");
+
+ speaker = new PiezoSpeaker(Device.Pins.D11);
+
+ audio = new MicroAudio(speaker);
+
+ return Task.CompletedTask;
+ }
+
+ public override async Task Run()
+ {
+ Resolver.Log.Info("Play happy birthday");
+ await HappyBirthDay(speaker);
+
+ await Task.Delay(1000);
+
+ Resolver.Log.Info("Play C scale");
+ var scale = new CScale();
+ await audio.PlaySong(scale);
+
+ await Task.Delay(1000);
+
+ Resolver.Log.Info("Sound effects test");
+ await SoundEffectsTest();
+
+ Resolver.Log.Info("Game effects test");
+ await GameEffectsTest();
+ }
+
+ Task HappyBirthDay(IToneGenerator speaker)
+ {
+ var happyBirthday = new Song();
+ happyBirthday.AddNote(new Note(Pitch.C, 3, NoteDuration.Quarter));
+ happyBirthday.AddNote(new Note(Pitch.C, 3, NoteDuration.Quarter));
+ happyBirthday.AddNote(new Note(Pitch.D, 3, NoteDuration.Half));
+ happyBirthday.AddNote(new Note(Pitch.C, 3, NoteDuration.Half));
+ happyBirthday.AddNote(new Note(Pitch.F, 3, NoteDuration.Half));
+ happyBirthday.AddNote(new Note(Pitch.E, 3, NoteDuration.Whole));
+
+ return happyBirthday.Play(speaker, 160);
+ }
+
+ async Task GameEffectsTest()
+ {
+ foreach (GameSoundEffect effect in Enum.GetValues(typeof(GameSoundEffect)))
+ {
+ Resolver.Log.Info($"Playing {effect} game effect...");
+ await audio.PlayGameSound(effect);
+ await Task.Delay(1000);
+ }
+
+ Resolver.Log.Info("Sound effects demo complete.");
+ }
+
+ async Task SoundEffectsTest()
+ {
+ foreach (SystemSoundEffect effect in Enum.GetValues(typeof(SystemSoundEffect)))
+ {
+ Resolver.Log.Info($"Playing {effect} sound effect...");
+ await audio.PlaySystemSound(effect);
+ await Task.Delay(1000);
+ }
+
+ Resolver.Log.Info("Sound effects demo complete.");
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/meadow.config.yaml b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/meadow.config.yaml
new file mode 100644
index 0000000000..32363cb69c
--- /dev/null
+++ b/Source/Meadow.Foundation.Libraries_and_Frameworks/Audio.MicroAudio/Samples/Audio.MicroAudio_Sample/meadow.config.yaml
@@ -0,0 +1,2 @@
+MonoControl:
+ Options: --jit
\ No newline at end of file
diff --git a/Source/Meadow.Foundation.sln b/Source/Meadow.Foundation.sln
index 564639055e..0e85ddfe25 100644
--- a/Source/Meadow.Foundation.sln
+++ b/Source/Meadow.Foundation.sln
@@ -1227,6 +1227,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mcp9600_Sample", "Meadow.Fo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mcp9601_Sample", "Meadow.Foundation.Peripherals\Sensors.Temperature.Mcp960x\Samples\Mcp9601_Sample\Mcp9601_Sample.csproj", "{41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Audio.MicroAudio", "Audio.MicroAudio", "{0236BB4E-B417-4549-B69E-79AC81FC3056}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Audio.MicroAudio", "Meadow.Foundation.Libraries_and_Frameworks\Audio.MicroAudio\Driver\Audio.MicroAudio.csproj", "{F3F3966C-E416-41EF-889B-518FFECFC780}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{99AABDF6-1EE4-4099-B61C-E49CA6F5CA0F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Audio.MicroAudio_Sample", "Meadow.Foundation.Libraries_and_Frameworks\Audio.MicroAudio\Samples\Audio.MicroAudio_Sample\Audio.MicroAudio_Sample.csproj", "{CDC8B582-C7F8-4578-8F1A-0B4B817D2632}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -2917,6 +2925,18 @@ Global
{41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Release|Any CPU.Build.0 = Release|Any CPU
{41A4E1A7-0BC4-474F-910F-F140EEA1A4BE}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {F3F3966C-E416-41EF-889B-518FFECFC780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F3F3966C-E416-41EF-889B-518FFECFC780}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F3F3966C-E416-41EF-889B-518FFECFC780}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {F3F3966C-E416-41EF-889B-518FFECFC780}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F3F3966C-E416-41EF-889B-518FFECFC780}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F3F3966C-E416-41EF-889B-518FFECFC780}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -3529,6 +3549,10 @@ Global
{754AFC87-A98F-4BD6-A934-61DB69C0B643} = {CBF95E20-6021-4E5B-807A-E099DBC98764}
{3AC34973-19FC-453A-A90E-4406EB355F72} = {573A2A08-CB36-480E-9C5D-56F851847045}
{41A4E1A7-0BC4-474F-910F-F140EEA1A4BE} = {573A2A08-CB36-480E-9C5D-56F851847045}
+ {0236BB4E-B417-4549-B69E-79AC81FC3056} = {E0384B86-37FC-403C-B1F7-AA5D1B869EB1}
+ {F3F3966C-E416-41EF-889B-518FFECFC780} = {0236BB4E-B417-4549-B69E-79AC81FC3056}
+ {99AABDF6-1EE4-4099-B61C-E49CA6F5CA0F} = {0236BB4E-B417-4549-B69E-79AC81FC3056}
+ {CDC8B582-C7F8-4578-8F1A-0B4B817D2632} = {99AABDF6-1EE4-4099-B61C-E49CA6F5CA0F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF7CA16F-8C38-4546-87A2-5DAAF58A1520}