6 #include <SDL2/SDL_mixer.h>
8 #include "./sound_medium.h"
14 #define SOUND_THRESHOLD_DISTANCE 1000.0f
21 point_t *channel_positions;
25 size_t channels_count;
28 static int mix_get_free_channel(int lower_channel,
31 assert(lower_channel >= 0);
32 assert(upper_channel >= 0);
33 assert(lower_channel <= upper_channel);
35 for (int i = lower_channel; i < upper_channel; ++i) {
36 if (!Mix_Playing(i)) {
44 static point_t *sound_medium_channel_position(sound_medium_t *sound_medium,
48 assert(sound_medium->lower_channel <= channel_number);
49 assert(channel_number <= sound_medium->upper_channel);
50 return sound_medium->channel_positions + channel_number - sound_medium->lower_channel;
53 sound_medium_t *create_sound_medium(Mix_Chunk **samples,
59 assert(samples_count > 0);
60 assert(lower_channel >= 0);
61 assert(upper_channel >= 0);
62 assert(lower_channel <= upper_channel);
64 lt_t *lt = create_lt();
69 sound_medium_t *sound_medium = PUSH_LT(lt, malloc(sizeof(sound_medium_t)), free);
70 if (sound_medium == NULL) {
71 throw_error(ERROR_TYPE_LIBC);
75 sound_medium->channels_count = (size_t) (upper_channel - lower_channel + 1);
76 sound_medium->channel_positions = PUSH_LT(
78 malloc(sizeof(point_t) * sound_medium->channels_count),
80 if (sound_medium->channel_positions == NULL) {
81 throw_error(ERROR_TYPE_LIBC);
85 sound_medium->samples = samples;
86 sound_medium->samples_count = samples_count;
87 sound_medium->paused = 0;
88 sound_medium->lower_channel = lower_channel;
89 sound_medium->upper_channel = upper_channel;
91 sound_medium->lt = lt;
96 void destroy_sound_medium(sound_medium_t *sound_medium)
99 RETURN_LT0(sound_medium->lt);
102 int sound_medium_play_sound(sound_medium_t *sound_medium,
107 assert(sound_medium);
111 if (sound_index < sound_medium->samples_count) {
112 const int free_channel = mix_get_free_channel(sound_medium->lower_channel,
113 sound_medium->upper_channel);
115 printf("Found free channel: %d\n", free_channel);
117 if (free_channel >= 0) {
118 *sound_medium_channel_position(sound_medium, free_channel) = position;
119 return Mix_PlayChannel(free_channel, sound_medium->samples[sound_index], loops);
126 int sound_medium_listen_sounds(sound_medium_t *sound_medium,
129 assert(sound_medium);
131 for (int i = sound_medium->lower_channel; i <= sound_medium->upper_channel; ++i) {
132 if (Mix_Playing(i)) {
133 const vec_t v = vec_from_ps(position, *sound_medium_channel_position(sound_medium, i));
134 const Sint16 angle = (Sint16) roundf(rad_to_deg(vec_arg(v)));
135 const Uint8 distance = (Uint8) roundf(MIN(vec_mag(v), SOUND_THRESHOLD_DISTANCE) / SOUND_THRESHOLD_DISTANCE * 255.0f);
136 Mix_SetPosition(i, angle, distance);
143 int sound_medium_toggle_pause(sound_medium_t *sound_medium)
145 assert(sound_medium);
147 if (sound_medium->paused) {
153 sound_medium->paused = !sound_medium->paused;