]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - share/examples/isdn/contrib/hplay.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / share / examples / isdn / contrib / hplay.c
1 /*---------------------------------------------------------------------------*
2  *
3  *      rsynth driver to output to 
4  *              - an open isdn4bsd telephone connection         or
5  *              - an output file                                or
6  *              - the /dev/audio device
7  *      ----------------------------------------------------------------
8  *
9  *      tested with rsynth-2.0
10  *
11  *      written by Hellmuth Michaelis (hm@kts.org)
12  *
13  *      last edit-date: [Fri May 25 15:21:33 2001]
14  *
15  * $FreeBSD$
16  *
17  *---------------------------------------------------------------------------*/
18
19 #include <config.h>
20 #include <useconfig.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <errno.h>
24 #include <ctype.h>
25 #include <fcntl.h>
26 #include <sys/file.h>
27 #include <sys/stat.h>
28 #include <sys/param.h>
29 #include <sys/signal.h>
30 #include <sys/ioctl.h>
31
32 #include <i4b/i4b_tel_ioctl.h>
33
34 #include "proto.h"
35 #include "getargs.h"
36 #include "hplay.h"
37 #include "l2u.h"
38
39 #define SAMP_RATE 8000
40 long samp_rate = SAMP_RATE;
41
42 char *prog = "hplay";
43
44 static int use_audio = 1;
45 static int use_isdn = 0;
46 static int unit_no = 0;
47
48 static int audio_fd = -1;
49 static int isdn_fd = -1;
50 static int file_fd = -1;
51
52 char *audio_dev = "/dev/dsp";
53 char *isdn_dev = "/dev/i4btel";
54 static char *ulaw_file = NULL;
55
56 int
57 audio_init(int argc, char *argv[])
58 {
59         char dev[64];
60         int format = CVT_ALAW2ULAW;
61
62         prog = argv[0];
63
64         argc = getargs("FreeBSD audio/i4b/file output driver",argc, argv,
65                 "a", NULL, &use_audio, "use /dev/audio (default)",
66                 "i", NULL, &use_isdn,  "use /dev/i4btel",
67                 "u", "%d", &unit_no,   "/dev/i4btel unit number (def = 0)",
68                 "f", "",   &ulaw_file, "u-law output to file",
69                 NULL);
70
71         if(help_only)
72                 return argc;
73
74         if(ulaw_file)
75         {
76                 if(strcmp(ulaw_file, "-") == 0)
77                 {
78                         file_fd = 1;                 /* stdout */
79                 }
80                 else
81                 {
82                         file_fd = open(ulaw_file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
83                         if(file_fd < 0)
84                                 fprintf(stderr, "ERROR: cannot open %s, error = %s\n", ulaw_file, strerror(errno));
85                 }
86         }
87
88         if(use_isdn)
89         {
90                 sprintf(dev, "%s%d", isdn_dev, unit_no);
91         
92                 if((isdn_fd = open(dev, O_WRONLY)) < 0)
93                 {
94                         fprintf(stderr, "ERROR: cannot open %s, error = %s\n", dev, strerror(errno));
95                 }
96         
97                 if((ioctl(isdn_fd, I4B_TEL_SETAUDIOFMT, &format)) < 0)
98                 {
99                         fprintf(stderr, "ioctl I4B_TEL_SETAUDIOFMT failed: %s", strerror(errno));
100                 }
101         }
102
103         if(use_audio)
104         {
105                 audio_fd = open(audio_dev, O_WRONLY | O_NDELAY);
106                 if(audio_fd < 0)
107                 {
108                         fprintf(stderr, "ERROR: cannot open %s, error = %s\n", audio_dev, strerror(errno));
109                 }
110         }
111
112         return argc;
113 }
114
115 void
116 audio_term()
117 {
118         int format = CVT_NONE;
119
120         if(isdn_fd >= 0)
121         {
122                 if((ioctl(isdn_fd, I4B_TEL_SETAUDIOFMT, &format)) < 0)
123                 {
124                         fprintf(stderr, "ioctl I4B_TEL_SETAUDIOFMT failed: %s", strerror(errno));
125                 }
126                 close(isdn_fd);
127                 isdn_fd = -1;
128         }
129
130         if(audio_fd >= 0)
131         {
132 #if 0
133                 ioctl(audio_fd, SNDCTL_DSP_SYNC, &dummy);
134 #endif
135                 close(audio_fd);
136                 audio_fd = -1;
137         }
138
139         if(file_fd >= 0)
140         {
141                 close(file_fd);
142                 file_fd = -1;
143         }
144 }
145
146 void
147 audio_play(int n, short *data)
148 {
149         int ret;
150         unsigned char *p;
151
152         if (n > 0)
153         {
154                 unsigned char *converted = (unsigned char *) malloc(n);
155                 int i;
156
157                 if(converted == NULL)
158                 {
159                         fprintf(stderr, "Could not allocate memory for conversion\n");
160                         exit(3);
161                 }
162
163                 for (i = 0; i < n; i++)
164                 {
165                         converted[i] = short2ulaw(data[i]);
166                 }
167
168                 if (isdn_fd >= 0)
169                 {
170                         p = converted;
171                         errno = 0;
172                         
173                         while((ret = write(isdn_fd, p, n)) != n)
174                         {
175                                 if(!errno)
176                                 {
177                                         p += ret;
178                                         if(p > (converted + n))
179                                                 break;
180                                 }
181                                 else
182                                 {
183                                         fprintf(stderr, "write /dev/i4btel ERROR: ret (%d) != n (%d), error = %s\n", ret, n, strerror(errno));
184                                         break;
185                                 }
186                         }
187                 }
188
189                 for (i = 0; i < n; i++)
190                         converted[i] = (data[i] - 32768) / 256;
191
192                 if(audio_fd >= 0)
193                 {
194                         p = converted;
195
196                         errno = 0;
197                         
198                         while((ret = write(audio_fd, p, n)) != n)
199                         {
200                                 if(!errno)
201                                 {
202                                         p += ret;
203                                         if(p > (converted + n))
204                                                 break;
205                                 }
206                                 else
207                                 {
208                                         fprintf(stderr, "write /dev/dsp ERROR: ret (%d) != n (%d), error = %s\n", ret, n, strerror(errno));
209                                         break;
210                                 }
211                         }
212                 }
213
214                 if(file_fd >= 0)
215                 {
216                         int ret;
217                         p = converted;
218
219                         errno = 0;
220                         
221                         while((ret = write(file_fd, p, n)) != n)
222                         {
223                                 if(!errno)
224                                 {
225                                         p += ret;
226                                         if(p > (converted + n))
227                                                 break;
228                                 }
229                                 else
230                                 {
231                                         fprintf(stderr, "write file ERROR: ret (%d) != n (%d), error = %s\n", ret, n, strerror(errno));
232                                         break;
233                                 }
234                         }
235                 }
236
237                 free(converted);
238         }
239 }
240
241 /* EOF */