+#include <assert.h>
#include <math.h>
#include "./point.h"
return result;
}
+vec_t vec_from_ps(point_t p1, point_t p2)
+{
+ vec_t result = {
+ .x = p2.x - p1.x,
+ .y = p2.y - p1.y
+ };
+ return result;
+}
+
+float vec_arg(vec_t v)
+{
+ return atan2f(v.y, v.x);
+}
+
+float vec_mag(vec_t v)
+{
+ return sqrtf(v.x * v.x + v.y * v.y);
+}
+
vec_t vec_sum(vec_t v1, vec_t v2)
{
vec_t result = {
#ifndef POINT_H_
#define POINT_H_
+#include "./pi.h"
+
typedef struct point_t {
float x, y;
} point_t;
typedef point_t vec_t;
vec_t vec(float x, float y);
+vec_t vec_from_ps(point_t p1, point_t p2);
+
+float vec_arg(vec_t v);
+float vec_mag(vec_t v);
+
+inline float rad_to_deg(float a)
+{
+ return 180 / PI * a;
+}
+
vec_t vec_sum(vec_t v1, vec_t v2);
vec_t vec_neg(vec_t v);
void vec_add(vec_t *v1, vec_t v2);
#include "./sound_medium.h"
#include "./lt.h"
#include "./error.h"
+#include "./pi.h"
+#include "./algo.h"
+
+#define SOUND_THRESHOLD_DISTANCE 200.0f
struct sound_medium_t
{
lt_t *lt;
Mix_Chunk **samples;
size_t samples_count;
+ point_t *channel_positions;
};
static int mix_get_free_channel(void)
RETURN_LT(lt, NULL);
}
+ sound_medium->channel_positions = PUSH_LT(lt, malloc(sizeof(point_t) * MIX_CHANNELS), free);
+ if (sound_medium->channel_positions == NULL) {
+ throw_error(ERROR_TYPE_LIBC);
+ RETURN_LT(lt, NULL);
+ }
+
sound_medium->samples = samples;
sound_medium->samples_count = samples_count;
RETURN_LT0(sound_medium->lt);
}
-/* TODO(#134): sound_medium doesn't take into account the positions of the sound and the listener */
int sound_medium_play_sound(sound_medium_t *sound_medium,
size_t sound_index,
point_t position)
const int free_channel = mix_get_free_channel();
if (free_channel >= 0) {
+ sound_medium->channel_positions[free_channel] = position;
return Mix_PlayChannel(free_channel, sound_medium->samples[sound_index], 0);
}
}
point_t position)
{
assert(sound_medium);
- (void) position;
+
+ for (int i = 0; i < MIX_CHANNELS; ++i) {
+ if (Mix_Playing(i)) {
+ const vec_t v = vec_from_ps(position, sound_medium->channel_positions[i]);
+ const Sint16 angle = (Sint16) roundf(rad_to_deg(vec_arg(v)));
+ const Uint8 distance = (Uint8) roundf(MIN(vec_mag(v), SOUND_THRESHOLD_DISTANCE) / SOUND_THRESHOLD_DISTANCE * 255.0f);
+ Mix_SetPosition(i, angle, distance);
+ }
+ }
+
return 0;
}