1 #include <stdlib.h>
2 #include <string.h>
3 #include "sexyal.h"
4 #include "convert.h"
5
6
7 /* kludge. yay. */
8 SexyAL_enumdevice *SexyALI_OSS_EnumerateDevices(void);
9 SexyAL_device *SexyALI_OSS_Open(char *id, SexyAL_format *format, SexyAL_buffering *buffering);
10 SexyAL_device *SexyALI_ESD_Open(char *id, SexyAL_format *format, SexyAL_buffering *buffering);
11 SexyAL_device *SexyALI_JACK_Open(char *id, SexyAL_format *format, SexyAL_buffering *buffering);
12 SexyAL_device *SexyALI_SDL_Open(char *id, SexyAL_format *format, SexyAL_buffering *buffering);
13 SexyAL_device *SexyALI_DSound_Open(char *id, SexyAL_format *format, SexyAL_buffering *buffering);
14
FtoB(const SexyAL_format * format,uint32_t frames)15 static uint32_t FtoB(const SexyAL_format *format, uint32_t frames)
16 {
17 return(frames*format->channels*(format->sampformat>>4));
18 }
19 /*
20 static uint32_t BtoF(const SexyAL_format *format, uint32_t bytes)
21 {
22 return(bytes / (format->channels * (format->sampformat>>4)));
23 }
24 */
CanWrite(SexyAL_device * device)25 static uint32_t CanWrite(SexyAL_device *device)
26 {
27 uint32_t bytes,frames;
28
29 bytes=device->RawCanWrite(device);
30 frames=bytes / device->format.channels / (device->format.sampformat>>4);
31
32 return(frames);
33 }
34
Write(SexyAL_device * device,void * data,uint32_t frames)35 static uint32_t Write(SexyAL_device *device, void *data, uint32_t frames)
36 {
37 uint8_t buffer[2048 * 4 * 2]; // Maximum frame size, 4 bytes * 2 channels
38 uint32_t frame_count = 0;
39
40 while(frames)
41 {
42 int32_t tmp;
43 uint32_t fctmp;
44
45 tmp=frames;
46 if(tmp>2048)
47 {
48 tmp=2048;
49 frames-=2048;
50 }
51 else frames-=tmp;
52
53 SexiALI_Convert(&device->srcformat, &device->format, buffer, data, tmp);
54
55 fctmp = device->RawWrite(device,buffer,FtoB(&device->format,tmp));
56 frame_count += fctmp;
57
58 if(fctmp != tmp) /* Uh oh. */
59 return(frame_count);
60 }
61 return(frame_count);
62 }
63
Close(SexyAL_device * device)64 static int Close(SexyAL_device *device)
65 {
66 return(device->RawClose(device));
67 }
68
SetConvert(struct __SexyAL_device * device,SexyAL_format * format)69 int SetConvert(struct __SexyAL_device *device, SexyAL_format *format)
70 {
71 memcpy(&device->srcformat,format,sizeof(SexyAL_format));
72 return(1);
73 }
74
Destroy(SexyAL * iface)75 void Destroy(SexyAL *iface)
76 {
77 free(iface);
78 }
79
80 static SexyAL_driver drivers[] =
81 {
82 #if HAVE_OSSDSP
83 { SEXYAL_TYPE_OSSDSP, "OSS(/dev/dsp*)", "oss", SexyALI_OSS_Open, SexyALI_OSS_EnumerateDevices },
84 #endif
85
86 #if HAVE_JACK
87 { SEXYAL_TYPE_JACK, "JACK", "jack", SexyALI_JACK_Open, NULL },
88 #endif
89
90 #if HAVE_SDL
91 { SEXYAL_TYPE_SDL, "SDL", "sdl", SexyALI_SDL_Open, NULL },
92 #endif
93
94 #if HAVE_ESOUND
95 { SEXYAL_TYPE_ESOUND, "EsounD", "esd", SexyALI_ESD_Open, NULL },
96 #endif
97
98 #if HAVE_DIRECTSOUND
99 { SEXYAL_TYPE_DIRECTSOUND, "DirectSound", "dsound", SexyALI_DSound_Open, NULL },
100 #endif
101
102 { 0, NULL, NULL, NULL, NULL }
103 };
104
FindDriver(int type)105 static SexyAL_driver *FindDriver(int type)
106 {
107 int x = 0;
108
109 while(drivers[x].name)
110 {
111 if(drivers[x].type == type)
112 return(&drivers[x]);
113
114 x++;
115 }
116 return(0);
117 }
118
Open(SexyAL * iface,char * id,SexyAL_format * format,SexyAL_buffering * buffering,int type)119 static SexyAL_device *Open(SexyAL *iface, char *id, SexyAL_format *format, SexyAL_buffering *buffering, int type)
120 {
121 SexyAL_device *ret;
122 SexyAL_driver *driver;
123
124
125 driver = FindDriver(type);
126 if(!driver)
127 return(0);
128
129 if(!(ret = driver->Open(id, format, buffering))) return(0);
130
131 ret->Write=Write;
132 ret->Close=Close;
133 ret->CanWrite=CanWrite;
134 ret->SetConvert=SetConvert;
135
136 return(ret);
137 }
138
EnumerateTypes(SexyAL * sal)139 static SexyAL_enumtype *EnumerateTypes(SexyAL *sal)
140 {
141 SexyAL_enumtype *typies;
142 int numdrivers = sizeof(drivers) / sizeof(SexyAL_driver);
143 int x;
144
145 typies = malloc(numdrivers * sizeof(SexyAL_enumtype));
146 memset(typies, 0, numdrivers * sizeof(SexyAL_enumtype));
147
148 x = 0;
149
150 do
151 {
152 typies[x].name = drivers[x].name;
153 typies[x].short_name = drivers[x].short_name;
154 typies[x].type = drivers[x].type;
155 } while(drivers[x++].name);
156
157 return(typies);
158 }
159
EnumerateDevices(SexyAL * iface,int type)160 static SexyAL_enumdevice * EnumerateDevices(SexyAL *iface, int type)
161 {
162 SexyAL_driver *driver;
163
164 driver = FindDriver(type);
165
166 if(!driver)
167 return(0);
168
169 if(driver->EnumerateDevices)
170 return(driver->EnumerateDevices());
171
172 return(0);
173 }
174
SexyAL_Init(int version)175 void *SexyAL_Init(int version)
176 {
177 SexyAL *iface;
178
179 iface=malloc(sizeof(SexyAL));
180
181 iface->Open=Open;
182 iface->Destroy=Destroy;
183
184 iface->EnumerateTypes = EnumerateTypes;
185 iface->EnumerateDevices = EnumerateDevices;
186 return((void *)iface);
187 }
188