1 /* gAlan - Graphical Audio Language
2 * Copyright (C) 1999 Tony Garnock-Jones
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <sys/types.h>
24 #include <sys/ioctl.h>
25 #include <sys/soundcard.h>
33 #include "generator.h"
40 #define DEFAULT_FRAGMENT_EXPONENT 12
44 typedef signed short OUTPUTSAMPLE
;
51 PRIVATE
int instance_count
= 0;
52 PRIVATE
char dspname
[256];
53 PRIVATE
int audio_fragment_exponent
= DEFAULT_FRAGMENT_EXPONENT
;
54 PRIVATE gboolean eightbit_in
= FALSE
;
56 PRIVATE
int open_audiofd(void) {
60 audiofd
= open(dspname
, O_RDONLY
);
62 perror("open_audiofd/oss_input");
65 RETURN_VAL_UNLESS(audiofd
!= -1, -1);
67 i
= (4 << 16) | audio_fragment_exponent
; /* 4 buffers */
68 RETURN_VAL_UNLESS(ioctl(audiofd
, SNDCTL_DSP_SETFRAGMENT
, &i
) != -1, -1);
70 i
= eightbit_in
? AFMT_S8
: AFMT_S16_NE
;
72 RETURN_VAL_UNLESS(ioctl(audiofd
, SNDCTL_DSP_SETFMT
, &i
) != -1, -1);
75 RETURN_VAL_UNLESS(ioctl(audiofd
, SNDCTL_DSP_STEREO
, &i
) != -1, -1);
78 RETURN_VAL_UNLESS(ioctl(audiofd
, SNDCTL_DSP_SPEED
, &i
) != -1, -1);
83 PRIVATE gboolean
init_instance(Generator
*g
) {
87 if (instance_count
> 1)
88 /* Not allowed more than one of these things. */
91 data
= safe_malloc(sizeof(Data
));
93 data
->audiofd
= open_audiofd();
95 data
->preread
= FALSE
;
96 if (data
->audiofd
< 0) {
98 popup_msgbox("Error", MSGBOX_OK
, 120000, MSGBOX_OK
,
99 "Could not open audio device, %s.", dspname
);
108 PRIVATE
void destroy_instance(Generator
*g
) {
109 Data
*data
= g
->data
;
112 close(data
->audiofd
);
120 PRIVATE gboolean
output_generator(Generator
*g
, SAMPLE
*buf
, int buflen
) {
121 Data
*data
= g
->data
;
126 gint8 samp
[MAXIMUM_REALTIME_STEP
];
128 if( ! data
->preread
) {
129 data
->preread
= TRUE
;
133 if (read(data
->audiofd
, samp
, sizeof(gint8
) * buflen
) < sizeof(gint8
) * buflen
) {
134 printf("."); fflush(stdout
);
137 for (i
= 0; i
< buflen
; i
++)
138 buf
[i
] = samp
[i
] / 128.0;
142 gint16 samp
[MAXIMUM_REALTIME_STEP
];
144 if( ! data
->preread
) {
145 data
->preread
= TRUE
;
149 if (read(data
->audiofd
, samp
, sizeof(gint16
) * buflen
) < sizeof(gint16
) * buflen
) {
150 printf("."); fflush(stdout
);
153 for (i
= 0; i
< buflen
; i
++)
154 buf
[i
] = samp
[i
] / 32768.0;
160 PRIVATE OutputSignalDescriptor output_sigs
[] = {
161 { "Output", SIG_FLAG_REALTIME
, { output_generator
, } },
165 PRIVATE
void setup_class(void) {
170 char *value
= prefs_get_item("input_plugin");
171 prefer
= value
? !strcmp(value
, "OSS") : FALSE
;
173 prefs_register_option("input_plugin", "OSS");
176 char *name
= prefs_get_item("input_oss_device");
177 sprintf(dspname
, "%s", name
? name
: "/dev/dsp");
179 prefs_register_option("input_oss_device", "/dev/dsp");
180 prefs_register_option("input_oss_device", "/dev/dsp0");
181 prefs_register_option("input_oss_device", "/dev/dsp1");
184 char *name
= prefs_get_item("input_oss_fragment_size");
186 if (name
== NULL
|| sscanf(name
, "%d", &audio_fragment_exponent
) != 1) {
187 audio_fragment_exponent
= DEFAULT_FRAGMENT_EXPONENT
;
190 audio_fragment_exponent
= MAX(audio_fragment_exponent
, 7);
192 prefs_register_option("input_oss_fragment_size", "7");
193 prefs_register_option("input_oss_fragment_size", "8");
194 prefs_register_option("input_oss_fragment_size", "9");
195 prefs_register_option("input_oss_fragment_size", "10");
196 prefs_register_option("input_oss_fragment_size", "11");
197 prefs_register_option("input_oss_fragment_size", "12");
198 prefs_register_option("input_oss_fragment_size", "13");
199 prefs_register_option("input_oss_fragment_size", "14");
200 prefs_register_option("input_oss_fragment_size", "15");
201 prefs_register_option("input_oss_fragment_size", "16");
204 char *num_bits
= prefs_get_item("input_oss_bits");
206 if (num_bits
== NULL
|| ( strcmp( num_bits
, "16" ) && strcmp( num_bits
, "8" ) ) )
209 eightbit_in
= strcmp(num_bits
, "8" ) ? FALSE
: TRUE
;
211 prefs_register_option("input_oss_bits", "16");
212 prefs_register_option("input_oss_bits", "8");
214 k
= gen_new_generatorclass("audio_in", prefer
, 0, 0,
215 NULL
, output_sigs
, NULL
,
216 init_instance
, destroy_instance
,
217 (AGenerator_pickle_t
) init_instance
, NULL
);
219 gencomp_register_generatorclass(k
, prefer
, "Sources/OSS Input",
224 PUBLIC
void init_plugin(void) {