1 #define AUDIO_BACKEND_AO 1
2 #define AUDIO_BACKEND_SDL 2
3 #define AUDIO_BACKEND_NOP 3
6 #define AUDIO_BACKEND AUDIO_BACKEND_AO
9 #if AUDIO_BACKEND == AUDIO_BACKEND_AO
10 #pragma RcB2 LINK "-lao"
11 #elif AUDIO_BACKEND == AUDIO_BACKEND_SDL
12 #pragma RcB2 LINK "-lSDL_sound" "-lSDL"
17 #if AUDIO_BACKEND == AUDIO_BACKEND_NOP
23 #define audio_init(X) do {} while(0)
24 #define audio_write(X, Y, Z) do {} while(0)
25 #define audio_close(X) do {} while(0)
27 #define AudioCTX NopAudio
29 #elif AUDIO_BACKEND == AUDIO_BACKEND_SDL
33 #include <SDL/SDL_audio.h>
36 pthread_mutex_t cb_lock
;
43 #define alock() pthread_mutex_lock(&self->cb_lock)
44 #define aunlock() pthread_mutex_unlock(&self->cb_lock)
46 static void sdl_callback(void *user
, Uint8
*stream
, int len
) {
47 struct SdlWriter
*self
= user
;
50 if((size_t) len
<= self
->buffer_used
) {
51 memcpy(stream
, self
->buffer
, len
);
52 size_t diff
= self
->buffer_used
- len
;
53 memmove(self
->buffer
, (char*)self
->buffer
+ len
, diff
);
54 self
->buffer_used
= diff
;
65 int SdlWriter_write(struct SdlWriter
*self
, void* buffer
, size_t bufsize
) {
68 if(self
->buffer_used
+ bufsize
> self
->buffer_size
) {
72 memcpy((char*)self
->buffer
+ self
->buffer_used
, buffer
, bufsize
);
73 self
->buffer_used
+= bufsize
;
84 #define NUM_CHANNELS 2
85 int SdlWriter_init(struct SdlWriter
*self
) {
86 SDL_Init(SDL_INIT_AUDIO
);
87 SDL_AudioSpec obtained
;
88 self
->fmt
.freq
= 11025; //44100;
89 self
->fmt
.format
= AUDIO_U8
; //AUDIO_S16;
90 self
->fmt
.channels
= 1; //NUM_CHANNELS;
91 self
->fmt
.samples
= 768; //COREMIXER_MAX_BUFFER;
92 self
->fmt
.callback
= sdl_callback
;
93 self
->fmt
.userdata
= self
;
94 pthread_mutex_init(&self
->cb_lock
, 0);
95 if(SDL_OpenAudio(&self
->fmt
, &obtained
) < 0) {
96 printf("sdl_openaudio: %s\n", SDL_GetError());
99 size_t max
= obtained
.samples
> self
->fmt
.samples
? obtained
.samples
: self
->fmt
.samples
;
100 self
->fmt
= obtained
;
101 /* the buffer must be twice as big as the biggest number of samples processed/consumed */
102 self
->buffer_size
= max
* sizeof(int16_t) * NUM_CHANNELS
* 2;
103 if(!(self
->buffer
= malloc(self
->buffer_size
))) return 0;
104 self
->buffer_used
= 0;
109 int SdlWriter_close(struct SdlWriter
*self
) {
113 self
->buffer_size
= 0;
114 pthread_mutex_destroy(&self
->cb_lock
);
115 SDL_QuitSubSystem(SDL_INIT_AUDIO
);
119 #define audio_init(X) SdlWriter_init(X)
120 #define audio_write(X, Y, Z) SdlWriter_write(X, Y, Z)
121 #define audio_close(X) SdlWriter_close(X)
123 #define AudioCTX SdlWriter
125 #elif AUDIO_BACKEND == AUDIO_BACKEND_AO
131 ao_sample_format format
;
135 int AoWriter_init(struct AoWriter
*self
) {
137 memset(self
, 0, sizeof(*self
));
138 self
->format
.bits
= 8;
139 self
->format
.channels
= 1;
140 self
->format
.rate
= 11025;
141 self
->format
.byte_format
= AO_FMT_LITTLE
;
142 self
->aodriver
= ao_default_driver_id();
143 self
->device
= ao_open_live(self
->aodriver
, &self
->format
, NULL
);
144 return self
->device
!= NULL
;
147 int AoWriter_write(struct AoWriter
*self
, void* buffer
, size_t bufsize
) {
148 return ao_play(self
->device
, buffer
, bufsize
);
151 int AoWriter_close(struct AoWriter
*self
) {
152 return ao_close(self
->device
);
155 #define audio_init(X) AoWriter_init(X)
156 #define audio_write(X, Y, Z) AoWriter_write(X, Y, Z)
157 #define audio_close(X) AoWriter_close(X)
159 #define AudioCTX AoWriter
163 #error unknown AUDIO_BACKEND