@@ -15,30 +15,66 @@ class Demo : public olc::PixelGameEngine
15
15
public:
16
16
bool OnUserCreate () override
17
17
{
18
+ /* *
19
+ * turn on background play so sound
20
+ * continues to play even if the app
21
+ * doesn't have focus.
22
+ */
18
23
ma.SetBackgroundPlay (true );
19
24
25
+ /* *
26
+ * load assets/sounds/song1.mp3 and
27
+ * keep track of it's id for later use
28
+ */
20
29
song1 = ma.LoadSound (" assets/sounds/song1.mp3" );
30
+
31
+ /* *
32
+ * ADVANCED NOTES
33
+ *
34
+ * Using ma.GetSound to get a pointer to the ma_sound
35
+ * associated with the sample ID, in this case song1.
36
+ *
37
+ * this allows us to use the miniaudio apis directly
38
+ * for anything that the PGEX doesn't abstract.
39
+ *
40
+ * Note: in miniaudio spatialization, y is the
41
+ * world UP axis. since this demo is 2d
42
+ * we set the Y of all the miniaudio coords
43
+ * to 0.0f.
44
+ */
21
45
ma_sound_set_position (ma.GetSound (song1), 0 .0f , 0 .0f , 0 .0f );
46
+
47
+ /* *
48
+ * using a linear attenuation allows us to accurately
49
+ * set the min/max distance at which the sound plays
50
+ *
51
+ * side effect of this method is it doesn't change
52
+ * volume of the sample as you move away. solution
53
+ * detailed below.
54
+ */
22
55
ma_sound_set_attenuation_model (ma.GetSound (song1), ma_attenuation_model_linear);
56
+
57
+ /* *
58
+ * min distance = 0
59
+ * max distance = 20 (15 for radius of sound, 5 to cover radius of listener)
60
+ */
23
61
ma_sound_set_min_distance (ma.GetSound (song1), 0 .0f );
24
62
ma_sound_set_max_distance (ma.GetSound (song1), 20 .0f );
25
- ma_sound_set_max_gain (ma.GetSound (song1), 1 .0f );
26
- ma_sound_set_min_gain (ma.GetSound (song1), 0 .0f );
27
-
63
+
64
+ // calculate the center of the screen
28
65
centerScreen = GetScreenSize () / 2 ;
29
66
return true ;
30
67
}
31
68
32
- olc::vf2d position{0 .0f , 0 .0f };
33
- float direction = 0 .0f ;
34
- olc::vf2d centerScreen;
35
-
36
69
bool OnUserUpdate (float fElapsedTime ) override
37
70
{
38
71
fElapsedTime = (fElapsedTime > thirtyFramesPerSecond) ? thirtyFramesPerSecond : fElapsedTime ;
39
72
40
73
if (GetKey (olc::SPACE).bPressed )
41
74
{
75
+ /* *
76
+ * start or stop playback of song1
77
+ */
42
78
ma.Toggle (song1);
43
79
}
44
80
@@ -50,31 +86,79 @@ class Demo : public olc::PixelGameEngine
50
86
if (GetKey (olc::A).bHeld || GetKey (olc::LEFT).bHeld ) rotationVelocity -= 1 .0f ;
51
87
if (GetKey (olc::D).bHeld || GetKey (olc::RIGHT).bHeld ) rotationVelocity += 1 .0f ;
52
88
53
- direction += rotationVelocity * 5 .0f * fElapsedTime ;
54
- olc::vf2d directionVector = olc::vf2d{ cosf (direction), sinf (direction) };
89
+ rotation += rotationVelocity * 5 .0f * fElapsedTime ;
90
+ /* *
91
+ * change the direction our listener is facing
92
+ * using the newly calculated rotation
93
+ */
94
+ olc::vf2d directionVector = olc::vf2d{ cosf (rotation), sinf (rotation) };
95
+
96
+ /* *
97
+ * calculate the velocity our listener is moving
98
+ * in the newly calculated direction vector
99
+ */
55
100
olc::vf2d velocity = directionVector * forwardVelocity * 20 .0f * fElapsedTime ;
101
+
102
+ /* *
103
+ * add velocity to position, thus moving the listener
104
+ */
56
105
position += velocity;
57
106
107
+ /* *
108
+ * As noted above, linear attenuation doesn't account
109
+ * sample's volume. this is perfectly fine for situations
110
+ * where you simply want a sound to play or not. however
111
+ * if you want to simulate distance, we need to calculate
112
+ * the volume of the sample.
113
+ */
114
+ float volume = std::clamp (1 .0f - (position.mag () / 20 .0f ), 0 .0f , 1 .0f );
115
+ ma_sound_set_volume (ma.GetSound (song1), volume);
116
+
117
+ /* *
118
+ * ADVANCED NOTES
119
+ *
120
+ * Using ma.Engine to get a pointer to the ma_engine
121
+ * associated with the pgex.
122
+ *
123
+ * this allows us to use the miniaudio apis directly
124
+ * for anything that the PGEX doesn't abstract.
125
+ */
58
126
ma_engine_listener_set_direction (ma.GetEngine (), 0 , directionVector.x , 0 .0f , directionVector.y );
59
127
ma_engine_listener_set_position (ma.GetEngine (), 0 , position.x , 0 .0f , position.y );
60
128
ma_engine_listener_set_velocity (ma.GetEngine (), 0 , velocity.x , 0 .0f , velocity.y );
61
129
62
130
Clear (olc::BLACK);
63
131
132
+ /* *
133
+ * draw a cirlce representing the sound
134
+ * offset by the center of the screen.
135
+ */
64
136
DrawCircle (centerScreen, 5 , olc::YELLOW);
137
+
138
+ /* *
139
+ * draw a circle representing the range of
140
+ * the sound offset by the center of the
141
+ * screen.
142
+ */
65
143
DrawCircle (centerScreen, 15 , olc::MAGENTA);
66
144
145
+ /* *
146
+ * draw a circle at the listener position offset
147
+ * by the center of the screen along with a line
148
+ * to indicate the direction the listener is facing.
149
+ */
67
150
DrawCircle (centerScreen + position, 5 , olc::WHITE);
68
151
DrawLine (centerScreen + position, centerScreen + position + (directionVector * 5 ), olc::WHITE);
69
152
70
153
71
154
DrawStringDecal ({5 , 5 }, \
72
155
" -------- INFO --- CONTROLS -\n " " \n "
73
156
" Forward/Backward (" + std::to_string (forwardVelocity) + " ) W,S or UP,DOWN\n " " \n "
74
- " Rotation (" + std::to_string (direction) + " ) A,D or LEFT,RIGHT\n " " \n "
157
+ " Rotation (" + std::to_string (rotation) + " ) A,D or LEFT,RIGHT\n " " \n "
75
158
" Position " + position.str () + " \n " " \n "
76
159
" Position Mag (" + std::to_string (position.mag ()) + " )\n " " \n "
77
160
" Toggle Sound (" + (ma.IsPlaying (song1) ? " Playing) " : " Not Playing)" ) + " SPACE\n "
161
+ " Volume (" + std::to_string (volume) + " )\n " " \n "
78
162
,
79
163
olc::WHITE, {0 .5f , 0 .5f });
80
164
@@ -91,8 +175,18 @@ class Demo : public olc::PixelGameEngine
91
175
#endif
92
176
}
93
177
178
+ // add the miniaudio pgex to PGE
94
179
olc::MiniAudio ma;
180
+ // keep track of the id the sample
95
181
int song1;
182
+ // position of our listener
183
+ olc::vf2d position{0 .0f , 0 .0f };
184
+ // rotational direction of our listener
185
+ float rotation = 0 .0f ;
186
+ // center of the screen
187
+ olc::vf2d centerScreen;
188
+
189
+
96
190
};
97
191
98
192
int main ()
0 commit comments