1 #include <stdlib.h>
2 #include <string.h>
3 #include "audio/audio.h"
4 #include "audio/sink.h"
5 #include "audio/sinks/openal_sink.h"
6 #include "utils/log.h"
7 
8 audio_sink *_global_sink = NULL;
9 
10 struct sink_info_t {
11     int (*sink_init_fn)(audio_sink *sink);
12     const char* name;
13 } sinks[] = {
14 #ifdef USE_OPENAL
15     {openal_sink_init, "openal"},
16 #endif // USE_OPENAL
17 #ifdef USE_SDLAUDIO
18     {sdl_sink_init, "sdl"},
19 #endif // USE_SDLAUDIO
20     {0, 0}
21 };
22 
audio_get_sink_count()23 int audio_get_sink_count() {
24     int count = 0;
25     int sink_id = 0;
26     while(sinks[sink_id++].name != 0) {
27         count++;
28     }
29     return count;
30 }
31 
audio_get_sink_name(int sink_id)32 const char* audio_get_sink_name(int sink_id) {
33     // Get sink
34     if(sink_id < 0 || sink_id >= audio_get_sink_count()) {
35         return NULL;
36     }
37     return sinks[sink_id].name;
38 }
39 
audio_get_first_sink_name()40 const char* audio_get_first_sink_name() {
41     if(audio_get_sink_count() > 0) {
42         return sinks[0].name;
43     }
44     return NULL;
45 }
46 
audio_is_sink_available(const char * sink_name)47 int audio_is_sink_available(const char* sink_name) {
48     for(int i = 0; i < audio_get_sink_count(); i++) {
49         if(strcmp(sink_name, sinks[i].name) == 0) {
50             return 1;
51         }
52     }
53     return 0;
54 }
55 
audio_render()56 void audio_render() {
57     if(_global_sink != NULL) {
58         sink_render(_global_sink);
59     }
60 }
61 
audio_init(const char * sink_name)62 int audio_init(const char* sink_name) {
63     struct sink_info_t si;
64     int found = 0;
65 
66     // If null sink given, disable audio
67     if(sink_name == NULL) {
68         INFO("Audio sink NOT initialized; audio not available.");
69         return 0;
70     }
71 
72     // Find requested sink
73     for(int i = 0; i < audio_get_sink_count(); i++) {
74         if(strcmp(sink_name, sinks[i].name) == 0) {
75             si = sinks[i];
76             found = 1;
77         }
78     }
79     if(!found) {
80         PERROR("Requested audio sink was not found!");
81         return 1;
82     }
83 
84     // Inform user
85     INFO("Using audio sink '%s'.", si.name);
86 
87     // Init sink
88     _global_sink = malloc(sizeof(audio_sink));
89     sink_init(_global_sink);
90     if(si.sink_init_fn(_global_sink) != 0) {
91         free(_global_sink);
92         _global_sink = NULL;
93         return 1;
94     }
95 
96     // Success
97     INFO("Audio system initialized.");
98     return 0;
99 }
100 
audio_close()101 void audio_close() {
102     if(_global_sink != NULL) {
103         sink_free(_global_sink);
104         free(_global_sink);
105         _global_sink = NULL;
106         INFO("Audio system closed.");
107     }
108 }
109 
audio_get_sink()110 audio_sink* audio_get_sink() {
111     return _global_sink;
112 }
113