Skip to content

Latest commit

 

History

History
269 lines (217 loc) · 5.4 KB

File metadata and controls

269 lines (217 loc) · 5.4 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*
sgi: audio output on SGI boxen
copyright ?-2013 by the mpg123 project - free software under the terms of the LGPL 2.1
see COPYING and AUTHORS files in distribution or http://mpg123.org
initially written (as it seems) by Thomas Woerner
*/
#include "out123_int.h"
#include <fcntl.h>
#include <dmedia/audio.h>
#include "errno.h"
#include "debug.h"
static int set_rate(out123_handle *ao, ALconfig config)
{
int dev = alGetDevice(config);
ALpv params[1];
/* Make sure the device is OK */
if(dev < 0)
{
error1("set_rate: %s", alGetErrorString(oserror()));
return -1;
}
if(ao->rate > 0)
{
params[0].param = AL_RATE;
params[0].value.ll = alDoubleToFixed((double)ao->rate);
if(alSetParams(dev, params, 1) < 0)
{
error1("set_rate: %s", alGetErrorString(oserror()));
return -1;
}
}
return 0;
}
static int set_channels(out123_handle *ao, ALconfig config)
{
int ret;
if(ao->channels == 2)
ret = alSetChannels(config, AL_STEREO);
else
ret = alSetChannels(config, AL_MONO);
if(ret < 0)
{
error1("set_channels : %s", alGetErrorString(oserror()));
return -1;
}
return 0;
}
static int set_format(out123_handle *ao, ALconfig config)
{
if(ao->format == MPG123_ENC_FLOAT_32)
{
if(alSetSampFmt(config, AL_SAMPFMT_FLOAT) < 0)
{
error1("SetSampFmt: %s", alGetErrorString(oserror()));
return -1;
}
} else
{
if(alSetSampFmt(config, AL_SAMPFMT_TWOSCOMP) < 0)
{
error1("SetSampFmt: %s", alGetErrorString(oserror()));
return -1;
}
if(alSetWidth(config, AL_SAMPLE_16) < 0)
{
error1("SetWidth: %s", alGetErrorString(oserror()));
return -1;
}
}
return 0;
}
static int open_sgi(out123_handle *ao)
{
int current_dev;
ALport port = NULL;
ALconfig config = alNewConfig();
ao->userptr = NULL;
/* Test for correct completion */
if(config == 0)
{
error1("open_sgi: %s", alGetErrorString(oserror()));
return -1;
}
/* Setup output device to specified device name. If there is no device name
specified in ao structure, use the default for output */
if((ao->device) != NULL)
{
current_dev = alGetResourceByName(AL_SYSTEM, ao->device, AL_OUTPUT_DEVICE_TYPE);
debug2("Dev: %s %i", ao->device, current_dev);
if(!current_dev)
{
int i, numOut;
char devname[32];
ALpv pv[1];
ALvalue *alvalues;
error2("Invalid audio resource: %s (%s)", ao->device, alGetErrorString(oserror()));
if((numOut= alQueryValues(AL_SYSTEM,AL_DEFAULT_OUTPUT,0,0,0,0))>=0)
fprintf(stderr, "There are %d output devices on this system.\n", numOut);
else
{
fprintf(stderr, "Can't find output devices. alQueryValues failed: %s\n", alGetErrorString(oserror()));
goto open_sgi_bad;
}
alvalues = malloc(sizeof(ALvalue) * numOut);
i = alQueryValues(AL_SYSTEM, AL_DEFAULT_OUTPUT, alvalues, numOut, pv, 0);
if(i == -1)
error1("alQueryValues: %s", alGetErrorString(oserror()));
else
{
for(i=0; i < numOut; i++)
{
pv[0].param = AL_NAME;
pv[0].value.ptr = devname;
pv[0].sizeIn = 32;
alGetParams(alvalues[i].i, pv, 1);
fprintf(stderr, "%i: %s\n", i, devname);
}
}
free(alvalues);
goto open_sgi_bad;
}
if(alSetDevice(config, current_dev) < 0)
{
error1("open: alSetDevice : %s",alGetErrorString(oserror()));
goto open_sgi_bad;
}
} else
current_dev = AL_DEFAULT_OUTPUT;
/* Set the device */
if(alSetDevice(config, current_dev) < 0)
{
error1("open_sgi: %s", alGetErrorString(oserror()));
goto open_sgi_bad;
}
/* Set port parameters */
if(alSetQueueSize(config, 131069) < 0)
{
error1("open_sgi: setting audio buffer failed: %s", alGetErrorString(oserror()));
goto open_sgi_bad;
}
if( set_format(ao, config) < 0
|| set_rate(ao, config) < 0
|| set_channels(ao, config) < 0 )
goto open_sgi_bad;
/* Open the audio port */
port = alOpenPort("mpg123-VSC", "w", config);
if(port == NULL)
{
error1("Unable to open audio channel: %s", alGetErrorString(oserror()));
goto open_sgi_bad;
}
ao->userptr = (void*)port;
alFreeConfig(config);
return 1;
open_sgi_bad:
/* clean up and return error */
alFreeConfig(config);
return -1;
}
static int get_formats_sgi(out123_handle *ao)
{
return MPG123_ENC_SIGNED_16|MPG123_ENC_FLOAT_32;
}
static int write_sgi(out123_handle *ao, unsigned char *buf, int len)
{
int length = len;
if(!ao || !ao->userptr) return -1;
ALport port = (ALport)ao->userptr;
if(ao->channels == 2) length >>= 2;
else length >>= 1;
if(ao->format == MPG123_ENC_FLOAT_32) length >>=1;
/* Not much error checking ... */
alWriteFrames(port, buf, length);
return len;
}
static int close_sgi(out123_handle *ao)
{
if(!ao || !ao->userptr) return -1;
ALport port = (ALport)ao->userptr;
if(port)
{
/* play all remaining samples */
while(alGetFilled(port) > 0) sginap(1);
alClosePort(port);
ao->userptr=NULL;
}
return 0;
}
static void flush_sgi(out123_handle *ao)
{
ALport port = (ALport)ao->userptr;
if(port) alDiscardFrames(port, alGetFilled(port));
}
static int init_sgi(out123_handle* ao)
{
if(ao == NULL) return -1;
/* Set callbacks */
ao->open = open_sgi;
ao->flush = flush_sgi;
ao->write = write_sgi;
ao->get_formats = get_formats_sgi;
ao->close = close_sgi;
/* Success */
return 0;
}
/*
Module information data structure
*/
mpg123_module_t mpg123_output_module_info =
{
/* api_version */ MPG123_MODULE_API_VERSION,
/* name */ "sgi",
/* description */ "Audio output for SGI.",
/* revision */ "$Rev:$",
/* handle */ NULL,
/* init_output */ init_sgi,
};