missing commit in generator.h
[galan.git] / plugins / liboss_input.c
blob75b5600a02120ee92b2827859a82106bd1f35b40
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
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
23 #include <sys/types.h>
24 #include <sys/ioctl.h>
25 #include <sys/soundcard.h>
26 #include <fcntl.h>
27 #include <unistd.h>
29 #include <gdk/gdk.h>
30 #include <gtk/gtk.h>
32 #include "global.h"
33 #include "generator.h"
34 #include "comp.h"
35 #include "control.h"
36 #include "gencomp.h"
37 #include "msgbox.h"
38 #include "prefs.h"
40 #define DEFAULT_FRAGMENT_EXPONENT 12
42 #define SIG_OUTPUT 0
44 typedef signed short OUTPUTSAMPLE;
46 typedef struct Data {
47 int audiofd;
48 gboolean preread;
49 } Data;
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) {
57 int i;
58 int audiofd;
60 audiofd = open(dspname, O_RDONLY);
61 if (audiofd == -1) {
62 perror("open_audiofd/oss_input");
63 return -1;
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);
74 i = 0;
75 RETURN_VAL_UNLESS(ioctl(audiofd, SNDCTL_DSP_STEREO, &i) != -1, -1);
77 i = SAMPLE_RATE;
78 RETURN_VAL_UNLESS(ioctl(audiofd, SNDCTL_DSP_SPEED, &i) != -1, -1);
80 return audiofd;
83 PRIVATE gboolean init_instance(Generator *g) {
84 Data *data;
86 instance_count++;
87 if (instance_count > 1)
88 /* Not allowed more than one of these things. */
89 return 0;
91 data = safe_malloc(sizeof(Data));
93 data->audiofd = open_audiofd();
95 data->preread = FALSE;
96 if (data->audiofd < 0) {
97 free(data);
98 popup_msgbox("Error", MSGBOX_OK, 120000, MSGBOX_OK,
99 "Could not open audio device, %s.", dspname);
100 return 0;
103 g->data = data;
105 return TRUE;
108 PRIVATE void destroy_instance(Generator *g) {
109 Data *data = g->data;
111 if (data != NULL) {
112 close(data->audiofd);
114 free(data);
117 instance_count--;
120 PRIVATE gboolean output_generator(Generator *g, SAMPLE *buf, int buflen) {
121 Data *data = g->data;
122 int i;
124 if( eightbit_in )
126 gint8 samp[MAXIMUM_REALTIME_STEP];
128 if( ! data->preread ) {
129 data->preread = TRUE;
130 return FALSE;
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;
140 else
142 gint16 samp[MAXIMUM_REALTIME_STEP];
144 if( ! data->preread ) {
145 data->preread = TRUE;
146 return FALSE;
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;
157 return TRUE;
160 PRIVATE OutputSignalDescriptor output_sigs[] = {
161 { "Output", SIG_FLAG_REALTIME, { output_generator, } },
162 { NULL, }
165 PRIVATE void setup_class(void) {
166 GeneratorClass *k;
167 gboolean prefer;
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" ) ) )
207 eightbit_in = FALSE;
208 else
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",
220 NULL,
221 NULL);
224 PUBLIC void init_plugin(void) {
225 setup_class();