Skip to content

Commit 5b1b837

Browse files
committed
Added events when fade-in/fade-out are complete
1 parent a106da4 commit 5b1b837

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

Docs/FadeInOutSampleProvider.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ var fade = new FadeInOutSampleProvider(audio, true);
1414
fade.BeginFadeIn(2000);
1515
```
1616

17+
After fade in is complete, `FadeInComplete` event is triggered:
18+
```c#
19+
fade.FadeInComplete += (sender, e) => {
20+
Console.WriteLine("Fade in was done!");
21+
};
22+
fade.BeginFadeIn(2000);
23+
```
24+
1725
Now we can pass our `FadeInOutSampleProvider` to an output device and start playing. We'll hear the audio fading in over the first two seconds.
1826

1927
```c#
@@ -28,6 +36,15 @@ At some point in the future, we might want to fade out, and we can trigger that
2836
fade.BeginFadeOut(2000);
2937
```
3038

39+
It also triggers `FadeOutComplete` event, when fade out is complete
40+
41+
```c#
42+
fade.FadeOutComplete += (sender, e) => {
43+
Console.WriteLine("Fade out was done!");
44+
};
45+
fade.BeginFadeOut(2000);
46+
```
47+
3148
Once the audio has faded out, the `FadeInOutSampleProvider` continues to read from its source but emits silence until it reaches its end, or until you call `BeginFadeIn` again.
3249

3350
### Taking it further

NAudio.Core/Wave/SampleProviders/FadeInOutSampleProvider.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace NAudio.Wave.SampleProviders
1+
using System;
2+
3+
namespace NAudio.Wave.SampleProviders
24
{
35
/// <summary>
46
/// Sample Provider to allow fading in and out
@@ -13,6 +15,16 @@ enum FadeState
1315
FadingOut,
1416
}
1517

18+
/// <summary>
19+
/// Raised when scheduled fade-in is done
20+
/// </summary>
21+
public event EventHandler FadeInComplete;
22+
23+
/// <summary>
24+
/// Raised when scheduled fade-out is done
25+
/// </summary>
26+
public event EventHandler FadeOutComplete;
27+
1628
private readonly object lockObject = new object();
1729
private readonly ISampleProvider source;
1830
private int fadeSamplePosition;
@@ -108,6 +120,8 @@ private void FadeOut(float[] buffer, int offset, int sourceSamplesRead)
108120
if (fadeSamplePosition > fadeSampleCount)
109121
{
110122
fadeState = FadeState.Silence;
123+
FadeOutComplete?.Invoke(this, EventArgs.Empty);
124+
111125
// clear out the end
112126
ClearBuffer(buffer, sample + offset, sourceSamplesRead - sample);
113127
break;
@@ -129,6 +143,8 @@ private void FadeIn(float[] buffer, int offset, int sourceSamplesRead)
129143
if (fadeSamplePosition > fadeSampleCount)
130144
{
131145
fadeState = FadeState.FullVolume;
146+
FadeInComplete?.Invoke(this, EventArgs.Empty);
147+
132148
// no need to multiply any more
133149
break;
134150
}

NAudioTests/WaveStreams/FadeInOutSampleProviderTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,61 @@ public void BufferIsZeroedAfterFadeOut()
120120
Assert.AreEqual(20, read);
121121
Assert.AreEqual(0, buffer[0]);
122122
}
123+
124+
[Test]
125+
public void FadeInCompleteInvoked()
126+
{
127+
// given
128+
var source = new TestSampleProvider(10, 1); // 10 samples per second
129+
source.UseConstValue = true;
130+
source.ConstValue = 100;
131+
var fade = new FadeInOutSampleProvider(source);
132+
var fadeInsCount = 0;
133+
fade.FadeInComplete += (sender, e) =>
134+
{
135+
fadeInsCount++;
136+
};
137+
138+
// when
139+
fade.BeginFadeIn(1000);
140+
141+
// then
142+
float[] buffer = new float[20];
143+
int read = fade.Read(buffer, 0, 20);
144+
Assert.AreEqual(20, read);
145+
Assert.AreEqual(0, buffer[0]); // start of fade-in
146+
Assert.AreEqual(50, buffer[5]); // half-way
147+
Assert.AreEqual(100, buffer[10]); // fully fade in
148+
Assert.AreEqual(100, buffer[15]); // fully fade in
149+
Assert.AreEqual(1, fadeInsCount); // we want one-shot event (when fade in was completed once)
150+
}
151+
152+
[Test]
153+
public void FadeOutCompleteInvoked()
154+
{
155+
// given
156+
var source = new TestSampleProvider(10, 1); // 10 samples per second
157+
source.UseConstValue = true;
158+
source.ConstValue = 100;
159+
var fade = new FadeInOutSampleProvider(source);
160+
var fadeOutsCount = 0;
161+
fade.FadeOutComplete += (sender, e) =>
162+
{
163+
fadeOutsCount++;
164+
};
165+
166+
// when
167+
fade.BeginFadeOut(1000);
168+
169+
// then
170+
float[] buffer = new float[20];
171+
int read = fade.Read(buffer, 0, 20);
172+
Assert.AreEqual(20, read);
173+
Assert.AreEqual(100, buffer[0]); // start of fade-out
174+
Assert.AreEqual(50, buffer[5]); // half-way
175+
Assert.AreEqual(0, buffer[10]); // fully fade out
176+
Assert.AreEqual(0, buffer[15]); // fully fade out
177+
Assert.AreEqual(1, fadeOutsCount); // we want one-shot event (when fade out was completed once)
178+
}
123179
}
124180
}

0 commit comments

Comments
 (0)