|
| 1 | +--- |
| 2 | +title: How to adjust Pitch and Volume |
| 3 | +description: Demonstrates how to manipulate the pitch and volume of sound effects as they play. |
| 4 | +requireMSLicense: true |
| 5 | +--- |
| 6 | + |
| 7 | +## Overview |
| 8 | + |
| 9 | +In this example, you will walk through the basics of dynamic sounds, using the more advanced [SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) cl;ass over the basic [SoundEffect.Play](xref:Microsoft.Xna.Framework.Audio.SoundEffect.Play) method used in [Playing a Sound](HowTo_PlayASound.md). |
| 10 | + |
| 11 | +## Using SoundEffectInstance |
| 12 | + |
| 13 | +The **[SoundEffect.Play](xref:Microsoft.Xna.Framework.Audio.SoundEffect.Play)** method allows you to specify the pitch and volume of a sound to play. However, after you call **[Play](xref:Microsoft.Xna.Framework.Audio.SoundEffect.Play)** you cannot modify the sound. |
| 14 | + |
| 15 | +Using **[SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance)** for a given **[SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect)**, allows you to change the **pitch** and **volume** of a sound at any time during playback. |
| 16 | + |
| 17 | +> [!NOTE] |
| 18 | +> The pitch of a sound changes the frequency of the sound, which in turn changes the speed of the sound. The volume of a sound changes the amplitude of the sound, which in turn changes the loudness of the sound. |
| 19 | +
|
| 20 | +## Requirements |
| 21 | + |
| 22 | +This sample uses a sound file named [tx0_fire1.wav](./files/tx0_fire1.wav), which you can download from [this link here](./files/tx0_fire1.wav). (save-as) |
| 23 | +But you can use your own if you wish. |
| 24 | + |
| 25 | +## Change Pitch and Volume of Sound |
| 26 | + |
| 27 | +1. Declare a **[SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect)** and a [Stream](http://msdn.microsoft.com/en-us/library/system.io.stream.aspx) file by using the method shown in [Playing a Sound](HowTo_PlayASound.md). In addition to the method described in [Playing a Sound](HowTo_PlayASound.md), declare a **[SoundEffectInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance)** and a **Sound Effect** field member. We also create two float fields for **pitch** and **volume** to store the pitch and volume of the sound effect and assign initial values to them. |
| 28 | + |
| 29 | + ```csharp |
| 30 | + // place these usings at the top of the file |
| 31 | + using System.IO; |
| 32 | + using Microsoft.Xna.Framework; |
| 33 | + using Microsoft.Xna.Framework.Audio; |
| 34 | + using Microsoft.Xna.Framework.Graphics; |
| 35 | + using Microsoft.Xna.Framework.Input; |
| 36 | + |
| 37 | + // place these fields at the top of the class |
| 38 | + private SoundEffect soundEffect; |
| 39 | + private SoundEffectInstance soundEffectInstance; |
| 40 | + private float pitch = 0.75f; |
| 41 | + private float volume = 0.5f; |
| 42 | + ``` |
| 43 | + |
| 44 | + > [!NOTE] |
| 45 | + > Usings are declared at the top of the file to ensure that the necessary namespaces are available to the class. The fields are declared at the top of the class to ensure that they are accessible to all methods in the class. |
| 46 | + |
| 47 | +2. In the [Game.LoadContent](xref:Microsoft.Xna.Framework.Game.LoadContent) method, set the **SoundEffectInstance** object to the return value of [SoundEffect.CreateInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance). |
| 48 | + |
| 49 | +3. In the **[Game.LoadContent](xref:Microsoft.Xna.Framework.Game.LoadContent)** method, set the **SoundEffectInstance** object to the return value of **[SoundEffect.CreateInstance](xref:Microsoft.Xna.Framework.Audio.SoundEffect.CreateInstance)**. We also optionally define a variable **soundFile** to store the location of the sound file being used with the **[TitleContainer.OpenStream](xref:Microsoft.Xna.Framework.TitleContainer#Microsoft_Xna_Framework_TitleContainer_OpenStream_System_String_)** method, which is accessed with the **using** keyword, and include a field member variable called **soundEffect**, to hold the stream. |
| 50 | + |
| 51 | + ```csharp |
| 52 | + using Stream soundfile = TitleContainer.OpenStream(@"Content\tx0_fire1.wav"); |
| 53 | + soundEffect = SoundEffect.FromStream(soundfile); |
| 54 | + soundEffectInstance = soundEffect.CreateInstance(); |
| 55 | + ``` |
| 56 | + |
| 57 | + >[IMPORTANT] |
| 58 | + > As we need the raw wav file and not a compressed version to access its stream, make sure to set the 'Build Action' in the MGCB tool to 'COPY' |
| 59 | + >  |
| 60 | + |
| 61 | +4. Adjust the sound to the desired level using the [SoundEffectInstance.Pitch](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Pitch) and [SoundEffectInstance.Volume](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Volume) properties. |
| 62 | + |
| 63 | + ```csharp |
| 64 | + // Pitch takes values from -1 to 1 |
| 65 | + soundEffectInstance.Pitch = pitch; |
| 66 | + |
| 67 | + // Volume only takes values from 0 to 1 |
| 68 | + soundEffectInstance.Volume = volume; |
| 69 | + ``` |
| 70 | + |
| 71 | +5. Play the sound using [SoundEffectInstance.Stop](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Play). |
| 72 | + |
| 73 | + ```csharp |
| 74 | + // Play Sound |
| 75 | + soundEffectInstance.Play(); |
| 76 | + ``` |
| 77 | + |
| 78 | + > [!NOTE] |
| 79 | + > An instance will play once, to loop the sound, you can use the **[SoundEffectInstance.IsLooped](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.IsLooped)** property to set the sound to loop. Also note that the sound will not repeat until the sound has finished playing. You can utilise the **[SoundEffectInstance.State](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.State)** property to check if the sound is playing, paused or stopped. Use the **[SoundEffectInstance.Stop](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance.Stop)** method to stop the sound. |
| 80 | + |
| 81 | +## An Extended Example |
| 82 | + |
| 83 | + 1. Below the **[Game.Draw](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Draw_Microsoft_Xna_Framework_GameTime_)** method, create a new method called **IsKeyPressed**, which will check if a specified key is pressed and return a boolean value of true if it has been pressed. |
| 84 | + |
| 85 | + ```csharp |
| 86 | + private bool IsKeyPressed(Keys key) |
| 87 | + { |
| 88 | + return Keyboard.GetState().IsKeyDown(key); |
| 89 | + } |
| 90 | + |
| 91 | + ``` |
| 92 | + |
| 93 | + 2. In the **[Game.Update](xref:Microsoft.Xna.Framework.Game#Microsoft_Xna_Framework_Game_Update_Microsoft_Xna_Framework_GameTime_)** method, we will add a check to see if the **Space** key is pressed and adjust the pitch and volume of the sound effect accordingly. The pitch and volume values are adjusted by +0.1f each time the **Space key** is pressed. The pitch values are clamped to a minimum value of -1.0f and a maximum value of 1.0f, and the volume values are then clamped to a minimum value of 0f and a maximum value of 1.0f. This is done to ensure that the pitch and volume values are within valid ranges. |
| 94 | + |
| 95 | + ```csharp |
| 96 | + // Check if the SpaceKey is pressed and play the instance |
| 97 | + if (IsKeyPressed(Keys.Space)) |
| 98 | + { |
| 99 | + pitch += 0.1f; |
| 100 | + volume += 0.1f; |
| 101 | + pitch = MathHelper.Clamp(pitch, -1.0f, 1.0f); |
| 102 | + volume = MathHelper.Clamp(volume, 0f, 1.0f); |
| 103 | + soundEffectInstance.Pitch = pitch; |
| 104 | + soundEffectInstance.Volume = volume; |
| 105 | + soundEffectInstance.Play(); |
| 106 | + } |
| 107 | + ``` |
| 108 | + |
| 109 | + > [!NOTE] |
| 110 | + > The **MathHelper.Clamp** method is used to ensure that the pitch and volume values are within the valid range. The pitch value is clamped between -1 and 1, while the volume value is clamped between 0 and 1. |
| 111 | + |
| 112 | + > [!IMPORTANT] |
| 113 | + > The check for the keypress does not prevent the call to the method repeating so any value entered may peak the value in a single key press. To prevent this, you can add a delay to the key press check, or use a boolean value to check if the key has been pressed and released. |
| 114 | + |
| 115 | +## Concepts |
| 116 | + |
| 117 | +* [Playing a Sound](HowTo_PlayASound.md) |
| 118 | + |
| 119 | + Demonstrates how to play a simple sound by using [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect). |
| 120 | + |
| 121 | +* [Looping a Sound](HowTo_LoopASound.md) |
| 122 | + |
| 123 | + Demonstrates how to loop a sound. |
| 124 | + |
| 125 | +* [Stream data from a Wav](HowTo_StreamDataFromWav.md) |
| 126 | + |
| 127 | + Demonstrates how to load a wav file through a file stream. |
| 128 | + |
| 129 | +* [Creating and Playing Sounds](../../whatis/WhatIs_Audio.md) |
| 130 | + |
| 131 | + Provides overviews about audio technology, and presents predefined scenarios to demonstrate how to use audio. |
| 132 | + |
| 133 | +## Reference |
| 134 | + |
| 135 | +* [SoundEffect Class](xref:Microsoft.Xna.Framework.Audio.SoundEffect) |
| 136 | + |
| 137 | + Provides a loaded sound resource. |
| 138 | + |
| 139 | +* [SoundEffectInstance Class](xref:Microsoft.Xna.Framework.Audio.SoundEffectInstance) |
| 140 | + |
| 141 | + Provides a single playing, paused, or stopped instance of a [SoundEffect](xref:Microsoft.Xna.Framework.Audio.SoundEffect) sound. |
0 commit comments