-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSoundGenerators.cs
More file actions
138 lines (113 loc) · 4.88 KB
/
SoundGenerators.cs
File metadata and controls
138 lines (113 loc) · 4.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SoundGenerators
{
/// <summary>
/// Базовый интерфейс генератора одного сэмпла (возвращает сэмпл на момент времени currentTime)
/// </summary>
public interface ISoundGenerator
{
float GenerateSample(float currentTime);
}
/// <summary>
/// Простая реализация генератора белого шума
/// </summary>
public class WhiteNoiseGenerator : ISoundGenerator
{
private readonly Random _rand = new Random();
private readonly float _amplitude;
public WhiteNoiseGenerator(float amplitude = 0.3f)
{
_amplitude = amplitude;
}
// Генерация отсчёта шума
public float GenerateSample(float currentTime)
{
// Пример белого шума в диапазоне [-_amplitude, +_amplitude]
return (float)(_rand.NextDouble() * 2.0 - 1.0) * _amplitude;
}
}
/// <summary>
/// Генератор тонального (синусоидального) сигнала с экспоненциальным затуханием.
/// </summary>
public class ExponentialSineGenerator : ISoundGenerator
{
/// <summary> Амплитуда (максимальное значение при t=0) </summary>
public float Amplitude { get; set; } = 1.0f;
/// <summary> Частота синусоиды (Гц) </summary>
public float Frequency { get; set; } = 440f;
/// <summary> Начальная фаза (в радианах) </summary>
public float InitialPhase { get; set; } = 0f;
/// <summary> Время начала звучания (в секундах), до этого сигнал = 0 </summary>
public float StartTime { get; set; } = 0f;
/// <summary> Время затухания (в секундах). Чем меньше, тем быстрее затухает. </summary>
public float DecayTime { get; set; } = 1f;
public ExponentialSineGenerator(
float amplitude,
float frequency,
float initialPhase,
float startTime,
float decayTime)
{
Amplitude = amplitude;
Frequency = frequency;
InitialPhase = initialPhase;
StartTime = startTime;
DecayTime = decayTime;
}
/// <summary>
/// Возвращает один отсчёт синусоиды с экспоненциальным затуханием.
/// </summary>
public float GenerateSample(float currentTime)
{
float t = currentTime - StartTime;
// Если сигнал ещё не начался
if (t < 0f)
return 0f;
// Можно оборвать сигнал
// if (t > DecayTime * 5f) return 0f;
// Экспоненциальная огибающая
float envelope = Amplitude * MathF.Exp(-t / DecayTime);
// Синусоида
float sample = envelope * MathF.Sin(2f * MathF.PI * Frequency * t + InitialPhase);
return sample;
}
}
/// <summary>
/// Генератор белого шума с экспоненциальным затуханием.
/// </summary>
public class ExponentialNoiseGenerator : ISoundGenerator
{
/// <summary> Начальная максимальная амплитуда шума </summary>
public float Amplitude { get; set; } = 1.0f;
/// <summary> Время начала (с), до которого сигнал = 0 </summary>
public float StartTime { get; set; } = 0f;
/// <summary> Время экспоненциального затухания (с) </summary>
public float DecayTime { get; set; } = 1f;
// Для генерации белого шума
private readonly Random _rand = new Random();
public ExponentialNoiseGenerator(
float amplitude,
float startTime,
float decayTime)
{
Amplitude = amplitude;
StartTime = startTime;
DecayTime = decayTime;
}
public float GenerateSample(float currentTime)
{
float t = currentTime - StartTime;
if (t < 0f)
return 0f;
// Экспоненциальная огибающая
float envelope = Amplitude * MathF.Exp(-t / DecayTime);
// Генерация белого шума в диапазоне [-1..+1]
float noise = (float)(_rand.NextDouble() * 2.0 - 1.0);
return envelope * noise;
}
}
}