]> git.lizzy.rs Git - nothing.git/blob - src/sound_medium.c
Naive MIN/MAX todo
[nothing.git] / src / sound_medium.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4
5 #include <SDL2/SDL.h>
6 #include <SDL2/SDL_mixer.h>
7
8 #include "./sound_medium.h"
9 #include "./lt.h"
10 #include "./error.h"
11 #include "./pi.h"
12 #include "./algo.h"
13
14 struct sound_medium_t
15 {
16     lt_t *lt;
17     Mix_Chunk **samples;
18     size_t samples_count;
19     int paused;
20     int lower_channel;
21     int upper_channel;
22     size_t channels_count;
23 };
24
25 static int mix_get_free_channel(int lower_channel,
26                                 int upper_channel)
27 {
28     assert(lower_channel >= 0);
29     assert(upper_channel >= 0);
30     assert(lower_channel <= upper_channel);
31
32     for (int i = lower_channel; i < upper_channel; ++i) {
33         if (!Mix_Playing(i)) {
34             return i;
35         }
36     }
37
38     return -1;
39 }
40
41 sound_medium_t *create_sound_medium(Mix_Chunk **samples,
42                                     size_t samples_count,
43                                     int lower_channel,
44                                     int upper_channel)
45 {
46     assert(samples);
47     assert(samples_count > 0);
48     assert(lower_channel >= 0);
49     assert(upper_channel >= 0);
50     assert(lower_channel <= upper_channel);
51
52     lt_t *lt = create_lt();
53     if (lt == NULL) {
54         return NULL;
55     }
56
57     sound_medium_t *sound_medium = PUSH_LT(lt, malloc(sizeof(sound_medium_t)), free);
58     if (sound_medium == NULL) {
59         throw_error(ERROR_TYPE_LIBC);
60         RETURN_LT(lt, NULL);
61     }
62
63     sound_medium->channels_count = (size_t) (upper_channel - lower_channel + 1);
64     sound_medium->samples = samples;
65     sound_medium->samples_count = samples_count;
66     sound_medium->paused = 0;
67     sound_medium->lower_channel = lower_channel;
68     sound_medium->upper_channel = upper_channel;
69
70     sound_medium->lt = lt;
71
72     return sound_medium;
73 }
74
75 void destroy_sound_medium(sound_medium_t *sound_medium)
76 {
77     assert(sound_medium);
78     RETURN_LT0(sound_medium->lt);
79 }
80
81 int sound_medium_play_sound(sound_medium_t *sound_medium,
82                             size_t sound_index,
83                             point_t position,
84                             int loops)
85 {
86     assert(sound_medium);
87     (void) sound_index;
88     (void) position;
89
90     if (sound_index < sound_medium->samples_count) {
91         const int free_channel = mix_get_free_channel(sound_medium->lower_channel,
92                                                       sound_medium->upper_channel);
93
94         printf("Found free channel: %d\n", free_channel);
95
96         if (free_channel >= 0) {
97             return Mix_PlayChannel(free_channel, sound_medium->samples[sound_index], loops);
98         }
99     }
100
101     return 0;
102 }
103
104 int sound_medium_toggle_pause(sound_medium_t *sound_medium)
105 {
106     assert(sound_medium);
107
108     if (sound_medium->paused) {
109         Mix_Resume(-1);
110     } else {
111         Mix_Pause(-1);
112     }
113
114     sound_medium->paused = !sound_medium->paused;
115
116     return 0;
117 }